[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n.idea/\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbuild/\nbld/\n[Bb]in/\n[Oo]bj/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n## TODO: Comment the next line if you want to checkin your\n## web deploy settings but do note that will include unencrypted\n## passwords\n#*.pubxml\n\n*.publishproj\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n\n# Windows Azure Build Output\ncsx/\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# LightSwitch generated files\nGeneratedArtifacts/\n_Pvt_Extensions/\nModelManifest.xml\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"VkLib\"]\n\tpath = VkLib\n\turl = https://github.com/artemshuba/VkLib.git\n"
  },
  {
    "path": ".nuget/NuGet.Config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <solution>\n    <add key=\"disableSourceControlIntegration\" value=\"true\" />\n  </solution>\n</configuration>"
  },
  {
    "path": ".nuget/NuGet.targets",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n    <PropertyGroup>\n        <SolutionDir Condition=\"$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'\">$(MSBuildProjectDirectory)\\..\\</SolutionDir>\n\n        <!-- Enable the restore command to run before builds -->\n        <RestorePackages Condition=\"  '$(RestorePackages)' == '' \">false</RestorePackages>\n\n        <!-- Property that enables building a package from a project -->\n        <BuildPackage Condition=\" '$(BuildPackage)' == '' \">false</BuildPackage>\n\n        <!-- Determines if package restore consent is required to restore packages -->\n        <RequireRestoreConsent Condition=\" '$(RequireRestoreConsent)' != 'false' \">true</RequireRestoreConsent>\n\n        <!-- Download NuGet.exe if it does not already exist -->\n        <DownloadNuGetExe Condition=\" '$(DownloadNuGetExe)' == '' \">false</DownloadNuGetExe>\n    </PropertyGroup>\n\n    <ItemGroup Condition=\" '$(PackageSources)' == '' \">\n        <!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\\NuGet\\NuGet.Config will be used -->\n        <!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->\n        <!--\n            <PackageSource Include=\"https://www.nuget.org/api/v2/\" />\n            <PackageSource Include=\"https://my-nuget-source/nuget/\" />\n        -->\n    </ItemGroup>\n\n    <PropertyGroup Condition=\" '$(OS)' == 'Windows_NT'\">\n        <!-- Windows specific commands -->\n        <NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), \".nuget\"))</NuGetToolsPath>\n    </PropertyGroup>\n\n    <PropertyGroup Condition=\" '$(OS)' != 'Windows_NT'\">\n        <!-- We need to launch nuget.exe with the mono command if we're not on windows -->\n        <NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>\n    </PropertyGroup>\n\n    <PropertyGroup>\n        <PackagesProjectConfig Condition=\" '$(OS)' == 'Windows_NT'\">$(MSBuildProjectDirectory)\\packages.$(MSBuildProjectName.Replace(' ', '_')).config</PackagesProjectConfig>\n        <PackagesProjectConfig Condition=\" '$(OS)' != 'Windows_NT'\">$(MSBuildProjectDirectory)\\packages.$(MSBuildProjectName).config</PackagesProjectConfig>\n    </PropertyGroup>\n\n    <PropertyGroup>\n      <PackagesConfig Condition=\"Exists('$(MSBuildProjectDirectory)\\packages.config')\">$(MSBuildProjectDirectory)\\packages.config</PackagesConfig>\n      <PackagesConfig Condition=\"Exists('$(PackagesProjectConfig)')\">$(PackagesProjectConfig)</PackagesConfig>\n    </PropertyGroup>\n    \n    <PropertyGroup>\n        <!-- NuGet command -->\n        <NuGetExePath Condition=\" '$(NuGetExePath)' == '' \">$(NuGetToolsPath)\\NuGet.exe</NuGetExePath>\n        <PackageSources Condition=\" $(PackageSources) == '' \">@(PackageSource)</PackageSources>\n\n        <NuGetCommand Condition=\" '$(OS)' == 'Windows_NT'\">\"$(NuGetExePath)\"</NuGetCommand>\n        <NuGetCommand Condition=\" '$(OS)' != 'Windows_NT' \">mono --runtime=v4.0.30319 \"$(NuGetExePath)\"</NuGetCommand>\n\n        <PackageOutputDir Condition=\"$(PackageOutputDir) == ''\">$(TargetDir.Trim('\\\\'))</PackageOutputDir>\n\n        <RequireConsentSwitch Condition=\" $(RequireRestoreConsent) == 'true' \">-RequireConsent</RequireConsentSwitch>\n        <NonInteractiveSwitch Condition=\" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' \">-NonInteractive</NonInteractiveSwitch>\n\n        <PaddedSolutionDir Condition=\" '$(OS)' == 'Windows_NT'\">\"$(SolutionDir) \"</PaddedSolutionDir>\n        <PaddedSolutionDir Condition=\" '$(OS)' != 'Windows_NT' \">\"$(SolutionDir)\"</PaddedSolutionDir>\n\n        <!-- Commands -->\n        <RestoreCommand>$(NuGetCommand) install \"$(PackagesConfig)\" -source \"$(PackageSources)\"  $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>\n        <BuildCommand>$(NuGetCommand) pack \"$(ProjectPath)\" -Properties \"Configuration=$(Configuration);Platform=$(Platform)\" $(NonInteractiveSwitch) -OutputDirectory \"$(PackageOutputDir)\" -symbols</BuildCommand>\n\n        <!-- We need to ensure packages are restored prior to assembly resolve -->\n        <BuildDependsOn Condition=\"$(RestorePackages) == 'true'\">\n            RestorePackages;\n            $(BuildDependsOn);\n        </BuildDependsOn>\n\n        <!-- Make the build depend on restore packages -->\n        <BuildDependsOn Condition=\"$(BuildPackage) == 'true'\">\n            $(BuildDependsOn);\n            BuildPackage;\n        </BuildDependsOn>\n    </PropertyGroup>\n\n    <Target Name=\"CheckPrerequisites\">\n        <!-- Raise an error if we're unable to locate nuget.exe  -->\n        <Error Condition=\"'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')\" Text=\"Unable to locate '$(NuGetExePath)'\" />\n        <!--\n        Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.\n        This effectively acts as a lock that makes sure that the download operation will only happen once and all\n        parallel builds will have to wait for it to complete.\n        -->\n        <MsBuild Targets=\"_DownloadNuGet\" Projects=\"$(MSBuildThisFileFullPath)\" Properties=\"Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)\" />\n    </Target>\n\n    <Target Name=\"_DownloadNuGet\">\n        <DownloadNuGet OutputFilename=\"$(NuGetExePath)\" Condition=\" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')\" />\n    </Target>\n\n    <Target Name=\"RestorePackages\" DependsOnTargets=\"CheckPrerequisites\">        \n        <Exec Command=\"$(RestoreCommand)\"\n              Condition=\"'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')\" />\n\n        <Exec Command=\"$(RestoreCommand)\"\n              LogStandardErrorAsError=\"true\"\n              Condition=\"'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')\" />\n    </Target>\n\n    <Target Name=\"BuildPackage\" DependsOnTargets=\"CheckPrerequisites\">\n        <Exec Command=\"$(BuildCommand)\"\n              Condition=\" '$(OS)' != 'Windows_NT' \" />\n\n        <Exec Command=\"$(BuildCommand)\"\n              LogStandardErrorAsError=\"true\"\n              Condition=\" '$(OS)' == 'Windows_NT' \" />\n    </Target>\n\n    <UsingTask TaskName=\"DownloadNuGet\" TaskFactory=\"CodeTaskFactory\" AssemblyFile=\"$(MSBuildToolsPath)\\Microsoft.Build.Tasks.v4.0.dll\">\n        <ParameterGroup>\n            <OutputFilename ParameterType=\"System.String\" Required=\"true\" />\n        </ParameterGroup>\n        <Task>\n            <Reference Include=\"System.Core\" />\n            <Using Namespace=\"System\" />\n            <Using Namespace=\"System.IO\" />\n            <Using Namespace=\"System.Net\" />\n            <Using Namespace=\"Microsoft.Build.Framework\" />\n            <Using Namespace=\"Microsoft.Build.Utilities\" />\n            <Code Type=\"Fragment\" Language=\"cs\">\n                <![CDATA[\n                try {\n                    OutputFilename = Path.GetFullPath(OutputFilename);\n\n                    Log.LogMessage(\"Downloading latest version of NuGet.exe...\");\n                    WebClient webClient = new WebClient();\n                    webClient.DownloadFile(\"https://www.nuget.org/nuget.exe\", OutputFilename);\n\n                    return true;\n                }\n                catch (Exception ex) {\n                    Log.LogErrorFromException(ex);\n                    return false;\n                }\n            ]]>\n            </Code>\n        </Task>\n    </UsingTask>\n</Project>\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   Copyright 2014 Artem Shuba\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Album/LastFmAlbum.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing LastFmLib.Core.Track;\nusing Newtonsoft.Json.Linq;\n\nnamespace LastFmLib.Core.Album\n{\n    public class LastFmAlbum\n    {\n        public string Mbid { get; set; }\n        public string Name { get; set; }\n        public string Artist { get; set; }\n        public string ImageSmall { get; set; }\n        public string ImageMedium { get; set; }\n        public string ImageLarge { get; set; }\n        public string ImageExtraLarge { get; set; }\n        public string ImageMega { get; set; }\n\n        public List<LastFmTrack> Tracks { get; set; }\n        public List<string> TopTags { get; set; }\n\n        public static LastFmAlbum FromJson(JToken json)\n        {\n            if (json == null)\n                throw new ArgumentException(\"Json can not be null.\");\n\n            var result = new LastFmAlbum();\n            if (json[\"mbid\"] != null)\n                result.Mbid = json[\"mbid\"].Value<string>();\n            result.Name = json[\"name\"].Value<string>();\n            if (json[\"artist\"] != null)\n            {\n                if (!json[\"artist\"].HasValues)\n                    result.Artist = json[\"artist\"].Value<string>();\n                else\n                {\n                    result.Artist = json[\"artist\"][\"name\"].Value<string>();\n                }\n            }\n\n            var imageToken = json[\"image\"];\n            if (imageToken != null)\n            {\n                foreach (var image in imageToken.Children())\n                {\n                    switch (image[\"size\"].Value<string>())\n                    {\n                        case \"small\":\n                            result.ImageSmall = image[\"#text\"].Value<string>();\n                            break;\n                        case \"medium\":\n                            result.ImageMedium = image[\"#text\"].Value<string>();\n                            break;\n                        case \"large\":\n                            result.ImageLarge = image[\"#text\"].Value<string>();\n                            break;\n                        case \"extralarge\":\n                            result.ImageExtraLarge = image[\"#text\"].Value<string>();\n                            break;\n                    }\n                }\n            }\n\n            if (json.SelectToken(\"tracks.track\") != null)\n            {\n                result.Tracks = new List<LastFmTrack>();\n\n                var trackJson = json.SelectToken(\"tracks.track\");\n                if (trackJson is JArray)\n                    result.Tracks.AddRange((from a in trackJson select LastFmTrack.FromJson(a)).ToList());\n                else\n                    result.Tracks.Add(LastFmTrack.FromJson(trackJson));\n            }\n\n            if (json.SelectToken(\"toptags.tag\") != null)\n            {\n                result.TopTags = new List<string>();\n                foreach (var tagToken in json.SelectToken(\"toptags.tag\"))\n                {\n                    if (tagToken is JProperty)\n                        result.TopTags.Add(((JProperty)tagToken).Value.Value<string>());\n                    else\n                        result.TopTags.Add(tagToken[\"name\"].Value<string>());\n                }\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Album/LastFmAlbumRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json.Linq;\n\nnamespace LastFmLib.Core.Album\n{\n    public class LastFmAlbumRequest\n    {\n        private readonly LastFm _lastFm;\n\n        public LastFmAlbumRequest(LastFm lastFm)\n        {\n            _lastFm = lastFm;\n        }\n\n        public async Task<List<LastFmAlbum>> Search(string album)\n        {\n            var parameters = new Dictionary<string, string>();\n            parameters.Add(\"album\", album);\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"album.search\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response.SelectToken(\"results.albummatches.album\") != null)\n            {\n                var albumJson = response.SelectToken(\"results.albummatches.album\");\n                if (albumJson is JArray)\n                    return\n                        (from a in response.SelectToken(\"results.albummatches.album\") select LastFmAlbum.FromJson(a)).ToList();\n                else\n                    return new List<LastFmAlbum>() { LastFmAlbum.FromJson(albumJson) };\n            }\n\n            return null;\n        }\n\n        public async Task<LastFmAlbum> GetInfo(string mbid, string album, string artist, bool autoCorrect = true)\n        {\n            var parameters = new Dictionary<string, string>();\n            if (!string.IsNullOrEmpty(mbid))\n                parameters.Add(\"mbid\", mbid);\n            else\n            {\n                parameters.Add(\"album\", album);\n                parameters.Add(\"artist\", artist);\n            }\n\n            if (autoCorrect)\n                parameters.Add(\"autocorrect\", \"1\");\n\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"album.getInfo\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response[\"album\"] != null)\n            {\n                return LastFmAlbum.FromJson(response[\"album\"]);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Artist/LastFmArtist.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Newtonsoft.Json.Linq;\n\nnamespace LastFmLib.Core.Artist\n{\n    public class LastFmArtist\n    {\n        public string Name { get; set; }\n        public string Mbid { get; set; }\n        public string ImageSmall { get; set; }\n        public string ImageMedium { get; set; }\n        public string ImageLarge { get; set; }\n        public string ImageExtraLarge { get; set; }\n        public string ImageMega { get; set; }\n\n        public List<string> TopTags { get; set; }\n\n        public List<LastFmArtist> SimilarArtists { get; set; }\n\n        public string Bio { get; set; }\n\n        public static LastFmArtist FromJson(JToken json)\n        {\n            if (json == null)\n                throw new ArgumentException(\"Json can not be null.\");\n\n            var result = new LastFmArtist();\n            result.Name = json[\"name\"].Value<string>();\n            if (json[\"mbid\"] != null)\n                result.Mbid = json[\"mbid\"].Value<string>();\n\n            var imageToken = json[\"image\"];\n            if (imageToken != null)\n            {\n                foreach (var image in imageToken.Children())\n                {\n                    if (image[\"#text\"] == null)\n                        continue;\n\n                    switch (image[\"size\"].Value<string>())\n                    {\n                        case \"small\":\n                            result.ImageSmall = image[\"#text\"].Value<string>();\n                            break;\n                        case \"medium\":\n                            result.ImageMedium = image[\"#text\"].Value<string>();\n                            break;\n                        case \"large\":\n                            result.ImageLarge = image[\"#text\"].Value<string>();\n                            break;\n                        case \"extralarge\":\n                            result.ImageExtraLarge = image[\"#text\"].Value<string>();\n                            break;\n                        case \"mega\":\n                            result.ImageMega = image[\"#text\"].Value<string>();\n                            break;\n                    }\n                }\n            }\n\n            if (json.SelectToken(\"tags.tag\") != null)\n            {\n                result.TopTags = new List<string>();\n                var tagToken = json.SelectToken(\"tags.tag\");\n                if (tagToken is JArray)\n                {\n                    foreach (var t in tagToken)\n                    {\n                        result.TopTags.Add(t[\"name\"].Value<string>());\n                    }\n                }\n                else\n                {\n                    result.TopTags.Add(tagToken[\"name\"].Value<string>());\n                }\n            }\n\n            if (json.SelectToken(\"similar.artist\") != null)\n            {\n                result.SimilarArtists = new List<LastFmArtist>();\n                var similarToken = json.SelectToken(\"similar.artist\");\n                if (similarToken is JArray)\n                {\n                    foreach (var artistToken in similarToken)\n                    {\n                        result.SimilarArtists.Add(FromJson(artistToken));\n                    }\n                }\n                else\n                {\n                    result.SimilarArtists.Add(FromJson(similarToken));\n                }\n            }\n\n            if (json.SelectToken(\"bio.summary\") != null)\n            {\n                result.Bio = json.SelectToken(\"bio.summary\").Value<string>().Trim();\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Artist/LastFmArtistRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing LastFmLib.Core.Album;\nusing LastFmLib.Core.Image;\nusing LastFmLib.Core.Track;\nusing Newtonsoft.Json.Linq;\n\nnamespace LastFmLib.Core.Artist\n{\n    public class LastFmArtistRequest\n    {\n        private readonly LastFm _lastFm;\n\n        public LastFmArtistRequest(LastFm lastFm)\n        {\n            _lastFm = lastFm;\n        }\n\n        [Obsolete(\"Last.FM no longer provides method artist.getImages.\", true)]\n        public async Task<List<LastFmImage>> GetImages(string artist, string mbid, int limit, bool autoCorrect = true, int minWidth = 500, int minHeight = 200)\n        {\n            var parameters = new Dictionary<string, string>();\n\n            if (!string.IsNullOrEmpty(mbid))\n                parameters.Add(\"mbid\", mbid);\n            else\n                parameters.Add(\"artist\", artist);\n\n            if (autoCorrect)\n                parameters.Add(\"autocorrect\", \"1\");\n\n            if (limit > 0)\n                parameters.Add(\"limit\", limit.ToString());\n\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"artist.getImages\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n            if (response[\"images\"] != null && response[\"images\"][\"image\"] != null)\n            {\n                var ie = new List<LastFmImage>();\n                foreach (var image in response[\"images\"][\"image\"])\n                {\n                    ie.Add(LastFmImage.FromJson(image));\n                }\n                return ie;\n            }\n\n            return null;\n        }\n\n\n        public async Task<List<LastFmArtist>> Search(string artist)\n        {\n            var parameters = new Dictionary<string, string>();\n            parameters.Add(\"artist\", artist);\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"artist.search\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response.SelectToken(\"results.artistmatches.artist\") != null)\n            {\n\n                var artistJson = response.SelectToken(\"results.artistmatches.artist\");\n                if (artistJson is JArray)\n                    return (from a in response.SelectToken(\"results.artistmatches.artist\")\n                            select LastFmArtist.FromJson(a)).ToList();\n                else\n                    return new List<LastFmArtist>() { LastFmArtist.FromJson(artistJson) };\n            }\n\n            return null;\n        }\n\n        public async Task<List<LastFmArtist>> GetSimilar(string artist, int count = 0)\n        {\n            var parameters = new Dictionary<string, string>();\n            parameters.Add(\"artist\", artist);\n            if (count > 0)\n                parameters.Add(\"limit\", count.ToString());\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"artist.getSimilar\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response.SelectToken(\"similarartists.artist\") != null)\n            {\n                return (from a in response.SelectToken(\"similarartists.artist\") select LastFmArtist.FromJson(a)).ToList();\n            }\n\n            return null;\n        }\n\n        public async Task<List<LastFmAlbum>> GetTopAlbums(string mbid, string artist, int count = 0)\n        {\n            var parameters = new Dictionary<string, string>();\n            if (!string.IsNullOrEmpty(mbid))\n                parameters.Add(\"mbid\", mbid);\n            else\n                parameters.Add(\"artist\", artist);\n            if (count > 0)\n                parameters.Add(\"limit\", count.ToString());\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"artist.getTopAlbums\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response.SelectToken(\"topalbums.album\") != null)\n            {\n                var albumToken = response.SelectToken(\"topalbums.album\");\n                if (albumToken.GetType() == typeof(JArray))\n                    return (from a in albumToken select LastFmAlbum.FromJson(a)).ToList();\n                else if (albumToken.GetType() == typeof(JObject))\n                {\n                    var result = new List<LastFmAlbum>();\n                    result.Add(LastFmAlbum.FromJson(albumToken));\n                    return result;\n                }\n            }\n\n            return null;\n        }\n\n        public async Task<List<LastFmTrack>> GetTopTracks(string mbid, string artist, int count = 0)\n        {\n            var parameters = new Dictionary<string, string>();\n            if (!string.IsNullOrEmpty(mbid))\n                parameters.Add(\"mbid\", mbid);\n            else\n                parameters.Add(\"artist\", artist);\n            if (count > 0)\n                parameters.Add(\"limit\", count.ToString());\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"artist.getTopTracks\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response.SelectToken(\"toptracks.track\") != null)\n            {\n                var tracksJson = response.SelectToken(\"toptracks.track\");\n                if (tracksJson is JArray)\n                    return (from a in tracksJson select LastFmTrack.FromJson(a)).ToList();\n                else\n                    return new List<LastFmTrack>() { LastFmTrack.FromJson(tracksJson) };\n            }\n\n            return null;\n        }\n\n        public async Task<LastFmArtist> GetInfo(string mbid, string artist)\n        {\n            var parameters = new Dictionary<string, string>();\n            if (!string.IsNullOrEmpty(mbid))\n                parameters.Add(\"mbid\", mbid);\n            else\n                parameters.Add(\"artist\", artist);\n            if (!string.IsNullOrEmpty(_lastFm.Lang))\n                parameters.Add(\"lang\", _lastFm.Lang);\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"artist.getInfo\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n            if (response[\"artist\"] != null)\n            {\n                return LastFmArtist.FromJson(response[\"artist\"]);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Auth/LastFmAuthRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\nnamespace LastFmLib.Core.Auth\n{\n    public class LastFmAuthRequest\n    {\n        private readonly LastFm _lastFm;\n\n        public LastFmAuthRequest(LastFm lastFm)\n        {\n            _lastFm = lastFm;\n        }\n\n\n        public async Task<LastFmAuthResult> GetMobileSession(string username, string password)\n        {\n            var parameters = new Dictionary<string, string>();\n\n            parameters.Add(\"username\", username);\n            parameters.Add(\"password\", password);\n\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n            parameters.Add(\"api_sig\", LastFmUtils.BuildSig(_lastFm.ApiSecret, \"auth.getMobileSession\", parameters));\n\n            var response = await new CoreRequest(new Uri(LastFmConst.MethodBaseSecure), null, \"POST\", parameters).Execute();\n\n            if (!LastFmErrorProcessor.ProcessError(response))\n                return null;\n\n            if (response[\"session\"] != null)\n            {\n                return LastFmAuthResult.FromJson(response[\"session\"]);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Auth/LastFmAuthResult.cs",
    "content": "﻿using System;\nusing Newtonsoft.Json.Linq;\n\nnamespace LastFmLib.Core.Auth\n{\n    public class LastFmAuthResult\n    {\n        public string Username { get; set; }\n\n        public string Key { get; set; }\n\n        public static LastFmAuthResult FromJson(JToken json)\n        {\n            if (json == null)\n                throw new ArgumentException(\"Json can not be null.\");\n\n            var result = new LastFmAuthResult();\n\n            result.Username = json[\"name\"].Value<string>();\n            result.Key = json[\"key\"].Value<string>();\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Chart/LastFmChartRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing LastFmLib.Core.Track;\n\nnamespace LastFmLib.Core.Chart\n{\n    public class LastFmChartRequest\n    {\n        private readonly LastFm _lastFm;\n\n        public LastFmChartRequest(LastFm lastFm)\n        {\n            _lastFm = lastFm;\n        }\n\n\n        public async Task<IEnumerable<LastFmTrack>> GetTopTracks(int count = 0)\n        {\n            var parameters = new Dictionary<string, string>();\n            if (count > 0)\n                parameters.Add(\"limit\", count.ToString());\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"chart.getTopTracks\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response.SelectToken(\"tracks.track\") != null)\n            {\n                return from a in response.SelectToken(\"tracks.track\") select LastFmTrack.FromJson(a);\n            }\n\n            return null;\n        }\n\n        public async Task<IEnumerable<LastFmTrack>> GetHypedTracks(int count = 0)\n        {\n            var parameters = new Dictionary<string, string>();\n            if (count > 0)\n                parameters.Add(\"limit\", count.ToString());\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await (new CoreRequest(new Uri(LastFmConst.MethodBase + \"chart.getHypedTracks\"), parameters).Execute());\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response.SelectToken(\"tracks.track\") != null)\n            {\n                return from a in response.SelectToken(\"tracks.track\") select LastFmTrack.FromJson(a);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/CoreRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Threading.Tasks;\nusing LastFmLib.Extensions;\nusing Newtonsoft.Json.Linq;\nusing System.Net.NetworkInformation;\n\nnamespace LastFmLib.Core\n{\n    /// <summary>\n    /// An object that performs request to server\n    /// </summary>\n    internal class CoreRequest\n    {\n        private readonly Uri _uri;\n        private readonly string _method;\n        private readonly Dictionary<string, string> _parameters;\n        private readonly Dictionary<string, string> _postParameters;\n\n        public CoreRequest(Uri uri)\n        {\n            _uri = uri;\n            _method = \"GET\";\n        }\n\n        public CoreRequest(Uri uri, Dictionary<string, string> parameters, string method = \"GET\", Dictionary<string, string> postParameters = null)\n        {\n            _uri = uri;\n            _method = method;\n            _parameters = parameters;\n            _postParameters = postParameters;\n        }\n\n        public async Task<JObject> Execute()\n        {\n            if (!NetworkInterface.GetIsNetworkAvailable())\n                throw new Exception(\"Network is not available.\");\n\n            var uri = GetFullUri(_parameters);\n            var request = WebRequest.CreateHttp(uri);\n            request.Method = _method;\n\n            Debug.WriteLine(\"Invoking \" + uri);\n\n            JObject response = null;\n\n            var httpClient = new HttpClient();\n\n            if (_method == \"GET\")\n            {\n                HttpResponseMessage responseMessage = await httpClient.GetAsync(uri);\n                string content = await responseMessage.Content.ReadAsStringAsync();\n                if (!string.IsNullOrEmpty(content))\n                    response = JObject.Parse(content);\n            }\n            else if (_method == \"POST\")\n            {\n                var postContent = new StringContent(_postParameters.ConstructQueryString());\n                postContent.Headers.ContentType = new MediaTypeHeaderValue(\"application/x-www-form-urlencoded\");\n                HttpResponseMessage responseMessage = await httpClient.PostAsync(uri, postContent);\n                string content = await responseMessage.Content.ReadAsStringAsync();\n                if (!string.IsNullOrEmpty(content))\n                    response = JObject.Parse(content);\n            }\n\n            return response;\n        }\n\n        private Uri GetFullUri(Dictionary<string, string> parameters)\n        {\n            if (parameters != null && parameters.Count > 0)\n            {\n                var paramStr = string.Join(\"&\",\n                                           parameters.Select(\n                                               kp => string.Format(\"{0}={1}\", Uri.EscapeDataString(kp.Key), Uri.EscapeDataString(kp.Value))));\n\n                return new Uri(string.Concat(_uri, \"&\", paramStr));\n            }\n\n            return _uri;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Image/LastFmImage.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing Newtonsoft.Json.Linq;\n\nnamespace LastFmLib.Core.Image\n{\n    public class LastFmImage\n    {\n        public double Width { get; set; }\n\n        public double Height { get; set; }\n\n        public double OriginalWidth { get; set; }\n\n        public double OriginalHeight { get; set; }\n\n        public string Original { get; set; }\n\n        public string Large { get; set; }\n\n        public string LargeSquare { get; set; }\n\n        public string Medium { get; set; }\n\n        public string Small { get; set; }\n\n        public string ExtraLarge { get; set; }\n\n        internal static LastFmImage FromJson(JToken json)\n        {\n            if (json == null)\n                throw new ArgumentException(\"Json can not be null.\");\n\n            var result = new LastFmImage();\n            var sizeToken = json.SelectToken(\"sizes.size\");\n            if (sizeToken != null)\n            {\n                foreach (var size in sizeToken.Children())\n                {\n                    switch (size[\"name\"].Value<string>())\n                    {\n                        case \"small\":\n                            result.Small = size[\"#text\"].Value<string>();\n                            result.Width = Convert.ToDouble(size[\"width\"].Value<string>());\n                            result.Height = Convert.ToDouble(size[\"height\"].Value<string>());\n                            break;\n                        case \"medium\":\n                            result.Medium = size[\"#text\"].Value<string>();\n                            result.Width = Convert.ToDouble(size[\"width\"].Value<string>());\n                            result.Height = Convert.ToDouble(size[\"height\"].Value<string>());\n                            break;\n                        case \"large\":\n                            result.Large = size[\"#text\"].Value<string>();\n                            result.Width = Convert.ToDouble(size[\"width\"].Value<string>());\n                            result.Height = Convert.ToDouble(size[\"height\"].Value<string>());\n                            break;\n                        case \"extralarge\":\n                            result.ExtraLarge = size[\"#text\"].Value<string>();\n                            result.Width = Convert.ToDouble(size[\"width\"].Value<string>());\n                            result.Height = Convert.ToDouble(size[\"height\"].Value<string>());\n                            break;\n                        case \"original\":\n                            result.Original = size[\"#text\"].Value<string>();\n                            result.Width = Convert.ToDouble(size[\"width\"].Value<string>());\n                            result.Height = Convert.ToDouble(size[\"height\"].Value<string>());\n                            result.OriginalWidth = Convert.ToDouble(size[\"width\"].Value<string>());\n                            result.OriginalHeight = Convert.ToDouble(size[\"height\"].Value<string>());\n                            break;\n                    }\n                }\n\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/LastFmErrorProcessor.cs",
    "content": "﻿using System.Diagnostics;\nusing LastFmLib.Error;\nusing Newtonsoft.Json.Linq;\n\nnamespace LastFmLib.Core\n{\n    internal static class LastFmErrorProcessor\n    {\n        public static bool ProcessError(JToken response)\n        {\n            if (response[\"error\"] != null)\n            {                     \n                Debug.WriteLine(\"Last FM: \" + response[\"message\"].Value<string>());\n\n                switch (response[\"error\"].Value<string>())\n                {\n                    case \"9\":\n                    case \"4\": //login error\n                        throw new LastFmLoginException();\n                    case \"6\": //artist not found\n                        return false;\n                }\n\n                return false;\n            }\n\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Tag/LastFmTagRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing LastFmLib.Core.Track;\nusing System.Linq;\n\nnamespace LastFmLib.Core.Tag\n{\n    public class LastFmTagRequest\n    {\n        private readonly LastFm _lastFm;\n\n        public LastFmTagRequest(LastFm lastFm)\n        {\n            _lastFm = lastFm;\n        }\n\n\n        public async Task<IEnumerable<LastFmTrack>> GetTopTracks(string tag, int limit = 20, int page = 0)\n        {\n            var parameters = new Dictionary<string, string>();\n\n            parameters.Add(\"tag\", tag);\n\n            if (limit > 0)\n                parameters.Add(\"limit\", limit.ToString());\n\n            if (page > 0)\n                parameters.Add(\"page\", page.ToString());\n\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await new CoreRequest(new Uri(LastFmConst.MethodBase + \"tag.getTopTracks\"), parameters).Execute();\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response.SelectToken(\"tracks.track\") != null)\n            {\n                return from t in response.SelectToken(\"tracks.track\") select LastFmTrack.FromJson(t);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Track/LastFmTrack.cs",
    "content": "﻿using System;\nusing Newtonsoft.Json.Linq;\n\nnamespace LastFmLib.Core.Track\n{\n    public class LastFmTrack\n    {\n        public string Id { get; set; }\n        public string Title { get; set; }\n        public int Duration { get; set; }\n        public string Artist { get; set; }\n        public string Album { get; set; }\n        public string ImageSmall { get; set; }\n        public string ImageMedium { get; set; }\n        public string ImageLarge { get; set; }\n        public string ImageExtraLarge { get; set; }\n        public string ImageMega { get; set; }\n\n        internal static LastFmTrack FromJson(JToken json)\n        {\n            if (json == null)\n                throw new ArgumentException(\"Json can not be null.\");\n\n            var result = new LastFmTrack();\n\n            if (json[\"name\"] != null)\n                result.Title = json[\"name\"].Value<string>();\n            if (json[\"artist\"] != null)\n            {\n                if (json.SelectToken(\"artist.name\") != null)\n                    result.Artist = json[\"artist\"][\"name\"].Value<string>();\n                else\n                    result.Artist = json[\"artist\"].Value<string>();\n            }\n            if (json[\"duration\"] != null && !string.IsNullOrEmpty(json[\"duration\"].Value<string>()))\n            {\n                result.Duration = json[\"duration\"].Value<int>();\n            }\n            if (json[\"album\"] != null)\n            {\n                result.Album = json[\"album\"][\"title\"].Value<string>();\n                var imageToken = json[\"album\"][\"image\"];\n                if (imageToken != null)\n                {\n                    foreach (var image in imageToken.Children())\n                    {\n                        switch (image[\"size\"].Value<string>())\n                        {\n                            case \"small\":\n                                result.ImageSmall = image[\"#text\"].Value<string>();\n                                break;\n                            case \"medium\":\n                                result.ImageMedium = image[\"#text\"].Value<string>();\n                                break;\n                            case \"large\":\n                                result.ImageLarge = image[\"#text\"].Value<string>();\n                                break;\n                            case \"extralarge\":\n                                result.ImageExtraLarge = image[\"#text\"].Value<string>();\n                                break;\n                        }\n                    }\n                }\n            }\n\n            var imgToken = json[\"image\"];\n            if (imgToken != null)\n            {\n                foreach (var image in imgToken.Children())\n                {\n                    switch (image[\"size\"].Value<string>())\n                    {\n                        case \"small\":\n                            result.ImageSmall = image[\"#text\"].Value<string>();\n                            break;\n                        case \"medium\":\n                            result.ImageMedium = image[\"#text\"].Value<string>();\n                            break;\n                        case \"large\":\n                            result.ImageLarge = image[\"#text\"].Value<string>();\n                            break;\n                        case \"extralarge\":\n                            result.ImageExtraLarge = image[\"#text\"].Value<string>();\n                            break;\n                    }\n                }\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/Track/LastFmTrackRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json.Linq;\n\nnamespace LastFmLib.Core.Track\n{\n    public class LastFmTrackRequest\n    {\n        private readonly LastFm _lastFm;\n\n        public LastFmTrackRequest(LastFm lastFm)\n        {\n            _lastFm = lastFm;\n        }\n\n        public async Task<LastFmTrack> GetInfo(string title, string artist, bool autoCorrect = true, string mbid = null)\n        {\n            var parameters = new Dictionary<string, string>();\n\n            if (!string.IsNullOrEmpty(mbid))\n                parameters.Add(\"mbid\", mbid);\n            else\n            {\n                parameters.Add(\"artist\", artist);\n                parameters.Add(\"track\", title);\n            }\n\n            if (autoCorrect)\n                parameters.Add(\"autocorrect\", \"1\");\n\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await new CoreRequest(new Uri(LastFmConst.MethodBase + \"track.getInfo\"), parameters).Execute();\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response[\"track\"] != null)\n            {\n                return LastFmTrack.FromJson(response[\"track\"]);\n            }\n\n            return null;\n        }\n\n        public async Task UpdateNowPlaying(string artist, string track, string mbid = null, int duration = 0,\n                                           string album = null, int trackNumber = -1, string albumArtist = null)\n        {\n\n            const string method = \"track.updateNowPlaying\";\n\n            var parameters = new Dictionary<string, string>();\n\n            parameters.Add(\"artist\", artist);\n            parameters.Add(\"track\", track);\n\n            if (album != null)\n                parameters.Add(\"album\", album);\n\n            if (trackNumber > -1)\n                parameters.Add(\"trackNumber\", trackNumber.ToString());\n\n            if (mbid != null)\n                parameters.Add(\"mbid\", mbid);\n\n            if (duration > 0)\n                parameters.Add(\"duration\", duration.ToString());\n\n            if (albumArtist != null)\n                parameters.Add(\"albumArtist\", albumArtist);\n\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n            parameters.Add(\"sk\", _lastFm.SessionKey);\n            parameters.Add(\"api_sig\", LastFmUtils.BuildSig(_lastFm.ApiSecret, method, parameters));\n\n            parameters[\"track\"] = Uri.EscapeDataString(track); //fix ampersand scrobbling\n            parameters[\"artist\"] = Uri.EscapeDataString(artist); //fix ampersand scrobbling\n\n\n            var response = await new CoreRequest(new Uri(LastFmConst.UrlBaseSecure), null, \"POST\", parameters).Execute();\n\n            LastFmErrorProcessor.ProcessError(response);\n        }\n\n        public async Task Scrobble(string artist, string track, string timeStamp, string mbid = null, int duration = 0,\n                                   string album = null, int trackNumber = -1, string albumArtist = null)\n        {\n\n            const string method = \"track.scrobble\";\n\n            var parameters = new Dictionary<string, string>();\n\n            parameters.Add(\"artist\", artist);\n            parameters.Add(\"track\", track);\n            parameters.Add(\"timestamp\", timeStamp);\n\n            if (album != null)\n                parameters.Add(\"album\", album);\n\n            if (trackNumber > -1)\n                parameters.Add(\"trackNumber\", trackNumber.ToString());\n\n            if (mbid != null)\n                parameters.Add(\"mbid\", mbid);\n\n            if (albumArtist != null)\n                parameters.Add(\"albumArtist\", albumArtist);\n\n            if (duration > 0)\n                parameters.Add(\"duration\", duration.ToString());\n\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n            parameters.Add(\"sk\", _lastFm.SessionKey);\n            parameters.Add(\"api_sig\", LastFmUtils.BuildSig(_lastFm.ApiSecret, method, parameters));\n\n\n            parameters[\"track\"] = Uri.EscapeDataString(track); //fix ampersand scrobbling\n            parameters[\"artist\"] = Uri.EscapeDataString(artist); //fix ampersand scrobbling\n\n            var response = await new CoreRequest(new Uri(LastFmConst.UrlBaseSecure), null, \"POST\", parameters).Execute();\n\n            LastFmErrorProcessor.ProcessError(response);\n        }\n\n        public async Task<List<LastFmTrack>> Search(string track, string artist)\n        {\n            var parameters = new Dictionary<string, string>();\n\n            parameters.Add(\"track\", track);\n            if (!string.IsNullOrEmpty(artist))\n                parameters.Add(\"artist\", artist);\n\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n\n            var response = await new CoreRequest(new Uri(LastFmConst.MethodBase + \"track.search\"), parameters).Execute();\n\n            LastFmErrorProcessor.ProcessError(response);\n\n            if (response.SelectToken(\"results.trackmatches.track\") != null)\n            {\n                var trackJson = response.SelectToken(\"results.trackmatches.track\");\n                if (trackJson is JArray)\n                    return (from t in response.SelectToken(\"results.trackmatches.track\")\n                           select LastFmTrack.FromJson(t)).ToList();\n                else\n                    return new List<LastFmTrack>() { LastFmTrack.FromJson(trackJson) };\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Core/User/LastFmUserRequest.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing LastFmLib.Core.Artist;\n\nnamespace LastFmLib.Core.User\n{\n    public class LastFmUserRequest\n    {\n        private readonly LastFm _lastFm;\n\n        public LastFmUserRequest(LastFm lastFm)\n        {\n            _lastFm = lastFm;\n        }\n\n        public async Task<IEnumerable<LastFmArtist>> GetRecommendedArtists(int count = 0)\n        {\n            var parameters = new Dictionary<string, string>();\n\n            if (count > 0)\n                parameters.Add(\"limit\", count.ToString());\n\n            parameters.Add(\"api_key\", _lastFm.ApiKey);\n            parameters.Add(\"sk\", _lastFm.SessionKey);\n            parameters.Add(\"api_sig\", LastFmUtils.BuildSig(_lastFm.ApiSecret, \"user.getRecommendedArtists\", parameters));\n\n            var response = await new CoreRequest(new Uri(LastFmConst.UrlBase), parameters, \"POST\").Execute();\n\n            LastFmErrorProcessor.ProcessError(response);\n\n\n            if (response.SelectToken(\"recommendations.artist\") != null)\n            {\n                return from a in response.SelectToken(\"recommendations.artist\") select LastFmArtist.FromJson(a);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Error/LastFmLoginException.cs",
    "content": "﻿using System;\n\nnamespace LastFmLib.Error\n{\n    public class LastFmLoginException : Exception\n    {\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Extensions/CommonExtensions.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Net;\n\nnamespace LastFmLib.Extensions\n{\n    public static class CommonExtensions\n    {\n        /// <summary>\n        /// Constructs a QueryString (string).\n        /// Consider this method to be the opposite of \"System.Web.HttpUtility.ParseQueryString\"\n        /// </summary>\n        /// <param name=\"parameters\">NameValueCollection</param>\n        /// <returns>string</returns>\n        public static string ConstructQueryString(this Dictionary<string, string> parameters)\n        {\n            return string.Join(\"&\", parameters.Select(pair => pair.Key).Distinct().Select(name => string.Concat(name, \"=\", WebUtility.HtmlEncode(parameters[name]))).ToArray());\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/Extensions/StreamExtensions.cs",
    "content": "﻿using System.Diagnostics;\nusing System.IO;\n\nnamespace LastFmLib.Extensions\n{\n    internal static class StreamExtensions\n    {\n        public static int CopyStream(this Stream source, Stream dest)\n        {\n            Debug.Assert(source != null);\n            Debug.Assert(dest != null);\n            var positionSource = source.Position;\n            var positionDest = dest.Position;\n\n            var buffer = new byte[4096];\n            var read = 0;\n            var total = 0;\n            while ((read = source.Read(buffer, 0, buffer.Length)) > 0)\n            {\n                total += read;\n                dest.Write(buffer, 0, read);\n            }\n            if (source.CanSeek)\n                source.Seek(positionSource, SeekOrigin.Begin);\n            if (dest.CanSeek)\n                dest.Seek(positionDest, SeekOrigin.Begin);\n            return total;\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/LastFM.cs",
    "content": "﻿using LastFmLib.Core.Album;\nusing LastFmLib.Core.Artist;\nusing LastFmLib.Core.Auth;\nusing LastFmLib.Core.Chart;\nusing LastFmLib.Core.Tag;\nusing LastFmLib.Core.Track;\nusing LastFmLib.Core.User;\n\nnamespace LastFmLib\n{\n    public class LastFm\n    {\n        private readonly string _apiKey;\n        private readonly string _apiSecret;\n\n        private LastFmArtistRequest _artist;\n        private LastFmAlbumRequest _album;\n        private LastFmTrackRequest _track;\n        private LastFmChartRequest _chart;\n        private LastFmAuthRequest _auth;\n        private LastFmUserRequest _user;\n        private LastFmTagRequest _tag;\n\n        internal string ApiKey\n        {\n            get { return _apiKey; }\n        }\n\n        internal string ApiSecret\n        {\n            get { return _apiSecret; }\n        }\n\n        public LastFmArtistRequest Artist\n        {\n            get\n            {\n                if (_artist == null)\n                    _artist = new LastFmArtistRequest(this);\n\n                return _artist;\n            }\n        }\n\n        public LastFmAlbumRequest Album\n        {\n            get\n            {\n                if (_album == null)\n                    _album = new LastFmAlbumRequest(this);\n\n                return _album;\n            }\n        }\n\n        public LastFmTrackRequest Track\n        {\n            get\n            {\n                if (_track == null)\n                    _track = new LastFmTrackRequest(this);\n\n                return _track;\n            }\n        }\n\n\n        public LastFmChartRequest Chart\n        {\n            get\n            {\n                if (_chart == null)\n                    _chart = new LastFmChartRequest(this);\n\n                return _chart;\n            }\n        }\n\n        public LastFmUserRequest User\n        {\n            get\n            {\n                if (_user == null)\n                    _user = new LastFmUserRequest(this);\n\n                return _user;\n            }\n        }\n\n        public LastFmTagRequest Tag\n        {\n            get\n            {\n                if (_tag == null)\n                    _tag = new LastFmTagRequest(this);\n\n                return _tag;\n            }\n        }\n\n        public LastFmAuthRequest Auth\n        {\n            get\n            {\n                if (_auth == null)\n                    _auth = new LastFmAuthRequest(this);\n                return _auth;\n            }\n        }\n\n        public string Lang { get; set; }\n\n        public string SessionKey { get; set; }\n\n        public LastFm(string apiKey, string apiSecret, string lang = null)\n        {\n            _apiKey = apiKey;\n            _apiSecret = apiSecret;\n            Lang = lang;\n        }\n    }\n}"
  },
  {
    "path": "LastFmLibPortable/Trunk/LastFmConst.cs",
    "content": "﻿namespace LastFmLib\n{\n    internal static class LastFmConst\n    {\n        internal const string AuthorizationUrlBase = \"http://www.last.fm/api/auth/?\";\n        internal const string MethodBase = \"http://ws.audioscrobbler.com/2.0/?format=json&method=\";\n        internal const string UrlBase = \"http://ws.audioscrobbler.com/2.0/?format=json\";\n        internal const string UrlBaseSecure = \"https://ws.audioscrobbler.com/2.0/?format=json\";\n        internal const string MethodBaseSecure = \"https://ws.audioscrobbler.com/2.0/?format=json\";\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/LastFmLibPortable.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netstandard2.0</TargetFramework>\n    <Version>1.0.2</Version>\n    <Authors>Artem Shuba</Authors>\n    <PackageId>LastFmLib</PackageId>\n    <Product>LastFmLib</Product>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Folder Include=\"Properties\\\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/LastFmUtils.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Cryptography;\nusing System.Text;\n\nnamespace LastFmLib\n{\n    internal class LastFmUtils\n    {\n        public static string BuildSig(string secretKey, string method, IDictionary<string, string> parameters)\n        {\n            parameters.Add(\"method\", method);\n            var temp = parameters.OrderBy(x => x.Key);\n            var s = new StringBuilder();\n            foreach (var p in temp)\n            {\n                s.Append(p.Key);\n                s.Append(p.Value);\n            }\n\n            s.Append(secretKey);\n            return Md5(s.ToString());\n        }\n\n        public static string Md5(string input)\n        {\n            using(var md5 = MD5.Create())\n            {\n                return GetMd5Hash(md5, input);\n            }\n        }\n\n        private static string GetMd5Hash(MD5 md5Hash, string input)\n        {\n\n            // Convert the input string to a byte array and compute the hash.\n            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));\n\n            // Create a new Stringbuilder to collect the bytes\n            // and create a string.\n            StringBuilder sBuilder = new StringBuilder();\n\n            // Loop through each byte of the hashed data \n            // and format each one as a hexadecimal string.\n            for (int i = 0; i < data.Length; i++)\n            {\n                sBuilder.Append(data[i].ToString(\"x2\"));\n            }\n\n            // Return the hexadecimal string.\n            return sBuilder.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "LastFmLibPortable/Trunk/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  \n</configuration>"
  },
  {
    "path": "LastFmLibPortable/Trunk/project.json",
    "content": "{\n  \"supports\": {\n    \"net46.app\": {},\n    \"dnxcore50.app\": {}\n  },\n  \"dependencies\": {\n    \"Microsoft.NETCore\": \"5.0.0\",\n    \"Microsoft.NETCore.Portable.Compatibility\": \"1.0.0\"\n  },\n  \"frameworks\": {\n    \"dotnet\": {\n      \"imports\": \"portable-net452\"\n    }\n  }\n}"
  },
  {
    "path": "Meridian/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <configSections>\n    <section name=\"nlog\" type=\"NLog.Config.ConfigSectionHandler, NLog\" />\n  </configSections>\n  <nlog xmlns=\"http://www.nlog-project.org/schemas/NLog.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n    <variable name=\"logDir\" value=\"${specialfolder:folder=MyDocuments}/Meridian/Logs/\" />\n    <variable name=\"detailedLayout\" value=\"${date:format=dd.MM.yyyy HH\\:mm\\:ss} (${level:uppercase=true}): ${logger} ${message}. ${exception:format=ToString}\" />\n    <targets>\n      <target name=\"fullLog\" xsi:type=\"File\" fileName=\"${logDir}/${date:format=yyyy-MM-dd}.log\" layout=\"${detailedLayout}\" />\n    </targets>\n    <rules>\n      <logger name=\"*\" minlevel=\"Trace\" writeTo=\"fullLog\" />\n    </rules>\n  </nlog>\n  <runtime>\n    <loadFromRemoteSources enabled=\"true\" />\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <probing privatePath=\"libs\" />\n      <dependentAssembly>\n        <assemblyIdentity name=\"Newtonsoft.Json\" publicKeyToken=\"30ad4fe6b2a6aeed\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-6.0.0.0\" newVersion=\"6.0.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Net.Http.Primitives\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.2.29.0\" newVersion=\"4.2.29.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"PortableRest\" publicKeyToken=\"109c5b6afe0e5188\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-2.5.0.0\" newVersion=\"2.5.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"ICSharpCode.SharpZipLib\" publicKeyToken=\"1b03e6acf1164f73\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-1.2.0.246\" newVersion=\"1.2.0.246\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Windows.Interactivity\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.5.0.0\" newVersion=\"4.5.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n  <startup>\n    <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.7.2\" />\n  </startup>\n</configuration>\n"
  },
  {
    "path": "Meridian/App.xaml",
    "content": "﻿<Application x:Class=\"Meridian.App\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:converters=\"clr-namespace:Neptune.UI.Converters;assembly=Neptune.Desktop\"\n             xmlns:viewModel=\"clr-namespace:Meridian.ViewModel\"\n             xmlns:converters1=\"clr-namespace:Meridian.Converters\"\n             StartupUri=\"MainWindow.xaml\" ShutdownMode=\"OnMainWindowClose\"\n             Startup=\"App_OnStartup\" Exit=\"App_OnExit\" DispatcherUnhandledException=\"App_OnDispatcherUnhandledException\">\n    <Application.Resources>\n        <ResourceDictionary>\n            <ResourceDictionary.MergedDictionaries>\n                <ResourceDictionary Source=\"/Resources/Themes/Accents/Blue.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Themes/Light.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/Icons.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/Animations.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/WindowButtons.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/ExpanderStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/ListBoxStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/AudioControlStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/SliderStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/ScrollbarStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/TextBoxStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/ComboBoxStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/ButtonStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/CheckBoxStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/ProgressBarStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/ContextMenuStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/TabControlStyles.xaml\" />\n                <ResourceDictionary Source=\"/Resources/Styles/Styles.xaml\" />\n\n                <ResourceDictionary>\n                    <viewModel:ViewModelLocator x:Key=\"Locator\"/>\n                    <converters:BooleanToVisibilityConverter x:Key=\"BoolToVisibilityConverter\"/>\n                    <converters:NullToVisibilityConverter x:Key=\"NullToVisibilityConverter\"/>\n                    <converters:NullToBooleanConverter x:Key=\"NullToBoolConverter\"/>\n                    <converters:StringToUpperConverter x:Key=\"StringToUpperConverter\"/>\n                    <converters:TimeSpanConverter x:Key=\"TimeSpanConverter\"/>\n                    <converters:InvertBooleanConverter x:Key=\"InvertBoolConverter\" />\n                    <converters1:AudioTimeSpanConverter x:Key=\"AudioTimeSpanConverter\"/>\n                    <converters1:AlbumContextMenuVisibilityConverter x:Key=\"AlbumContextMenuVisibilityConverter\"/>\n                    <converters:BooleanToObjectConverter x:Key=\"PlayIconConverter\" TrueObject=\"/Meridian;component/Resources/Images/pause_thumb.png\" FalseObject=\"/Meridian;component/Resources/Images/play_thumb.png\"/>\n                </ResourceDictionary>\n                <ResourceDictionary Source=\"/Resources/Styles/DataTemplates.xaml\" />\n                <ResourceDictionary Source=\"/Layout/Templates/PageBaseTemplate.xaml\" />\n                <ResourceDictionary Source=\"/Layout/Templates/TwoColumnPageLayoutTemplate.xaml\" />\n            </ResourceDictionary.MergedDictionaries>\n        </ResourceDictionary>\n    </Application.Resources>\n</Application>\n"
  },
  {
    "path": "Meridian/App.xaml.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Reflection;\nusing System.Windows;\nusing System.Windows.Forms;\nusing System.Windows.Threading;\nusing Meridian.Controls;\nusing Meridian.Domain;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.View.Flyouts;\nusing Meridian.ViewModel;\nusing Yandex.Metrica;\nusing Application = System.Windows.Application;\n\nnamespace Meridian\n{\n    /// <summary>\n    /// Interaction logic for App.xaml\n    /// </summary>\n    public partial class App : Application\n    {\n        private NotifyIcon _trayIcon;\n\n        public static readonly string Root = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);\n\n        private async void App_OnStartup(object sender, StartupEventArgs e)\n        {\n            LoggingService.Log(\"Meridian v\" + Assembly.GetExecutingAssembly().GetName().Version + \" started. OS: \" + Environment.OSVersion);\n\n            //DispatcherHelper.Initialize();\n\n            Settings.Load();\n\n            if (Settings.Instance.SendStats)\n            {\n                YandexMetricaFolder.SetCurrent(Directory.GetCurrentDirectory());\n                YandexMetrica.Activate(\"60fb8ba9-ab3c-4ee8-81ac-559c8aeb305e\"); //Yandex Metrica\n            }\n\n            System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(Settings.Instance.Language);\n            System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture;\n\n            if (Settings.Instance.Accounts.Count == 0)\n            {\n                Settings.Instance.Accounts.Add(new Account() { Id = \"vk\", Title = MainResources.SettingsAccountsVk });\n                Settings.Instance.Accounts.Add(new Account() { Id = \"lasfm\", Title = MainResources.SettingsAccountsLastFm });\n            }\n\n            ServiceLocator.DataBaseService.Initialize();\n\n            if (Settings.Instance.NeedClean)\n            {\n                ViewModelLocator.UpdateService.Clean();\n\n                Settings.Instance.NeedClean = false;\n            }\n\n            switch (Settings.Instance.AccentColor)\n            {\n                case \"Red\":\n                case \"Emerald\":\n                case \"Magenta\":\n                case \"Mango\":\n                case \"Sea\":\n                case \"Sky\":\n                case \"Purple\":\n                case \"Pink\":\n                    Resources.MergedDictionaries[0].Source = new Uri(string.Format(\"/Resources/Themes/Accents/{0}.xaml\", Settings.Instance.AccentColor), UriKind.Relative);\n                    break;\n\n                default:\n                    Resources.MergedDictionaries[0].Source = new Uri(\"/Resources/Themes/Accents/Blue.xaml\", UriKind.Relative);\n                    break;\n            }\n\n            switch (Settings.Instance.Theme)\n            {\n                case \"Light\":\n                case \"Dark\":\n                case \"Graphite\":\n                case \"Accent\":\n                    Resources.MergedDictionaries[1].Source = new Uri(string.Format(\"/Resources/Themes/{0}.xaml\", Settings.Instance.Theme), UriKind.Relative);\n                    break;\n\n                default:\n                    Resources.MergedDictionaries[1].Source = new Uri(\"/Resources/Themes/Light.xaml\", UriKind.Relative);\n                    break;\n            }\n\n            if (Settings.Instance.EnableTrayIcon)\n                AddTrayIcon();\n\n            ViewModelLocator.Vkontakte.UseHttps = Settings.Instance.UseHttps;\n\n            AudioService.Load();\n        }\n\n        private void App_OnExit(object sender, ExitEventArgs e)\n        {\n            RemoveTrayIcon();\n\n            AudioService.Save();\n            AudioService.Dispose();\n        }\n\n        private void App_OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)\n        {\n            LoggingService.Log(e.Exception);\n\n            Dispatcher.Invoke(async () =>\n            {\n                e.Handled = true;\n\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new CommonErrorView();\n                var restart = (bool)await flyout.ShowAsync();\n                if (restart)\n                {\n                    Process.Start(Application.ResourceAssembly.Location);\n                }\n\n                Shutdown();\n            });\n\n        }\n\n        public void AddTrayIcon()\n        {\n            if (_trayIcon != null)\n            {\n                return;\n            }\n\n            _trayIcon = new NotifyIcon\n            {\n                Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location),\n                Text = \"Meridian \" + Assembly.GetExecutingAssembly().GetName().Version.ToString(2)\n            };\n            _trayIcon.MouseClick += TrayIconOnMouseClick;\n            _trayIcon.Visible = true;\n\n            _trayIcon.ContextMenuStrip = new ContextMenuStrip();\n            var closeItem = new System.Windows.Forms.ToolStripMenuItem();\n            closeItem.Text = MainResources.Close;\n            closeItem.Click += (s, e) =>\n            {\n                foreach (Window window in Windows)\n                {\n                    window.Close();\n                }\n            };\n            _trayIcon.ContextMenuStrip.Items.Add(closeItem);\n        }\n\n        private void TrayIconOnMouseClick(object sender, MouseEventArgs mouseEventArgs)\n        {\n            foreach (Window window in Windows)\n            {\n                if (window.Visibility == Visibility.Collapsed)\n                {\n                    window.Visibility = Visibility.Visible;\n                    window.Show();\n                }\n\n                window.Activate();\n\n                if (window.WindowState == WindowState.Minimized)\n                    window.WindowState = WindowState.Normal;\n            }\n        }\n\n        public void RemoveTrayIcon()\n        {\n            if (_trayIcon != null)\n            {\n                _trayIcon.MouseClick -= TrayIconOnMouseClick;\n                _trayIcon.Visible = false;\n                _trayIcon.Dispose();\n                _trayIcon = null;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Behaviours/AutoScrollToCurrentItemBehaviour.cs",
    "content": "﻿using System;\nusing System.Windows.Controls;\nusing GalaSoft.MvvmLight.Messaging;\nusing Meridian.Services;\nusing Meridian.ViewModel.Messages;\nusing Microsoft.Xaml.Behaviors;\n\nnamespace Meridian.Behaviours\n{\n    public class AutoScrollToCurrentItemBehaviour : Behavior<ListBox>\n    {\n        protected override void OnAttached()\n        {\n            Messenger.Default.Register<CurrentAudioChangedMessage>(this, OnCurrentAudioChanged);\n\n            if (AudioService.CurrentAudio != null)\n                AssociatedObject.ScrollIntoView(AudioService.CurrentAudio);\n        }\n\n        protected override void OnDetaching()\n        {\n            Messenger.Default.Unregister<CurrentAudioChangedMessage>(this, OnCurrentAudioChanged);\n        }\n\n        private void OnCurrentAudioChanged(CurrentAudioChangedMessage message)\n        {\n            Dispatcher.BeginInvoke(new Action(() =>\n            {\n                if (AssociatedObject != null && message.NewAudio != null)\n                {\n                    AssociatedObject.ScrollIntoView(message.NewAudio);\n                }\n            }));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Behaviours/FocusBehaviour.cs",
    "content": "﻿using Microsoft.Xaml.Behaviors;\nusing System.Windows;\nusing System.Windows.Controls;\n\nnamespace Meridian.Behaviours\n{\n    public class FocusBehavior : Behavior<Control>\n    {\n        /// <summary>\n        /// IsFocused dependency property\n        /// </summary>\n        public static readonly DependencyProperty IsFocusedProperty =\n            DependencyProperty.Register(\n            \"IsFocused\",\n            typeof(bool),\n            typeof(FocusBehavior),\n            new PropertyMetadata(false, (d, e) =>\n            {\n                if ((bool)e.NewValue && ((FocusBehavior)d).AssociatedObject != null)\n                    ((FocusBehavior)d).AssociatedObject.Focus();\n            }));\n\n        /// <summary>\n        /// HasInitialFocus dependency property\n        /// </summary>\n        public static readonly DependencyProperty HasInitialFocusProperty =\n            DependencyProperty.Register(\n            \"HasInitialFocus\",\n            typeof(bool),\n            typeof(FocusBehavior),\n            new PropertyMetadata(false, null));\n\n        /// <summary>\n        /// Имеет ли контрол фокус\n        /// </summary>\n        public bool IsFocused\n        {\n            get { return (bool)GetValue(IsFocusedProperty); }\n            set { SetValue(IsFocusedProperty, value); }\n        }\n\n        /// <summary>\n        /// Имеет ли контрол фокус при инициализации\n        /// </summary>\n        public bool HasInitialFocus\n        {\n            get { return (bool)GetValue(HasInitialFocusProperty); }\n            set { SetValue(HasInitialFocusProperty, value); }\n        }\n\n        protected override void OnAttached()\n        {\n            AssociatedObject.GotFocus += (sender, args) => IsFocused = true;\n            AssociatedObject.LostFocus += (sender, a) => IsFocused = false;\n            AssociatedObject.Loaded += (o, a) =>\n            {\n                if (HasInitialFocus || IsFocused)\n                    AssociatedObject.Focus();\n            };\n\n            base.OnAttached();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Behaviours/TransitionBehaviour.cs",
    "content": "﻿using Microsoft.Xaml.Behaviors;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Media.Animation;\n\nnamespace Meridian.Behaviours\n{\n    public class TransitionBehaviour : Behavior<FrameworkElement>\n    {\n        public static readonly DependencyProperty TransitionProperty =\n            DependencyProperty.Register(\"Transition\", typeof(Storyboard), typeof(TransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard Transition\n        {\n            get { return (Storyboard)GetValue(TransitionProperty); }\n            set { SetValue(TransitionProperty, value); }\n        }\n\n        public static readonly DependencyProperty TransitionDelayProperty =\n            DependencyProperty.Register(\"TransitionDelay\", typeof(int), typeof(TransitionBehaviour), new PropertyMetadata(300));\n\n        public int TransitionDelay\n        {\n            get { return (int)GetValue(TransitionDelayProperty); }\n            set { SetValue(TransitionDelayProperty, value); }\n        }\n\n        public static readonly DependencyProperty TransitionIndexProperty =\n            DependencyProperty.RegisterAttached(\"TransitionIndex\", typeof(int), typeof(TransitionBehaviour), new PropertyMetadata(default(int)));\n\n        public static void SetTransitionIndex(UIElement element, int value)\n        {\n            element.SetValue(TransitionIndexProperty, value);\n        }\n\n        public static int GetTransitionIndex(UIElement element)\n        {\n            return (int)element.GetValue(TransitionIndexProperty);\n        }\n\n        public static readonly DependencyProperty IgnoreTransitionProperty =\n            DependencyProperty.RegisterAttached(\"IgnoreTransition\", typeof(bool), typeof(TransitionBehaviour), new PropertyMetadata(default(bool)));\n\n        public static void SetIgnoreTransition(UIElement element, bool value)\n        {\n            element.SetValue(IgnoreTransitionProperty, value);\n        }\n\n        public static bool GetIgnoreTransition(UIElement element)\n        {\n            return (bool)element.GetValue(IgnoreTransitionProperty);\n        }\n\n        protected override void OnAttached()\n        {\n            AssociatedObject.Loaded += AssociatedObject_Loaded;\n            if (AssociatedObject is ListBox)\n            {\n                var listBox = (ListBox)AssociatedObject;\n                listBox.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;\n            }\n\n            base.OnAttached();\n        }\n\n        protected override void OnDetaching()\n        {\n            AssociatedObject.Loaded -= AssociatedObject_Loaded;\n            if (AssociatedObject is ListBox)\n            {\n                var listBox = (ListBox)AssociatedObject;\n                listBox.ItemContainerGenerator.StatusChanged -= ItemContainerGenerator_StatusChanged;\n            }\n\n            base.OnDetaching();\n        }\n\n        private List<FrameworkElement> _lastTargets;\n        void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)\n        {\n            if (((ItemContainerGenerator)sender).Status == GeneratorStatus.ContainersGenerated)\n            {\n                var targets = GetTargets();\n                if (targets == null)\n                    return;\n\n                var newItems = targets.Where(t => !_lastTargets.Contains(t)).ToList();\n                if (newItems.Count == 0)\n                {\n                    _lastTargets.Clear();\n                }\n\n                for (var index = 0; index < newItems.Count; index++)\n                {\n                    if ((bool)targets[index].GetValue(IgnoreTransitionProperty))\n                        continue;\n\n                    var transitionIndex = Convert.ToInt32(targets[index].GetValue(TransitionIndexProperty));\n                    for (var i = 1; i < Transition.Children.Count; i++)\n                    {\n                        Transition.Children[i].BeginTime = TimeSpan.FromMilliseconds(TransitionDelay * (transitionIndex != 0 ? transitionIndex : index));\n                    }\n\n                    Transition.Begin(newItems[index]);\n                }\n            }\n            else if (((ItemContainerGenerator)sender).Status == GeneratorStatus.GeneratingContainers)\n            {\n                _lastTargets = GetTargets();\n            }\n        }\n\n        void AssociatedObject_Loaded(object sender, RoutedEventArgs e)\n        {\n            var targets = GetTargets();\n            if (targets == null)\n                return;\n\n            for (var index = 0; index < targets.Count; index++)\n            {\n                if ((bool)targets[index].GetValue(IgnoreTransitionProperty))\n                    continue;\n\n                var transitionIndex = Convert.ToInt32(targets[index].GetValue(TransitionIndexProperty));\n                for (var i = 1; i < Transition.Children.Count; i++)\n                {\n                    Transition.Children[i].BeginTime = TimeSpan.FromMilliseconds(TransitionDelay * (transitionIndex != 0 ? transitionIndex : index));\n                }\n\n                Transition.Begin(targets[index]);\n            }\n        }\n\n        List<FrameworkElement> GetTargets()\n        {\n            var result = new List<FrameworkElement>();\n\n            if (AssociatedObject is ListBox)\n            {\n                var itemsControl = ((ListBox)AssociatedObject);\n                var count = itemsControl.Items.Count;\n\n                for (int i = 0; i < count; i++)\n                {\n                    var container = (FrameworkElement)itemsControl.ItemContainerGenerator.ContainerFromIndex(i);\n                    if (container != null)\n                        result.Add(container);\n                }\n            }\n            else if (AssociatedObject is ItemsControl)\n            {\n                var itemsControl = ((ItemsControl)AssociatedObject);\n                var count = itemsControl.Items.Count;\n\n                for (int i = 0; i < count; i++)\n                {\n                    var container = (FrameworkElement)itemsControl.ItemContainerGenerator.ContainerFromIndex(i);\n                    if (container != null)\n                        result.Add(container);\n                }\n            }\n            else if (AssociatedObject is Panel)\n            {\n                var panel = (Panel)AssociatedObject;\n                var count = panel.Children.Count;\n                for (int i = 0; i < count; i++)\n                {\n                    result.Add((FrameworkElement)panel.Children[i]);\n                }\n            }\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Behaviours/VisibilityTransitionBehaviour.cs",
    "content": "﻿using Microsoft.Xaml.Behaviors;\nusing System.Windows;\nusing System.Windows.Media.Animation;\n\nnamespace Meridian.Behaviours\n{\n    public class VisibilityTransitionBehaviour : Behavior<FrameworkElement>\n    {\n\n        public static readonly DependencyProperty ValueProperty =\n            DependencyProperty.Register(\"Value\", typeof(Visibility), typeof(VisibilityTransitionBehaviour), new PropertyMetadata(default(Visibility), PropertyChangedCallback));\n\n        public Visibility Value\n        {\n            get { return (Visibility)GetValue(ValueProperty); }\n            set { SetValue(ValueProperty, value); }\n        }\n\n        private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var b = (VisibilityTransitionBehaviour)d;\n\n            b.TransitionOut((Visibility)e.OldValue);\n        }\n\n\n        public static readonly DependencyProperty AnimationOutProperty =\n            DependencyProperty.Register(\"AnimationOut\", typeof(Storyboard), typeof(VisibilityTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationOut\n        {\n            get { return (Storyboard)GetValue(AnimationOutProperty); }\n            set { SetValue(AnimationOutProperty, value); }\n        }\n\n        public static readonly DependencyProperty AnimationInProperty =\n            DependencyProperty.Register(\"AnimationIn\", typeof(Storyboard), typeof(VisibilityTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationIn\n        {\n            get { return (Storyboard)GetValue(AnimationInProperty); }\n            set { SetValue(AnimationInProperty, value); }\n        }\n\n        protected override void OnAttached()\n        {\n            AssociatedObject.Visibility = Value;\n\n            base.OnAttached();\n        }\n\n        private void TransitionOut(Visibility oldValue)\n        {\n            if (AssociatedObject == null)\n                return;\n\n            if (AnimationOut == null || oldValue == Visibility.Collapsed)\n            {\n                TransitionIn();\n            }\n            else\n            {\n                AnimationOut.Completed += AnimationOutCompleted;\n                AnimationOut.Begin(AssociatedObject);\n            }\n        }\n\n        private void TransitionIn()\n        {\n            if (AssociatedObject == null)\n                return;\n\n            AssociatedObject.Visibility = Value;\n            if (AnimationIn != null)\n            {\n                AnimationIn.Begin(AssociatedObject);\n            }\n        }\n        void AnimationOutCompleted(object sender, object e)\n        {\n            AnimationOut.Completed -= AnimationOutCompleted;\n            TransitionIn();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/BindablePasswordBox.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\n\nnamespace Meridian.Controls\n{\n    public sealed class BindablePasswordBox : Decorator\n    {\n        /// <summary>\n        /// The password dependency property.\n        /// </summary>\n        public static readonly DependencyProperty PasswordProperty;\n\n        private bool _isPreventCallback;\n        private readonly RoutedEventHandler _savedCallback;\n\n        /// <summary>\n        /// Static constructor to initialize the dependency properties.\n        /// </summary>\n        static BindablePasswordBox()\n        {\n            PasswordProperty = DependencyProperty.Register(\n                \"Password\",\n                typeof(string),\n                typeof(BindablePasswordBox),\n                new FrameworkPropertyMetadata(\"\", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnPasswordPropertyChanged))\n            );\n        }\n\n        /// <summary>\n        /// Saves the password changed callback and sets the child element to the password box.\n        /// </summary>\n        public BindablePasswordBox()\n        {\n            _savedCallback = HandlePasswordChanged;\n\n            var passwordBox = new PasswordBox();\n            passwordBox.Style = Application.Current.Resources[\"CommonPasswordBoxStyle\"] as Style;\n            passwordBox.PasswordChanged += _savedCallback;\n            Child = passwordBox;\n        }\n\n        /// <summary>\n        /// The password dependency property.\n        /// </summary>\n        public string Password\n        {\n            get { return GetValue(PasswordProperty) as string; }\n            set { SetValue(PasswordProperty, value); }\n        }\n\n        /// <summary>\n        /// Handles changes to the password dependency property.\n        /// </summary>\n        /// <param name=\"d\">the dependency object</param>\n        /// <param name=\"eventArgs\">the event args</param>\n        private static void OnPasswordPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs eventArgs)\n        {\n            var bindablePasswordBox = (BindablePasswordBox)d;\n            var passwordBox = (PasswordBox)bindablePasswordBox.Child;\n\n            if (bindablePasswordBox._isPreventCallback)\n            {\n                return;\n            }\n\n            passwordBox.PasswordChanged -= bindablePasswordBox._savedCallback;\n            passwordBox.Password = (eventArgs.NewValue != null) ? eventArgs.NewValue.ToString() : \"\";\n            passwordBox.PasswordChanged += bindablePasswordBox._savedCallback;\n        }\n\n        /// <summary>\n        /// Handles the password changed event.\n        /// </summary>\n        /// <param name=\"sender\">the sender</param>\n        /// <param name=\"eventArgs\">the event args</param>\n        private void HandlePasswordChanged(object sender, RoutedEventArgs eventArgs)\n        {\n            var passwordBox = (PasswordBox)sender;\n\n            _isPreventCallback = true;\n            Password = passwordBox.Password;\n            _isPreventCallback = false;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/BusyIndicator.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Threading;\n\nnamespace Meridian.Controls\n{\n    /// <summary>\n    /// A control to provide a visual indicator when an application is busy.\n    /// </summary>\n    [TemplateVisualState(Name = \"Idle\", GroupName = \"BusyStates\")]\n    [TemplateVisualState(Name = \"Busy\", GroupName = \"BusyStates\")]\n    [TemplateVisualState(Name = \"Error\", GroupName = \"BusyStates\")]\n    [TemplateVisualState(Name = \"Visible\", GroupName = \"VisibilityStates\")]\n    [TemplateVisualState(Name = \"Hidden\", GroupName = \"VisibilityStates\")]\n    [StyleTypedProperty(Property = \"BusyContentStyle\", StyleTargetType = typeof(ContentPresenter))]\n    public class BusyIndicator : ContentControl\n    {\n        /// <summary>\n        /// Identifies the IsBusy dependency property.\n        /// </summary>\n        public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register(\n            \"IsBusy\",\n            typeof(bool),\n            typeof(BusyIndicator),\n            new PropertyMetadata(false, new PropertyChangedCallback(OnIsBusyChanged)));\n\n        /// <summary>\n        /// Gets or sets a value indicating whether the busy indicator should show.\n        /// </summary>\n        public bool IsBusy\n        {\n            get\n            {\n                return (bool)GetValue(IsBusyProperty);\n            }\n            set\n            {\n                SetValue(IsBusyProperty, value);\n            }\n        }\n\n        /// <summary>\n        /// Identifies the FocusAferBusy dependency property.\n        /// </summary>\n        public static readonly DependencyProperty FocusAferBusyProperty = DependencyProperty.Register(\n            \"FocusAferBusy\",\n            typeof(Control),\n            typeof(BusyIndicator),\n            new PropertyMetadata(null));\n\n        /// <summary>\n        /// Gets or sets a Control that should get focus when the busy indicator disapears.\n        /// </summary>\n        public Control FocusAferBusy\n        {\n            get\n            {\n                return (Control)GetValue(FocusAferBusyProperty);\n            }\n            set\n            {\n                SetValue(FocusAferBusyProperty, value);\n            }\n        }\n\n        /// <summary>\n        /// Identifies the BusyContent dependency property.\n        /// </summary>\n        public static readonly DependencyProperty BusyContentProperty = DependencyProperty.Register(\n            \"BusyContent\",\n            typeof(object),\n            typeof(BusyIndicator),\n            new PropertyMetadata(null));\n\n        /// <summary>\n        /// Gets or sets a value indicating the busy content to display to the user.\n        /// </summary>\n        public object BusyContent\n        {\n            get\n            {\n                return (object)GetValue(BusyContentProperty);\n            }\n            set\n            {\n                SetValue(BusyContentProperty, value);\n            }\n        }\n\n        /// <summary>\n        /// Identifies the BusyTemplate dependency property.\n        /// </summary>\n        public static readonly DependencyProperty BusyContentTemplateProperty = DependencyProperty.Register(\n            \"BusyContentTemplate\",\n            typeof(DataTemplate),\n            typeof(BusyIndicator),\n            new PropertyMetadata(null));\n\n        /// <summary>\n        /// Gets or sets a value indicating the template to use for displaying the busy content to the user.\n        /// </summary>\n        public DataTemplate BusyContentTemplate\n        {\n            get\n            {\n                return (DataTemplate)GetValue(BusyContentTemplateProperty);\n            }\n            set\n            {\n                SetValue(BusyContentTemplateProperty, value);\n            }\n        }\n\n        public static readonly DependencyProperty ErrorProperty = DependencyProperty.Register(\n            \"Error\", typeof(string), typeof(BusyIndicator), new PropertyMetadata(default(string), OnErrorPropertyChanged));\n\n        private static void OnErrorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            ((BusyIndicator)d).ChangeVisualState(true);\n        }\n\n        public string Error\n        {\n            get { return (string)GetValue(ErrorProperty); }\n            set { SetValue(ErrorProperty, value); }\n        }\n\n        /// <summary>\n        /// Identifies the ProgressBarStyle dependency property.\n        /// </summary>\n        public static readonly DependencyProperty BusyContentStyleProperty = DependencyProperty.Register(\n            \"BusyContentStyle\",\n            typeof(Style),\n            typeof(BusyIndicator),\n            new PropertyMetadata(null));\n\n        /// <summary>\n        /// Gets or sets a value indicating the style to use for the progress bar.\n        /// </summary>\n        public Style BusyContentStyle\n        {\n            get\n            {\n                return (Style)GetValue(BusyContentStyleProperty);\n            }\n            set\n            {\n                SetValue(BusyContentStyleProperty, value);\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets a value indicating whether the BusyContent is visible.\n        /// </summary>\n        protected bool IsContentVisible\n        {\n            get;\n            set;\n        }\n\n\n        static BusyIndicator()\n        {\n            DefaultStyleKeyProperty.OverrideMetadata(typeof(BusyIndicator), new FrameworkPropertyMetadata(typeof(BusyIndicator)));\n        }\n\n        /// <summary>\n        /// Overrides the OnApplyTemplate method.\n        /// </summary>\n        public override void OnApplyTemplate()\n        {\n            base.OnApplyTemplate();\n            ChangeVisualState(false);\n        }\n\n        /// <summary>\n        /// Changes the control's visual state(s).\n        /// </summary>\n        /// <param name=\"useTransitions\">True if state transitions should be used.</param>\n        protected virtual void ChangeVisualState(bool useTransitions)\n        {\n            if (string.IsNullOrEmpty(Error))\n                VisualStateManager.GoToState(this, IsBusy ? \"Busy\" : \"Idle\", useTransitions);\n            else\n                VisualStateManager.GoToState(this, \"Error\", useTransitions);\n\n            VisualStateManager.GoToState(this, IsContentVisible ? \"Visible\" : \"Hidden\", useTransitions);\n        }\n\n        /// <summary>\n        /// IsBusyProperty property changed handler.\n        /// </summary>\n        /// <param name=\"d\">BusyIndicator that changed its IsBusy.</param>\n        /// <param name=\"e\">Event arguments.</param>\n        private static void OnIsBusyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            ((BusyIndicator)d).OnIsBusyChanged(e);\n        }\n\n        /// <summary>\n        /// IsBusyProperty property changed handler.\n        /// </summary>\n        /// <param name=\"e\">Event arguments.</param>\n        protected virtual void OnIsBusyChanged(DependencyPropertyChangedEventArgs e)\n        {\n            if (IsBusy)\n            {\n                // Go visible now\n                IsContentVisible = true;\n            }\n            else\n            {\n                // No longer visible\n                if (string.IsNullOrEmpty(Error))\n                {\n                    IsContentVisible = false;\n\n                    if (this.FocusAferBusy != null)\n                    {\n                        this.FocusAferBusy.Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>\n                        {\n                            this.FocusAferBusy.Focus();\n                            this.FocusAferBusy = null;\n                        }\n                            ));\n                    }\n                }\n                else\n                {\n                    IsContentVisible = true;\n                }\n            }\n\n            ChangeVisualState(true);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/ContentTransitionControl.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Controls.ContentTransitionControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"300\">\n    <UserControl.Resources>\n        <Storyboard x:Key=\"TransitionOut\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.6\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\">\n                <DiscreteObjectKeyFrame KeyTime=\"0:0:0.6\" Value=\"{x:Static Visibility.Collapsed}\"/>\n            </ObjectAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard x:Key=\"TransitionIn\">\n            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty=\"Visibility\">\n                <DiscreteObjectKeyFrame KeyTime=\"0:0:0\" Value=\"{x:Static Visibility.Visible}\"/>\n            </ObjectAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\" />\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.6\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n    </UserControl.Resources>\n\n    <Grid x:Name=\"LayoutRoot\">\n        <ContentControl x:Name=\"Control1\" HorizontalContentAlignment=\"Stretch\"/>\n        <ContentControl x:Name=\"Control2\" HorizontalContentAlignment=\"Stretch\"/>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/Controls/ContentTransitionControl.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Media.Animation;\n\nnamespace Meridian.Controls\n{\n    /// <summary>\n    /// Interaction logic for ContentTransitionControl.xaml\n    /// </summary>\n    public partial class ContentTransitionControl : UserControl\n    {\n        private ContentControl _currentControl;\n        private ContentControl _newControl;\n\n        public new static readonly DependencyProperty ContentTemplateProperty =\n            DependencyProperty.Register(\"ContentTemplate\", typeof(DataTemplate), typeof(ContentTransitionControl), new PropertyMetadata(default(DataTemplate), ContentTemplatePropertyChanged));\n\n        public static readonly DependencyProperty SourceProperty =\n            DependencyProperty.Register(\"Source\", typeof(object), typeof(ContentTransitionControl), new PropertyMetadata(default(object), SourcePropertyChanged));\n\n        private static void SourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var control = (ContentTransitionControl)d;\n\n            control._currentControl.Content = e.NewValue;\n\n            control.Swap();\n\n            if (e.OldValue != null)\n                control.AnimateOut();\n\n            if (e.NewValue != null)\n                control.AnimateIn();\n        }\n\n        public object Source\n        {\n            get { return GetValue(SourceProperty); }\n            set { SetValue(SourceProperty, value); }\n        }\n\n        private static void ContentTemplatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var control = (ContentTransitionControl)d;\n\n            control._currentControl.ContentTemplate = (DataTemplate)e.NewValue;\n            control._newControl.ContentTemplate = (DataTemplate)e.NewValue;\n        }\n\n        public new DataTemplate ContentTemplate\n        {\n            get { return (DataTemplate)GetValue(ContentTemplateProperty); }\n            set { SetValue(ContentTemplateProperty, value); }\n        }\n\n        public ContentTransitionControl()\n        {\n            InitializeComponent();\n\n            _currentControl = Control1;\n            _newControl = Control2;\n        }\n\n        private void Swap()\n        {\n            var x = _currentControl;\n            _currentControl = _newControl;\n            _newControl = x;\n        }\n\n        private void AnimateOut()\n        {\n            var s = (Storyboard)Resources[\"TransitionOut\"];\n            s.Begin(_currentControl);\n        }\n\n        private void AnimateIn()\n        {\n            var s = (Storyboard)Resources[\"TransitionIn\"];\n            s.Begin(_newControl);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/ExtendedListBox.cs",
    "content": "﻿using System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing System.Windows.Media;\n\nnamespace Meridian.Controls\n{\n    public class ExtendedListBox : ListBox\n    {\n        private ScrollViewer _scrollViewer;\n\n        public static readonly DependencyProperty LoadMoreCommandProperty =\n            DependencyProperty.Register(\"LoadMoreCommand\", typeof(ICommand), typeof(ExtendedListBox), new PropertyMetadata(default(ICommand)));\n\n        public ICommand LoadMoreCommand\n        {\n            get { return (ICommand)GetValue(LoadMoreCommandProperty); }\n            set { SetValue(LoadMoreCommandProperty, value); }\n        }\n\n        public ExtendedListBox()\n        {\n            Unloaded += ExtendedListBox_Unloaded;\n        }\n\n        void ExtendedListBox_Unloaded(object sender, RoutedEventArgs e)\n        {\n            if (_scrollViewer != null)\n                _scrollViewer.ScrollChanged -= _scrollViewer_ScrollChanged;\n        }\n\n        public override void OnApplyTemplate()\n        {\n            _scrollViewer = (ScrollViewer)FindElementRecursive(this, typeof(ScrollViewer));\n            _scrollViewer.ScrollChanged += _scrollViewer_ScrollChanged;\n\n            base.OnApplyTemplate();\n        }\n\n        void _scrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)\n        {\n            if (_scrollViewer == null || LoadMoreCommand == null)\n                return;\n\n            if (e.VerticalOffset == _scrollViewer.ScrollableHeight && e.VerticalChange != 0)\n                LoadMoreCommand.Execute(null);\n        }\n\n        private UIElement FindElementRecursive(FrameworkElement parent, Type targetType)\n        {\n            int childCount = VisualTreeHelper.GetChildrenCount(parent);\n            UIElement returnElement = null;\n            if (childCount > 0)\n            {\n                for (int i = 0; i < childCount; i++)\n                {\n                    var element = VisualTreeHelper.GetChild(parent, i);\n                    if (element.GetType() == targetType)\n                    {\n                        return element as UIElement;\n                    }\n                    else\n                    {\n                        returnElement = FindElementRecursive(VisualTreeHelper.GetChild(parent, i) as FrameworkElement, targetType);\n                    }\n                }\n            }\n            return returnElement;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/FlyoutContent.cs",
    "content": "﻿using System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing GalaSoft.MvvmLight.Command;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.Controls\n{\n    public class FlyoutContent : UserControl\n    {\n        #region Commands\n\n        public RelayCommand CloseCommand { get; private set; }\n\n        #endregion\n\n        public FlyoutContent()\n        {\n            InitializeCommand();\n        }\n\n        private void InitializeCommand()\n        {\n            CloseCommand = new RelayCommand(Close);\n        }\n\n        protected void Close()\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n                flyout.Close();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/FlyoutControl.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Controls.FlyoutControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"300\"\n             Grid.RowSpan=\"100\" Grid.ColumnSpan=\"100\"\n             x:Name=\"rootElement\">\n    <UserControl.Resources>\n        <Storyboard x:Key=\"CloseAnim\" Completed=\"CloseAnim_OnCompleted\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n    </UserControl.Resources>\n    <UserControl.Triggers>\n        <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n            <BeginStoryboard>\n                <Storyboard>\n                    <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"content\" Storyboard.TargetProperty=\"(UIElement.RenderTransform).(ScaleTransform.ScaleX)\">\n                        <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"1.07\"/>\n                        <EasingDoubleKeyFrame KeyTime=\"0:0:0.3\" Value=\"1\">\n                            <EasingDoubleKeyFrame.EasingFunction>\n                                <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"4\"/>\n                            </EasingDoubleKeyFrame.EasingFunction>\n                        </EasingDoubleKeyFrame>\n                    </DoubleAnimationUsingKeyFrames>\n                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                        <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n                        <EasingDoubleKeyFrame KeyTime=\"0:0:0.35\" Value=\"1\">\n                            <EasingDoubleKeyFrame.EasingFunction>\n                                <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                            </EasingDoubleKeyFrame.EasingFunction>\n                        </EasingDoubleKeyFrame>\n                    </DoubleAnimationUsingKeyFrames>\n                </Storyboard>\n            </BeginStoryboard>\n        </EventTrigger>\n    </UserControl.Triggers>\n    <Grid>\n        <Rectangle Fill=\"Black\" Opacity=\"0.4\"/>\n        <ContentControl x:Name=\"content\" Content=\"{Binding FlyoutContent, ElementName=rootElement}\" ContentTemplate=\"{Binding FlyoutContentTemplate, ElementName=rootElement}\"\n                        RenderTransformOrigin=\"0.5,0.5\">\n            <ContentControl.RenderTransform>\n                <ScaleTransform ScaleY=\"{Binding RelativeSource={RelativeSource Self}, Path=ScaleX}\"/>\n            </ContentControl.RenderTransform>\n        </ContentControl>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/Controls/FlyoutControl.xaml.cs",
    "content": "﻿using System;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Forms;\nusing System.Windows.Input;\nusing System.Windows.Media.Animation;\nusing GongSolutions.Wpf.DragDrop.Utilities;\nusing Application = System.Windows.Application;\nusing MessageBox = System.Windows.MessageBox;\nusing Panel = System.Windows.Controls.Panel;\nusing UserControl = System.Windows.Controls.UserControl;\n\nnamespace Meridian.Controls\n{\n    /// <summary>\n    /// Interaction logic for FlyoutControl.xaml\n    /// </summary>\n    public partial class FlyoutControl : UserControl\n    {\n        private object _result = null;\n\n        public static readonly DependencyProperty FlyoutContentProperty =\n            DependencyProperty.Register(\"FlyoutContent\", typeof(object), typeof(FlyoutControl), new PropertyMetadata(default(object)));\n\n        public object FlyoutContent\n        {\n            get { return (object)GetValue(FlyoutContentProperty); }\n            set { SetValue(FlyoutContentProperty, value); }\n        }\n\n        public static readonly DependencyProperty FlyoutContentTemplateProperty =\n            DependencyProperty.Register(\"FlyoutContentTemplate\", typeof(DataTemplate), typeof(FlyoutControl), new PropertyMetadata(default(DataTemplate)));\n\n        public DataTemplate FlyoutContentTemplate\n        {\n            get { return (DataTemplate)GetValue(FlyoutContentTemplateProperty); }\n            set { SetValue(FlyoutContentTemplateProperty, value); }\n        }\n\n        public delegate void ClosedEventHandler(object result);\n        public event ClosedEventHandler Closed;\n\n        public FlyoutControl()\n        {\n            InitializeComponent();\n        }\n\n        public void Show()\n        {\n            var mainWindow = Application.Current.MainWindow;\n            if (mainWindow.Content == null)\n                return;\n\n            var panel = mainWindow.GetVisualDescendent<Panel>(); //mainWindow.Content as Panel;\n            if (panel == null)\n            {\n                return;\n            }\n\n            panel.Children.Add(this);\n        }\n\n        public Task<object> ShowAsync()\n        {\n            var tcs = new TaskCompletionSource<object>();\n\n            Show();\n            Closed += (result) => tcs.TrySetResult(result);\n\n            return tcs.Task;\n        }\n\n        public void Close(object result = null)\n        {\n            _result = result;\n\n            ((Storyboard)Resources[\"CloseAnim\"]).Begin(this);\n        }\n\n        public void CloseNow(object result = null)\n        {\n            _result = result;\n\n            CloseInternal();\n        }\n\n        private void CloseAnim_OnCompleted(object sender, EventArgs e)\n        {\n            CloseInternal();\n        }\n\n        private void CloseInternal()\n        {\n            var mainWindow = Application.Current.MainWindow;\n\n            if (mainWindow.Content == null)\n                return;\n\n            var panel = mainWindow.GetVisualDescendent<Panel>();//mainWindow.Content as Panel;\n            if (panel == null)\n            {\n                return;\n            }\n\n            panel.Children.Remove(this);\n\n            if (Closed != null)\n                Closed(_result);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/ImageTransitionControl.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Controls.ImageTransitionControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"300\" x:Name=\"rootElement\">\n    <UserControl.Resources>\n        <Storyboard x:Key=\"BgTransitionOut\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\" Storyboard.TargetName=\"BackgroundRectangle\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.9\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard x:Key=\"BgTransitionIn\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\" Storyboard.TargetName=\"BackgroundRectangle\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\" />\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.7\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        \n        <Storyboard x:Key=\"TransitionOut\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.9\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard x:Key=\"TransitionIn\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\" />\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.9\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n    </UserControl.Resources>\n\n    <Grid>\n        <Rectangle x:Name=\"BackgroundRectangle\" Fill=\"{Binding ElementName=rootElement, Path=ImageBackground}\" Opacity=\"0\"/>\n        <Grid x:Name=\"LayoutRoot\">\n            <Image x:Name=\"Image1\" Stretch=\"UniformToFill\" Opacity=\"0\" HorizontalAlignment=\"{Binding ElementName=rootElement, Path=HorizontalContentAlignment}\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n            <Image x:Name=\"Image2\" Stretch=\"UniformToFill\" HorizontalAlignment=\"{Binding ElementName=rootElement, Path=HorizontalContentAlignment}\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n        </Grid>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/Controls/ImageTransitionControl.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Media;\nusing System.Windows.Media.Animation;\n\nnamespace Meridian.Controls\n{\n    /// <summary>\n    /// Interaction logic for ImageTransitionControl.xaml\n    /// </summary>\n    public partial class ImageTransitionControl : UserControl\n    {\n        private Image _currentImage;\n        private Image _newImage;\n\n        public static readonly DependencyProperty SourceProperty =\n            DependencyProperty.Register(\"Source\", typeof(ImageSource), typeof(ImageTransitionControl), new PropertyMetadata(default(ImageSource), ImageSourcePropertyChanged));\n\n        private static void ImageSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var control = (ImageTransitionControl)d;\n\n            control.Swap();\n\n            control._newImage.Source = (ImageSource)e.NewValue;\n\n            if (e.OldValue != null)\n                control.AnimateOut();\n\n            if (e.NewValue != null)\n            {\n                control.AnimateIn();\n            }\n        }\n\n        public ImageSource Source\n        {\n            get { return (ImageSource)GetValue(SourceProperty); }\n            set { SetValue(SourceProperty, value); }\n        }\n\n        public static readonly DependencyProperty ImageOpacityProperty =\n            DependencyProperty.Register(\"ImageOpacity\", typeof(double), typeof(ImageTransitionControl), new PropertyMetadata(default(double), ImageOpacityPropertyChanged));\n\n        private static void ImageOpacityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var control = (ImageTransitionControl)d;\n\n            if (e.NewValue != null)\n            {\n                var storyboard = (Storyboard)control.Resources[\"TransitionIn\"];\n                var anim = (DoubleAnimationUsingKeyFrames)storyboard.Children[0];\n                var keyFrame = anim.KeyFrames[1];\n                keyFrame.Value = (double)e.NewValue;\n            }\n        }\n\n        public double ImageOpacity\n        {\n            get { return (double)GetValue(ImageOpacityProperty); }\n            set { SetValue(ImageOpacityProperty, value); }\n        }\n\n\n        public static readonly DependencyProperty ImageBackgroundProperty =\n            DependencyProperty.Register(\"ImageBackground\", typeof(Brush), typeof(ImageTransitionControl), new PropertyMetadata(default(Brush)));\n\n\n        public Brush ImageBackground\n        {\n            get { return (Brush)GetValue(ImageBackgroundProperty); }\n            set { SetValue(ImageBackgroundProperty, value); }\n        }\n\n        public ImageTransitionControl()\n        {\n            InitializeComponent();\n\n            _currentImage = Image1;\n            _newImage = Image2;\n        }\n\n        private void Swap()\n        {\n            var x = _currentImage;\n            _currentImage = _newImage;\n            _newImage = x;\n        }\n\n        private void AnimateOut()\n        {\n            var s = (Storyboard)Resources[\"TransitionOut\"];\n\n            s.Begin(_currentImage);\n\n            s = (Storyboard)Resources[\"BgTransitionOut\"];\n\n            s.Begin();\n        }\n\n        private void AnimateIn()\n        {\n            var s = (Storyboard)Resources[\"TransitionIn\"];\n\n            s.Begin(_newImage);\n\n            s = (Storyboard)Resources[\"BgTransitionIn\"];\n\n            s.Begin();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/LocalSearchControl.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Controls.LocalSearchControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:controls=\"clr-namespace:Meridian.Controls\"\n             xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n             xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"300\"\n             x:Name=\"rootElement\"\n             Loaded=\"LocalSearchControl_OnLoaded\" KeyDown=\"LocalSearchControl_OnKeyDown\"\n             GotFocus=\"LocalSearchControl_OnGotFocus\" IsVisibleChanged=\"LocalSearchControl_OnIsVisibleChanged\">\n    <i:Interaction.Behaviors>\n        <behaviours:VisibilityTransitionBehaviour Value=\"{Binding IsActive, ElementName=rootElement, Converter={StaticResource BoolToVisibilityConverter}}\" AnimationIn=\"{StaticResource LocalSearchBoxTransitionIn}\" AnimationOut=\"{StaticResource LocalSearchBoxTransitionOut}\"/>\n    </i:Interaction.Behaviors>\n    <UserControl.RenderTransform>\n        <TranslateTransform />\n    </UserControl.RenderTransform>\n    <Border x:Name=\"LocalSearchBoxRootBorder\" Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Top\" Width=\"200\" Margin=\"0,-1,20,0\" BorderThickness=\"1,0,1,1\" HorizontalAlignment=\"Right\"\n            SnapsToDevicePixels=\"False\">\n        <Border.BorderBrush>\n            <SolidColorBrush Color=\"{DynamicResource ForegroundColor}\" Opacity=\"0.15\"/>\n        </Border.BorderBrush>\n        <Grid>\n            <controls:TextBoxWithHint x:Name=\"LocalSearchBox\" Style=\"{StaticResource LocalSearchBoxStyle}\" Padding=\"0,0,20,0\" Margin=\"10,10,5,10\" Hint=\"Start typing\" Height=\"24\" \n                                      HintStyle=\"{StaticResource TextBoxHintStyle}\"\n                                      TextChanged=\"LocalSearchBox_OnTextChanged\">\n            </controls:TextBoxWithHint>\n            <Button x:Name=\"CloseLocalSearchBoxButton\" Width=\"12\" Background=\"Transparent\" HorizontalAlignment=\"Right\" Margin=\"0,1,10,0\"\n                        Template=\"{StaticResource CancelSearchBoxButton}\" Click=\"CloseLocalSearchBoxButton_OnClick\"/>\n        </Grid>\n    </Border>\n</UserControl>\n"
  },
  {
    "path": "Meridian/Controls/LocalSearchControl.xaml.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Input;\nusing System.Windows.Threading;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.Controls\n{\n    /// <summary>\n    /// Interaction logic for LocalSearchControl.xaml\n    /// </summary>\n    public partial class LocalSearchControl : UserControl\n    {\n        #region IsActive property\n\n        public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register(\n            \"IsActive\", typeof(bool), typeof(LocalSearchControl), new PropertyMetadata(default(bool), IsActiveChanged));\n\n        private static void IsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var c = (LocalSearchControl)d;\n            if ((bool)e.NewValue)\n            {\n                //c.Visibility = Visibility.Visible;\n            }\n            else\n            {\n                //c.Visibility = Visibility.Collapsed;\n                c.LocalSearchBox.Text = string.Empty;\n            }\n        }\n\n        public bool IsActive\n        {\n            get { return (bool)GetValue(IsActiveProperty); }\n            set { SetValue(IsActiveProperty, value); }\n        }\n\n        #endregion\n\n        #region Source property\n\n        public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(\n            \"Source\", typeof(CollectionViewSource), typeof(LocalSearchControl), new PropertyMetadata(default(CollectionViewSource)));\n\n        public CollectionViewSource Source\n        {\n            get { return (CollectionViewSource)GetValue(SourceProperty); }\n            set { SetValue(SourceProperty, value); }\n        }\n\n        #endregion\n\n        #region Filter property\n\n        public static readonly DependencyProperty FilterProperty = DependencyProperty.Register(\n            \"Filter\", typeof(Predicate<object>), typeof(LocalSearchControl), new PropertyMetadata(default(Predicate<object>)));\n\n        public Predicate<object> Filter\n        {\n            get { return (Predicate<object>)GetValue(FilterProperty); }\n            set { SetValue(FilterProperty, value); }\n        }\n\n        #endregion\n\n        #region Query property\n\n        public static readonly DependencyProperty QueryProperty = DependencyProperty.Register(\n            \"Query\", typeof(string), typeof(LocalSearchControl), new PropertyMetadata(default(string)));\n\n        public string Query\n        {\n            get { return (string)GetValue(QueryProperty); }\n            set { SetValue(QueryProperty, value); }\n        }\n\n        #endregion\n\n        public bool IsFiltering { get; set; }\n\n        public LocalSearchControl()\n        {\n            InitializeComponent();\n        }\n\n        public static LocalSearchControl GetForCurrentView()\n        {\n            return (Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is LocalSearchControl) as LocalSearchControl);\n        }\n\n        private void LocalSearchControl_OnLoaded(object sender, RoutedEventArgs e)\n        {\n\n        }\n\n        private void LocalSearchBox_OnTextChanged(object sender, TextChangedEventArgs e)\n        {\n            Query = LocalSearchBox.Text;\n\n            if (Source != null && Source.View != null)\n            {\n                Source.IsLiveFilteringRequested = !string.IsNullOrEmpty(Query);\n                IsFiltering = !string.IsNullOrEmpty(Query);\n                if (Source.View.Filter == null)\n                    Source.View.Filter = Filter;\n                else\n                    Source.View.Refresh();\n            }\n        }\n\n        private void CloseLocalSearchBoxButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            IsActive = false;\n        }\n\n        private void LocalSearchControl_OnKeyDown(object sender, KeyEventArgs e)\n        {\n            if (e.Key == Key.Escape)\n                IsActive = false;\n        }\n\n        private void LocalSearchControl_OnGotFocus(object sender, RoutedEventArgs e)\n        {\n            LocalSearchBox.Focus();\n        }\n\n        private void LocalSearchControl_OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)\n        {\n            if ((bool)e.NewValue)\n            {\n                //майкрософт, убей себя пожалуйста об стену\n                Dispatcher.BeginInvoke(DispatcherPriority.ContextIdle, new Action(() => LocalSearchBox.Focus()));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/NotificationControl.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Controls.NotificationControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"300\"\n             x:Name=\"rootElement\">\n    <UserControl.Resources>\n        <Storyboard x:Key=\"SwitchInAnim\" Completed=\"SwitchInAnim_OnCompleted\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"StatusTextBlockRenderTransform\" Storyboard.TargetProperty=\"Y\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0:0:0.0\" Value=\"-20\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.6\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"StatusTextBlock\" Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0:0:0.0\" Value=\"0\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.6\" Value=\"0.6\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard x:Key=\"SwitchOutAnim\" Completed=\"SwitchOutAnim_OnCompleted\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"StatusTextBlock\" Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.4\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n    </UserControl.Resources>\n    <Grid>\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"Auto\"/>\n            <ColumnDefinition />\n        </Grid.ColumnDefinitions>\n        <ProgressBar x:Name=\"ProgressBar\" Style=\"{StaticResource CommonProgressBarStyle}\" VerticalAlignment=\"Center\" Margin=\"3,2,10,0\" Visibility=\"Collapsed\" Padding=\"0\" Width=\"150\" Height=\"5\" Value=\"{Binding Progress, ElementName=rootElement}\"/>\n \n        <TextBlock Grid.Column=\"1\"  Name=\"StatusTextBlock\" FontSize=\"11\" Margin=\"0,0,0,0\" Text=\"{Binding Status, ElementName=rootElement}\"\n                   TextTrimming=\"CharacterEllipsis\" Foreground=\"{DynamicResource ForegroundBrush}\" Opacity=\"0.6\">\n            <TextBlock.RenderTransform>\n                <TranslateTransform x:Name=\"StatusTextBlockRenderTransform\"/>\n            </TextBlock.RenderTransform>\n        </TextBlock>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/Controls/NotificationControl.xaml.cs",
    "content": "﻿using System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Media.Animation;\nusing System.Windows.Threading;\n\nnamespace Meridian.Controls\n{\n    /// <summary>\n    /// Interaction logic for NotificationControl.xaml\n    /// </summary>\n    public partial class NotificationControl : UserControl\n    {\n        private DispatcherTimer _timer;\n        private bool _isStatusVisible;\n\n        public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(\n          \"Status\", typeof(string), typeof(NotificationControl), new PropertyMetadata(null, OnNotificationChanged));\n\n        public static readonly DependencyProperty ProgressProperty = DependencyProperty.Register(\n            \"Progress\", typeof (int), typeof (NotificationControl), new PropertyMetadata(default(int), ProgressChanged));\n\n        private static void ProgressChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var control = (NotificationControl) d;\n            if ((int)e.NewValue >= 100)\n                control.ProgressBar.Visibility = Visibility.Collapsed;\n            else\n                control.ProgressBar.Visibility = Visibility.Visible;\n        }\n\n        public int Progress\n        {\n            get { return (int) GetValue(ProgressProperty); }\n            set { SetValue(ProgressProperty, value); }\n        }\n\n        public string Status\n        {\n            get { return (string)GetValue(StatusProperty); }\n            set\n            {\n                SetValue(StatusProperty, value);\n            }\n        }\n\n        public NotificationControl()\n        {\n            InitializeComponent();\n\n            _timer = new DispatcherTimer();\n            _timer.Interval = TimeSpan.FromSeconds(3);\n            _timer.Tick += TimerTick;\n        }\n\n        private void TimerTick(object sender, EventArgs e)\n        {\n            //UpdateStatus(string.Empty);\n            Status = string.Empty;\n\n            _timer.Stop();\n\n            var outAnim = (Storyboard)Resources[\"SwitchOutAnim\"];\n            outAnim.Begin(this);\n        }\n\n        private void UpdateStatus(string newValue)\n        {\n            //var outAnim = (Storyboard)Resources[\"SwitchOutAnim\"];\n            //outAnim.Begin(this);\n\n            var inAnim = (Storyboard)Resources[\"SwitchInAnim\"];\n            inAnim.Begin();\n        }\n\n        private static void OnNotificationChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)\n        {\n            var control = (NotificationControl)o;\n\n            if (e.NewValue != null)\n                control.UpdateStatus(e.NewValue.ToString());\n            //else if (e.NewValue == null)\n            //    control.UpdateStatus(string.Empty);\n        }\n\n        private void SwitchOutAnim_OnCompleted(object sender, EventArgs e)\n        {\n            //this.StatusTextBlock.Text = Status;\n\n            //var inAnim = (Storyboard)Resources[\"SwitchInAnim\"];\n            //inAnim.Begin(this);\n\n            //if (!string.IsNullOrEmpty(_newValue))\n            //{\n            //    _timer.Stop();\n            //    _timer.Start();\n            //}\n        }\n\n        private void SwitchInAnim_OnCompleted(object sender, EventArgs e)\n        {\n            if (!string.IsNullOrEmpty(Status))\n            {\n                _timer.Stop();\n                _timer.Start();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/PageBase.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Windows;\nusing System.Windows.Controls;\n\nnamespace Meridian.Controls\n{\n    public sealed class NavigationContext\n    {\n        private readonly Dictionary<string, object> _parameters;\n\n        public Dictionary<string, object> Parameters\n        {\n            get { return _parameters; }\n            set\n            {\n                if (value == null)\n                    return;\n\n                foreach (var kp in value)\n                {\n                    _parameters.Add(kp.Key, kp.Value);\n                }\n            }\n        }\n\n        public NavigationContext()\n        {\n            _parameters = new Dictionary<string, object>();\n        }\n    }\n\n    public class PageBase : Page\n    {\n        public NavigationContext NavigationContext { get; set; }\n\n        public PageBase()\n        {\n            NavigationContext = new NavigationContext();\n\n            this.Loaded += PageBase_Loaded;\n            this.Unloaded += PageBase_Unloaded;\n        }\n\n        public virtual void OnNavigatedTo()\n        {\n\n        }\n\n        public virtual void OnNavigatedFrom()\n        {\n\n        }\n\n        private void PageBase_Unloaded(object sender, RoutedEventArgs e)\n        {\n            this.Loaded -= PageBase_Loaded;\n            this.Unloaded -= PageBase_Unloaded;\n\n            OnNavigatedFrom();\n        }\n\n        private void PageBase_Loaded(object sender, RoutedEventArgs e)\n        {\n            OnNavigatedTo();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/PlayerControl.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Controls.PlayerControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             xmlns:controls=\"clr-namespace:Meridian.Controls\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"185\"\n             DataContext=\"{Binding Main, Source={StaticResource Locator}}\">\n    <StackPanel>\n        <Grid Height=\"150\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"150\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n            <Grid>\n                <Rectangle Fill=\"{DynamicResource AccentBrush}\" Opacity=\"0.6\"/>\n                <Image Source=\"/Resources/Images/cover_default.png\" Margin=\"50\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                <controls:ImageTransitionControl Source=\"{Binding TrackImage}\" HorizontalContentAlignment=\"Center\"/>\n            </Grid>\n            <StackPanel Grid.Column=\"1\" Orientation=\"Vertical\" HorizontalAlignment=\"Left\"  VerticalAlignment=\"Center\" Margin=\"0,0,0,0\">\n                <ToggleButton Margin=\"0,0,0,0\" Width=\"32\" Height=\"32\" IsChecked=\"{Binding Main.EnableStatusBroadcasting, Mode=TwoWay, Source={StaticResource Locator}}\" Style=\"{StaticResource VkStatusButtonStyle}\"\n                              IsEnabled=\"{Binding Main.CanBroadcast, Source={StaticResource Locator}}\"\n                          ToolTip=\"{x:Static localization:MainResources.VkStatusBroadcasting}\" Command=\"{Binding VkBroadcastCommand}\">\n                    <ToggleButton.RenderTransform>\n                        <TranslateTransform />\n                    </ToggleButton.RenderTransform>\n                </ToggleButton>\n\n                <ToggleButton Width=\"32\" Height=\"32\" Margin=\"0,7,0,3\" IsEnabled=\"True\" IsChecked=\"{Binding Main.EnableScrobbling, Mode=TwoWay, Source={StaticResource Locator}}\" Style=\"{StaticResource LastFmScrobbleButtonStyle}\"\n                          ToolTip=\"{x:Static localization:MainResources.LastFmScrobbling}\">\n                    <ToggleButton.RenderTransform>\n                        <TranslateTransform />\n                    </ToggleButton.RenderTransform>\n                </ToggleButton>\n\n                <ToggleButton Width=\"32\" Height=\"32\" Margin=\"0,10,0,0\" IsChecked=\"{Binding Main.Shuffle, Mode=TwoWay, Source={StaticResource Locator}}\" Style=\"{StaticResource ShuffleButtonStyle}\"\n                          ToolTip=\"{x:Static localization:MainResources.Shuffle}\">\n                    <ToggleButton.RenderTransform>\n                        <TranslateTransform />\n                    </ToggleButton.RenderTransform>\n                </ToggleButton>\n\n                <ToggleButton Width=\"32\" Height=\"32\" Margin=\"0,10,0,0\" IsChecked=\"{Binding Main.Repeat, Mode=TwoWay, Source={StaticResource Locator}}\" Style=\"{StaticResource RepeatButtonStyle}\"\n                          ToolTip=\"{x:Static localization:MainResources.Repeat}\">\n                    <ToggleButton.RenderTransform>\n                        <TranslateTransform />\n                    </ToggleButton.RenderTransform>\n                </ToggleButton>\n            </StackPanel>\n        </Grid>\n\n        <Popup x:Name=\"CurrentAudioMenuPopup\" PlacementTarget=\"{Binding ElementName=CurrentAudioMenuButton}\" StaysOpen=\"False\" HorizontalOffset=\"20\" VerticalOffset=\"10\"\n               PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=CurrentAudioMenuButton, Path=IsChecked, Mode=TwoWay}\">\n            <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"#a0a0a0\" DataContext=\"{Binding CurrentAudio}\">\n                <ItemsControl>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAdd}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              Click=\"MenuItem_OnClick\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuEdit}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}}\" Command=\"{Binding Main.EditAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              Click=\"MenuItem_OnClick\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuRemove}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              Click=\"MenuItem_OnClick\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuShare}\" Command=\"{Binding Main.ShareAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              Click=\"MenuItem_OnClick\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuLyrics}\" IsEnabled=\"{Binding HasLyrics}\" Command=\"{Binding Main.ShowLyricsCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              Click=\"MenuItem_OnClick\"/>\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuStartRadio}\" Command=\"{Binding Main.StartTrackRadioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              Click=\"MenuItem_OnClick\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuShowArtistInfo}\" Command=\"{Binding Main.ShowArtistInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" \n                              Click=\"MenuItem_OnClick\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuSearchArtist}\" Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" \n                              Click=\"MenuItem_OnClick\"/>\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding Main.AddToNowPlayingCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              Click=\"MenuItem_OnClick\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuPlayNext}\" Command=\"{Binding Main.PlayAudioNextCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              Click=\"MenuItem_OnClick\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuCopyInfo}\" Command=\"{Binding Main.CopyInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              Click=\"MenuItem_OnClick\"/>\n\n                </ItemsControl>\n            </Border>\n        </Popup>\n\n        <ToggleButton x:Name=\"CurrentAudioMenuButton\" Style=\"{StaticResource CurrentAudioMenuButtonStyle}\">\n            <StackPanel DataContext=\"{Binding CurrentAudio}\" HorizontalAlignment=\"Left\" Width=\"150\">\n                <TextBlock Text=\"{Binding Title, Converter={StaticResource StringToUpperConverter}}\" FontWeight=\"Bold\" FontSize=\"15\" TextTrimming=\"CharacterEllipsis\" MaxHeight=\"36\"\n                       Foreground=\"{DynamicResource SidebarForegroundBrush}\" ToolTip=\"{Binding Title}\">\n                </TextBlock>\n                <TextBlock Text=\"{Binding Artist}\" FontWeight=\"Normal\" FontSize=\"14\" Opacity=\"0.6\" Margin=\"0,0,0,0\" TextTrimming=\"CharacterEllipsis\"\n                       Foreground=\"{DynamicResource SidebarForegroundBrush}\" ToolTip=\"{Binding Artist}\">\n                </TextBlock>\n            </StackPanel>\n        </ToggleButton>\n\n        <Grid HorizontalAlignment=\"Left\" Margin=\"0,10,0,0\" Width=\"150\">\n            <Grid.RowDefinitions>\n                <RowDefinition />\n                <RowDefinition />\n            </Grid.RowDefinitions>\n            <Slider IsMoveToPointEnabled=\"True\"\n                Value=\"{Binding Main.CurrentAudioPositionSeconds, Source={StaticResource Locator}, Mode=TwoWay}\" Maximum=\"{Binding Main.CurrentAudioDuration.TotalSeconds, Source={StaticResource Locator}, Mode=OneWay}\"\n                Style=\"{StaticResource CommonSliderStyle}\" Background=\"{DynamicResource SidebarSliderBackgroundBrush}\" />\n            <TextBlock Text=\"{Binding Main.CurrentAudioPosition, Source={StaticResource Locator}, Converter={StaticResource AudioTimeSpanConverter}}\" FontSize=\"10\" Opacity=\"0.5\" Margin=\"0,17,0,0\" Foreground=\"{DynamicResource SidebarForegroundBrush}\"/>\n            <TextBlock Text=\"{Binding Main.CurrentAudioDuration, Source={StaticResource Locator}, Converter={StaticResource AudioTimeSpanConverter}}\" FontSize=\"10\" Opacity=\"0.5\" Margin=\"0,17,0,0\" HorizontalAlignment=\"Right\" Foreground=\"{DynamicResource SidebarForegroundBrush}\"/>\n        </Grid>\n\n        <Border Width=\"150\" HorizontalAlignment=\"Left\">\n            <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Center\" Margin=\"0,0,10,0\">\n                <Button Margin=\"0,0,7,0\" Command=\"{Binding Main.PrevAudioCommand, Source={StaticResource Locator}}\" Width=\"26\" Height=\"26\" Style=\"{StaticResource PrevButtonStyle}\" Foreground=\"{DynamicResource SidebarForegroundBrush}\"\n                    ToolTip=\"{x:Static localization:MainResources.PrevTrack}\">\n                    <Button.RenderTransform>\n                        <TranslateTransform />\n                    </Button.RenderTransform>\n                </Button>\n                <ToggleButton Width=\"36\" Height=\"36\" IsChecked=\"{Binding IsPlaying, Mode=TwoWay}\" Command=\"{Binding Main.PlayPauseCommand, Source={StaticResource Locator}}\" Style=\"{StaticResource PlayPauseButtonStyle}\" Foreground=\"{DynamicResource SidebarForegroundBrush}\"\n                          ToolTip=\"{x:Static localization:MainResources.PlayPause}\">\n                    <ToggleButton.RenderTransform>\n                        <TranslateTransform />\n                    </ToggleButton.RenderTransform>\n                </ToggleButton>\n                <Button Margin=\"7,0,0,0\" Command=\"{Binding Main.NextAudioCommand, Source={StaticResource Locator}}\" Width=\"26\" Height=\"26\" Style=\"{StaticResource NextButtonStyle}\" Foreground=\"{DynamicResource SidebarForegroundBrush}\"\n                    ToolTip=\"{x:Static localization:MainResources.NextTrack}\">\n                    <Button.RenderTransform>\n                        <TranslateTransform />\n                    </Button.RenderTransform>\n                </Button>\n            </StackPanel>\n        </Border>\n\n        <Border Width=\"150\" HorizontalAlignment=\"Left\" Margin=\"0,5,0,0\">\n            <controls:VolumeControl Margin=\"5,0,5,0\" Volume=\"{Binding Volume, Mode=TwoWay}\"/>\n        </Border>\n    </StackPanel>\n</UserControl>\n"
  },
  {
    "path": "Meridian/Controls/PlayerControl.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\n\nnamespace Meridian.Controls\n{\n    /// <summary>\n    /// Interaction logic for PlayerControl.xaml\n    /// </summary>\n    public partial class PlayerControl : UserControl\n    {\n        public PlayerControl()\n        {\n            InitializeComponent();\n        }\n\n        private void MenuItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            CurrentAudioMenuPopup.SetValue(Popup.IsOpenProperty, false);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/ShareBarControl.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Controls.ShareBarControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:dragDrop=\"clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"150\" d:DesignWidth=\"500\"\n             Background=\"{DynamicResource MainBackgroundBrush}\"\n             x:Name=\"rootElement\">\n    <Grid x:Name=\"rootGrid\" Margin=\"24,10,24,10\"              \n          dragDrop:DragDrop.IsDropTarget=\"True\" dragDrop:DragDrop.DragHandler=\"{Binding}\" dragDrop:DragDrop.DropHandler=\"{Binding}\">\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition />\n            <ColumnDefinition Width=\"Auto\"/>\n        </Grid.ColumnDefinitions>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        \n        <Rectangle Fill=\"Transparent\" Grid.ColumnSpan=\"2\" Grid.RowSpan=\"2\"/>\n\n        <TextBlock Text=\"{x:Static localization:MainResources.ShareBarTitle}\" Foreground=\"{DynamicResource ForegroundBrush}\" HorizontalAlignment=\"Center\" FontSize=\"16\" Opacity=\"0.2\" VerticalAlignment=\"Top\" Margin=\"0,-5,0,0\"/>\n        \n        <ItemsControl Grid.Row=\"1\" ItemsSource=\"{Binding Tracks}\" Margin=\"0,5,0,5\">\n            <ItemsControl.ItemsPanel>\n                <ItemsPanelTemplate>\n                    <WrapPanel Orientation=\"Vertical\"/>\n                </ItemsPanelTemplate>\n            </ItemsControl.ItemsPanel>\n            <ItemsControl.ItemTemplate>\n                <DataTemplate>\n                    <Button Style=\"{StaticResource SimpleButtonStyle}\" Width=\"180\" Margin=\"0,0,10,0\">\n                        <Grid >\n                            <Grid.ColumnDefinitions>\n                                <ColumnDefinition />\n                                <ColumnDefinition Width=\"Auto\"/>\n                            </Grid.ColumnDefinitions>\n                            <TextBlock x:Name=\"Title\" Text=\"{Binding Title}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"14\" TextTrimming=\"CharacterEllipsis\"\n                                    ToolTip=\"{Binding Title}\"/>\n                            <Button Grid.Column=\"1\" Style=\"{StaticResource CloseButtonStyle}\" SnapsToDevicePixels=\"True\" Command=\"{Binding DataContext.RemoveTrackCommand, ElementName=rootGrid}\" CommandParameter=\"{Binding}\"\n                                    VerticalAlignment=\"Center\" Margin=\"3,0,0,0\"/>\n                        </Grid>\n                    </Button>\n                </DataTemplate>\n            </ItemsControl.ItemTemplate>\n        </ItemsControl>\n        \n        <StackPanel Orientation=\"Horizontal\" Grid.Row=\"2\" HorizontalAlignment=\"Right\">\n            <Button Style=\"{StaticResource HighlightedButtonStyle}\" Content=\"{x:Static localization:MainResources.NextButton}\" Margin=\"0,0,15,0\" IsEnabled=\"{Binding CanGoNext}\" Command=\"{Binding GoNextCommand}\"/>\n            <Button Style=\"{StaticResource CommonButtonStyle}\" Content=\"{x:Static localization:MainResources.CancelButton}\" Command=\"{Binding CancelCommand}\"/>\n        </StackPanel>\n\n        <Rectangle Fill=\"{StaticResource SplitterBrush}\" Height=\"1\"  Margin=\"-24,-34,-24,0\" Opacity=\"0.3\"/>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/Controls/ShareBarControl.xaml.cs",
    "content": "﻿using System.Windows.Controls;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Flyouts;\n\nnamespace Meridian.Controls\n{\n    /// <summary>\n    /// Interaction logic for ShareBarControl.xaml\n    /// </summary>\n    public partial class ShareBarControl : UserControl\n    {\n        private ShareViewModel _viewModel;\n\n        public ShareBarControl()\n        {\n            InitializeComponent();\n\n            _viewModel = new ShareViewModel();\n            rootGrid.DataContext = _viewModel;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/TextBoxWithHint.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\n\nnamespace Meridian.Controls\n{\n    public class TextBoxWithHint : TextBox\n    {\n        private ContentControl _hintContent;\n\n        public static readonly DependencyProperty HintProperty =\n            DependencyProperty.Register(\"Hint\", typeof(object), typeof(TextBoxWithHint), new PropertyMetadata(default(object)));\n\n        public static readonly DependencyProperty HintStyleProperty =\n            DependencyProperty.Register(\"HintStyle\", typeof(Style), typeof(TextBoxWithHint), new PropertyMetadata(default(Style)));\n\n        public Style HintStyle\n        {\n            get { return (Style)GetValue(HintStyleProperty); }\n            set { SetValue(HintStyleProperty, value); }\n        }\n\n        public object Hint\n        {\n            get { return GetValue(HintProperty); }\n            set { SetValue(HintProperty, value); }\n        }\n\n        public TextBoxWithHint()\n        {\n            DefaultStyleKey = typeof(TextBoxWithHint);\n        }\n\n        public override void OnApplyTemplate()\n        {\n            base.OnApplyTemplate();\n\n            _hintContent = GetTemplateChild(\"HintContent\") as ContentControl;\n            DetermineHintVisibility();\n        }\n\n        protected override void OnGotFocus(RoutedEventArgs e)\n        {\n            DetermineHintVisibility();\n            base.OnGotFocus(e);\n        }\n\n        protected override void OnLostFocus(RoutedEventArgs e)\n        {\n            DetermineHintVisibility();\n            base.OnLostFocus(e);\n        }\n\n        protected override void OnTextChanged(TextChangedEventArgs e)\n        {\n            DetermineHintVisibility();\n            base.OnTextChanged(e);\n        }\n\n        private void DetermineHintVisibility()\n        {\n            if(_hintContent != null)\n            {\n                if (string.IsNullOrEmpty(this.Text) && !IsFocused)\n                {\n                    _hintContent.Visibility = Visibility.Visible;\n                }\n                else\n                {\n                    _hintContent.Visibility = Visibility.Collapsed;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/VirtualizingWrapPanel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Media;\n\nnamespace Meridian.Controls\n{\n    public class VirtualizingWrapPanel : VirtualizingPanel, IScrollInfo\n    {\n        private const double ScrollLineAmount = 16.0;\n\n        private Size _extentSize;\n        private Size _viewportSize;\n        private Point _offset;\n        private ItemsControl _itemsControl;\n        private readonly Dictionary<UIElement, Rect> _childLayouts = new Dictionary<UIElement, Rect>();\n\n        public static readonly DependencyProperty ItemWidthProperty =\n            DependencyProperty.Register(\"ItemWidth\", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(1.0, HandleItemDimensionChanged));\n\n        public static readonly DependencyProperty ItemHeightProperty =\n            DependencyProperty.Register(\"ItemHeight\", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(1.0, HandleItemDimensionChanged));\n\n        private static readonly DependencyProperty VirtualItemIndexProperty =\n            DependencyProperty.RegisterAttached(\"VirtualItemIndex\", typeof(int), typeof(VirtualizingWrapPanel), new PropertyMetadata(-1));\n        private IRecyclingItemContainerGenerator _itemsGenerator;\n\n        private bool _isInMeasure;\n\n        private static int GetVirtualItemIndex(DependencyObject obj)\n        {\n            return (int)obj.GetValue(VirtualItemIndexProperty);\n        }\n\n        private static void SetVirtualItemIndex(DependencyObject obj, int value)\n        {\n            obj.SetValue(VirtualItemIndexProperty, value);\n        }\n\n        public double ItemHeight\n        {\n            get { return (double)GetValue(ItemHeightProperty); }\n            set { SetValue(ItemHeightProperty, value); }\n        }\n\n        public double ItemWidth\n        {\n            get { return (double)GetValue(ItemWidthProperty); }\n            set { SetValue(ItemWidthProperty, value); }\n        }\n\n        public VirtualizingWrapPanel()\n        {\n            //if (!DesignerProperties.IsInDesignTool)\n            //{\n            Dispatcher.BeginInvoke(new Action(Initialize));\n            //}\n        }\n\n        private void Initialize()\n        {\n            _itemsControl = ItemsControl.GetItemsOwner(this);\n            _itemsGenerator = (IRecyclingItemContainerGenerator)ItemContainerGenerator;\n\n            InvalidateMeasure();\n        }\n\n        protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args)\n        {\n            base.OnItemsChanged(sender, args);\n\n            InvalidateMeasure();\n        }\n\n        protected override Size MeasureOverride(Size availableSize)\n        {\n            if (_itemsControl == null)\n            {\n                _itemsControl = ItemsControl.GetItemsOwner(this);\n            }\n\n            if (_itemsControl == null)\n            {\n                return availableSize;\n            }\n\n            _isInMeasure = true;\n            _childLayouts.Clear();\n\n            var extentInfo = GetExtentInfo(availableSize, ItemHeight);\n\n            EnsureScrollOffsetIsWithinConstrains(extentInfo);\n\n            var layoutInfo = GetLayoutInfo(availableSize, ItemHeight, extentInfo);\n\n            RecycleItems(layoutInfo);\n\n            if (_itemsGenerator == null)\n                Initialize();\n\n            // Determine where the first item is in relation to previously realized items\n            var generatorStartPosition = _itemsGenerator.GeneratorPositionFromIndex(layoutInfo.FirstRealizedItemIndex);\n\n            var visualIndex = 0;\n\n            var currentX = layoutInfo.FirstRealizedItemLeft;\n            var currentY = layoutInfo.FirstRealizedLineTop;\n\n            using (_itemsGenerator.StartAt(generatorStartPosition, GeneratorDirection.Forward, true))\n            {\n                for (var itemIndex = layoutInfo.FirstRealizedItemIndex; itemIndex <= layoutInfo.LastRealizedItemIndex; itemIndex++, visualIndex++)\n                {\n                    bool newlyRealized;\n\n                    var child = (UIElement)_itemsGenerator.GenerateNext(out newlyRealized);\n                    if (child == null)\n                        continue;\n\n                    SetVirtualItemIndex(child, itemIndex);\n\n                    if (newlyRealized)\n                    {\n                        InsertInternalChild(visualIndex, child);\n                    }\n                    else\n                    {\n                        // check if item needs to be moved into a new position in the Children collection\n                        if (visualIndex < Children.Count)\n                        {\n                            if (Children[visualIndex] != child)\n                            {\n                                var childCurrentIndex = Children.IndexOf(child);\n\n                                if (childCurrentIndex >= 0)\n                                {\n                                    RemoveInternalChildRange(childCurrentIndex, 1);\n                                }\n\n                                InsertInternalChild(visualIndex, child);\n                            }\n                        }\n                        else\n                        {\n                            // we know that the child can't already be in the children collection\n                            // because we've been inserting children in correct visualIndex order,\n                            // and this child has a visualIndex greater than the Children.Count\n                            AddInternalChild(child);\n                        }\n                    }\n\n                    // only prepare the item once it has been added to the visual tree\n                    _itemsGenerator.PrepareItemContainer(child);\n\n                    child.Measure(new Size(ItemWidth, ItemHeight));\n\n                    _childLayouts.Add(child, new Rect(currentX, currentY, ItemWidth, ItemHeight));\n\n                    if (currentX + ItemWidth * 2 >= availableSize.Width)\n                    {\n                        // wrap to a new line\n                        currentY += ItemHeight;\n                        currentX = 0;\n                    }\n                    else\n                    {\n                        currentX += ItemWidth;\n                    }\n                }\n            }\n\n            RemoveRedundantChildren();\n            UpdateScrollInfo(availableSize, extentInfo);\n\n            var desiredSize = new Size(double.IsInfinity(availableSize.Width) ? 100 : availableSize.Width,\n                                       double.IsInfinity(availableSize.Height) ? 100 : availableSize.Height);\n\n            _isInMeasure = false;\n\n            return desiredSize;\n        }\n\n        private void EnsureScrollOffsetIsWithinConstrains(ExtentInfo extentInfo)\n        {\n            _offset.Y = Clamp(_offset.Y, 0, extentInfo.MaxVerticalOffset);\n        }\n\n        private void RecycleItems(ItemLayoutInfo layoutInfo)\n        {\n            foreach (UIElement child in Children)\n            {\n                var virtualItemIndex = GetVirtualItemIndex(child);\n\n                if (virtualItemIndex < layoutInfo.FirstRealizedItemIndex || virtualItemIndex > layoutInfo.LastRealizedItemIndex)\n                {\n                    var generatorPosition = _itemsGenerator.GeneratorPositionFromIndex(virtualItemIndex);\n                    if (generatorPosition.Index >= 0)\n                    {\n                        _itemsGenerator.Recycle(generatorPosition, 1);\n                    }\n                }\n\n                SetVirtualItemIndex(child, -1);\n            }\n        }\n\n        protected override Size ArrangeOverride(Size finalSize)\n        {\n            foreach (UIElement child in Children)\n            {\n                child.Arrange(_childLayouts[child]);\n            }\n\n            return finalSize;\n        }\n\n        private void UpdateScrollInfo(Size availableSize, ExtentInfo extentInfo)\n        {\n            _viewportSize = availableSize;\n            _extentSize = new Size(availableSize.Width, extentInfo.ExtentHeight);\n\n            InvalidateScrollInfo();\n        }\n\n        private void RemoveRedundantChildren()\n        {\n            // iterate backwards through the child collection because we're going to be\n            // removing items from it\n            for (var i = Children.Count - 1; i >= 0; i--)\n            {\n                var child = Children[i];\n\n                // if the virtual item index is -1, this indicates\n                // it is a recycled item that hasn't been reused this time round\n                if (GetVirtualItemIndex(child) == -1)\n                {\n                    RemoveInternalChildRange(i, 1);\n                }\n            }\n        }\n\n        private ItemLayoutInfo GetLayoutInfo(Size availableSize, double itemHeight, ExtentInfo extentInfo)\n        {\n            if (_itemsControl == null)\n            {\n                return new ItemLayoutInfo();\n            }\n\n            // we need to ensure that there is one realized item prior to the first visible item, and one after the last visible item,\n            // so that keyboard navigation works properly. For example, when focus is on the first visible item, and the user\n            // navigates up, the ListBox selects the previous item, and the scrolls that into view - and this triggers the loading of the rest of the items \n            // in that row\n\n            var firstVisibleLine = (int)Math.Floor(VerticalOffset / itemHeight);\n\n            var firstRealizedIndex = Math.Max(extentInfo.ItemsPerLine * firstVisibleLine - 1, 0);\n            var firstRealizedItemLeft = firstRealizedIndex % extentInfo.ItemsPerLine * ItemWidth - HorizontalOffset;\n            var firstRealizedItemTop = (firstRealizedIndex / extentInfo.ItemsPerLine) * itemHeight - VerticalOffset;\n\n            var firstCompleteLineTop = (firstVisibleLine == 0 ? firstRealizedItemTop : firstRealizedItemTop + ItemHeight);\n            var completeRealizedLines = (int)Math.Ceiling((availableSize.Height - firstCompleteLineTop) / itemHeight);\n\n            var lastRealizedIndex = Math.Min(firstRealizedIndex + completeRealizedLines * extentInfo.ItemsPerLine + 2, _itemsControl.Items.Count - 1);\n\n            return new ItemLayoutInfo\n            {\n                FirstRealizedItemIndex = firstRealizedIndex,\n                FirstRealizedItemLeft = firstRealizedItemLeft,\n                FirstRealizedLineTop = firstRealizedItemTop,\n                LastRealizedItemIndex = lastRealizedIndex,\n            };\n        }\n\n        private ExtentInfo GetExtentInfo(Size viewPortSize, double itemHeight)\n        {\n            if (_itemsControl == null)\n            {\n                return new ExtentInfo();\n            }\n\n            var itemsPerLine = Math.Max((int)Math.Floor(viewPortSize.Width / ItemWidth), 1);\n            var totalLines = (int)Math.Ceiling((double)_itemsControl.Items.Count / itemsPerLine);\n            var extentHeight = Math.Max(totalLines * ItemHeight, viewPortSize.Height);\n\n            return new ExtentInfo()\n            {\n                ItemsPerLine = itemsPerLine,\n                TotalLines = totalLines,\n                ExtentHeight = extentHeight,\n                MaxVerticalOffset = extentHeight - viewPortSize.Height,\n            };\n        }\n\n        public void LineUp()\n        {\n            SetVerticalOffset(VerticalOffset - ScrollLineAmount);\n        }\n\n        public void LineDown()\n        {\n            SetVerticalOffset(VerticalOffset + ScrollLineAmount);\n        }\n\n        public void LineLeft()\n        {\n            SetHorizontalOffset(HorizontalOffset + ScrollLineAmount);\n        }\n\n        public void LineRight()\n        {\n            SetHorizontalOffset(HorizontalOffset - ScrollLineAmount);\n        }\n\n        public void PageUp()\n        {\n            SetVerticalOffset(VerticalOffset - ViewportHeight);\n        }\n\n        public void PageDown()\n        {\n            SetVerticalOffset(VerticalOffset + ViewportHeight);\n        }\n\n        public void PageLeft()\n        {\n            SetHorizontalOffset(HorizontalOffset + ItemWidth);\n        }\n\n        public void PageRight()\n        {\n            SetHorizontalOffset(HorizontalOffset - ItemWidth);\n        }\n\n        public void MouseWheelUp()\n        {\n            SetVerticalOffset(VerticalOffset - ScrollLineAmount * SystemParameters.WheelScrollLines);\n        }\n\n        public void MouseWheelDown()\n        {\n            SetVerticalOffset(VerticalOffset + ScrollLineAmount * SystemParameters.WheelScrollLines);\n        }\n\n        public void MouseWheelLeft()\n        {\n            SetHorizontalOffset(HorizontalOffset - ScrollLineAmount * SystemParameters.WheelScrollLines);\n        }\n\n        public void MouseWheelRight()\n        {\n            SetHorizontalOffset(HorizontalOffset + ScrollLineAmount * SystemParameters.WheelScrollLines);\n        }\n\n        public void SetHorizontalOffset(double offset)\n        {\n            if (_isInMeasure)\n            {\n                return;\n            }\n\n            offset = Clamp(offset, 0, ExtentWidth - ViewportWidth);\n            _offset = new Point(offset, _offset.Y);\n\n            InvalidateScrollInfo();\n            InvalidateMeasure();\n        }\n\n        public void SetVerticalOffset(double offset)\n        {\n            if (_isInMeasure)\n            {\n                return;\n            }\n\n            offset = Clamp(offset, 0, ExtentHeight - ViewportHeight);\n            _offset = new Point(_offset.X, offset);\n\n            InvalidateScrollInfo();\n            InvalidateMeasure();\n        }\n\n        public Rect MakeVisible(Visual visual, Rect rectangle)\n        {\n            return new Rect();\n        }\n\n        public ItemLayoutInfo GetVisibleItemsRange()\n        {\n            return GetLayoutInfo(_viewportSize, ItemHeight, GetExtentInfo(_viewportSize, ItemHeight));\n        }\n\n        public bool CanVerticallyScroll\n        {\n            get;\n            set;\n        }\n\n        public bool CanHorizontallyScroll\n        {\n            get;\n            set;\n        }\n\n        public double ExtentWidth\n        {\n            get { return _extentSize.Width; }\n        }\n\n        public double ExtentHeight\n        {\n            get { return _extentSize.Height; }\n        }\n\n        public double ViewportWidth\n        {\n            get { return _viewportSize.Width; }\n        }\n\n        public double ViewportHeight\n        {\n            get { return _viewportSize.Height; }\n        }\n\n        public double HorizontalOffset\n        {\n            get { return _offset.X; }\n        }\n\n        public double VerticalOffset\n        {\n            get { return _offset.Y; }\n        }\n\n        public ScrollViewer ScrollOwner\n        {\n            get;\n            set;\n        }\n\n        private void InvalidateScrollInfo()\n        {\n            if (ScrollOwner != null)\n            {\n                ScrollOwner.InvalidateScrollInfo();\n            }\n        }\n\n        private static void HandleItemDimensionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var wrapPanel = (d as VirtualizingWrapPanel);\n\n            wrapPanel.InvalidateMeasure();\n        }\n\n\n        private double Clamp(double value, double min, double max)\n        {\n            return Math.Min(Math.Max(value, min), max);\n        }\n\n        internal class ExtentInfo\n        {\n            public int ItemsPerLine;\n            public int TotalLines;\n            public double ExtentHeight;\n            public double MaxVerticalOffset;\n        }\n    }\n\n    public class ItemLayoutInfo\n    {\n        public int FirstRealizedItemIndex;\n        public double FirstRealizedLineTop;\n        public double FirstRealizedItemLeft;\n        public int LastRealizedItemIndex;\n    }\n}\n"
  },
  {
    "path": "Meridian/Controls/VolumeControl.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Controls.VolumeControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"20\" d:DesignWidth=\"300\"\n             Background=\"Transparent\"\n             x:Name=\"rootElement\" MouseWheel=\"VolumeControl_OnMouseWheel\">\n    <Grid>\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"Auto\"/>\n            <ColumnDefinition />\n            <ColumnDefinition Width=\"Auto\"/>\n        </Grid.ColumnDefinitions>\n        <Button Grid.Column=\"0\" x:Name=\"MinVolumeButton\" Template=\"{StaticResource MuteButton}\" Width=\"14\" Margin=\"0,-4,10,0\" Click=\"MuteButton_OnClick\" HorizontalAlignment=\"Center\" Opacity=\"0.5\"/>\n        <Slider IsMoveToPointEnabled=\"True\" Grid.Column=\"1\" VerticalAlignment=\"Center\" Background=\"{DynamicResource SidebarSliderBackgroundBrush}\"\n                Maximum=\"100\"\n                Style=\"{StaticResource VolumeSliderStyle}\" Value=\"{Binding Volume, Mode=TwoWay, ElementName=rootElement}\"/>\n        <Button Grid.Column=\"2\" x:Name=\"MaxVolumeButton\" Template=\"{StaticResource VolumeButton}\" Width=\"14\" Margin=\"10,-3,0,0\" Click=\"VolumeButton_OnClick\" HorizontalAlignment=\"Center\" Opacity=\"0.5\"/>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/Controls/VolumeControl.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\n\nnamespace Meridian.Controls\n{\n    /// <summary>\n    /// Interaction logic for VolumeControl.xaml\n    /// </summary>\n    public partial class VolumeControl : UserControl\n    {\n        public static readonly DependencyProperty VolumeProperty =\n            DependencyProperty.Register(\"Volume\", typeof(double), typeof(VolumeControl), new PropertyMetadata(default(double)));\n\n        public double Volume\n        {\n            get { return (double)GetValue(VolumeProperty); }\n            set { SetValue(VolumeProperty, value); }\n        }\n\n        public static readonly DependencyProperty IsMuteProperty =\n            DependencyProperty.Register(\"IsMute\", typeof(bool), typeof(VolumeControl), new PropertyMetadata(default(bool)));\n\n        public bool IsMute\n        {\n            get { return (bool)GetValue(IsMuteProperty); }\n            set { SetValue(IsMuteProperty, value); }\n        }\n\n\n        public VolumeControl()\n        {\n            InitializeComponent();\n        }\n\n        private void VolumeButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            Volume = 100;\n        }\n\n        private void VolumeControl_OnMouseWheel(object sender, MouseWheelEventArgs e)\n        {\n            //if (!VolumePopup.IsOpen)\n            //    VolumePopup.IsOpen = true;\n            \n            if (e.Delta < 0)\n            {\n                Volume -= 5;\n                if (Volume < 0)\n                    Volume = 0;\n            }\n            else\n            {\n                Volume += 5;\n                if (Volume > 100)\n                    Volume = 100;\n            }\n        }\n\n        private void MuteButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            Volume = 0;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Converters/AlbumContextMenuVisibilityConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Windows;\nusing System.Windows.Data;\nusing VkLib.Core.Audio;\n\nnamespace Meridian.Converters\n{\n    public class AlbumContextMenuVisibilityConverter : IValueConverter\n    {\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            var album = value as VkAudioAlbum;\n            if (album == null)\n                return Visibility.Visible;\n\n            if (album.OwnerId != 0)\n                return Visibility.Visible;\n\n            return Visibility.Collapsed;\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Converters/AlbumListItemContainerSelector.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing VkLib.Core.Audio;\n\nnamespace Meridian.Converters\n{\n    public class AlbumListItemContainerStyleSelector : StyleSelector\n    {\n        /// <summary>\n        /// Стиль для стандартных альбомов (\"все аудиозаписи, \"со стены\" и т.п.)\n        /// </summary>\n        public Style DefaultItemStyle { get; set; }\n\n        /// <summary>\n        /// Стиль для пользовательских альбомов\n        /// </summary>\n        public Style ItemStyle { get; set; }\n\n        /// <summary>\n        /// Стиль для разделителя\n        /// </summary>\n        public Style SeparatorStyle { get; set; }\n\n        /// <summary>\n        /// Стиль для кнопки создания альбома\n        /// </summary>\n        public Style AddAlbumStyle { get; set; }\n\n        public override Style SelectStyle(object item, DependencyObject container)\n        {\n            var album = item as VkPlaylist;\n            if (album != null)\n            {\n\n                switch ((int)album.Id)\n                {\n                    case -1:\n                    case -100:\n                    case -101:\n                        return DefaultItemStyle;\n\n                    case int.MinValue:\n                        return SeparatorStyle;\n\n                    default:\n                        return ItemStyle;\n                }\n            }\n\n            return base.SelectStyle(item, container);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Converters/AudioTemplateSelector.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing Meridian.Model;\n\nnamespace Meridian.Converters\n{\n    public class AudioTemplateSelector : DataTemplateSelector\n    {\n        public DataTemplate AudioTemplate { get; set; }\n\n        public DataTemplate LocalAudioTemplate { get; set; }\n\n        public DataTemplate PostTemplate { get; set; }\n\n        public override DataTemplate SelectTemplate(object item, DependencyObject container)\n        {\n            if (item is AudioPost)\n                return PostTemplate;\n\n            if (item is LocalAudio)\n                return LocalAudioTemplate;\n\n            if (item is Audio)\n                return AudioTemplate;\n\n            return AudioTemplate;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Converters/AudioTimeSpanConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Windows.Data;\n\nnamespace Meridian.Converters\n{\n    public class AudioTimeSpanConverter : IValueConverter\n    {\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            var timeSpan = (TimeSpan) value;\n            if (timeSpan.Hours > 0)\n                return timeSpan.ToString(\"h\\\\:mm\\\\:ss\");\n            return timeSpan.ToString(\"m\\\\:ss\");\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Converters/BooleanToValueConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Windows.Data;\n\nnamespace Meridian.Converters\n{\n    public class BooleanToValueConverter : IValueConverter\n    {\n        public object TrueValue { get; set; }\n\n        public object FalseValue { get; set; }\n\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            var v = (bool) value;\n            if (v)\n                return TrueValue;\n            return FalseValue;\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Converters/MainMenuGroupStyleSelector.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\n\nnamespace Meridian.Converters\n{\n    public class MainMenuGroupStyleSelector : StyleSelector\n    {\n        public Style EmptyHeaderGroupStyle { get; set; }\n\n        public Style NormalGroupStyle { get; set; }\n\n        public override Style SelectStyle(object item, DependencyObject container)\n        {\n            var group = item as CollectionViewGroup;\n            if (group == null)\n                return null;\n\n            if (string.IsNullOrEmpty((string) group.Name))\n                return EmptyHeaderGroupStyle;\n\n            return NormalGroupStyle;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Converters/SearchResultTemplateSelector.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing LastFmLib.Core.Album;\nusing LastFmLib.Core.Artist;\nusing Meridian.Model;\nusing VkLib.Core.Groups;\n\nnamespace Meridian.Converters\n{\n    public class SearchResultTemplateSelector : DataTemplateSelector\n    {\n        public DataTemplate TrackTemplate { get; set; }\n\n        public DataTemplate LocalTrackTemplate { get; set; }\n\n        public DataTemplate AlbumTemplate { get; set; }\n\n        public DataTemplate LocalAlbumTemplate { get; set; }\n\n        public DataTemplate ArtistTemplate { get; set; }\n\n        public DataTemplate LocalArtistTemplate { get; set; }\n\n        public DataTemplate SocietyTemplate { get; set; }\n\n        public override DataTemplate SelectTemplate(object item, DependencyObject container)\n        {\n            if (item is LocalAudio)\n                return LocalTrackTemplate;\n            else if (item is Audio)\n                return TrackTemplate;\n            else if (item is LastFmAlbum)\n                return AlbumTemplate;\n            else if (item is LastFmArtist)\n                return ArtistTemplate;\n            else if (item is VkGroup)\n                return SocietyTemplate;\n            else if (item is AudioAlbum)\n                return LocalAlbumTemplate;\n            else if (item is AudioArtist)\n                return LocalArtistTemplate;\n            return null;\n        }\n    }\n\n    public class SearchResultStyleSelector : StyleSelector\n    {\n        public Style TrackStyle { get; set; }\n\n        public Style AlbumStyle { get; set; }\n\n        public Style ArtistStyle { get; set; }\n\n        public Style LocalArtistStyle { get; set; }\n\n        public Style SocietyStyle { get; set; }\n\n        public override Style SelectStyle(object item, DependencyObject container)\n        {\n            if (item is Audio)\n                return TrackStyle;\n            else if (item is LastFmAlbum || item is AudioAlbum)\n                return AlbumStyle;\n            else if (item is LastFmArtist)\n                return ArtistStyle;\n            else if (item is AudioArtist)\n                return LocalArtistStyle;\n            else if (item is VkGroup)\n                return SocietyStyle;\n            return null;\n        }\n    }\n\n    public class SearchListBoxStyleSelector : IValueConverter\n    {\n        public Style TracksStyle { get; set; }\n\n        public Style AlbumsStyle { get; set; }\n\n        public Style ArtistsStyle { get; set; }\n\n        public Style LocalArtistsStyle { get; set; }\n\n        public Style SocietiesStyle { get; set; }\n\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            var index = (int)value;\n            switch (index)\n            {\n                case 0:\n                    return TracksStyle;\n                case 1:\n                    return AlbumsStyle;\n                case 2:\n                    return ArtistsStyle;\n                case 3:\n                    return TracksStyle;\n                case 4:\n                    return AlbumsStyle;\n                case 5:\n                    return LocalArtistsStyle;\n            }\n            return null;\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Domain/Settings.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\nusing System.Windows;\nusing System.Windows.Input;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.Services.Media.Core;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing Newtonsoft.Json.Serialization;\nusing VkLib.Core.Auth;\nusing VkLib.Core.Groups;\nusing Meridian.Controls;\nusing Meridian.View.Flyouts;\nusing System.Diagnostics;\n\nnamespace Meridian.Domain\n{\n    public class Settings\n    {\n        private const string SETTINGS_FILE = \"Meridian.settings\";\n\n        private static Settings _instance = new Settings();\n\n        public static Settings Instance\n        {\n            get { return _instance; }\n        }\n\n        public List<Account> Accounts { get; set; } \n\n        public VkAccessToken AccessToken { get; set; }\n\n        public bool Shuffle { get; set; }\n\n        public bool Repeat { get; set; }\n\n        public float Volume { get; set; }\n\n        public bool IsMuted { get; set; }\n\n        public bool EnableStatusBroadcasting { get; set; }\n\n        public bool EnableScrobbling { get; set; }\n\n        public string LastFmUsername { get; set; }\n\n        public string LastFmSession { get; set; }\n\n        public bool CheckForUpdates { get; set; }\n\n        public bool InstallDevUpdates { get; set; }\n\n        public bool NeedClean { get; set; }\n\n        public string AccentColor { get; set; }\n\n        public string Theme { get; set; }\n\n        public string Language { get; set; }\n\n        public bool SendStats { get; set; }\n\n        public bool ShowTrackNotifications { get; set; }\n\n        public bool EnableTrayIcon { get; set; }\n\n        public bool ShowBackgroundArt { get; set; }\n\n        public bool ShowBackgroundArtCompactMode { get; set; }\n\n        public bool BlurBackground { get; set; }\n\n        public bool DownloadArtistArt { get; set; }\n\n        public bool DownloadAlbumArt { get; set; }\n\n        public bool TellRequestShown { get; set; }\n\n        public DateTime FirstStart { get; set; }\n\n        public MediaEngine MediaEngine { get; set; }\n\n        public List<VkGroup> FeedSocieties { get; set; }\n\n        public bool EnableRemotePlay { get; set; }\n\n        public int RemotePlayPort { get; set; }\n\n        public string RemotePlayAddress { get; set; }\n\n        public bool UseHttps { get; set; }\n\n        #region Window settings\n\n        public double Width { get; set; }\n        public double Height { get; set; }\n        public double Top { get; set; }\n        public double Left { get; set; }\n        public bool IsWindowMaximized { get; set; }\n        public double CompactTop { get; set; }\n        public double CompactLeft { get; set; }\n        public UIMode LastCompactMode { get; set; }\n\n        #endregion\n\n        #region Hotkeys\n\n        public Key NextHotKey { get; set; }\n        public ModifierKeys NextHotKeyModifier { get; set; }\n        public Key PrevHotKey { get; set; }\n        public ModifierKeys PrevHotKeyModifier { get; set; }\n        public Key PlayPauseHotKey { get; set; }\n        public ModifierKeys PlayPauseHotKeyModifier { get; set; }\n        public Key ShowHideHotKey { get; set; }\n        public ModifierKeys ShowHideHotKeyModifier { get; set; }\n        public Key LikeDislikeHotKey { get; set; }\n        public ModifierKeys LikeDislikeHotKeyModifier { get; set; }\n        public Key ShuffleHotKey { get; set; }\n        public ModifierKeys ShuffleHotKeyModifier { get; set; }\n        public Key RepeatHotKey { get; set; }\n        public ModifierKeys RepeatHotKeyModifier { get; set; }\n        public Key IncreaseVolumeHotKey { get; set; }\n        public ModifierKeys IncreaseVolumeHotKeyModifier { get; set; }\n        public Key DecreaseVolumeHotKey { get; set; }\n        public ModifierKeys DecreaseVolumeHotKeyModifier { get; set; }\n        public Key FastForwardHotKey { get; set; }\n        public ModifierKeys FastForwardHotKeyModifier { get; set; }\n        public Key RewindHotKey { get; set; }\n        public ModifierKeys RewindHotKeyModifier { get; set; }\n\n        #endregion\n\n        public Settings()\n        {\n            Width = 1024;\n            Height = 650;\n\n            Left = SystemParameters.PrimaryScreenWidth / 2 - Width / 2;\n            Top = SystemParameters.PrimaryScreenHeight / 2 - Height / 2;\n\n            CompactLeft = SystemParameters.PrimaryScreenWidth / 2 - 250 / 2;\n            CompactTop = SystemParameters.PrimaryScreenHeight / 2 - 160 / 2;\n\n            Volume = 0.5f;\n\n            CheckForUpdates = true;\n\n            AccentColor = \"Blue\";\n            Theme = \"Light\";\n            Language = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;\n\n            ShowTrackNotifications = true;\n\n            SendStats = true;\n\n            FirstStart = DateTime.Now;\n\n            DownloadArtistArt = true;\n            DownloadAlbumArt = true;\n\n            BlurBackground = false;\n            ShowBackgroundArt = true;\n            ShowBackgroundArtCompactMode = true;\n\n            Accounts = new List<Account>();\n\n            MediaEngine = MediaEngine.Uwp;\n\n            FeedSocieties = new List<VkGroup>();\n\n            EnableRemotePlay = false;\n            RemotePlayPort = 9999;\n\n            UseHttps = false;\n        }\n\n        public static void Load()\n        {\n            if (!File.Exists(SETTINGS_FILE))\n                return;\n\n            try\n            {\n                var json = File.ReadAllText(SETTINGS_FILE);\n                if (string.IsNullOrEmpty(json))\n                    return;\n\n                var serializer = new JsonSerializer();\n                var o = (JObject)JsonConvert.DeserializeObject(json);\n                var settings = serializer.Deserialize<Settings>(o.CreateReader());\n                _instance = settings;\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        public async void Save()\n        {\n            try\n            {\n                var settings = new JsonSerializerSettings()\n                {\n                    ContractResolver = new CamelCasePropertyNamesContractResolver()\n                };\n\n                var json = JsonConvert.SerializeObject(this, settings);\n\n                File.WriteAllText(SETTINGS_FILE, json);\n            }\n            catch (UnauthorizedAccessException ex)\n            {\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new CommonErrorView(ErrorResources.AccessDeniedErrorTitle, ErrorResources.AccessDeniedErrorDescription);\n                flyout.ShowAsync().ContinueWith(t =>\n                {\n                    if ((bool)t.Result == true)\n                    {\n                        var info = new ProcessStartInfo();\n                        info.UseShellExecute = true;\n                        info.FileName = Application.ResourceAssembly.Location;\n                        info.WorkingDirectory = Environment.CurrentDirectory;\n                        info.Verb = \"runas\";\n\n                        Process.Start(info);\n                    }\n\n                    Application.Current.Shutdown();\n\n                    LoggingService.Log(ex);\n                });\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Extensions/AudioExtensions.cs",
    "content": "﻿using System;\nusing LastFmLib.Core.Track;\nusing Meridian.Model;\nusing Meridian.ViewModel;\n\nnamespace Meridian.Extensions\n{\n    public static class AudioExtensions\n    {\n        public static VkAudio ToAudio(this VkLib.Core.Audio.VkAudio audio)\n        {\n            var result = new VkAudio();\n            result.Id = audio.Id.ToString();\n            result.Title = audio.Title;\n            result.Artist = audio.Artist;\n            result.AlbumId = audio.AlbumId;\n            result.Duration = audio.Duration;\n            result.LyricsId = audio.LyricsId;\n            result.OwnerId = audio.OwnerId;\n            result.Source = audio.Url;\n            result.GenreId = audio.GenreId;\n            result.IsAddedByCurrentUser = audio.OwnerId == ViewModelLocator.Vkontakte.AccessToken.UserId;\n            if (audio.Album?.Thumb != null && !string.IsNullOrWhiteSpace(audio.Album.Thumb.Photo300))\n                result.AlbumCover = new Uri(audio.Album.Thumb.Photo300);\n\n            return result;\n        }\n\n        public static VkAudio ToAudio(this LastFmTrack audio)\n        {\n            var result = new VkAudio();\n            result.Title = audio.Title;\n            result.Artist = audio.Artist;\n            result.Duration = TimeSpan.FromSeconds(audio.Duration);\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Extensions/CommonExtensions.cs",
    "content": "﻿using System;\n\nnamespace Meridian.Extensions\n{\n    public static class CommonExtensions\n    {\n        public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>\n        {\n            if (val.CompareTo(min) < 0) return min;\n            else if (val.CompareTo(max) > 0) return max;\n            else return val;\n        }\n\n        public static bool Contains(this string source, string toCheck, StringComparison comp)\n        {\n            return source.IndexOf(toCheck, comp) >= 0;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Extensions/ListExtensions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\n\nnamespace Meridian.Extensions\n{\n    public static class ListExtensions\n    {\n        public static void Shuffle<T>(this IList<T> list)\n        {\n            var rng = new Random(Environment.TickCount);\n            int n = list.Count;\n            while (n > 1)\n            {\n                n--;\n                int k = rng.Next(n + 1);\n                T value = list[k];\n                list[k] = list[n];\n                list[n] = value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Extensions/SocketExtensions.cs",
    "content": "﻿using System;\nusing System.Net.Sockets;\nusing System.Threading.Tasks;\n\nnamespace Meridian.Extensions\n{\n    public static class SocketExtensions\n    {\n        public static Task<int> ReceiveAsync(this Socket socket, byte[] buffer, int offset, int size, SocketFlags socketFlags)\n        {\n            var tcs = new TaskCompletionSource<int>(socket);\n            socket.BeginReceive(buffer, offset, size, socketFlags, iar =>\n            {\n                var t = (TaskCompletionSource<int>)iar.AsyncState;\n                var s = (Socket)t.Task.AsyncState;\n                try { t.TrySetResult(s.EndReceive(iar)); }\n                catch (Exception exc) { t.TrySetException(exc); }\n            }, tcs);\n            return tcs.Task;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/AlbumCoversHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing Meridian.Model;\n\nnamespace Meridian.Helpers\n{\n    public static class AlbumCoversHelper\n    {\n        private const int MAX_PARALLEL_ITEMS = 3;\n\n        private static readonly Dictionary<string, List<AudioAlbum>> _requestQueue = new Dictionary<string, List<AudioAlbum>>();\n        private static readonly object _syncRoot = new object();\n        private static bool _isQueueWorking;\n\n        /// <summary>\n        /// Ставит трек в очередь на получение обложки. Когда очередь подойдет, треку будет присвоена обложка.\n        /// </summary>\n        /// <param name=\"target\"></param>\n        public static void RequestCover(AudioAlbum target)\n        {\n            //ставим трек в очередь и сразу возвращаем null\n            EnqueueCoverRequest(target);\n        }\n\n        /// <summary>\n        /// Получить обложку\n        /// </summary>\n        /// <param name=\"target\"></param>\n        public static Task<ImageSource> GetCover(AudioAlbum target)\n        {\n            return GetImage(target.CoverPath);\n        }\n\n        private static void EnqueueCoverRequest(AudioAlbum target)\n        {\n            lock (_syncRoot)\n            {\n                if (_requestQueue.ContainsKey(target.Id))\n                {\n                    if (_requestQueue[target.Id].All(t => t != target))\n                        _requestQueue[target.Id].Add(target);\n                }\n                else\n                {\n                    _requestQueue.Add(target.Id, new List<AudioAlbum>() { target });\n                }\n            }\n\n            if (!_isQueueWorking)\n                Task.Run(() => StartQueueProcessing()); //вся обработка очереди производится в 1 потоке\n        }\n\n        private static async void StartQueueProcessing()\n        {\n            _isQueueWorking = true;\n\n            while (_requestQueue.Count > 0)\n            {\n                List<KeyValuePair<string, List<AudioAlbum>>> queueItems;\n\n                lock (_syncRoot)\n                {\n                    queueItems = _requestQueue.Take(MAX_PARALLEL_ITEMS).ToList(); //берем несколько элементов очереди\n                }\n\n                var runningTasks = new List<Task<KeyValuePair<string, ImageSource>>>();\n\n                foreach (var queuItem in queueItems)\n                {\n                    var album = queuItem.Value.FirstOrDefault();\n                    if (album == null)\n                        continue;\n                    runningTasks.Add(ProcessQueueItem(queuItem.Key, album.CoverPath));\n                }\n\n                var covers = await Task.WhenAll(runningTasks);\n\n                runningTasks.Clear();\n\n\n                foreach (var keyValuePair in covers)\n                {\n                    if (queueItems.All(i => i.Key != keyValuePair.Key))\n                        continue;\n\n                    var q = queueItems.First(i => i.Key == keyValuePair.Key); //находим соответствующий элемент\n                    for (var i = 0; i < q.Value.Count; i++) //передаем в каждый callback полученную обложку\n                    {\n                        //await Task.Delay(20);\n\n                        var target = q.Value[i];\n                        if (target != null)\n                        {\n                            KeyValuePair<string, ImageSource> pair = keyValuePair;\n                            Application.Current.Dispatcher.Invoke(() =>\n                            {\n                                target.Cover = pair.Value;\n                            });\n                        }\n                    }\n\n                    lock (_syncRoot)\n                    {\n                        _requestQueue.Remove(q.Key); //удаляем их из очереди\n                    }\n                }\n\n                await Task.Delay(100);\n            }\n\n            _isQueueWorking = false;\n\n        }\n\n        private static async Task<KeyValuePair<string, ImageSource>> ProcessQueueItem(string albumId, string coverPath)\n        {\n            ImageSource source = null;\n            try\n            {\n                source = await GetImage(coverPath);\n            }\n            catch (Exception ex)\n            {\n                Debug.WriteLine(ex);\n            }\n\n            return new KeyValuePair<string, ImageSource>(albumId, source);\n        }\n\n        private static async Task<ImageSource> GetImage(string coverPath)\n        {\n            using (var audioFile = TagLib.File.Create(coverPath))\n            {\n                var image = audioFile.Tag.Pictures.FirstOrDefault();\n                if (image != null)\n                {\n                    var ms = new MemoryStream();\n                    await ms.WriteAsync(image.Data.Data, 0, image.Data.Data.Length);\n                    ms.Seek(0, SeekOrigin.Begin);\n\n                    BitmapImage bi = null;\n\n                    //await DispatcherHelper.RunAsync(() =>\n                    //{\n                        bi = new BitmapImage();\n                    //});\n\n                    try\n                    {\n                        bi.BeginInit();\n                        bi.StreamSource = ms;\n                        bi.EndInit();\n                    }\n                    catch (Exception ex)\n                    {\n                        Debug.WriteLine(ex);\n                        return null;\n                    }\n                    bi.Freeze();\n                    return bi;\n                }\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/ArtistImageHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing Meridian.Model;\nusing Meridian.Services;\n\nnamespace Meridian.Helpers\n{\n    public static class ArtistImageHelper\n    {\n        private const int MAX_PARALLEL_ITEMS = 3;\n\n        private static readonly Dictionary<string, List<AudioArtist>> _requestQueue = new Dictionary<string, List<AudioArtist>>();\n        private static readonly object _syncRoot = new object();\n        private static bool _isQueueWorking;\n\n        /// <summary>\n        /// Ставит трек в очередь на получение обложки. Когда очередь подойдет, треку будет присвоена обложка.\n        /// </summary>\n        /// <param name=\"target\"></param>\n        public static void RequestCover(AudioArtist target)\n        {\n            //ставим трек в очередь и сразу возвращаем null\n            EnqueueCoverRequest(target);\n        }\n\n        /// <summary>\n        /// Получить обложку\n        /// </summary>\n        /// <param name=\"target\"></param>\n        public static Task<ImageSource> GetCover(AudioArtist target)\n        {\n            return GetImage(target.Title);\n        }\n\n        private static void EnqueueCoverRequest(AudioArtist target)\n        {\n            lock (_syncRoot)\n            {\n                if (_requestQueue.ContainsKey(target.Id))\n                {\n                    if (_requestQueue[target.Id].All(t => t != target))\n                        _requestQueue[target.Id].Add(target);\n                }\n                else\n                {\n                    _requestQueue.Add(target.Id, new List<AudioArtist>() { target });\n                }\n            }\n\n            if (!_isQueueWorking)\n                Task.Run(() => StartQueueProcessing()); //вся обработка очереди производится в 1 потоке\n        }\n\n        private static async void StartQueueProcessing()\n        {\n            _isQueueWorking = true;\n\n            while (_requestQueue.Count > 0)\n            {\n                List<KeyValuePair<string, List<AudioArtist>>> queueItems;\n\n                lock (_syncRoot)\n                {\n                    queueItems = _requestQueue.Take(MAX_PARALLEL_ITEMS).ToList(); //берем несколько элементов очереди\n                }\n\n                var runningTasks = new List<Task<KeyValuePair<string, ImageSource>>>();\n\n                foreach (var queuItem in queueItems)\n                {\n                    var artist = queuItem.Value.FirstOrDefault();\n                    if (artist == null)\n                        continue;\n                    runningTasks.Add(ProcessQueueItem(queuItem.Key, artist.Title));\n                }\n\n                var covers = await Task.WhenAll(runningTasks);\n\n                runningTasks.Clear();\n\n\n                foreach (var keyValuePair in covers)\n                {\n                    if (queueItems.All(i => i.Key != keyValuePair.Key))\n                        continue;\n\n                    var q = queueItems.First(i => i.Key == keyValuePair.Key); //находим соответствующий элемент\n                    for (var i = 0; i < q.Value.Count; i++) //передаем в каждый callback полученную обложку\n                    {\n                        //await Task.Delay(20);\n\n                        var target = q.Value[i];\n                        if (target != null)\n                        {\n                            KeyValuePair<string, ImageSource> pair = keyValuePair;\n                            Application.Current.Dispatcher.Invoke(() =>\n                            {\n                                target.Image = pair.Value;\n                            });\n                        }\n                    }\n\n                    lock (_syncRoot)\n                    {\n                        _requestQueue.Remove(q.Key); //удаляем их из очереди\n                    }\n                }\n\n                await Task.Delay(100);\n            }\n\n            _isQueueWorking = false;\n        }\n\n        private static async Task<KeyValuePair<string, ImageSource>> ProcessQueueItem(string albumId, string artist)\n        {\n            ImageSource source = await GetImage(artist);\n\n            return new KeyValuePair<string, ImageSource>(albumId, source);\n        }\n\n        private static async Task<ImageSource> GetImage(string artist)\n        {\n            try\n            {\n                ImageSource cachedImage = await GetImageAsync(artist);\n                return cachedImage;\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            return null;\n        }\n\n        private static Task<ImageSource> GetImageAsync(string artist)\n        {\n            var tcs = new TaskCompletionSource<ImageSource>();\n\n            Application.Current.Dispatcher.Invoke(async () =>\n            {\n                var cachedImage = await CacheService.GetCachedImage(\"artists/\" + CacheService.GetSafeFileName(artist + \"_big.jpg\"));\n                if (cachedImage != null)\n                {\n                    tcs.SetResult(cachedImage);\n                    return;\n                }\n\n                var imageUri = await DataService.GetArtistImage(artist, true);\n                if (imageUri != null)\n                {\n                    cachedImage = await CacheService.CacheImage(imageUri.OriginalString,\n                                \"artists/\" + CacheService.GetSafeFileName(artist + \"_big.jpg\"));\n\n                    tcs.SetResult(cachedImage);\n                }\n\n                tcs.SetResult(null);\n            });\n\n            return tcs.Task;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/DateTimeConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\n\nnamespace Meridian.Helpers\n{\n    /// <summary>\n    /// Utilities to convert dates to and from unix time.\n    /// </summary>\n    public static class DateTimeConverter\n    {\n        private static readonly string[] Iso8601Format = new[]\n                                                             {\n                                                                 \"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'\",\n                                                                 @\"yyyy-MM-dd\\THH:mm:ssK\"\n                                                             };\n        /// <summary>\n        /// Gets the epoch time.\n        /// </summary>\n        /// <value>The epoch time.</value>\n        public static DateTime Epoch\n        {\n            get { return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); }\n        }\n\n        /// <summary>\n        /// Converts a unix time string to a DateTime object.\n        /// </summary>\n        /// <param name=\"unixTime\">The unix time.</param>\n        /// <returns>The DateTime object.</returns>\n        public static DateTime FromUnixTime(double unixTime)\n        {\n            return Epoch.AddSeconds(unixTime);\n        }\n\n        /// <summary>\n        /// Converts a unix time string to a DateTime object.\n        /// </summary>\n        /// <param name=\"unixTime\">The string representation of the unix time.</param>\n        /// <returns>The DateTime object.</returns>\n        public static DateTime FromUnixTime(string unixTime)\n        {\n            double d;\n            if (!double.TryParse(unixTime, out d))\n            {\n                return FromUnixTime(0D);\n            }\n\n            return FromUnixTime(d);\n        }\n\n        /// <summary>\n        /// Converts a DateTime object to unix time.\n        /// </summary>\n        /// <param name=\"dateTime\">The date time.</param>\n        /// <returns>The unix date time.</returns>\n        public static double ToUnixTime(DateTime dateTime)\n        {\n            return (dateTime.ToUniversalTime() - Epoch).TotalSeconds;\n        }\n\n        /// <summary>\n        /// Converts a DateTimeOffset object to unix time.\n        /// </summary>\n        /// <param name=\"dateTime\">The date time.</param>\n        /// <returns>The unix date time.</returns>\n        public static double ToUnixTime(DateTimeOffset dateTime)\n        {\n            return (dateTime.ToUniversalTime() - Epoch).TotalSeconds;\n        }\n\n        /// <summary>\n        /// Converts to specified <see cref=\"DateTime\"/> to ISO-8601 format (yyyy-MM-ddTHH:mm:ssZ).\n        /// </summary>\n        /// <param name=\"dateTime\">\n        /// The date time.\n        /// </param>\n        /// <returns>\n        /// Returns the string representation of date time in ISO-8601 format (yyyy-MM-ddTHH:mm:ssZ).\n        /// </returns>\n        public static string ToIso8601FormattedDateTime(DateTime dateTime)\n        {\n            return dateTime.ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture);\n        }\n\n        /// <summary>\n        /// Converts ISO-8601 format (yyyy-MM-ddTHH:mm:ssZ) date time to <see cref=\"DateTime\"/>.\n        /// </summary>\n        /// <param name=\"iso8601DateTime\">\n        /// The ISO-8601 formatted date time.\n        /// </param>\n        /// <returns>\n        /// Returns the <see cref=\"DateTime\"/> equivalent to the ISO-8601 formatted date time. \n        /// </returns>\n        public static DateTime FromIso8601FormattedDateTime(string iso8601DateTime)\n        {\n            return DateTime.ParseExact(iso8601DateTime, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/FilesHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Meridian.Services;\nusing Microsoft.WindowsAPICodePack.Shell;\n\nnamespace Meridian.Helpers\n{\n    public static class FilesHelper\n    {\n        public static List<string> GetMusicFiles()\n        {\n            var musicFiles = new List<string>();\n\n            if (ShellLibrary.IsPlatformSupported)\n            {\n                var library = ShellLibrary.Load(\"Music\", true);\n                foreach (var folder in library)\n                {\n\n                    if (!Directory.Exists(folder.Path))\n                        continue;\n\n                    var files = GetDirectoryFiles(folder.Path, \"*.*\", SearchOption.AllDirectories)\n                        .Where(s => s.EndsWith(\".mp3\", StringComparison.OrdinalIgnoreCase)\n                                        || s.EndsWith(\".wma\", StringComparison.OrdinalIgnoreCase)).ToList();\n                    //var files = Directory.EnumerateFiles(folder.Path, \"*.*\", SearchOption.AllDirectories)\n                    //        .Where(s => s.EndsWith(\".mp3\", StringComparison.OrdinalIgnoreCase)\n                    //                    || s.EndsWith(\".wma\", StringComparison.OrdinalIgnoreCase)).ToList();\n\n                    musicFiles.AddRange(files);\n                }\n            }\n            else\n            {\n                musicFiles =\n                    Directory.EnumerateFiles(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic), \"*.*\", SearchOption.AllDirectories)\n                        .Where(s => s.EndsWith(\".mp3\", StringComparison.OrdinalIgnoreCase)\n                                    || s.EndsWith(\".wma\", StringComparison.OrdinalIgnoreCase)).ToList();\n            }\n\n            return musicFiles;\n        }\n\n\n        //http://stackoverflow.com/questions/5098011/directory-enumeratefiles-unauthorizedaccessexception\n        /// <summary>\n        /// A safe way to get all the files in a directory and sub directory without crashing on UnauthorizedException\n        /// </summary>\n        /// <param name=\"rootPath\">Starting directory</param>\n        /// <param name=\"patternMatch\">Filename pattern match</param>\n        /// <param name=\"searchOption\">Search subdirectories or only top level directory for files</param>\n        /// <returns>List of files</returns>\n        public static IEnumerable<string> GetDirectoryFiles(string rootPath, string patternMatch, SearchOption searchOption)\n        {\n            IEnumerable<string> foundFiles = Enumerable.Empty<string>(); // Start with an empty container\n\n            if (searchOption == SearchOption.AllDirectories)\n            {\n                try\n                {\n                    IEnumerable<string> subDirs = Directory.EnumerateDirectories(rootPath);\n                    foreach (string dir in subDirs)\n                    {\n                        foundFiles = foundFiles.Concat(GetDirectoryFiles(dir, patternMatch, searchOption)); // Add files in subdirectories recursively to the list\n                    }\n                }\n                catch (UnauthorizedAccessException) { } // Incase we have an access error - we don't want to mask the rest\n            }\n\n            try\n            {\n                foundFiles = foundFiles.Concat(Directory.EnumerateFiles(rootPath, patternMatch)); // Add files from the current directory to the list\n            }\n            catch (UnauthorizedAccessException) { } // Incase we have an access error - we don't want to mask the rest\n\n            return foundFiles; // This is it finally\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/HotKeyManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Windows;\nusing System.Windows.Input;\nusing System.Windows.Interop;\nusing Meridian.Domain;\nusing Meridian.Services;\nusing Meridian.ViewModel;\nusing Application = System.Windows.Application;\n\nnamespace Meridian.Helpers\n{\n    public sealed class HotKey : IDisposable\n    {\n        public event Action<HotKey> HotKeyPressed;\n\n        private readonly int _id;\n        private bool _isKeyRegistered;\n        readonly IntPtr _handle;\n\n        public HotKey(ModifierKeys modifierKeys, Key key, Window window)\n            : this(modifierKeys, key, new WindowInteropHelper(window))\n        {\n\n        }\n\n        public HotKey(ModifierKeys modifierKeys, Key key, WindowInteropHelper window)\n            : this(modifierKeys, key, window.Handle)\n        {\n\n        }\n\n        public HotKey(ModifierKeys modifierKeys, Key key, IntPtr windowHandle)\n        {\n            Key = key;\n            KeyModifier = modifierKeys;\n            _id = GetHashCode();\n            _handle = windowHandle;\n            RegisterHotKey();\n            ComponentDispatcher.ThreadPreprocessMessage += ThreadPreprocessMessageMethod;\n        }\n\n        ~HotKey()\n        {\n            Dispose();\n        }\n\n        public Key Key { get; private set; }\n\n        public ModifierKeys KeyModifier { get; private set; }\n\n        public void RegisterHotKey()\n        {\n            if (Key == Key.None)\n                return;\n            if (_isKeyRegistered)\n                UnregisterHotKey();\n            _isKeyRegistered = NativeMethods.RegisterHotKey(_handle, _id, KeyModifier, KeyInterop.VirtualKeyFromKey(Key));\n        }\n\n        public void UnregisterHotKey()\n        {\n            _isKeyRegistered = !NativeMethods.UnregisterHotKey(_handle, _id);\n        }\n\n        public void Dispose()\n        {\n            if (_isKeyRegistered)\n            {\n                try\n                {\n                    ComponentDispatcher.ThreadPreprocessMessage -= ThreadPreprocessMessageMethod;\n                }\n                catch\n                {\n\n                }\n\n                UnregisterHotKey();\n            }\n        }\n\n        private void ThreadPreprocessMessageMethod(ref MSG msg, ref bool handled)\n        {\n            if (!handled)\n            {\n                if (msg.message == NativeMethods.WM_HOTKEY\n                    && (int)(msg.wParam) == _id)\n                {\n                    OnHotKeyPressed();\n                    handled = true;\n                }\n            }\n        }\n\n        private void OnHotKeyPressed()\n        {\n            if (HotKeyPressed != null)\n                HotKeyPressed(this);\n        }\n    }\n\n    public class HotKeyManager : IDisposable\n    {\n        private readonly IntPtr handle;\n        private List<HotKey> hotKeys;\n\n        public HotKeyManager(IntPtr handle)\n        {\n            this.handle = handle;\n\n            RegisterHotkey(ModifierKeys.None, Key.MediaPlayPause);\n            RegisterHotkey(ModifierKeys.None, Key.MediaNextTrack);\n            RegisterHotkey(ModifierKeys.None, Key.MediaPreviousTrack);\n            RegisterHotkey(ModifierKeys.None, Key.MediaStop);\n            RegisterHotkey(ModifierKeys.None, Key.Play);\n            RegisterHotkey(ModifierKeys.None, Key.Pause);\n            RegisterHotkey(ModifierKeys.None, Key.SelectMedia);\n        }\n\n        public void RegisterHotkey(ModifierKeys modifier, Key key)\n        {\n            if (key == Key.None)\n                return;\n\n            if (hotKeys == null)\n                hotKeys = new List<HotKey>();\n            var hotkey = new HotKey(modifier, key, handle);\n            hotkey.HotKeyPressed += HotKeyPressed;\n\n            hotKeys.Add(hotkey);\n        }\n\n        public void RegisterHotkey(ModifierKeys modifier, Key key, Action<HotKey> action)\n        {\n            if (key == Key.None)\n                return;\n            if (hotKeys == null)\n                hotKeys = new List<HotKey>();\n            var hotkey = new HotKey(modifier, key, handle);\n            hotkey.HotKeyPressed += action;\n\n            hotKeys.Add(hotkey);\n        }\n\n        public void UnregisterHotkey(ModifierKeys modifier, Key key)\n        {\n            if (key == Key.None)\n                return;\n            foreach (var hotKey in hotKeys)\n            {\n                if (hotKey.Key == key && hotKey.KeyModifier == modifier)\n                {\n                    hotKey.HotKeyPressed -= HotKeyPressed;\n                    hotKey.Dispose();\n                    hotKeys.Remove(hotKey);\n                    break;\n                }\n            }\n        }\n\n        public bool IsRegistered(ModifierKeys modifier, Key key)\n        {\n            if (key == Key.None)\n                return false;\n            foreach (var hotKey in hotKeys)\n            {\n                if (hotKey.Key == key && hotKey.KeyModifier == modifier)\n                {\n                    return true;\n                }\n            }\n\n            return false;\n        }\n\n        public void InitializeHotkeys()\n        {\n            RegisterHotkey(Settings.Instance.NextHotKeyModifier, Settings.Instance.NextHotKey, h => AudioService.SkipNext());\n            RegisterHotkey(Settings.Instance.PrevHotKeyModifier, Settings.Instance.PrevHotKey, h => AudioService.Prev());\n            RegisterHotkey(Settings.Instance.PlayPauseHotKeyModifier, Settings.Instance.PlayPauseHotKey, h =>\n            {\n                if (AudioService.IsPlaying)\n                    AudioService.Pause();\n                else\n                    AudioService.Play();\n            });\n\n            RegisterHotkey(Settings.Instance.LikeDislikeHotKeyModifier, Settings.Instance.LikeDislikeHotKey, h =>\n            {\n                ViewModelLocator.Main.AddRemoveAudioCommand.Execute(ViewModelLocator.Main.CurrentAudio);\n            });\n\n            RegisterHotkey(Settings.Instance.ShuffleHotKeyModifier, Settings.Instance.ShuffleHotKey, h => ViewModelLocator.Main.Shuffle = !ViewModelLocator.Main.Shuffle);\n            RegisterHotkey(Settings.Instance.RepeatHotKeyModifier, Settings.Instance.RepeatHotKey, h => ViewModelLocator.Main.Repeat = !ViewModelLocator.Main.Repeat);\n            RegisterHotkey(Settings.Instance.IncreaseVolumeHotKeyModifier, Settings.Instance.IncreaseVolumeHotKey, h => ViewModelLocator.Main.Volume += 5);\n            RegisterHotkey(Settings.Instance.DecreaseVolumeHotKeyModifier, Settings.Instance.DecreaseVolumeHotKey, h => ViewModelLocator.Main.Volume -= 5);\n\n            RegisterHotkey(Settings.Instance.ShowHideHotKeyModifier, Settings.Instance.ShowHideHotKey, h =>\n            {\n                if (Application.Current.MainWindow.WindowState != WindowState.Minimized)\n                    Application.Current.MainWindow.WindowState = WindowState.Minimized;\n                else\n                    Application.Current.MainWindow.WindowState = WindowState.Normal;\n            });\n\n            RegisterHotkey(Settings.Instance.FastForwardHotKeyModifier, Settings.Instance.FastForwardHotKey, h => AudioService.FastForward(7));\n\n            RegisterHotkey(Settings.Instance.RewindHotKeyModifier, Settings.Instance.RewindHotKey, h => AudioService.Rewind(7));\n        }\n\n        void HotKeyPressed(HotKey obj)\n        {\n            switch (obj.Key)\n            {\n                case Key.MediaPlayPause:\n                    if (AudioService.IsPlaying)\n                        AudioService.Pause();\n                    else\n                        AudioService.Play();\n                    break;\n                case Key.MediaNextTrack:\n                    AudioService.SkipNext();\n                    break;\n                case Key.MediaPreviousTrack:\n                    AudioService.Prev();\n                    break;\n                case Key.MediaStop:\n                    AudioService.Stop();\n                    break;\n                case Key.SelectMedia:\n                    if (Application.Current.MainWindow.WindowState == WindowState.Minimized)\n                        Application.Current.MainWindow.WindowState = WindowState.Normal;\n                    else if (Application.Current.MainWindow.IsActive)\n                        Application.Current.MainWindow.WindowState = WindowState.Minimized;\n                    else\n                    {\n                        Application.Current.MainWindow.Show();\n                        Application.Current.MainWindow.Activate();\n                    }\n                    break;\n            }\n        }\n\n        public void Dispose()\n        {\n            foreach (var hotKey in hotKeys)\n            {\n                hotKey.HotKeyPressed -= HotKeyPressed;\n                hotKey.Dispose();\n                break;\n            }\n\n            hotKeys.Clear();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/ImageAsyncHelper.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.Net;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\n\nnamespace Meridian.Helpers\n{\n    public class NullImageConverter : IValueConverter\n    {\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            if (value == null || string.IsNullOrEmpty(((Uri)value).OriginalString))\n                return DependencyProperty.UnsetValue;\n            return value;\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            throw new NotImplementedException();\n        }\n    }\n\n    public class ImageAsyncHelper : DependencyObject\n    {\n        Uri _givenUri;\n\n        private static NullImageConverter _converter;\n\n        private static NullImageConverter Converter\n        {\n            get\n            {\n                if (_converter == null)\n                    _converter = new NullImageConverter();\n\n                return _converter;\n            }\n        }\n\n        public static Uri GetSourceUri(DependencyObject obj) { return (Uri)obj.GetValue(SourceUriProperty); }\n        public static void SetSourceUri(DependencyObject obj, Uri value) { obj.SetValue(SourceUriProperty, value); }\n        public static readonly DependencyProperty SourceUriProperty = DependencyProperty.RegisterAttached(\"SourceUri\", typeof(Uri), typeof(ImageAsyncHelper), new PropertyMetadata(SourceUriChanged));\n\n        private static void SourceUriChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            ((Image)d).SetBinding(Image.SourceProperty,\n                new Binding(\"VerifiedUri\")\n                {\n                    Source = new ImageAsyncHelper { _givenUri = e.NewValue as Uri },\n                    IsAsync = true,\n                    Converter = Converter\n                });\n        }\n\n        public Uri VerifiedUri\n        {\n            get\n            {\n                try\n                {\n                    if (_givenUri != null && !string.IsNullOrEmpty(_givenUri.OriginalString))\n                    {\n                        Dns.GetHostEntry(_givenUri.DnsSafeHost);\n                        return _givenUri;\n                    }\n                }\n                catch (Exception ex)\n                {\n                    Debug.WriteLine(ex);\n                }\n                return _givenUri;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/LongRunningOperation.cs",
    "content": "﻿using System.ComponentModel;\nusing System.Runtime.CompilerServices;\n\nnamespace Meridian.Helpers\n{\n    public class LongRunningOperation : INotifyPropertyChanged\n    {\n        private bool _isWorking;\n        private string _error;\n\n        public bool IsWorking\n        {\n            get { return _isWorking; }\n            set\n            {\n                if (_isWorking == value)\n                    return;\n\n                _isWorking = value;\n                OnPropertyChanged();\n            }\n        }\n\n        public string Error\n        {\n            get { return _error; }\n            set\n            {\n                if (_error == value)\n                    return;\n\n                _error = value;\n                OnPropertyChanged();\n            }\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/Md5Helper.cs",
    "content": "﻿using System.Security.Cryptography;\nusing System.Text;\n\nnamespace Meridian.Helpers\n{\n    public static class Md5Helper\n    {\n        public static string Md5(string input)\n        {\n            // step 1, calculate MD5 hash from input\n            MD5 md5 = System.Security.Cryptography.MD5.Create();\n            byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(input);\n            byte[] hash = md5.ComputeHash(inputBytes);\n\n            // step 2, convert byte array to hex string\n            StringBuilder sb = new StringBuilder();\n            for (int i = 0; i < hash.Length; i++)\n            {\n                sb.Append(hash[i].ToString(\"X2\"));\n            }\n            return sb.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/NativeMethods.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\nusing System.Windows.Input;\n\nnamespace Meridian.Helpers\n{\n    public static class NativeMethods\n    {\n        public const int WM_HOTKEY = 0x0312;\n\n        [DllImport(\"user32.dll\")]\n        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, UInt32 wParam, IntPtr lParam);\n\n        [DllImport(\"user32.dll\", SetLastError = true)]\n        public static extern bool RegisterHotKey(IntPtr hWnd, int id, ModifierKeys fsModifiers, int vk);\n\n        [DllImport(\"user32.dll\", SetLastError = true)]\n        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);\n\n        public static void SizeWindow(IntPtr handle)\n        {\n            SendMessage(handle, 274, 61448, IntPtr.Zero);\n        }\n\n        public static void SizeWindowLeft(IntPtr handle)\n        {\n            SendMessage(handle, 274, 61441, IntPtr.Zero);\n        }\n\n        public static void SizeWindowTop(IntPtr handle)\n        {\n            SendMessage(handle, 274, 61443, IntPtr.Zero);\n        }\n\n        public static void SizeWindowBottom(IntPtr handle)\n        {\n            SendMessage(handle, 274, 61446, IntPtr.Zero);\n        }\n\n        public static void SizeWindowRight(IntPtr handle)\n        {\n            SendMessage(handle, 274, 61442, IntPtr.Zero);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/NetworkHelper.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Sockets;\n\nnamespace Meridian.Helpers\n{\n    public static class NetworkHelper\n    {\n        public static List<string> GetLocalIpAddresses()\n        {\n            if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())\n            {\n                return null;\n            }\n\n\n            IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());\n\n            return host.AddressList.Where(a => a.AddressFamily == AddressFamily.InterNetwork).Select(a => a.ToString()).ToList();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Helpers/StringHelper.cs",
    "content": "﻿using System;\nusing System.Linq;\n\nnamespace Meridian.Helpers\n{\n    public static class StringHelper\n    {\n        public static string FormatSize(double bytes, string[] orders = null)\n        {\n            const int scale = 1024;\n\n            if (orders == null)\n                orders = new[] { \"GB\", \"MB\", \"KB\", \"Bytes\" };\n\n            long max = (long)Math.Pow(scale, orders.Length - 1);\n\n            foreach (string order in orders)\n            {\n                if (bytes > max)\n                    return string.Format(\"{0:##.##} {1}\", decimal.Divide((decimal)bytes, max), order);\n\n                max /= scale;\n            }\n            return \"0 Bytes\";\n        }\n\n        public static string ToUtf8(string input)\n        {\n            if (string.IsNullOrEmpty(input))\n                return input;\n\n            return new string(input.ToCharArray().\n                Select(x => ((x + 848) >= 'А' && (x + 848) <= 'ё') ? (char)(x + 848) : x).\n                ToArray());\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Layout/Controls/HeaderControl.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Layout.Controls.HeaderControl\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"64\" d:DesignWidth=\"300\"\n             x:Name=\"rootElement\">\n    <Grid>\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"20\"/>\n            <ColumnDefinition />\n        </Grid.ColumnDefinitions>\n        <Grid.RowDefinitions>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"140\" StaysOpen=\"False\" VerticalOffset=\"10\"\n               PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n            <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"#a0a0a0\">\n                <ItemsControl ItemsSource=\"{Binding MenuItems, ElementName=rootElement}\"/>\n            </Border>\n        </Popup>\n        <Button Grid.Column=\"0\" Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                HorizontalAlignment=\"Left\"\n                Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n        <ToggleButton Grid.Column=\"1\" x:Name=\"HeaderButton\" Content=\"{Binding Header, ElementName=rootElement}\" Style=\"{StaticResource HeaderButtonStyle}\"/>\n        \n        <TextBlock Text=\"{Binding SubHeader, ElementName=rootElement}\" Foreground=\"{DynamicResource ForegroundBrush}\" Opacity=\"0.6\" Grid.Column=\"1\"\n                   Grid.Row=\"1\" Margin=\"6,-10,0,0\" FontSize=\"14\"\n                   Visibility=\"{Binding RelativeSource={RelativeSource Self}, Path=Text, Converter={StaticResource NullToVisibilityConverter}}\"/>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/Layout/Controls/HeaderControl.xaml.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\n\nnamespace Meridian.Layout.Controls\n{\n    /// <summary>\n    /// Interaction logic for HeaderControl.xaml\n    /// </summary>\n    public partial class HeaderControl : UserControl\n    {\n        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(\n            \"Header\", typeof(object), typeof(HeaderControl), new PropertyMetadata(default(object)));\n\n        public object Header\n        {\n            get { return (object)GetValue(HeaderProperty); }\n            set { SetValue(HeaderProperty, value); }\n        }\n\n        public static readonly DependencyProperty SubHeaderProperty = DependencyProperty.Register(\n            \"SubHeader\", typeof (string), typeof (HeaderControl), new PropertyMetadata(default(string)));\n\n        public string SubHeader\n        {\n            get { return (string) GetValue(SubHeaderProperty); }\n            set { SetValue(SubHeaderProperty, value); }\n        }\n\n        public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(\n            \"MenuItems\", typeof(List<MenuItem>), typeof(HeaderControl), new PropertyMetadata(new List<MenuItem>(), OnMenuItemsPropertyChanged));\n\n        private static void OnMenuItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var control = (HeaderControl)d;\n            if (e.NewValue != null && ((List<MenuItem>)e.NewValue).Count > 0)\n                control.HeaderButton.IsEnabled = true;\n            else\n                control.HeaderButton.IsEnabled = false;\n        }\n\n        public List<MenuItem> MenuItems\n        {\n            get { return (List<MenuItem>)GetValue(MenuItemsProperty); }\n            set { SetValue(MenuItemsProperty, value); }\n        }\n\n        public HeaderControl()\n        {\n            InitializeComponent();\n\n            Loaded += OnLoaded;\n            Unloaded += OnUnloaded;\n        }\n\n        private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)\n        {\n            foreach (var menuItem in MenuItems)\n            {\n                menuItem.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(MenuItemClicked));\n            }\n        }\n\n        private void OnUnloaded(object sender, RoutedEventArgs e)\n        {\n            foreach (var menuItem in MenuItems)\n            {\n                menuItem.RemoveHandler(MenuItem.ClickEvent, new RoutedEventHandler(MenuItemClicked));\n            }\n        }\n\n        private void MenuItemClicked(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetValue(Popup.IsOpenProperty, false);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Layout/Controls/PageTabControl.cs",
    "content": "﻿using System.Collections.Specialized;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing Neptune.Extensions;\n\nnamespace Meridian.Layout.Controls\n{\n    /// <summary>\n    /// Tab control which hides tabs panel if there are only one tab\n    /// </summary>\n    public class PageTabControl : TabControl\n    {\n        private bool _isTabsVisible = true;\n\n        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)\n        {\n            base.OnItemsChanged(e);\n\n            ShowHideTabsPanel(!(Items.IsNullOrEmpty() || Items.Count == 1));\n        }\n\n        private void ShowHideTabsPanel(bool show)\n        {\n            if (_isTabsVisible == show)\n                return;\n\n            var tabPanel = GetTemplateChild(\"headerPanel\") as TabPanel;\n            if (tabPanel != null)\n            {\n                tabPanel.Height = show ? double.NaN : 0;\n\n                _isTabsVisible = show;\n            }\n        }\n\n        public override void OnApplyTemplate()\n        {\n            base.OnApplyTemplate();\n\n            ShowHideTabsPanel(!(Items.IsNullOrEmpty() || Items.Count == 1));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Layout/LayoutBase.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\n\nnamespace Meridian.Layout\n{\n    public class LayoutBase : Control\n    {\n    }\n}\n"
  },
  {
    "path": "Meridian/Layout/PageBase.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Meridian.ViewModel;\n\nnamespace Meridian.Layout\n{\n    public class PageBase : Page\n    {\n        /// <summary>\n        /// Content property\n        /// </summary>\n        public new static readonly DependencyProperty ContentProperty = DependencyProperty.Register(\n            \"Content\", typeof(List<object>), typeof(PageBase), new PropertyMetadata(new List<object>()));\n\n        public new List<object> Content\n        {\n            get { return (List<object>)GetValue(ContentProperty); }\n            set { SetValue(ContentProperty, value); }\n        }\n\n        /// <summary>\n        /// Header property\n        /// </summary>\n        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(\n            \"Header\", typeof(object), typeof(PageBase), new PropertyMetadata(default(object)));\n\n        public object Header\n        {\n            get { return GetValue(HeaderProperty); }\n            set { SetValue(HeaderProperty, value); }\n        }\n\n        /// <summary>\n        /// SubHeader property\n        /// </summary>\n        public static readonly DependencyProperty SubHeaderProperty = DependencyProperty.Register(\n            \"SubHeader\", typeof (string), typeof (PageBase), new PropertyMetadata(default(string)));\n\n        public string SubHeader\n        {\n            get { return (string) GetValue(SubHeaderProperty); }\n            set { SetValue(SubHeaderProperty, value); }\n        }\n\n        /// <summary>\n        /// Header menu items property\n        /// </summary>\n        public static readonly DependencyProperty HeaderMenuItemsProperty = DependencyProperty.Register(\n            \"HeaderMenuItems\", typeof(List<MenuItem>), typeof(PageBase), new PropertyMetadata(new List<MenuItem>()));\n\n        public List<MenuItem> HeaderMenuItems\n        {\n            get { return (List<MenuItem>)GetValue(HeaderMenuItemsProperty); }\n            set { SetValue(HeaderMenuItemsProperty, value); }\n        }\n\n        /// <summary>\n        /// Selected tab index property\n        /// </summary>\n        public static readonly DependencyProperty SelectedTabIndexProperty = DependencyProperty.Register(\n            \"SelectedTabIndex\", typeof (int), typeof (PageBase), new PropertyMetadata(default(int)));\n\n        public int SelectedTabIndex\n        {\n            get { return (int) GetValue(SelectedTabIndexProperty); }\n            set { SetValue(SelectedTabIndexProperty, value); }\n        }\n\n        /// <summary>\n        /// Navigation context\n        /// </summary>\n        public NavigationContext NavigationContext { get; set; }\n\n\n        public PageBase()\n        {\n            Style = (Style)Application.Current.Resources[\"PageBaseStyle\"];\n\n            HeaderMenuItems = new List<MenuItem>();\n            Content = new List<object>();\n\n            NavigationContext = new NavigationContext();\n\n            this.Loaded += OnLoaded;\n            this.Unloaded += OnUnloaded;\n        }\n\n        private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)\n        {\n            var vm = DataContext as ViewModelBase;\n            if (vm != null)\n                vm.Activate();\n\n            OnNavigatedTo();\n        }\n\n        private void OnUnloaded(object sender, RoutedEventArgs routedEventArgs)\n        {\n            var vm = DataContext as ViewModelBase;\n            if (vm != null)\n                vm.Deactivate();\n\n            OnNavigatedFrom();\n        }\n\n        public virtual void OnNavigatedTo()\n        {\n\n        }\n\n        public virtual void OnNavigatedFrom()\n        {\n\n        }\n    }\n\n    public sealed class NavigationContext\n    {\n        private readonly Dictionary<string, object> _parameters;\n\n        public Dictionary<string, object> Parameters\n        {\n            get { return _parameters; }\n            set\n            {\n                if (value == null)\n                    return;\n\n                foreach (var kp in value)\n                {\n                    _parameters.Add(kp.Key, kp.Value);\n                }\n            }\n        }\n\n        public NavigationContext()\n        {\n            _parameters = new Dictionary<string, object>();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Layout/Templates/PageBaseTemplate.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:layout=\"clr-namespace:Meridian.Layout\"\n                    xmlns:controls=\"clr-namespace:Meridian.Layout.Controls\"\n                    xmlns:controls1=\"clr-namespace:Meridian.Controls\"\n                    xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n                    xmlns:command=\"clr-namespace:GalaSoft.MvvmLight;assembly=GalaSoft.MvvmLight\"\n                    xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\">\n    <Style x:Key=\"PageBaseStyle\" TargetType=\"layout:PageBase\" x:Shared=\"False\">\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"layout:PageBase\">\n                    <Grid>\n                        <Grid.RowDefinitions>\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition />\n                        </Grid.RowDefinitions>\n\n                        <controls:HeaderControl Grid.Row=\"0\" Header=\"{TemplateBinding Header}\" MenuItems=\"{TemplateBinding HeaderMenuItems}\"\n                                                SubHeader=\"{TemplateBinding SubHeader}\">\n                            <controls:HeaderControl.RenderTransform>\n                                <TranslateTransform />\n                            </controls:HeaderControl.RenderTransform>\n                            <controls:HeaderControl.Triggers>\n                                <EventTrigger RoutedEvent=\"Page.Loaded\">\n                                    <BeginStoryboard Storyboard=\"{StaticResource PageHeaderLoadAnim}\" />\n                                </EventTrigger>\n                            </controls:HeaderControl.Triggers>\n                        </controls:HeaderControl>\n\n                        <controls:PageTabControl Grid.Row=\"1\" ItemsSource=\"{TemplateBinding Content}\" Style=\"{StaticResource CommonTabControlStyle}\"\n                                    ItemContainerStyle=\"{StaticResource CommonTabItemStyle}\" SelectedIndex=\"{Binding SelectedTabIndex, RelativeSource={RelativeSource FindAncestor, AncestorType=layout:PageBase}, Mode=TwoWay}\">\n                            <controls:PageTabControl.RenderTransform>\n                                <TranslateTransform />\n                            </controls:PageTabControl.RenderTransform>\n                            <controls:PageTabControl.Triggers>\n                                <EventTrigger RoutedEvent=\"Page.Loaded\">\n                                    <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n                                </EventTrigger>\n                            </controls:PageTabControl.Triggers>\n                        </controls:PageTabControl>\n\n                        <Grid x:Name=\"SearchBoxGrid\" HorizontalAlignment=\"Right\" VerticalAlignment=\"Top\" Margin=\"0,45,10,0\" Width=\"170\" Height=\"24\">\n                            <controls1:TextBoxWithHint x:Name=\"SearchBox\" Padding=\"8,0,30,0\" HorizontalAlignment=\"Stretch\" Style=\"{StaticResource SearchBoxStyle}\" FontWeight=\"Regular\" \n                                                       Hint=\"{x:Static localization:MainResources.Search}\" HintStyle=\"{StaticResource TextBoxHintStyle}\" Text=\"{Binding Query}\">\n                                <i:Interaction.Triggers>\n                                    <i:EventTrigger EventName=\"KeyUp\">\n                                        <i:InvokeCommandAction Command=\"{Binding Main.SearchKeyUpCommand, Source={StaticResource Locator}}\" PassEventArgsToCommand=\"True\"/>\n                                    </i:EventTrigger>\n                                </i:Interaction.Triggers>\n                            </controls1:TextBoxWithHint>\n                            <Button x:Name=\"SearchButton\" IsEnabled=\"{Binding Text, ElementName=SearchBox, Converter={StaticResource NullToBoolConverter}, ConverterParameter=True}\" Width=\"12\" Margin=\"5,5,7,5\" HorizontalAlignment=\"Right\" \n                                    Template=\"{StaticResource SearchBoxButton}\"\n                                    Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Text, ElementName=SearchBox}\"/>\n                        </Grid>\n\n\n                        <!--<Grid VerticalAlignment=\"Top\" HorizontalAlignment=\"Right\" Margin=\"10,7,183,10\" DataContext=\"{Binding Main, Source={StaticResource Locator}}\">\n                            <Border x:Name=\"photoMask\" CornerRadius=\"20\" Background=\"{StaticResource MainBackgroundBrush}\" Width=\"28\" Height=\"28\" HorizontalAlignment=\"Right\"/>\n\n                            <StackPanel Orientation=\"Horizontal\">\n                                <TextBlock Text=\"{Binding User.FirstName}\" VerticalAlignment=\"Center\" Margin=\"0,0,10,0\"\n                                           FontSize=\"12\" Opacity=\"0.5\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                <Image Source=\"{Binding User.Photo}\" Width=\"28\" Height=\"28\">\n                                    <Image.OpacityMask>\n                                        <VisualBrush Visual=\"{Binding ElementName=photoMask}\"/>\n                                    </Image.OpacityMask>\n                                </Image>\n                            </StackPanel>\n                        </Grid>-->\n                    </Grid>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Layout/Templates/TwoColumnPageLayoutTemplate.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:layout=\"clr-namespace:Meridian.Layout\">\n    <Style x:Key=\"TwoColumnPageLayoutStyle\" TargetType=\"layout:TwoColumnPageLayout\" x:Shared=\"False\">\n        <Setter Property=\"MainContent\" Value=\"{Binding Content[0], RelativeSource={RelativeSource AncestorType=layout:PageBase}}\" />\n        <Setter Property=\"RightContent\" Value=\"{Binding Content[1], RelativeSource={RelativeSource AncestorType=layout:PageBase}}\" />\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"layout:TwoColumnPageLayout\">\n                    <Grid>\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition />\n                            <ColumnDefinition Width=\"180\"/>\n                        </Grid.ColumnDefinitions>\n                        <ContentPresenter Content=\"{TemplateBinding MainContent}\" />\n                        \n                        <Rectangle Grid.Column=\"1\" Fill=\"{DynamicResource MainBackgroundBrush}\" Margin=\"0,0,0,-25\" Opacity=\"0.4\"/>\n                        <ContentPresenter Content=\"{TemplateBinding RightContent}\" Grid.Column=\"1\"/>\n                        <Rectangle Width=\"1\" Grid.Column=\"1\" HorizontalAlignment=\"Left\" Fill=\"{DynamicResource MainBackgroundSplitterBrush}\" SnapsToDevicePixels=\"True\" Margin=\"-1,0,0,0\"/>\n                    </Grid>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Layout/TwoColumnPageLayout.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\n\nnamespace Meridian.Layout\n{\n    public class TwoColumnPageLayout : LayoutBase\n    {\n        public static readonly DependencyProperty MainContentProperty = DependencyProperty.Register(\n               \"MainContent\", typeof(object), typeof(TwoColumnPageLayout), new PropertyMetadata(default(object)));\n\n        public object MainContent\n        {\n            get { return (object)GetValue(MainContentProperty); }\n            set { SetValue(MainContentProperty, value); }\n        }\n\n        public static readonly DependencyProperty RightContentProperty = DependencyProperty.Register(\n            \"RightContent\", typeof (object), typeof (TwoColumnPageLayout), new PropertyMetadata(default(object)));\n\n        public object RightContent\n        {\n            get { return (object) GetValue(RightContentProperty); }\n            set { SetValue(RightContentProperty, value); }\n        }\n\n        public TwoColumnPageLayout()\n        {\n            Style = (Style)Application.Current.Resources[\"TwoColumnPageLayoutStyle\"];\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/MainWindow.xaml",
    "content": "﻿<Window x:Class=\"Meridian.MainWindow\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n        xmlns:converters=\"clr-namespace:Neptune.UI.Converters;assembly=Neptune.Desktop\"\n        xmlns:controls=\"clr-namespace:Meridian.Controls\"\n        xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n        xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n        xmlns:converters1=\"clr-namespace:Meridian.Converters\"\n        MinWidth=\"850\" MinHeight=\"570\"\n        WindowStartupLocation=\"Manual\" ShowInTaskbar=\"{Binding ShowTrayIcon, Converter={StaticResource InvertBoolConverter}}\"\n        Background=\"{DynamicResource MainBackgroundBrush}\"\n        DataContext=\"{Binding Main, Source={StaticResource Locator}}\"\n        WindowState=\"{Binding WindowState}\" Left=\"{Binding WindowLeft}\" Top=\"{Binding WindowTop}\"\n        Width=\"{Binding WindowWidth}\" Height=\"{Binding WindowHeight}\" Title=\"{Binding WindowTitle}\"\n        KeyUp=\"MainWindow_OnKeyUp\"\n        MouseMove=\"MainWindow_OnMouseMove\" Loaded=\"MainWindow_OnLoaded\" Closing=\"MainWindow_OnClosing\"\n        StateChanged=\"MainWindow_OnStateChanged\">\n    <Window.Resources>\n        <converters:BooleanToObjectConverter x:Key=\"WindowMarginConverter\" TrueObject=\"6,6,6,0\" FalseObject=\"0\"/>\n\n        <CollectionViewSource x:Key=\"MainMenuGroups\" Source=\"{Binding MainMenuItems}\">\n            <CollectionViewSource.GroupDescriptions>\n                <PropertyGroupDescription PropertyName=\"Group\"/>\n            </CollectionViewSource.GroupDescriptions>\n        </CollectionViewSource>\n\n        <Style x:Key=\"NormalGroupStyle\" TargetType=\"{x:Type GroupItem}\">\n            <Setter Property=\"Margin\" Value=\"0,0,0,0\"/>\n            <Setter Property=\"Template\">\n                <Setter.Value>\n                    <ControlTemplate TargetType=\"{x:Type GroupItem}\">\n                        <Grid Margin=\"0,0,0,20\">\n                            <Grid.ColumnDefinitions>\n                                <ColumnDefinition Width=\"Auto\"/>\n                                <ColumnDefinition />\n                            </Grid.ColumnDefinitions>\n                            <Grid.RowDefinitions>\n                                <RowDefinition Height=\"Auto\"/>\n                                <RowDefinition />\n                            </Grid.RowDefinitions>\n                            <Path Data=\"{Binding Items[0].GroupIcon}\" Stretch=\"Uniform\" Fill=\"{DynamicResource SidebarForegroundBrush}\" Height=\"8\" Margin=\"17,1,-10,0\" Opacity=\"0.4\" VerticalAlignment=\"Center\"\n                                  Visibility=\"{Binding Items[0].GroupIcon, Converter={StaticResource NullToVisibilityConverter}}\"/>\n                            <TextBlock Grid.Column=\"1\" FontWeight=\"SemiBold\" Text=\"{Binding Path=Name}\" Margin=\"17,0,0,0\" FontSize=\"12\" Foreground=\"{DynamicResource SidebarGroupForegroundBrush}\"/>\n                            <ItemsPresenter Grid.Row=\"1\" Grid.ColumnSpan=\"2\" Margin=\"0,5,0,0\"/>\n                        </Grid>\n                    </ControlTemplate>\n                </Setter.Value>\n            </Setter>\n        </Style>\n\n        <Style x:Key=\"EmptyHeaderGroupStyle\" TargetType=\"{x:Type GroupItem}\">\n            <Setter Property=\"Margin\" Value=\"0,0,0,0\"/>\n            <Setter Property=\"Template\">\n                <Setter.Value>\n                    <ControlTemplate TargetType=\"{x:Type GroupItem}\">\n                        <Grid Margin=\"0,0,0,20\">\n                            <ItemsPresenter Margin=\"0,0,0,0\"/>\n                        </Grid>\n                    </ControlTemplate>\n                </Setter.Value>\n            </Setter>\n        </Style>\n\n        <converters1:MainMenuGroupStyleSelector x:Key=\"MainMenuGroupStyleSelector\" NormalGroupStyle=\"{StaticResource NormalGroupStyle}\" EmptyHeaderGroupStyle=\"{StaticResource EmptyHeaderGroupStyle}\"/>\n    </Window.Resources>\n    <Window.Style>\n        <Style TargetType=\"Window\">\n            <Setter Property=\"WindowChrome.WindowChrome\">\n                <Setter.Value>\n                    <WindowChrome NonClientFrameEdges=\"None\" GlassFrameThickness=\"0,0,0,1\" ResizeBorderThickness=\"7\" CaptionHeight=\"0\" CornerRadius=\"0\"/>\n                </Setter.Value>\n            </Setter>\n        </Style>\n    </Window.Style>\n    <!--<Window.TaskbarItemInfo>\n        <TaskbarItemInfo x:Name=\"Taskbar\">\n            <TaskbarItemInfo.ThumbButtonInfos>\n                <ThumbButtonInfo ImageSource=\"/Meridian;component/Resources/Images/prev_thumb.png\" \n                                 Command=\"{Binding Main.PrevAudioCommand, Source={StaticResource Locator}}\"/>\n                <ThumbButtonInfo ImageSource=\"{Binding Main.IsPlaying, Source={StaticResource Locator}, Converter={StaticResource PlayIconConverter}}\"\n                                 Command=\"{Binding Main.PlayPauseCommand, Source={StaticResource Locator}}\"/>\n                <ThumbButtonInfo ImageSource=\"/Meridian;component/Resources/Images/next_thumb.png\"\n                                 Command=\"{Binding Main.NextAudioCommand, Source={StaticResource Locator}}\"/>\n            </TaskbarItemInfo.ThumbButtonInfos>\n        </TaskbarItemInfo>\n    </Window.TaskbarItemInfo>-->\n    <Window.InputBindings>\n        <KeyBinding Gesture=\"CTRL+F\" Command=\"{Binding ShowLocalSearchCommand}\" />\n    </Window.InputBindings>\n    <Grid x:Name=\"RootGrid\" Background=\"{DynamicResource MainBackgroundBrush}\" Margin=\"{Binding IsWindowMaximized, Converter={StaticResource WindowMarginConverter}}\">\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"Auto\"/>\n            <ColumnDefinition />\n        </Grid.ColumnDefinitions>\n        <Grid.RowDefinitions>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <Rectangle Fill=\"Black\" Grid.RowSpan=\"2\" Visibility=\"{Binding ShowSidebar, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n        <!-- Menu -->\n        <Grid Width=\"220\" Visibility=\"{Binding ShowSidebar, Converter={StaticResource BoolToVisibilityConverter}}\" Background=\"{DynamicResource SidebarBackgroundBrush}\" Grid.RowSpan=\"2\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\"/>\n                <RowDefinition />\n                <RowDefinition Height=\"Auto\"/>\n            </Grid.RowDefinitions>\n            <StackPanel>\n                <Button x:Name=\"MeridianButton\" HorizontalAlignment=\"Left\" Margin=\"0,5,0,0\"\n                        Foreground=\"{DynamicResource SidebarForegroundBrush}\"\n                        Command=\"{Binding GoToSettingsCommand}\" ToolTip=\"{x:Static localization:MainResources.Settings}\">\n                    <Button.Template>\n                        <ControlTemplate TargetType=\"{x:Type Button}\">\n                            <StackPanel x:Name=\"rootPanel\" Opacity=\"0.7\" Orientation=\"Horizontal\" Background=\"Transparent\">\n                                <TextBlock x:Name=\"Title\" VerticalAlignment=\"Center\" HorizontalAlignment=\"Left\" Foreground=\"{TemplateBinding Foreground}\" Opacity=\"1\" FontSize=\"13\" Margin=\"25,1,0,0\" Text=\"Meridian\" FontWeight=\"Regular\" TextOptions.TextFormattingMode=\"Display\"/>\n                                <Path x:Name=\"Icon\" Data=\"{StaticResource SettingsIcon}\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Width=\"12\" Margin=\"8,3,0,0\"/>\n                            </StackPanel>\n                            <ControlTemplate.Triggers>\n                                <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                                    <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"rootPanel\"/>\n                                </Trigger>\n                                <Trigger Property=\"IsPressed\" Value=\"True\">\n                                    <Setter Property=\"Opacity\" Value=\"0.6\" TargetName=\"rootPanel\"/>\n                                </Trigger>\n                            </ControlTemplate.Triggers>\n                        </ControlTemplate>\n                    </Button.Template>\n                </Button>\n\n                <controls:PlayerControl Margin=\"25,10,0,10\"/>\n            </StackPanel>\n\n            <ListBox Grid.Row=\"1\" Padding=\"0,0,0,10\" Margin=\"0,12,0,0\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\" ItemsSource=\"{Binding Source={StaticResource MainMenuGroups}}\"\n                     Foreground=\"White\" Style=\"{StaticResource CommonListBoxStyle}\" ItemContainerStyle=\"{StaticResource MainMenuListBoxItemStyle}\"\n                     HorizontalContentAlignment=\"Stretch\"\n                     SelectedItem=\"{Binding SelectedMainMenuItem}\" SelectedIndex=\"{Binding SelectedMainMenuItemIndex, Mode=TwoWay}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:TransitionBehaviour Transition=\"{StaticResource MainMenuLoadAnim}\" TransitionDelay=\"40\"/>\n                </i:Interaction.Behaviors>\n                <ListBox.GroupStyle>\n                    <GroupStyle ContainerStyleSelector=\"{StaticResource MainMenuGroupStyleSelector}\" />\n                </ListBox.GroupStyle>\n                <ListBox.ItemTemplate>\n                    <DataTemplate>\n                        <Grid>\n                            <Grid.ColumnDefinitions>\n                                <ColumnDefinition />\n                                <ColumnDefinition Width=\"Auto\"/>\n                            </Grid.ColumnDefinitions>\n                            <TextBlock Text=\"{Binding Title}\" FontWeight=\"Regular\" FontSize=\"14\"/>\n                            <Path Grid.Column=\"1\"  Data=\"{Binding Icon}\" Fill=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}, Path=Foreground}\" Width=\"12\" Stretch=\"Uniform\" Margin=\"0,0,12,0\" SnapsToDevicePixels=\"False\"/>\n                        </Grid>\n                    </DataTemplate>\n                </ListBox.ItemTemplate>\n            </ListBox>\n        </Grid>\n\n        <Grid Grid.Column=\"1\" Grid.Row=\"0\" MaxWidth=\"800\" MaxHeight=\"800\" Margin=\"0,90,0,0\" HorizontalAlignment=\"Right\" VerticalAlignment=\"Top\" ClipToBounds=\"True\" Opacity=\"0.4\"\n              Visibility=\"{Binding ShowBackgroundArt, Converter={StaticResource BoolToVisibilityConverter}}\">\n            <Grid.OpacityMask>\n                <LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\">\n                    <GradientStop Offset=\"0\" Color=\"Transparent\"/>\n                    <GradientStop Offset=\"0.5\" Color=\"White\"/>\n                    <GradientStop Offset=\"1\" Color=\"Transparent\"/>\n                </LinearGradientBrush>\n            </Grid.OpacityMask>\n\n            <controls:ImageTransitionControl x:Name=\"BackgroundArtControl\" Source=\"{Binding ArtistImage}\" Margin=\"0,0,0,0\" HorizontalContentAlignment=\"Right\">\n                <controls:ImageTransitionControl.OpacityMask>\n                    <LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"1,0\">\n                        <GradientStop Offset=\"0\" Color=\"Transparent\"/>\n                        <GradientStop Offset=\"1\" Color=\"White\"/>\n                    </LinearGradientBrush>\n                </controls:ImageTransitionControl.OpacityMask>\n            </controls:ImageTransitionControl>\n        </Grid>\n\n        <Frame x:Name=\"RootFrame\" NavigationUIVisibility=\"Hidden\" Grid.Column=\"1\">\n\n        </Frame>\n\n        <controls:ShareBarControl Grid.Column=\"1\" Height=\"100\" Visibility=\"Collapsed\"\n                                    VerticalAlignment=\"Bottom\">\n            <i:Interaction.Behaviors>\n                <behaviours:VisibilityTransitionBehaviour Value=\"{Binding ShowShareBar, Converter={StaticResource BoolToVisibilityConverter}}\"\n                                                               AnimationIn=\"{StaticResource ShareBarTransitionIn}\"\n                                                               AnimationOut=\"{StaticResource ShareBarTransitionOut}\"/>\n            </i:Interaction.Behaviors>\n        </controls:ShareBarControl>\n\n        <Rectangle Fill=\"{DynamicResource SidebarForegroundBrush}\" Width=\"1\" HorizontalAlignment=\"Right\" Opacity=\"0.1\" Grid.RowSpan=\"2\" Visibility=\"{Binding ShowSidebar, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n\n        <!--<Grid x:Name=\"SearchBoxGrid\" Grid.Column=\"1\" HorizontalAlignment=\"Right\" VerticalAlignment=\"Top\" Margin=\"0,45,10,0\" Width=\"170\" Height=\"24\" Visibility=\"{Binding ShowSidebar, Converter={StaticResource BoolToVisibilityConverter}}\">\n            <controls:TextBoxWithHint x:Name=\"SearchBox\" Padding=\"8,0,30,0\" HorizontalAlignment=\"Stretch\" Style=\"{StaticResource SearchBoxStyle}\" FontWeight=\"Regular\" Hint=\"{x:Static localization:MainResources.Search}\" HintStyle=\"{StaticResource TextBoxHintStyle}\"\n                                              KeyUp=\"SearchBox_OnKeyUp\"/>\n            <Button x:Name=\"SearchButton\" IsEnabled=\"{Binding Text, ElementName=SearchBox, Converter={StaticResource NullToBoolConverter}, ConverterParameter=True}\" Width=\"12\" Margin=\"5,5,7,5\" HorizontalAlignment=\"Right\" \n                            Template=\"{StaticResource SearchBoxButton}\"\n                            Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Text, ElementName=SearchBox}\"/>\n        </Grid>-->\n\n        <controls:NotificationControl x:Name=\"NotificationControl\" Grid.Column=\"1\" HorizontalAlignment=\"Left\" VerticalAlignment=\"Top\" Margin=\"24,0,0,0\"\n                                      Visibility=\"{Binding ShowSidebar, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n        <!-- Update progress bar -->\n        <Grid Grid.Column=\"1\" VerticalAlignment=\"Top\" HorizontalAlignment=\"Left\" Width=\"150\" Visibility=\"{Binding ShowSidebar, Converter={StaticResource BoolToVisibilityConverter}}\">\n            <ProgressBar Style=\"{StaticResource CommonProgressBarStyle}\" Margin=\"25,5,0,0\" Padding=\"0\"\n                         Visibility=\"{Binding UpdateService.IsUpdating, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"\n                         Value=\"{Binding UpdateService.UpdateProgress, Source={StaticResource Locator}, Mode=OneWay}\"/>\n        </Grid>\n\n        <StackPanel Grid.Column=\"1\" Orientation=\"Horizontal\" VerticalAlignment=\"Top\" HorizontalAlignment=\"Right\" Margin=\"10,10,10,10\" Visibility=\"{Binding ShowWindowButtons, Converter={StaticResource BoolToVisibilityConverter}}\">\n            <Button Style=\"{StaticResource MiniModeButtonStyle}\" Margin=\"0,0,20,0\" SnapsToDevicePixels=\"True\" Command=\"{Binding SwitchUIModeCommand}\"\n                    ToolTip=\"{x:Static localization:MainResources.CompactMode}\" Visibility=\"{Binding ShowSidebar, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n            <Button Style=\"{StaticResource MinimizeButtonStyle}\" VerticalAlignment=\"Bottom\" Margin=\"0,0,20,0\" SnapsToDevicePixels=\"True\" Command=\"{Binding MinimizeWindowCommand}\" ToolTip=\"{x:Static localization:MainResources.Minimize}\"/>\n            <ToggleButton x:Name=\"MaximizeButton\" Style=\"{StaticResource MaximizeButtonStyle}\" VerticalAlignment=\"Bottom\" Margin=\"0,0,20,0\" SnapsToDevicePixels=\"True\" IsChecked=\"{Binding IsWindowMaximized, Mode=OneWay}\" Command=\"{Binding MaximizeWindowCommand}\"\n                          ToolTip=\"{x:Static localization:MainResources.Maximize}\"/>\n            <Button Style=\"{StaticResource CloseButtonStyle}\" SnapsToDevicePixels=\"True\" Command=\"{Binding CloseWindowCommand}\" ToolTip=\"{x:Static localization:MainResources.Close}\"/>\n        </StackPanel>\n        <ResizeGrip Grid.Column=\"1\" Grid.Row=\"0\" Grid.RowSpan=\"2\" x:Name=\"ResizeGrip\" Cursor=\"SizeNWSE\"  HorizontalAlignment=\"Right\" VerticalAlignment=\"Bottom\" MouseMove=\"ResizeGripMouseMove\"/>\n    </Grid>\n</Window>\n"
  },
  {
    "path": "Meridian/MainWindow.xaml.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Input;\nusing System.Windows.Interop;\nusing System.Windows.Media;\nusing System.Windows.Media.Effects;\nusing GalaSoft.MvvmLight.Messaging;\nusing Meridian.Controls;\nusing Meridian.Domain;\nusing Meridian.Helpers;\nusing Meridian.Services;\nusing Meridian.View.Flyouts;\nusing Meridian.View.Main;\nusing Meridian.ViewModel;\nusing Neptune.Messages;\nusing Neptune.UI.Extensions;\nusing Meridian.View.Settings;\n\nnamespace Meridian\n{\n    /// <summary>\n    /// Interaction logic for MainWindow.xaml\n    /// </summary>\n    public partial class MainWindow : Window\n    {\n        private IntPtr _windowHandle;\n        private bool _clearStack;\n\n        public MainWindow()\n        {\n            InitializeComponent();\n        }\n\n        private void MainWindow_OnMouseMove(object sender, MouseEventArgs e)\n        {\n            if (e.LeftButton == MouseButtonState.Pressed && e.GetPosition(this).Y < 30)\n            {\n                if (WindowState == WindowState.Maximized)\n                {\n                    Top = -e.GetPosition(this).Y / 2;\n                    WindowState = WindowState.Normal;\n                }\n                else\n                {\n                    DragMove();\n\n\n                    ViewModelLocator.Main.WindowLeft = Left;\n                    ViewModelLocator.Main.WindowTop = Top;\n                }\n            }\n        }\n\n        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            _windowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle;\n\n            RootFrame.Navigated += RootFrame_Navigated;\n            RootFrame.Navigating += RootFrame_Navigating;\n\n            Top = Settings.Instance.Top;\n            Left = Settings.Instance.Left;\n            Width = Settings.Instance.Width;\n            Height = Settings.Instance.Height;\n\n            if (Settings.Instance.AccessToken != null && !Settings.Instance.AccessToken.HasExpired)\n            {\n                ViewModelLocator.Vkontakte.AccessToken = Settings.Instance.AccessToken;\n\n                ViewModelLocator.Main.ShowSidebar = true;\n\n                Messenger.Default.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Main.MusicView\"\n                });\n\n                ViewModelLocator.Main.LoadUserInfo();\n\n                /*if (!Settings.Instance.TellRequestShown && (DateTime.Now - Settings.Instance.FirstStart).TotalDays >= 3)\n                {\n                    Settings.Instance.TellRequestShown = true;\n                    Settings.Instance.Save();\n                    TellFriendsRequest();\n                }*/\n            }\n            else\n            {\n                Messenger.Default.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Main.LoginView\"\n                });\n            }\n\n            ViewModelLocator.Main.Initialize();\n            NotificationService.Initialize(NotificationControl);\n\n            BackgroundArtControl.Effect = Settings.Instance.BlurBackground ? new BlurEffect() { RenderingBias = RenderingBias.Quality, Radius = 35} : null;\n\n            if (Settings.Instance.EnableTrayIcon)\n                WindowStyle = WindowStyle.ToolWindow;\n        }\n\n        void RootFrame_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)\n        {\n            if (RootFrame.Content is LoginView && !(e.Content is SettingsView))\n            {\n                _clearStack = true;\n            }\n        }\n\n        void RootFrame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)\n        {\n            if (_clearStack)\n            {\n                _clearStack = false;\n\n                while (RootFrame.CanGoBack)\n                {\n                    RootFrame.RemoveBackEntry();\n                }\n            }\n\n            ViewModelLocator.Main.UpdateCanGoBack();\n        }\n\n        private void ResizeGripMouseMove(object sender, MouseEventArgs e)\n        {\n            //if (e.LeftButton == MouseButtonState.Pressed && Application.Current.MainWindow.WindowState != WindowState.Maximized)\n            //{\n            //    NativeMethods.SizeWindow(_windowHandle);\n\n            //    ViewModelLocator.Main.WindowWidth = Width;\n            //    ViewModelLocator.Main.WindowHeight = Height;\n            //}\n        }\n\n        private void MainWindow_OnClosing(object sender, CancelEventArgs e)\n        {\n            Settings.Instance.Save();\n        }\n\n        private void SearchBox_OnKeyUp(object sender, KeyEventArgs e)\n        {\n            //if (e.Key == Key.Enter && !string.IsNullOrWhiteSpace(SearchBox.Text))\n            //{\n            //    ViewModelLocator.Main.SearchCommand.Execute(SearchBox.Text);\n            //}\n        }\n\n        private void MainWindow_OnKeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.Key == Key.Escape)\n            {\n                var flyout = RootGrid.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n                if (flyout != null)\n                    flyout.Close();\n            }\n        }\n\n        private void TellFriendsRequest()\n        {\n            var flyout = new FlyoutControl();\n            flyout.FlyoutContent = new TellFriendsRequestView();\n            flyout.Show();\n        }\n\n        private void MainWindow_OnStateChanged(object sender, EventArgs e)\n        {\n            if (WindowState == WindowState.Minimized && Settings.Instance.EnableTrayIcon)\n            {\n                Hide();\n                Visibility = Visibility.Collapsed;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Meridian.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n  <PropertyGroup>\n    <OutputType>WinExe</OutputType>\n    <TargetFramework>netcoreapp3.1</TargetFramework>\n    <UseWPF>true</UseWPF>\n    <UseWindowsForms>true</UseWindowsForms>\n    <StartupObject>Meridian.App</StartupObject>\n    <Version>5.5.791</Version>\n    <Authors>Artem Shuba</Authors>\n    <Copyright>© Artem Shuba 2011 ― 2020</Copyright>\n    <PackageIcon>icon.ico</PackageIcon>\n    <Platforms>AnyCPU;x86</Platforms>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x86'\">\n    <WarningLevel>0</WarningLevel>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <None Remove=\"Resources\\Images\\cover_default.png\" />\n    <None Remove=\"Resources\\Images\\echonest_logo_light.gif\" />\n    <None Remove=\"Resources\\Images\\lastfm_logo.gif\" />\n    <None Remove=\"Resources\\Images\\next_thumb.png\" />\n    <None Remove=\"Resources\\Images\\pause_thumb.png\" />\n    <None Remove=\"Resources\\Images\\play_thumb.png\" />\n    <None Remove=\"Resources\\Images\\prev_thumb.png\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"gong-wpf-dragdrop\" Version=\"2.2.0\" />\n    <PackageReference Include=\"Microsoft.Xaml.Behaviors.Wpf\" Version=\"1.1.19\" />\n    <PackageReference Include=\"MvvmLightLibsStd10\" Version=\"5.4.1.1\" />\n    <PackageReference Include=\"NAudio\" Version=\"1.10.0\" />\n    <PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.1\" />\n    <PackageReference Include=\"NLog\" Version=\"4.7.0\" />\n    <PackageReference Include=\"SharpZipLib\" Version=\"1.3.3\" />\n    <PackageReference Include=\"sqlite-net\" Version=\"1.6.292\" />\n    <PackageReference Include=\"taglib\" Version=\"2.1.0\" />\n    <PackageReference Include=\"WindowsAPICodePack-Core\" Version=\"1.1.2\" />\n    <PackageReference Include=\"WindowsAPICodePack-Shell\" Version=\"1.1.1\" />\n    <PackageReference Include=\"Yandex.Metrica\" Version=\"3.5.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\LastFmLibPortable\\Trunk\\LastFmLibPortable.csproj\" />\n    <ProjectReference Include=\"..\\Neptune\\Trunk\\Neptune.Base\\Neptune.Base.csproj\" />\n    <ProjectReference Include=\"..\\Neptune\\Trunk\\Neptune.Desktop\\Neptune.Desktop.csproj\" />\n    <ProjectReference Include=\"..\\VkLib\\VkLib.csproj\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Reference Include=\"Windows\">\n      <HintPath>..\\..\\..\\..\\..\\..\\..\\Program Files (x86)\\Windows Kits\\10\\UnionMetadata\\10.0.18362.0\\Windows.winmd</HintPath>\n      <IsWinMDFile>true</IsWinMDFile>\n    </Reference>\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Include=\"icon.ico\">\n      <Pack>True</Pack>\n      <PackagePath></PackagePath>\n    </None>\n  </ItemGroup>\n\n  <ItemGroup>\n    <Resource Include=\"Resources\\Images\\cover_default.png\">\n      <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n    </Resource>\n    <Resource Include=\"Resources\\Images\\echonest_logo_light.gif\">\n      <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n    </Resource>\n    <Resource Include=\"Resources\\Images\\lastfm_logo.gif\">\n      <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n    </Resource>\n    <Resource Include=\"Resources\\Images\\next_thumb.png\">\n      <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n    </Resource>\n    <Resource Include=\"Resources\\Images\\pause_thumb.png\">\n      <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n    </Resource>\n    <Resource Include=\"Resources\\Images\\play_thumb.png\">\n      <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n    </Resource>\n    <Resource Include=\"Resources\\Images\\prev_thumb.png\">\n      <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n    </Resource>\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "Meridian/Model/Account.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Runtime.CompilerServices;\nusing GalaSoft.MvvmLight.Messaging;\nusing Meridian.Domain;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Messages;\nusing VkLib.Auth;\n\nnamespace Meridian.Model\n{\n    public class LoginParams\n    {\n        public string Login { get; set; }\n\n        public string Password { get; set; }\n\n        public Dictionary<string, string> AdditionalParams { get; set; }\n\n        public LoginParams()\n        {\n            AdditionalParams = new Dictionary<string, string>();\n        }\n    }\n\n    /// <summary>\n    /// Account\n    /// </summary>\n    public class Account : INotifyPropertyChanged\n    {\n        private bool _isLoggedIn;\n\n        /// <summary>\n        /// Id\n        /// </summary>\n        public string Id { get; set; }\n\n        /// <summary>\n        /// TItle\n        /// </summary>\n        public string Title { get; set; }\n\n        /// <summary>\n        /// Is user logged in using this account\n        /// </summary>\n        public bool IsLoggedIn\n        {\n            get { return _isLoggedIn; }\n            set\n            {\n                if (_isLoggedIn == value)\n                    return;\n\n                _isLoggedIn = value;\n                OnPropertyChanged();\n            }\n        }\n\n        public virtual void Login(LoginParams loginParams)\n        {\n            \n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n\n    public class VkAccount : Account\n    {\n        private const VkScopeSettings ScopeSettings = VkScopeSettings.CanAccessAudios | VkScopeSettings.CanAccessVideos | VkScopeSettings.CanAccessFriends |\n              VkScopeSettings.CanAccessGroups | VkScopeSettings.CanAccessWall | VkScopeSettings.CanAccessStatus | VkScopeSettings.CanAccessPhotos;\n\n        public override async void Login(LoginParams loginParams)\n        {\n            var vk = ViewModelLocator.Vkontakte;\n            var captchaSid = loginParams.AdditionalParams.ContainsKey(\"captchaSid\") ? loginParams.AdditionalParams[\"captchaSid\"] : null;\n            var captchaKey = loginParams.AdditionalParams.ContainsKey(\"captchaKey\") ? loginParams.AdditionalParams[\"captchaKey\"] : null;\n\n            var token = await vk.Auth.Login(loginParams.Login, loginParams.Password, ScopeSettings, captchaSid, captchaKey);\n            if (token == null || token.Token == null)\n            {\n                throw new ArgumentException(\"AccessToken is empty\");\n            }\n            else\n            {\n                Domain.Settings.Instance.AccessToken = token;\n                Domain.Settings.Instance.Save();\n                Messenger.Default.Send(new LoginMessage() { Type = LoginType.LogIn, Service = \"vk\" });\n            }\n        }\n    }\n\n    public class LastFmAccount : Account\n    {\n        public override async void Login(LoginParams loginParams)\n        {\n            var lastFm = ViewModelLocator.LastFm;\n\n            var result = await lastFm.Auth.GetMobileSession(loginParams.Login, loginParams.Password);\n            if (result == null || result.Key == null)\n            {\n                throw new ArgumentException(\"Session key is empty\");\n            }\n            else\n            {\n                lastFm.SessionKey = result.Key;\n                Domain.Settings.Instance.LastFmUsername = result.Username;\n                Domain.Settings.Instance.LastFmSession = result.Key;\n                Domain.Settings.Instance.Save();\n\n                Messenger.Default.Send(new LoginMessage() { Type = LoginType.LogIn, Service = \"lastfm\" });\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/Audio.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing Newtonsoft.Json;\nusing SQLite;\n\nnamespace Meridian.Model\n{\n    /// <summary>\n    /// Base audio class\n    /// </summary>\n    public class Audio : INotifyPropertyChanged\n    {\n        private string _title;\n        private string _artist;\n        private TimeSpan _duration;\n\n        private bool _isPlaying;\n        private int _order;\n\n        /// <summary>\n        /// Id\n        /// </summary>\n        [PrimaryKey]\n        [Unique]\n        [NotNull]\n        public string Id { get; set; }\n\n        /// <summary>\n        /// File path or url\n        /// </summary>\n        public string Source { get; set; }\n\n        /// <summary>\n        /// Title\n        /// </summary>\n        public string Title\n        {\n            get { return _title; }\n            set\n            {\n                if (_title == value)\n                    return;\n\n                _title = value;\n                OnPropertyChanged(\"Title\");\n            }\n        }\n\n        /// <summary>\n        /// Artist\n        /// </summary>\n        public string Artist\n        {\n            get { return _artist; }\n            set\n            {\n                if (_artist == value)\n                    return;\n\n                _artist = value;\n                OnPropertyChanged(\"Artist\");\n            }\n        }\n\n        /// <summary>\n        /// Duration\n        /// </summary>\n        public TimeSpan Duration\n        {\n            get { return _duration; }\n            set\n            {\n                if (_duration == value)\n                    return;\n\n                _duration = value;\n                OnPropertyChanged(\"Duration\");\n            }\n        }\n\n        /// <summary>\n        /// Is audio playing\n        /// </summary>\n        [JsonIgnore]\n        [Ignore]\n        public bool IsPlaying\n        {\n            get { return _isPlaying; }\n            set\n            {\n                if (_isPlaying == value)\n                    return;\n\n                _isPlaying = value;\n                OnPropertyChanged(\"IsPlaying\");\n            }\n        }\n\n        /// <summary>\n        /// Audio order in list (used for numeric lists)\n        /// </summary>\n        [JsonIgnore]\n        [Ignore]\n        public int Order\n        {\n            get { return _order; }\n            set\n            {\n                if (_order == value)\n                    return;\n\n                _order = value;\n                OnPropertyChanged(\"Order\");\n            }\n        }\n\n        /// <summary>\n        /// Album cover uri\n        /// </summary>\n        public Uri AlbumCover { get; set; }\n\n        /// <summary>\n        /// Returns a copy of current audio object\n        /// </summary>\n        /// <returns></returns>\n        public virtual Audio Clone()\n        {\n            var audio = new Audio();\n            audio.Id = this.Id;\n            audio.Title = this.Title;\n            audio.Artist = this.Artist;\n            audio.Duration = this.Duration;\n            audio.IsPlaying = this.IsPlaying;\n            audio.AlbumCover = this.AlbumCover;\n\n            return audio;\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged(string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n\n    /// <summary>\n    /// Vk audio\n    /// </summary>\n    public class VkAudio : Audio\n    {\n        private string _lyrics;\n        private bool _isAddedByCurrentUser;\n\n        /// <summary>\n        /// Album id\n        /// </summary>\n        public long AlbumId { get; set; }\n\n        /// <summary>\n        /// Owner id\n        /// </summary>\n        public long OwnerId { get; set; }\n\n        /// <summary>\n        /// Lyrics\n        /// </summary>\n        public string Lyrics\n        {\n            get { return _lyrics; }\n            set\n            {\n                if (_lyrics == value)\n                    return;\n\n                _lyrics = value;\n                OnPropertyChanged(\"Lyrics\");\n            }\n        }\n\n        /// <summary>\n        /// Lyrics id\n        /// </summary>\n        public long LyricsId { get; set; }\n\n        /// <summary>\n        /// Genre id\n        /// </summary>\n        public long GenreId { get; set; }\n\n        /// <summary>\n        /// Has lyrics (used for binding)\n        /// </summary>\n        public bool HasLyrics\n        {\n            get { return LyricsId != 0; }\n        }\n\n        /// <summary>\n        /// Is audio added by current user\n        /// </summary>\n        public bool IsAddedByCurrentUser\n        {\n            get { return _isAddedByCurrentUser; }\n            set\n            {\n                if (_isAddedByCurrentUser == value)\n                    return;\n\n                _isAddedByCurrentUser = value;\n                OnPropertyChanged(\"IsAddedByCurrentUser\");\n            }\n        }\n\n        public override Audio Clone()\n        {\n            var audio = new VkAudio();\n            audio.Id = this.Id;\n            audio.OwnerId = this.OwnerId;\n            audio.AlbumId = this.AlbumId;\n            audio.Title = this.Title;\n            audio.Artist = this.Artist;\n            audio.Duration = this.Duration;\n            audio.GenreId = this.GenreId;\n            audio.Lyrics = this.Lyrics;\n            audio.LyricsId = this.LyricsId;\n            audio.IsAddedByCurrentUser = this.IsAddedByCurrentUser;\n            audio.AlbumCover = this.AlbumCover;\n\n            return audio;\n        }\n    }\n\n    public class LocalAudio : Audio\n    {\n        private string _album;\n\n        /// <summary>\n        /// Album\n        /// </summary>\n        public string Album\n        {\n            get { return _album; }\n            set\n            {\n                if (_album == value)\n                    return;\n\n                _album = value;\n                OnPropertyChanged();\n            }\n        }\n\n        /// <summary>\n        /// Album id\n        /// </summary>\n        public string AlbumId { get; set; }\n\n        /// <summary>\n        /// Artist id\n        /// </summary>\n        public string ArtistId { get; set; }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/AudioAlbum.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.ComponentModel;\nusing System.IO;\nusing System.Runtime.CompilerServices;\nusing System.Windows.Media;\nusing Meridian.Helpers;\nusing SQLite;\n\nnamespace Meridian.Model\n{\n    public class AudioAlbum : INotifyPropertyChanged\n    {\n        private ImageSource _cover;\n        private bool _coverRequested;\n\n        [PrimaryKey]\n        [Unique]\n        [NotNull]\n        public string Id { get; set; }\n\n        public string Title { get; set; }\n\n        public string Artist { get; set; }\n\n        public string ArtistId { get; set; }\n\n        public string CoverPath { get; set; }\n\n        public int Year { get; set; }\n\n        [Ignore]\n        public List<Audio> Tracks { get; set; }\n\n        [Ignore]\n        public ImageSource Cover\n        {\n            get\n            {\n                GetCover();\n                return _cover;\n            }\n            set\n            {\n                if (_cover == value)\n                    return;\n\n                _cover = value;\n                OnPropertyChanged();\n            }\n        }\n\n        private void GetCover()\n        {\n            if (_coverRequested || string.IsNullOrEmpty(CoverPath) || !File.Exists(CoverPath))\n                return;\n            _coverRequested = true;\n\n            AlbumCoversHelper.RequestCover(this);\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/AudioArtist.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Runtime.CompilerServices;\nusing System.Windows.Media;\nusing Meridian.Helpers;\nusing SQLite;\n\nnamespace Meridian.Model\n{\n    public class AudioArtist : INotifyPropertyChanged\n    {\n        private ImageSource _image;\n        private bool _imageRequested;\n\n        [PrimaryKey]\n        [Unique]\n        [NotNull]\n        public string Id { get; set; }\n\n        public string Title { get; set; }\n\n        [Ignore]\n        public List<Audio> Tracks { get; set; }\n\n        [Ignore]\n        public List<AudioAlbum> Albums { get; set; }\n\n        [Ignore]\n        public ImageSource Image\n        {\n            get\n            {\n                GetImage();\n                return _image;\n            }\n            set\n            {\n                if (_image == value)\n                    return;\n\n                _image = value;\n                OnPropertyChanged();\n            }\n        }\n\n        public AudioArtist()\n        {\n            Tracks = new List<Audio>();\n            Albums = new List<AudioAlbum>();\n        }\n\n\n        private void GetImage()\n        {\n            if (_imageRequested)\n                return;\n            _imageRequested = true;\n\n            ArtistImageHelper.RequestCover(this);\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/AudioPost.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing VkLib.Core.Users;\n\nnamespace Meridian.Model\n{\n    /// <summary>\n    /// Пост с аудиозаписями\n    /// </summary>\n    public class AudioPost : Audio\n    {\n        /// <summary>\n        /// Текст\n        /// </summary>\n        public string Text { get; set; }\n\n        /// <summary>\n        /// Аудиозаписи\n        /// </summary>\n        public List<Audio> Audios { get; set; }\n\n        /// <summary>\n        /// Автор\n        /// </summary>\n        public VkProfile Author { get; set; }\n\n        /// <summary>\n        /// Дата публикации\n        /// </summary>\n        public DateTime Date { get; set; }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/ColorScheme.cs",
    "content": "﻿namespace Meridian.Model\n{\n    public class ColorScheme\n    {\n        public string Name { get; set; }\n\n        public string Color { get; set; }\n\n        public ColorScheme(string name, string color)\n        {\n            Name = name;\n            Color = color;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/ItemsResponse.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Meridian.Model\n{\n    public class ItemsResponse<T>\n    {\n        public static ItemsResponse<T> Empty = new ItemsResponse<T>();\n\n        /// <summary>\n        /// Total items count that can be requested\n        /// </summary>\n        public int TotalCount { get; set; }\n\n        /// <summary>\n        /// Items\n        /// </summary>\n        public List<T> Items { get; set; }\n\n\n        public ItemsResponse()\n        {\n\n        }\n\n        public ItemsResponse(List<T> items, int totalCount = 0)\n        {\n            Items = items;\n\n            if (totalCount == 0 && items != null)\n                TotalCount = items.Count;\n            else\n                TotalCount = totalCount;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/MainMenuItem.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Meridian.Model\n{\n    public class MainMenuItem\n    {\n        /// <summary>\n        /// Group title\n        /// </summary>\n        public string Group { get; set; }\n\n        /// <summary>\n        /// Group icon\n        /// </summary>\n        public object GroupIcon { get; set; }\n\n        /// <summary>\n        /// Title\n        /// </summary>\n        public string Title { get; set; }\n\n        /// <summary>\n        /// Page\n        /// </summary>\n        public string Page { get; set; }\n\n        /// <summary>\n        /// Icon\n        /// </summary>\n        public object Icon { get; set; }\n    }\n\n\n    public class MenuItemsCollection : List<MainMenuItem>\n    {\n\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/NewsItemsResponse.cs",
    "content": "﻿using System.Collections.Generic;\nusing VkLib.Core.News;\n\nnamespace Meridian.Model\n{\n    public class NewsItemsResponse<T> : ItemsResponse<T>\n    {\n        public string NextFrom { get; set; }\n\n        public NewsItemsResponse(List<T> items, int totalCount = 0)\n            : base(items, totalCount)\n        {\n\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/Recommendation.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Meridian.Resources.Localization;\n\nnamespace Meridian.Model\n{\n    /// <summary>\n    /// Объект, представляющий собой рекомендацию (например для жанров - это жанр)\n    /// </summary>\n    public class Recommendation\n    {\n        /// <summary>\n        /// Порядок группы\n        /// </summary>\n        public int GroupOrder { get; set; }\n\n        /// <summary>\n        /// Группа\n        /// </summary>\n        public string Group { get; set; }\n\n        /// <summary>\n        /// Отображаемый заголовок\n        /// </summary>\n        public string Title { get; set; }\n\n        /// <summary>\n        /// Внутренний ключ (например для жанров - ключевое слово жанра на английском)\n        /// </summary>\n        public string Key { get; set; }\n    }\n\n    public class RecommendationsCollection : List<Recommendation>\n    {\n\n    }\n\n    public class GenreRecommendation : Recommendation\n    {\n        public GenreRecommendation()\n        {\n            Group = MainResources.RecommendationsGenresGroup;\n            GroupOrder = 2;\n        }\n    }\n\n    public class MoodRecommendation : Recommendation\n    {\n        public MoodRecommendation()\n        {\n            Group = MainResources.RecommendationsMoodsGroup;\n            GroupOrder = 1;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/SearchMenuItem.cs",
    "content": "﻿namespace Meridian.Model\n{\n    public class SearchMenuItem\n    {\n        public string Group { get; set; }\n\n        public string Title { get; set; }\n\n        public object GroupIcon { get; set; }\n\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/Settings/SettingsEngine.cs",
    "content": "﻿using Meridian.Services.Media.Core;\n\nnamespace Meridian.Model.Settings\n{\n    public class SettingsEngine\n    {\n        public string Title { get; set; }\n\n        public MediaEngine Engine { get; set; }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/Settings/SettingsHotKey.cs",
    "content": "﻿using System.ComponentModel;\n\nnamespace Meridian.Model\n{\n    /// <summary>\n    /// Модель горячей клавиши для экрана настроек\n    /// </summary>\n    public class SettingsHotkey : INotifyPropertyChanged\n    {\n        private bool _ctrl;\n        private bool _alt;\n        private bool _shift;\n        private string _title;\n        private string _key;\n\n        public string Id { get; set; }\n\n        public bool Ctrl\n        {\n            get { return _ctrl; }\n            set\n            {\n                if (_ctrl == value)\n                    return;\n\n                _ctrl = value;\n                OnPropertyChanged(\"Ctrl\");\n            }\n        }\n\n\n        public bool Shift\n        {\n            get { return _shift; }\n            set\n            {\n                if (_shift == value)\n                    return;\n\n                _shift = value;\n                OnPropertyChanged(\"Shift\");\n            }\n        }\n\n\n        public bool Alt\n        {\n            get { return _alt; }\n            set\n            {\n                if (_alt == value)\n                    return;\n\n                _alt = value;\n                OnPropertyChanged(\"Alt\");\n            }\n        }\n\n        public string Title\n        {\n            get { return _title; }\n            set\n            {\n                if (_title == value)\n                    return;\n\n                _title = value;\n                OnPropertyChanged(\"Title\");\n            }\n        }\n\n        public string Key\n        {\n            get { return _key; }\n            set\n            {\n                if (_key == value)\n                    return;\n\n                _key = value;\n                OnPropertyChanged(\"Key\");\n            }\n\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged(string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/Settings/SettingsLanguage.cs",
    "content": "﻿namespace Meridian.Model\n{\n    public class SettingsLanguage\n    {\n        public string LanguageCode { get; set; }\n\n        public string Title { get; set; }\n    }\n}\n"
  },
  {
    "path": "Meridian/Model/UIMode.cs",
    "content": "﻿namespace Meridian.Model\n{\n    public enum UIMode\n    {\n        Normal,\n        Compact,\n        CompactLandscape\n    }\n}\n"
  },
  {
    "path": "Meridian/Properties/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Meridian.Properties {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Meridian.Properties.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Meridian/Properties/Settings.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Meridian.Properties {\n    \n    \n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator\", \"16.5.0.0\")]\n    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {\n        \n        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));\n        \n        public static Settings Default {\n            get {\n                return defaultInstance;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Properties/Settings.settings",
    "content": "﻿<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"uri:settings\" CurrentProfile=\"(Default)\">\n  <Profiles>\n    <Profile Name=\"(Default)\" />\n  </Profiles>\n  <Settings />\n</SettingsFile>"
  },
  {
    "path": "Meridian/RemotePlay/RemotePlayService.cs",
    "content": "﻿using System;\nusing System.Net;\nusing Meridian.Domain;\nusing Meridian.Services;\nusing Meridian.ViewModel;\nusing Newtonsoft.Json.Linq;\n\nnamespace Meridian.RemotePlay\n{\n    public class RemotePlayService\n    {\n        private static RemotePlayService _instance = new RemotePlayService();\n        private SimpleWebServer _server;\n\n        public static RemotePlayService Instance\n        {\n            get { return _instance; }\n        }\n\n        public async void Start()\n        {\n            try\n            {\n                //save hostname and port to vk server\n                await ViewModelLocator.Vkontakte.Storage.Set(\"remoteServer\", Settings.Instance.RemotePlayAddress + \":\" + Settings.Instance.RemotePlayPort);\n\n                if (_server != null)\n                    _server.Stop();\n\n                _server = new SimpleWebServer();\n                _server.OnReceivedData = OnReceveData;\n                _server.Start(IPAddress.Any, Settings.Instance.RemotePlayPort);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(\"Unable to start remote service: \" + ex);\n            }\n        }\n\n        public async void Stop()\n        {\n            if (_server != null)\n            {\n                _server.Stop();\n                _server = null;\n            }\n\n            try\n            {\n                //clear hostname and port to vk server\n                await ViewModelLocator.Vkontakte.Storage.Set(\"remoteServer\", \"\");\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(\"Unable to stop remote service: \" + ex);\n            }\n        }\n\n        private void OnReceveData(string data)\n        {\n            if (string.IsNullOrWhiteSpace(data))\n                return;\n\n            try\n            {\n                var json = JObject.Parse(data);\n                if (json[\"command\"] != null)\n                {\n                    switch (json[\"command\"].Value<string>())\n                    {\n                        case \"play\":\n                            if (!ViewModelLocator.Main.IsPlaying)\n                                ViewModelLocator.Main.PlayPauseCommand.Execute(null);\n                            break;\n\n                        case \"pause\":\n                            if (ViewModelLocator.Main.IsPlaying)\n                                ViewModelLocator.Main.PlayPauseCommand.Execute(null);\n                            break;\n\n                        case \"next\":\n                            ViewModelLocator.Main.NextAudioCommand.Execute(null);\n                            break;\n\n                        case \"prev\":\n                            ViewModelLocator.Main.PrevAudioCommand.Execute(null);\n                            break;\n\n                        case \"seek\":\n                            if (json[\"commandParam\"] != null)\n                            {\n                                ViewModelLocator.Main.CurrentAudioPositionSeconds = json[\"commandParam\"].Value<double>();\n                            }\n                            break;\n\n                        case \"volume\":\n                            if (json[\"commandParam\"] != null)\n                            {\n                                ViewModelLocator.Main.Volume = json[\"commandParam\"].Value<float>();\n                            }\n                            break;\n\n                        case \"shuffle\":\n                            if (json[\"commandParam\"] != null)\n                            {\n                                ViewModelLocator.Main.Shuffle = json[\"commandParam\"].Value<bool>();\n                            }\n                            break;\n\n                        case \"repeat\":\n                            if (json[\"commandParam\"] != null)\n                            {\n                                ViewModelLocator.Main.Repeat = json[\"commandParam\"].Value<bool>();\n                            }\n                            break;\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/RemotePlay/SimpleHttpRequest.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net;\n\nnamespace Meridian.RemotePlay\n{\n    public class SimpleHttpRequest\n    {\n        public string RequestTarget { get; set; }\n\n        public Dictionary<string, string> Headers { get; set; }\n\n        public string Body { get; set; }\n\n        public SimpleHttpRequest()\n        {\n            Headers = new Dictionary<string, string>();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/RemotePlay/SimpleHttpResponse.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Net;\nusing System.Text;\n\nnamespace Meridian.RemotePlay\n{\n    public class SimpleHttpResponse\n    {\n        public string Status { get; set; }\n\n        public Dictionary<string, string> Headers { get; set; }\n\n        public SimpleHttpResponse()\n        {\n            Status = \"HTTP/1.1 200 OK\";\n            Headers = new Dictionary<string, string>();\n        }\n\n        public override string ToString()\n        {\n            var sb = new StringBuilder();\n            sb.AppendLine(Status);\n\n            if (Headers != null)\n            {\n                foreach (var header in Headers)\n                {\n                    sb.AppendLine(header.Key + \": \" + header.Value);\n                }\n            }\n\n            sb.AppendLine(\"\");\n            return sb.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/RemotePlay/SimpleWebServer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Http.Headers;\nusing System.Net.Sockets;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing Meridian.Services;\nusing Meridian.ViewModel;\nusing Neptune.Extensions;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Serialization;\n\nnamespace Meridian.RemotePlay\n{\n    public class SimpleWebServer\n    {\n        private const string DefaultResponseHeaders = \"HTTP/1.1 200 OK\\nContent-type: text/html\\nContent-Length: {0}\\r\\n\\r\\n{1}\";\n        private TcpListener _listener;\n        private bool _run;\n\n        public Action<string> OnReceivedData;\n\n        public void Start(IPAddress address, int port)\n        {\n            if (_listener != null)\n                _listener.Stop();\n\n            _listener = new TcpListener(address, port);\n            _listener.Start();\n\n            _run = true;\n\n            Listen();\n        }\n\n        public void Stop()\n        {\n            _run = false;\n            _listener.Stop();\n        }\n\n        private async void Listen()\n        {\n            if (!_run)\n                return;\n\n            TcpClient client = null;\n\n            try\n            {\n                client = await _listener.AcceptTcpClientAsync();\n            }\n            catch (Exception)\n            {\n            }\n\n            if (!_run || client == null)\n                return;\n\n            var buffer = new byte[client.ReceiveBufferSize];\n            var stream = client.GetStream();\n\n            SimpleHttpRequest simpleRequest = null;\n\n            if (stream.CanRead)\n            {\n                try\n                {\n                    var received = await stream.ReadAsync(buffer, 0, buffer.Length);\n                    if (received > 0)\n                    {\n                        var requestString = Encoding.UTF8.GetString(buffer, 0, received);\n                        if (!string.IsNullOrEmpty(requestString))\n                        {\n                            Debug.WriteLine(\"Request: \" + requestString);\n\n                            simpleRequest = ProcessRequest(requestString);\n\n                            if (!string.IsNullOrEmpty(simpleRequest.Body))\n                            {\n                                if (OnReceivedData != null)\n                                    OnReceivedData(simpleRequest.Body);\n                            }\n                        }\n                    }\n                }\n                catch (Exception ex)\n                {\n                    Debug.WriteLine(ex);\n                }\n\n            }\n\n            if (simpleRequest != null)\n            {\n                string target = \"/index.html\";\n                if (simpleRequest.RequestTarget.Length > 1)\n                {\n                    target = simpleRequest.RequestTarget;\n                }\n\n                if (target.StartsWith(\"/api\"))\n                {\n                    await ApiResponse(simpleRequest, target, stream);\n                }\n                else\n                {\n                    await FileResponse(simpleRequest, target, stream);\n                }\n            }\n\n            Listen();\n        }\n\n        private SimpleHttpRequest ProcessRequest(string request)\n        {\n            var requestTarget = Regex.Match(request, @\"^\\w+\\s+([^\\s\\?]+)[^\\s]*\\s+HTTP/.*|\").Groups[1].Value;\n\n            //if(requestTarget == \"/api\")\n            //    Debugger.Break();\n            var lines = request.Split(new[] { Environment.NewLine }, StringSplitOptions.None);\n            var i = 1;\n\n            var headers = new Dictionary<string, string>();\n            var body = string.Empty;\n\n            for (i = 1; i < lines.Length; i++) //first line contains mehtod like GET or POST, skip it\n            {\n                var line = lines[i];\n                if (!line.Contains(\":\"))\n                {\n                    //headers ended\n                    break;\n                }\n\n                var headerName = line.Substring(0, line.IndexOf(\":\"));\n                var headerValue = line.Substring(line.IndexOf(\":\") + 1);\n                if (!headers.ContainsKey(headerName))\n                    headers.Add(headerName, headerValue);\n            }\n\n            if (lines.Length > i)\n            {\n                var sb = new StringBuilder();\n                for (i = i + 1; i < lines.Length; i++)\n                    sb.AppendLine(lines[i]);\n\n                body = sb.ToString();\n            }\n\n            //Safari on iOS and IE on Windows Phone doesn't most of time doesn't send data in the post\n            //so using x-data header to pass commands instead of request body\n            if (headers.ContainsKey(\"x-data\"))\n            {\n                body = headers[\"x-data\"];\n            }\n\n            return new SimpleHttpRequest() { RequestTarget = requestTarget, Headers = headers, Body = body };\n        }\n\n        private async Task ApiResponse(SimpleHttpRequest request, string target, Stream responseStream)\n        {\n            try\n            {\n                var method = target.Substring(target.LastIndexOf(\"/\"));\n                var responseText = string.Empty;\n                var jsonSettings = new JsonSerializerSettings()\n                {\n                    ContractResolver = new CamelCasePropertyNamesContractResolver()\n                };\n\n                switch (method)\n                {\n                    case \"/api\":\n                        //just return ok\n                        responseText = JsonConvert.SerializeObject(new { response = 1 });\n                        break;\n\n                    case \"/currentTrack\":\n                        //return current track\n                        responseText = JsonConvert.SerializeObject(new { response = new { track = ViewModelLocator.Main.CurrentAudio, currentTime = ViewModelLocator.Main.CurrentAudioPositionSeconds, duration = ViewModelLocator.Main.CurrentAudioDuration.TotalSeconds, shuffle = ViewModelLocator.Main.Shuffle, repeat = ViewModelLocator.Main.Repeat } }, Formatting.None, jsonSettings);\n                        break;\n\n                    case \"/isPlaying\":\n                        //return isPlaying\n                        responseText = JsonConvert.SerializeObject(new { response = ViewModelLocator.Main.IsPlaying }, Formatting.None, jsonSettings);\n                        break;\n\n                    case \"/volume\":\n                        //return volume\n                        responseText = JsonConvert.SerializeObject(new { response = ViewModelLocator.Main.Volume }, Formatting.None, jsonSettings);\n                        break;\n                }\n\n                var response = new SimpleHttpResponse();\n                var contentType = \"application/json\";\n\n                var responseBytes = Encoding.UTF8.GetBytes(responseText.ToString());\n\n                response.Headers.Add(\"Content-Length\", responseBytes.Length.ToString());\n                response.Headers.Add(\"Content-Type\", contentType);\n\n                responseStream.WriteText(response.ToString() + responseText);\n                responseStream.Dispose();\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private async Task FileResponse(SimpleHttpRequest request, string target, Stream responseStream)\n        {\n            var streamResourceInfo = Application.GetContentStream(new Uri(\"pack://application:,,,/Meridian;component/RemotePlay/web\" + target));\n            if (streamResourceInfo != null)\n            {\n                try\n                {\n                    var response = new SimpleHttpResponse();\n\n                    var length = streamResourceInfo.Stream.Length;\n                    var extension = Path.GetExtension(target);\n                    var contentType = \"application/\" + extension;\n\n                    switch (extension)\n                    {\n                        case \".html\":\n                        case \".htm\":\n                            contentType = \"text/html\";\n                            break;\n\n                        case \".js\":\n                            contentType = \"application/javascript\";\n                            break;\n\n                        case \".css\":\n                            contentType = \"text/css\";\n                            break;\n\n                        case \".png\":\n                            contentType = \"image/png\";\n                            break;\n\n                        case \".svg\":\n                            contentType = \"image/svg+xml\";\n                            break;\n                    }\n\n                    response.Headers.Add(\"Content-Length\", length.ToString());\n                    response.Headers.Add(\"Content-Type\", contentType);\n\n                    var headerBytes = Encoding.UTF8.GetBytes(response.ToString());\n                    responseStream.Write(headerBytes, 0, headerBytes.Length);\n                    streamResourceInfo.Stream.CopyTo(responseStream);\n                    await responseStream.FlushAsync();\n                    responseStream.Close();\n                    responseStream.Dispose();\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n            }\n            else\n            {\n                var response = new SimpleHttpResponse();\n                response.Status = \"HTTP/1.1 404 NOT FOUND\";\n                response.Headers.Add(\"Content-Length\", \"0\");\n                responseStream.WriteText(response.ToString());\n                responseStream.Dispose();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/RemotePlay/web/index.html",
    "content": "﻿<!DOCTYPE html>\n<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1\">\n    <title>Meridian RemotePlay</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"styles/index.css\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"styles/player.css\">\n    <script type=\"text/javascript\" src=\"lib/jquery-2.1.3.min.js\"></script>\n    <script type=\"text/javascript\" src=\"lib/jquery-ui.min.js\"></script>\n    <script type=\"text/javascript\" src=\"lib/jquery.ui.touch-punch.min.js\"></script>\n    <script type=\"text/javascript\" src=\"js/utils.js\"></script>\n    <script type=\"text/javascript\" src=\"js/index.js\"></script>\n</head>\n<body>\n    <div id=\"playerControl\">\n        <div style=\"position: relative\">\n            <div class=\"coverButtonsBlock\">\n                <div style=\"position: relative; height: 188px\">\n                    <!--<button id=\"vk\" class=\"coverButton\">\n                        <svg viewBox=\"0 0 60 45\">\n                            <use xlink:href=\"img/player.svg#vk\"></use>\n                        </svg>\n                    </button>-->\n                    <!--<button id=\"like\" class=\"coverButton\">\n                        <svg viewBox=\"0 0 76 80\">\n                            <use xlink:href=\"img/player.svg#like\"></use>\n                        </svg>\n                    </button>\n                    <button id=\"shuffle\" class=\"coverButton\">\n                        <svg viewBox=\"0 0 41.17 47.50\">\n                            <use xlink:href=\"img/player.svg#shuffle\"></use>\n                        </svg>\n                    </button>\n                    <button id=\"repeat\" class=\"coverButton\">\n                        <svg viewBox=\"0 0 14.24 13.37\">\n                            <use xlink:href=\"img/player.svg#repeat\"></use>\n                        </svg>\n                    </button>-->\n                </div>\n            </div>\n        </div>\n\n\n        <span id=\"currentAudioTitle\"></span>\n        <span id=\"currentAudioArtist\"></span>\n    </div>\n\n    <div class=\"progress\">\n        <section id=\"progressBarContainer\">\n            <div id=\"progressBarBg\"></div>\n            <div id=\"progressBar\"></div>\n        </section>\n\n\n        <div style=\"width: auto; height: 20pt; line-height: 20pt; margin-left: 12pt; margin-right: 12pt\">\n            <span id=\"currentTime\">0:00</span>\n            <span id=\"duration\">0:00</span>\n        </div>\n    </div>\n\n    <div id=\"playerControls\" class=\"state-play\">\n        <button id=\"prev\" class=\"controlButton\">\n            <svg viewBox=\"0 0 80 80\">\n                <use xlink:href=\"img/player.svg#prev\"></use>\n            </svg>\n        </button>\n        <button id=\"play\" class=\"controlButton play\">\n            <svg viewBox=\"0 0 80 80\">\n                <use xlink:href=\"img/player.svg#play\"></use>\n            </svg>\n        </button>\n        <button id=\"pause\" class=\"controlButton pause\">\n            <svg viewBox=\"0 0 80 80\">\n                <use xlink:href=\"img/player.svg#pause\"></use>\n            </svg>\n        </button>\n        <button id=\"next\" class=\"controlButton\">\n            <svg viewBox=\"0 0 80 80\">\n                <use xlink:href=\"./img/player.svg#next\"></use>\n            </svg>\n        </button>\n    </div>\n\n    <div id=\"volumeWrapper\">\n        <img id=\"volumeMute\" class=\"volumeIcon\" src=\"img/light/volume_mute.png\" />\n        <section id=\"volumeBarContainer\">\n            <div id=\"volumeBarBg\"></div>\n            <div id=\"volumeBar\"></div>\n        </section>\n        <img id=\"volumeMax\" class=\"volumeIcon\" src=\"img/light/volume.png\" />\n    </div>\n\n    <script type=\"text/javascript\" src=\"lib/svg4everybody.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "Meridian/RemotePlay/web/js/index.js",
    "content": "﻿$(document).ready(function () {\n    var positionChanging = false;\n\n    var play = document.getElementById(\"play\");\n    var pause = document.getElementById(\"pause\");\n    var prev = document.getElementById(\"prev\");\n    var next = document.getElementById(\"next\");\n    var playerControls = document.getElementById(\"playerControls\");\n\n    var currentAudioTitle = document.getElementById(\"currentAudioTitle\");\n    var currentAudioArtist = document.getElementById(\"currentAudioArtist\");\n\n    var currentTime = document.getElementById(\"currentTime\");\n    var duration = document.getElementById(\"duration\");\n\n    play.onclick = onPlay;\n    pause.onclick = onPause;\n    next.onclick = onNext;\n    prev.onclick = onPrev;\n\n    var progressBar = $(\"#progressBar\");\n    progressBar.slider({\n        range: \"min\",\n        value: 0,\n        slide: onSliderChanged\n    });\n\n\n    var volumeBar = $(\"#volumeBar\");\n    volumeBar.slider({\n        range: \"min\",\n        max: 100,\n        slide: onVolumeSliderChanged\n    });\n\n    api(\"/isPlaying\", null, null, function (isPlaying) {\n        setIsPlaying(isPlaying);\n    });\n\n    api(\"/volume\", null, null, function (volume) {\n        volumeBar.slider({ value: volume });\n    });\n\n    setInterval(function () {\n        api(\"/isPlaying\", null, null, function (isPlaying) {\n            setIsPlaying(isPlaying);\n        });\n\n        api(\"/currentTrack\", null, null, function (trackInfo) {\n            currentAudioTitle.innerText = trackInfo.track.title;\n            currentAudioArtist.innerText = trackInfo.track.artist;\n\n            currentTime.innerText = trackInfo.currentTime.toString().toShortTimeString();\n            duration.innerText = trackInfo.duration.toString().toShortTimeString();\n\n            if (!positionChanging)\n                progressBar.slider({ value: trackInfo.currentTime, max: trackInfo.duration });\n        });\n    }, 1000);\n\n\n    function onPlay() {\n        api(\"\", \"play\", null, function (ok) {\n            if (ok)\n                setIsPlaying(true);\n        });\n    }\n\n\n    function onPause() {\n        api(\"\", \"pause\", null, function (ok) {\n            if (ok)\n                setIsPlaying(false);\n        });\n    }\n\n    function onNext() {\n        api(\"\", \"next\", null, function (ok) {\n\n        });\n\n    }\n\n    function onPrev() {\n        api(\"\", \"prev\", null);\n    }\n\n    function onSliderChanged(event, ui) {\n        positionChanging = true;\n\n        api(\"\", \"seek\", ui.value, function (ok) {\n            currentTime.innerText = ui.value.toString().toShortTimeString();\n        });\n\n        positionChanging = false;\n    }\n\n\n    function onVolumeSliderChanged(event, ui) {\n        api(\"\", \"volume\", ui.value, function (ok) {\n\n        });\n    }\n\n    function setIsPlaying(isPlaying) {\n        if (isPlaying) {\n            playerControls.className = 'state-play';\n        } else {\n            playerControls.className = 'state-pause';\n        }\n    }\n\n    function api(method, command, commandParam, cb) {\n        var postData = {};\n        if (command)\n            postData = { v: 1, command: command, commandParam: commandParam };\n\n        //Safari on iOS and IE on Windows Phone doesn't most of time doesn't send data in the post\n        //so using x-data header to pass commands instead of request body\n        $.ajax({\n            url: \"/api\" + method,\n            cache: false,\n            headers: { \"cache-control\": \"max-age=0\", \"x-data\": JSON.stringify(postData)},\n            type: \"POST\",\n            contentType: \"application/json\",\n            dataType: \"json\",\n            //data: JSON.stringify(postData),\n            success: function (data) {\n                cb(data.response);\n            }\n        });\n    }\n});"
  },
  {
    "path": "Meridian/RemotePlay/web/js/utils.js",
    "content": "﻿if (!String.prototype.toShortTimeString) {\n    String.prototype.toShortTimeString = function () {\n        var sec_num = parseInt(this, 10); // don't forget the second param\n        var hours = Math.floor(sec_num / 3600);\n        var minutes = Math.floor((sec_num - (hours * 3600)) / 60);\n        var seconds = sec_num - (hours * 3600) - (minutes * 60);\n\n        if (minutes < 10) {\n            minutes = minutes;\n        }\n        if (seconds < 10) {\n            seconds = \"0\" + seconds;\n        }\n        var time = minutes + ':' + seconds;\n        return time;\n    }\n}"
  },
  {
    "path": "Meridian/RemotePlay/web/lib/svg4everybody.js",
    "content": "﻿!function (e, t, n, o, r, i) { function a(t, n) { if (n) { var o = n.getAttribute(\"viewBox\"), r = e.createDocumentFragment(), i = n.cloneNode(!0); if (o && t.setAttribute(\"viewBox\", o), i.childNodes.length > 0) for (; i.childNodes.length;) r.appendChild(i.childNodes[0]); else r.appendChild(i); t.appendChild(r) } } function l() { var t = this, n = e.createElement(\"x\"), o = t.s; n.innerHTML = t.responseText, t.onload = function () { o.splice(0).map(function (e) { a(e[0], n.querySelector(\"#\" + e[1].replace(/(\\W)/g, \"\\\\$1\"))) }) }, t.onload() } function d() { for (var i; i = t[0];) if (r) { var s = new Image; s.src = i.getAttribute(\"xlink:href\").replace(\"#\", \".\").replace(/^\\./, \"\") + \".png\", i.parentNode.replaceChild(s, i) } else { var c = i.parentNode, u = i.getAttribute(\"xlink:href\").split(\"#\"), p = u[0], g = u[1]; if (c.removeChild(i), p.length) { var m = o[p] = o[p] || new XMLHttpRequest; m.s || (m.s = [], m.open(\"GET\", p), m.onload = l, m.send()), m.s.push([c, g]), 4 === m.readyState && m.onload() } else a(c, e.getElementById(g)) } n(d) } (r || i) && t.length > 0 && d() }(document, document.getElementsByTagName(\"use\"), window.requestAnimationFrame || window.setTimeout, {}, /MSIE\\s[1-8]\\b/.test(navigator.userAgent), /Trident\\/[567]\\b/.test(navigator.userAgent) || (navigator.userAgent.match(/AppleWebKit\\/(\\d+)/) || [])[1] < 537, document.createElement(\"svg\"), document.createElement(\"use\"));"
  },
  {
    "path": "Meridian/RemotePlay/web/styles/index.css",
    "content": "﻿html {\n    position: relative;\n    width: 100%;\n    height: 100%;\n    min-height: 300pt;\n    margin-bottom: 20pt;\n}\n\nbody {\n    font-family: \"Segoe UI\",\"Segoe\",Tahoma,Arial,sans-serif;\n    margin: 0;\n}\n\n.playerButton {\n    background: transparent;\n    border: none;\n}\n\n#prev:hover img {\n    content: url(../img/prev_hover.png);\n}\n\n#play:hover img {\n    content: url(../img/play_hover.png);\n}\n\n#next:hover img {\n    content: url(../img/next_hover.png);\n}\n"
  },
  {
    "path": "Meridian/RemotePlay/web/styles/player.css",
    "content": "﻿#playerControl {\n    margin-top: 30pt;\n}\n\n    #playerControl #progressBar {\n        width: auto;\n        padding: 0;\n        margin: 0;\n    }\n\n/* progress bar */\n\n#progressBarContainer {\n    width: auto;\n    height: auto;\n    margin: 10pt 20pt -5pt 20pt;\n    position: relative;\n}\n\n#progressBar {\n    height: 10pt;\n}\n\n#progressBarBg {\n    height: 4pt;\n    background-color: #dddddd;\n}\n\n#progressBar .ui-slider-handle {\n    position: absolute;\n    z-index: 2;\n    width: 15pt;\n    height: 15pt;\n    cursor: pointer;\n    background: white no-repeat 50% 50%;\n    border: 1pt solid rgba(0, 0, 0, 0.1);\n    font-weight: bold;\n    outline: none;\n    top: -7pt;\n    margin-left: -7pt;\n    border-radius: 15pt;\n    box-shadow: 0 1.5pt 3pt rgba(0,0,0,0.2);\n}\n\n#progressBar .ui-slider-range {\n    position: absolute;\n    border: 0;\n    top: 0;\n    height: 4pt;\n    background-color: #006ac1;\n}\n\n/* volume bar */\n\n#volumeWrapper {\n    position: absolute;\n    height: 36pt;\n    width: 188pt;\n    left: calc(50% - 94pt);\n    bottom: 20pt;\n}\n\n#volumeBarContainer {\n    width: 118pt;\n    height: auto;\n    /*margin: 10pt 30pt -5pt;*/\n    position: absolute;\n    top: 50%;\n    left: calc(50% - 59pt);\n}\n\n#volumeBar {\n    height: 10pt;\n    left: 20pt;\n}\n\n#volumeBarBg {\n    height: 3pt;\n    background-color: #dddddd;\n}\n\n#volumeBar .ui-slider-handle {\n    position: absolute;\n    z-index: 2;\n    width: 12pt;\n    height: 12pt;\n    cursor: pointer;\n    background: white no-repeat 50% 50%;\n    border: 1pt solid rgba(0, 0, 0, 0.1);\n    font-weight: bold;\n    outline: none;\n    top: -7pt;\n    margin-left: -7pt;\n    border-radius: 15pt;\n    box-shadow: 0 1.5pt 3pt rgba(0,0,0,0.2);\n}\n\n#volumeBar .ui-slider-range {\n    background: #444444;\n    position: absolute;\n    border: 0;\n    top: 0;\n    height: 3pt;\n}\n\n.volumeIcon {\n    width: 36pt;\n    height: 36pt;\n    opacity: 0.3;\n    top: 2pt;\n    position: absolute;\n}\n\n#volumeMute {\n    left: -8pt;\n}\n\n#volumeMax {\n    right: -8pt;\n}\n\n/* */\n\n#playerControl #currentAudioTitle {\n    display: block;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    overflow: hidden;\n    font-size: 18pt;\n    font-weight: bold;\n    text-transform: uppercase;\n    height: 24pt;\n    margin-top: 80pt;\n    margin-left: 20pt;\n    margin-right: 20pt;\n    text-align: center;\n}\n\n#playerControl #currentAudioArtist {\n    display: block;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    overflow: hidden;\n    font-weight: normal;\n    height: 20pt;\n    margin-left: 20pt;\n    margin-right: 20pt;\n    text-align: center;\n    font-size: 16pt;\n}\n\n.progress {\n    width: 100%;\n    position: absolute;\n    bottom: 110pt;\n}\n\n#currentTime {\n    display: inline-block;\n    font-size: 12pt;\n    font-weight: normal;\n    opacity: 0.7;\n}\n\n#duration {\n    display: inline-block;\n    float: right;\n    font-size: 12pt;\n    font-weight: normal;\n    opacity: 0.7;\n}\n\n/* control buttons */\n#playerControls {\n    width: auto;\n    height: 32pt;\n    position: absolute;\n    bottom: 60pt;\n    min-width: 200pt;\n    left: calc(50% - 100pt);\n}\n\n    #playerControls .controlButton {\n        min-width: 0pt;\n        min-height: 0pt;\n        background-color: transparent;\n        border: none;\n        width: 30pt;\n        height: 30pt;\n        outline: none;\n        fill: #1e1e1e;\n        position: absolute;\n    }\n\n        #playerControls .controlButton:active {\n            fill: black;\n        }\n\n\n    #playerControls .play {\n        width: 34pt;\n        height: 34pt;\n        top: -2pt;\n        left: calc(50% - 17pt);\n    }\n\n    #playerControls .pause {\n        width: 32pt;\n        height: 32pt;\n        top: -2pt;\n        left: calc(50% - 16pt);\n    }\n\n    #playerControls #prev {\n        margin-left: -25pt;\n        left: calc(50% - 35pt);\n    }\n\n    #playerControls #next {\n        margin-left: 27pt;\n        left: 50%;\n    }\n\n    #playerControls.state-play .play{\n        display: none;\n    }\n\n    #playerControls.state-play .pause{\n        display: inline-block;\n    }\n\n    #playerControls.state-pause .play{\n        display: inline-block;\n    }\n\n    #playerControls.state-pause .pause{\n        display: none;\n    }\n\n/* */\n\n#playerControl .coverButtonsBlock {\n    position: absolute;\n    top: 0;\n    right: 14pt;\n    width: 20pt;\n}\n\n    #playerControl .coverButtonsBlock .coverButton {\n        min-width: 0;\n        min-height: 0;\n        height: 20pt;\n        width: 100%;\n        padding: 0;\n        background: none;\n        opacity: 0.5;\n        outline: none;\n        border: none;\n        padding: 3pt;\n        position: absolute;\n    }\n\n        #playerControl .coverButtonsBlock .coverButton:hover {\n            opacity: 0.6;\n        }\n\n        #playerControl .coverButtonsBlock .coverButton:active {\n            transform: scale(0.92, 0.92);\n        }\n\n        #playerControl .coverButtonsBlock .coverButton#vk {\n            top: 10pt;\n        }\n\n        #playerControl .coverButtonsBlock .coverButton#like {\n            padding: 0;\n            height: 25pt;\n            width: 25pt;\n            margin-left: -3pt;\n        }\n\n        #playerControl .coverButtonsBlock .coverButton#shuffle {\n            padding: 4pt;\n            top: 50%;\n            margin-top: -15pt;\n        }\n\n            #playerControl .coverButtonsBlock .coverButton#shuffle.active {\n                opacity: 1;\n            }\n\n        #playerControl .coverButtonsBlock .coverButton#repeat {\n            bottom: 10pt;\n        }\n\n            #playerControl .coverButtonsBlock .coverButton#repeat.active {\n                opacity: 1;\n            }\n"
  },
  {
    "path": "Meridian/Resources/Localization/ErrorResources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Meridian.Resources.Localization {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    public class ErrorResources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal ErrorResources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Meridian.Resources.Localization.ErrorResources\", typeof(ErrorResources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Meridian doesn&apos;t have rights to write content in the current folder. Please restart application with administrative privilegies..\n        /// </summary>\n        public static string AccessDeniedErrorDescription {\n            get {\n                return ResourceManager.GetString(\"AccessDeniedErrorDescription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to save settings.\n        /// </summary>\n        public static string AccessDeniedErrorTitle {\n            get {\n                return ResourceManager.GetString(\"AccessDeniedErrorTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to play audio.\n        /// </summary>\n        public static string AudioFailedErrorHeaderCommon {\n            get {\n                return ResourceManager.GetString(\"AudioFailedErrorHeaderCommon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please check your internet connection and try again. Error code: 0xC00D0035.\n        /// </summary>\n        public static string ConnectionError {\n            get {\n                return ResourceManager.GetString(\"ConnectionError\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You should choose which societies will be shown in the feed.\n        /// </summary>\n        public static string FeedSocietiesEmpty {\n            get {\n                return ResourceManager.GetString(\"FeedSocietiesEmpty\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to load albums.\n        /// </summary>\n        public static string LoadAlbumsErrorCommon {\n            get {\n                return ResourceManager.GetString(\"LoadAlbumsErrorCommon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Albums list is empty.\n        /// </summary>\n        public static string LoadAlbumsErrorEmpty {\n            get {\n                return ResourceManager.GetString(\"LoadAlbumsErrorEmpty\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to load artists.\n        /// </summary>\n        public static string LoadArtistsErrorCommon {\n            get {\n                return ResourceManager.GetString(\"LoadArtistsErrorCommon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Artists list is empty.\n        /// </summary>\n        public static string LoadArtistsErrorEmpty {\n            get {\n                return ResourceManager.GetString(\"LoadArtistsErrorEmpty\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Access to audio list is denied.\n        /// </summary>\n        public static string LoadAudiosErrorAccessDenied {\n            get {\n                return ResourceManager.GetString(\"LoadAudiosErrorAccessDenied\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to load audios.\n        /// </summary>\n        public static string LoadAudiosErrorCommon {\n            get {\n                return ResourceManager.GetString(\"LoadAudiosErrorCommon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Audio list is empty.\n        /// </summary>\n        public static string LoadAudiosErrorEmpty {\n            get {\n                return ResourceManager.GetString(\"LoadAudiosErrorEmpty\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to load friends.\n        /// </summary>\n        public static string LoadFriendsErrorCommon {\n            get {\n                return ResourceManager.GetString(\"LoadFriendsErrorCommon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You have 0 friends :(.\n        /// </summary>\n        public static string LoadFriendsErrorEmpty {\n            get {\n                return ResourceManager.GetString(\"LoadFriendsErrorEmpty\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to perform search.\n        /// </summary>\n        public static string LoadSearchErrorCommon {\n            get {\n                return ResourceManager.GetString(\"LoadSearchErrorCommon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Nothing found.\n        /// </summary>\n        public static string LoadSearchErrorEmpty {\n            get {\n                return ResourceManager.GetString(\"LoadSearchErrorEmpty\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to load societies.\n        /// </summary>\n        public static string LoadSocietiesErrorCommon {\n            get {\n                return ResourceManager.GetString(\"LoadSocietiesErrorCommon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Societies list is empty.\n        /// </summary>\n        public static string LoadSocietiesErrorEmpty {\n            get {\n                return ResourceManager.GetString(\"LoadSocietiesErrorEmpty\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to load subscriptions.\n        /// </summary>\n        public static string LoadSubscriptionsErrorCommon {\n            get {\n                return ResourceManager.GetString(\"LoadSubscriptionsErrorCommon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You are not subscribed to anyone.\n        /// </summary>\n        public static string LoadSubscriptionsErrorEmpty {\n            get {\n                return ResourceManager.GetString(\"LoadSubscriptionsErrorEmpty\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to sign in. Check your login and password and try again..\n        /// </summary>\n        public static string LoginErrorInvalidClient {\n            get {\n                return ResourceManager.GetString(\"LoginErrorInvalidClient\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Validation is required. You will be redirected to validation page..\n        /// </summary>\n        public static string LoginErrorNeedValidation {\n            get {\n                return ResourceManager.GetString(\"LoginErrorNeedValidation\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Windows Media Player 10 or higher is required to play music..\n        /// </summary>\n        public static string WmpMissingError {\n            get {\n                return ResourceManager.GetString(\"WmpMissingError\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Resources/Localization/ErrorResources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AccessDeniedErrorDescription\" xml:space=\"preserve\">\n    <value>Meridian doesn't have rights to write content in the current folder. Please restart application with administrative privilegies.</value>\n  </data>\n  <data name=\"AccessDeniedErrorTitle\" xml:space=\"preserve\">\n    <value>Unable to save settings</value>\n  </data>\n  <data name=\"AudioFailedErrorHeaderCommon\" xml:space=\"preserve\">\n    <value>Unable to play audio</value>\n  </data>\n  <data name=\"ConnectionError\" xml:space=\"preserve\">\n    <value>Please check your internet connection and try again. Error code: 0xC00D0035</value>\n  </data>\n  <data name=\"FeedSocietiesEmpty\" xml:space=\"preserve\">\n    <value>You should choose which societies will be shown in the feed</value>\n  </data>\n  <data name=\"LoadAlbumsErrorCommon\" xml:space=\"preserve\">\n    <value>Unable to load albums</value>\n  </data>\n  <data name=\"LoadAlbumsErrorEmpty\" xml:space=\"preserve\">\n    <value>Albums list is empty</value>\n  </data>\n  <data name=\"LoadArtistsErrorCommon\" xml:space=\"preserve\">\n    <value>Unable to load artists</value>\n  </data>\n  <data name=\"LoadArtistsErrorEmpty\" xml:space=\"preserve\">\n    <value>Artists list is empty</value>\n  </data>\n  <data name=\"LoadAudiosErrorAccessDenied\" xml:space=\"preserve\">\n    <value>Access to audio list is denied</value>\n  </data>\n  <data name=\"LoadAudiosErrorCommon\" xml:space=\"preserve\">\n    <value>Unable to load audios</value>\n  </data>\n  <data name=\"LoadAudiosErrorEmpty\" xml:space=\"preserve\">\n    <value>Audio list is empty</value>\n  </data>\n  <data name=\"LoadFriendsErrorCommon\" xml:space=\"preserve\">\n    <value>Unable to load friends</value>\n  </data>\n  <data name=\"LoadFriendsErrorEmpty\" xml:space=\"preserve\">\n    <value>You have 0 friends :(</value>\n  </data>\n  <data name=\"LoadSearchErrorCommon\" xml:space=\"preserve\">\n    <value>Unable to perform search</value>\n  </data>\n  <data name=\"LoadSearchErrorEmpty\" xml:space=\"preserve\">\n    <value>Nothing found</value>\n  </data>\n  <data name=\"LoadSocietiesErrorCommon\" xml:space=\"preserve\">\n    <value>Unable to load societies</value>\n  </data>\n  <data name=\"LoadSocietiesErrorEmpty\" xml:space=\"preserve\">\n    <value>Societies list is empty</value>\n  </data>\n  <data name=\"LoadSubscriptionsErrorCommon\" xml:space=\"preserve\">\n    <value>Unable to load subscriptions</value>\n  </data>\n  <data name=\"LoadSubscriptionsErrorEmpty\" xml:space=\"preserve\">\n    <value>You are not subscribed to anyone</value>\n  </data>\n  <data name=\"LoginErrorInvalidClient\" xml:space=\"preserve\">\n    <value>Unable to sign in. Check your login and password and try again.</value>\n  </data>\n  <data name=\"LoginErrorNeedValidation\" xml:space=\"preserve\">\n    <value>Validation is required. You will be redirected to validation page.</value>\n  </data>\n  <data name=\"WmpMissingError\" xml:space=\"preserve\">\n    <value>Windows Media Player 10 or higher is required to play music.</value>\n  </data>\n</root>"
  },
  {
    "path": "Meridian/Resources/Localization/ErrorResources.ru.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AccessDeniedErrorDescription\" xml:space=\"preserve\">\n    <value>Отсутствуют права на запись в текущую папку. Пожалуйста, перезапустите приложение с правами администратора.</value>\n  </data>\n  <data name=\"AccessDeniedErrorTitle\" xml:space=\"preserve\">\n    <value>Не удалось сохранить настройки</value>\n  </data>\n  <data name=\"AudioFailedErrorHeaderCommon\" xml:space=\"preserve\">\n    <value>Не удалось воспроизвести аудиозапись</value>\n  </data>\n  <data name=\"ConnectionError\" xml:space=\"preserve\">\n    <value>Пожалуйста, проверьте соединение с Интернетом и попробуйте снова. Код ошибки: 0xC00D0035</value>\n  </data>\n  <data name=\"FeedSocietiesEmpty\" xml:space=\"preserve\">\n    <value>Выберите сообщества, из которых будет отображаться музыка в ленте</value>\n  </data>\n  <data name=\"LoadAlbumsErrorCommon\" xml:space=\"preserve\">\n    <value>Не удалось загрузить список альбомов</value>\n  </data>\n  <data name=\"LoadAlbumsErrorEmpty\" xml:space=\"preserve\">\n    <value>Список альбомов пуст</value>\n  </data>\n  <data name=\"LoadArtistsErrorCommon\" xml:space=\"preserve\">\n    <value>Не удалось загрузить список исполнителей</value>\n  </data>\n  <data name=\"LoadArtistsErrorEmpty\" xml:space=\"preserve\">\n    <value>Список исполнителей пуст</value>\n  </data>\n  <data name=\"LoadAudiosErrorAccessDenied\" xml:space=\"preserve\">\n    <value>Список аудиозаписей недоступен</value>\n  </data>\n  <data name=\"LoadAudiosErrorCommon\" xml:space=\"preserve\">\n    <value>Не удалось загрузить список аудиозаписей</value>\n  </data>\n  <data name=\"LoadAudiosErrorEmpty\" xml:space=\"preserve\">\n    <value>Список аудиозаписей пуст</value>\n  </data>\n  <data name=\"LoadFriendsErrorCommon\" xml:space=\"preserve\">\n    <value>Не удалось загрузить список друзей</value>\n  </data>\n  <data name=\"LoadFriendsErrorEmpty\" xml:space=\"preserve\">\n    <value>У вас нет друзей :(</value>\n  </data>\n  <data name=\"LoadSearchErrorCommon\" xml:space=\"preserve\">\n    <value>Не удалось выполнить поиск</value>\n  </data>\n  <data name=\"LoadSearchErrorEmpty\" xml:space=\"preserve\">\n    <value>Ничего не найдено</value>\n  </data>\n  <data name=\"LoadSocietiesErrorCommon\" xml:space=\"preserve\">\n    <value>Не удалось загрузить список сообществ</value>\n  </data>\n  <data name=\"LoadSocietiesErrorEmpty\" xml:space=\"preserve\">\n    <value>Список сообществ пуст</value>\n  </data>\n  <data name=\"LoadSubscriptionsErrorCommon\" xml:space=\"preserve\">\n    <value>Не удалось загрузить список подписок</value>\n  </data>\n  <data name=\"LoadSubscriptionsErrorEmpty\" xml:space=\"preserve\">\n    <value>Вы еще ни на кого не подписались</value>\n  </data>\n  <data name=\"LoginErrorInvalidClient\" xml:space=\"preserve\">\n    <value>Не удалось войти. Проверьте ваш логин и пароль, и попробуйте снова.</value>\n  </data>\n  <data name=\"LoginErrorNeedValidation\" xml:space=\"preserve\">\n    <value>Необходимо подтверждение. Вы будете перенаправлены на страницу подтверждения.</value>\n  </data>\n  <data name=\"WmpMissingError\" xml:space=\"preserve\">\n    <value>Для воспроизведения музыки требуется Windows Media Player 10 или выше.</value>\n  </data>\n</root>"
  },
  {
    "path": "Meridian/Resources/Localization/MainResources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Meridian.Resources.Localization {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    public class MainResources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal MainResources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Meridian.Resources.Localization.MainResources\", typeof(MainResources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Tell friends.\n        /// </summary>\n        public static string AboutTellFriends {\n            get {\n                return ResourceManager.GetString(\"AboutTellFriends\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Would you like to help us? Then please tell friends about Meridian..\n        /// </summary>\n        public static string AboutTellFriendsTitle {\n            get {\n                return ResourceManager.GetString(\"AboutTellFriendsTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Meridian is the best way to listen to music from Vkontakte..\n        /// </summary>\n        public static string AboutTellMessage {\n            get {\n                return ResourceManager.GetString(\"AboutTellMessage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Albums.\n        /// </summary>\n        public static string AlbumsTab {\n            get {\n                return ResourceManager.GetString(\"AlbumsTab\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to All societies.\n        /// </summary>\n        public static string AllSocieties {\n            get {\n                return ResourceManager.GetString(\"AllSocieties\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to ALBUMS.\n        /// </summary>\n        public static string ArtistAlbums {\n            get {\n                return ResourceManager.GetString(\"ArtistAlbums\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to RELATED ARTISTS.\n        /// </summary>\n        public static string ArtistRelatedArtists {\n            get {\n                return ResourceManager.GetString(\"ArtistRelatedArtists\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show all.\n        /// </summary>\n        public static string ArtistShowAll {\n            get {\n                return ResourceManager.GetString(\"ArtistShowAll\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Artists.\n        /// </summary>\n        public static string ArtistsTab {\n            get {\n                return ResourceManager.GetString(\"ArtistsTab\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to TOP TRACKS.\n        /// </summary>\n        public static string ArtistTopTracks {\n            get {\n                return ResourceManager.GetString(\"ArtistTopTracks\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Go back.\n        /// </summary>\n        public static string BackButton {\n            get {\n                return ResourceManager.GetString(\"BackButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Cancel.\n        /// </summary>\n        public static string CancelButton {\n            get {\n                return ResourceManager.GetString(\"CancelButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enter symbols from the picture.\n        /// </summary>\n        public static string CaptchaEnterSymbols {\n            get {\n                return ResourceManager.GetString(\"CaptchaEnterSymbols\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Confirmation.\n        /// </summary>\n        public static string CaptchaTitle {\n            get {\n                return ResourceManager.GetString(\"CaptchaTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Close.\n        /// </summary>\n        public static string Close {\n            get {\n                return ResourceManager.GetString(\"Close\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to We are sorry but something goes wrong. We will try to fix this as soon as possible..\n        /// </summary>\n        public static string CommonErrorViewContent {\n            get {\n                return ResourceManager.GetString(\"CommonErrorViewContent\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Restart.\n        /// </summary>\n        public static string CommonErrorViewRestart {\n            get {\n                return ResourceManager.GetString(\"CommonErrorViewRestart\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Oh... something happened :(.\n        /// </summary>\n        public static string CommonErrorViewTitle {\n            get {\n                return ResourceManager.GetString(\"CommonErrorViewTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Compact mode.\n        /// </summary>\n        public static string CompactMode {\n            get {\n                return ResourceManager.GetString(\"CompactMode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Pin on top of other windows.\n        /// </summary>\n        public static string CompactModePin {\n            get {\n                return ResourceManager.GetString(\"CompactModePin\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to tracklist.\n        /// </summary>\n        public static string CompactModeTracklist {\n            get {\n                return ResourceManager.GetString(\"CompactModeTracklist\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add to my music.\n        /// </summary>\n        public static string ContextMenuAdd {\n            get {\n                return ResourceManager.GetString(\"ContextMenuAdd\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add to album.\n        /// </summary>\n        public static string ContextMenuAddToAlbum {\n            get {\n                return ResourceManager.GetString(\"ContextMenuAddToAlbum\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add to now playing.\n        /// </summary>\n        public static string ContextMenuAddToNowPlaying {\n            get {\n                return ResourceManager.GetString(\"ContextMenuAddToNowPlaying\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Copy title and artist.\n        /// </summary>\n        public static string ContextMenuCopyInfo {\n            get {\n                return ResourceManager.GetString(\"ContextMenuCopyInfo\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Copy to my albums.\n        /// </summary>\n        public static string ContextMenuCopyToMyAlbums {\n            get {\n                return ResourceManager.GetString(\"ContextMenuCopyToMyAlbums\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Edit.\n        /// </summary>\n        public static string ContextMenuEdit {\n            get {\n                return ResourceManager.GetString(\"ContextMenuEdit\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to View lyrics.\n        /// </summary>\n        public static string ContextMenuLyrics {\n            get {\n                return ResourceManager.GetString(\"ContextMenuLyrics\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Play.\n        /// </summary>\n        public static string ContextMenuPlay {\n            get {\n                return ResourceManager.GetString(\"ContextMenuPlay\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Play next.\n        /// </summary>\n        public static string ContextMenuPlayNext {\n            get {\n                return ResourceManager.GetString(\"ContextMenuPlayNext\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove from my music.\n        /// </summary>\n        public static string ContextMenuRemove {\n            get {\n                return ResourceManager.GetString(\"ContextMenuRemove\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove from now playing.\n        /// </summary>\n        public static string ContextMenuRemoveFromNowPlaying {\n            get {\n                return ResourceManager.GetString(\"ContextMenuRemoveFromNowPlaying\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove.\n        /// </summary>\n        public static string ContextMenuRemoveRadio {\n            get {\n                return ResourceManager.GetString(\"ContextMenuRemoveRadio\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show more of this.\n        /// </summary>\n        public static string ContextMenuSearchArtist {\n            get {\n                return ResourceManager.GetString(\"ContextMenuSearchArtist\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Share.\n        /// </summary>\n        public static string ContextMenuShare {\n            get {\n                return ResourceManager.GetString(\"ContextMenuShare\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show artist info.\n        /// </summary>\n        public static string ContextMenuShowArtistInfo {\n            get {\n                return ResourceManager.GetString(\"ContextMenuShowArtistInfo\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Start radio.\n        /// </summary>\n        public static string ContextMenuStartRadio {\n            get {\n                return ResourceManager.GetString(\"ContextMenuStartRadio\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add.\n        /// </summary>\n        public static string CreateStationAdd {\n            get {\n                return ResourceManager.GetString(\"CreateStationAdd\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Artist.\n        /// </summary>\n        public static string CreateStationArtist {\n            get {\n                return ResourceManager.GetString(\"CreateStationArtist\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Edit station.\n        /// </summary>\n        public static string CreateStationEdit {\n            get {\n                return ResourceManager.GetString(\"CreateStationEdit\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Save station.\n        /// </summary>\n        public static string CreateStationSave {\n            get {\n                return ResourceManager.GetString(\"CreateStationSave\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You can add up to 5 artists.\n        /// </summary>\n        public static string CreateStationSubtitle {\n            get {\n                return ResourceManager.GetString(\"CreateStationSubtitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to New station.\n        /// </summary>\n        public static string CreateStationTitle {\n            get {\n                return ResourceManager.GetString(\"CreateStationTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Delete.\n        /// </summary>\n        public static string Delete {\n            get {\n                return ResourceManager.GetString(\"Delete\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Title.\n        /// </summary>\n        public static string EditAlbumName {\n            get {\n                return ResourceManager.GetString(\"EditAlbumName\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to New album.\n        /// </summary>\n        public static string EditAlbumNewTitle {\n            get {\n                return ResourceManager.GetString(\"EditAlbumNewTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Save changes.\n        /// </summary>\n        public static string EditAlbumSave {\n            get {\n                return ResourceManager.GetString(\"EditAlbumSave\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Edit album.\n        /// </summary>\n        public static string EditAlbumTitle {\n            get {\n                return ResourceManager.GetString(\"EditAlbumTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Artist.\n        /// </summary>\n        public static string EditAudioArtist {\n            get {\n                return ResourceManager.GetString(\"EditAudioArtist\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Lyrics.\n        /// </summary>\n        public static string EditAudioLyrics {\n            get {\n                return ResourceManager.GetString(\"EditAudioLyrics\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Title.\n        /// </summary>\n        public static string EditAudioName {\n            get {\n                return ResourceManager.GetString(\"EditAudioName\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Save changes.\n        /// </summary>\n        public static string EditAudioSave {\n            get {\n                return ResourceManager.GetString(\"EditAudioSave\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Edit audio.\n        /// </summary>\n        public static string EditAudioTitle {\n            get {\n                return ResourceManager.GetString(\"EditAudioTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Favorites.\n        /// </summary>\n        public static string FavoritesTab {\n            get {\n                return ResourceManager.GetString(\"FavoritesTab\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add society.\n        /// </summary>\n        public static string FeedAdd {\n            get {\n                return ResourceManager.GetString(\"FeedAdd\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add society.\n        /// </summary>\n        public static string FeedAddSocietyTitle {\n            get {\n                return ResourceManager.GetString(\"FeedAddSocietyTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to SOCIETIES.\n        /// </summary>\n        public static string FeedSocieties {\n            get {\n                return ResourceManager.GetString(\"FeedSocieties\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to New music from your favorite societies.\n        /// </summary>\n        public static string FeedSubHeader {\n            get {\n                return ResourceManager.GetString(\"FeedSubHeader\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Normal mode.\n        /// </summary>\n        public static string FullMode {\n            get {\n                return ResourceManager.GetString(\"FullMode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clear.\n        /// </summary>\n        public static string HeaderMenuClear {\n            get {\n                return ResourceManager.GetString(\"HeaderMenuClear\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Find in list.\n        /// </summary>\n        public static string HeaderMenuLocalSearch {\n            get {\n                return ResourceManager.GetString(\"HeaderMenuLocalSearch\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Refresh.\n        /// </summary>\n        public static string HeaderMenuRefresh {\n            get {\n                return ResourceManager.GetString(\"HeaderMenuRefresh\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Save to my music.\n        /// </summary>\n        public static string HeaderMenuSave {\n            get {\n                return ResourceManager.GetString(\"HeaderMenuSave\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Share.\n        /// </summary>\n        public static string HeaderMenuShare {\n            get {\n                return ResourceManager.GetString(\"HeaderMenuShare\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Landscape mode.\n        /// </summary>\n        public static string LandscapeMode {\n            get {\n                return ResourceManager.GetString(\"LandscapeMode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Login.\n        /// </summary>\n        public static string LastFmLoginTitle {\n            get {\n                return ResourceManager.GetString(\"LastFmLoginTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Scrobble to Last.FM.\n        /// </summary>\n        public static string LastFmScrobbling {\n            get {\n                return ResourceManager.GetString(\"LastFmScrobbling\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Go to settings.\n        /// </summary>\n        public static string LastFmScrobblingGoSettings {\n            get {\n                return ResourceManager.GetString(\"LastFmScrobblingGoSettings\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to To enable scrobbling you need to connect your Last.FM account in settings. Would you like to do it now?.\n        /// </summary>\n        public static string LastFmScrobblingMessage {\n            get {\n                return ResourceManager.GetString(\"LastFmScrobblingMessage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Last.FM scrobbling.\n        /// </summary>\n        public static string LastFmScrobblingTitle {\n            get {\n                return ResourceManager.GetString(\"LastFmScrobblingTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Loading.\n        /// </summary>\n        public static string Loading {\n            get {\n                return ResourceManager.GetString(\"Loading\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Go to settings..\n        /// </summary>\n        public static string LoginGoToSettings {\n            get {\n                return ResourceManager.GetString(\"LoginGoToSettings\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please wait, we are just loading your profile.\n        /// </summary>\n        public static string LoginLoading {\n            get {\n                return ResourceManager.GetString(\"LoginLoading\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sign in.\n        /// </summary>\n        public static string LoginLoginButton {\n            get {\n                return ResourceManager.GetString(\"LoginLoginButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Login, e-mail or phone number.\n        /// </summary>\n        public static string LoginLoginTitle {\n            get {\n                return ResourceManager.GetString(\"LoginLoginTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Password.\n        /// </summary>\n        public static string LoginPasswordTitle {\n            get {\n                return ResourceManager.GetString(\"LoginPasswordTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to New to VK? Sign Up now!.\n        /// </summary>\n        public static string LoginRegisterButton {\n            get {\n                return ResourceManager.GetString(\"LoginRegisterButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Login with VK.\n        /// </summary>\n        public static string LoginStartLoginButton {\n            get {\n                return ResourceManager.GetString(\"LoginStartLoginButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Let&apos;s start.\n        /// </summary>\n        public static string LoginWelcome {\n            get {\n                return ResourceManager.GetString(\"LoginWelcome\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Collection.\n        /// </summary>\n        public static string MainMenuCollection {\n            get {\n                return ResourceManager.GetString(\"MainMenuCollection\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Feed.\n        /// </summary>\n        public static string MainMenuFeed {\n            get {\n                return ResourceManager.GetString(\"MainMenuFeed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Friends.\n        /// </summary>\n        public static string MainMenuFriends {\n            get {\n                return ResourceManager.GetString(\"MainMenuFriends\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to THIS PC.\n        /// </summary>\n        public static string MainMenuLocalTitle {\n            get {\n                return ResourceManager.GetString(\"MainMenuLocalTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to MAIN.\n        /// </summary>\n        public static string MainMenuMainTitle {\n            get {\n                return ResourceManager.GetString(\"MainMenuMainTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to My music.\n        /// </summary>\n        public static string MainMenuMyMusic {\n            get {\n                return ResourceManager.GetString(\"MainMenuMyMusic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Now playing.\n        /// </summary>\n        public static string MainMenuNowPlaying {\n            get {\n                return ResourceManager.GetString(\"MainMenuNowPlaying\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to PEOPLE.\n        /// </summary>\n        public static string MainMenuPeopleTitle {\n            get {\n                return ResourceManager.GetString(\"MainMenuPeopleTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Popular.\n        /// </summary>\n        public static string MainMenuPopular {\n            get {\n                return ResourceManager.GetString(\"MainMenuPopular\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Radio.\n        /// </summary>\n        public static string MainMenuRadio {\n            get {\n                return ResourceManager.GetString(\"MainMenuRadio\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Recommendations.\n        /// </summary>\n        public static string MainMenuRecommendations {\n            get {\n                return ResourceManager.GetString(\"MainMenuRecommendations\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Societies.\n        /// </summary>\n        public static string MainMenuSocieties {\n            get {\n                return ResourceManager.GetString(\"MainMenuSocieties\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Subscriptions.\n        /// </summary>\n        public static string MainMenuSubscriptions {\n            get {\n                return ResourceManager.GetString(\"MainMenuSubscriptions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to VK.\n        /// </summary>\n        public static string MainMenuVkTitle {\n            get {\n                return ResourceManager.GetString(\"MainMenuVkTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Maximize.\n        /// </summary>\n        public static string Maximize {\n            get {\n                return ResourceManager.GetString(\"Maximize\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Minimize.\n        /// </summary>\n        public static string Minimize {\n            get {\n                return ResourceManager.GetString(\"Minimize\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to cool.\n        /// </summary>\n        public static string MoodsCool {\n            get {\n                return ResourceManager.GetString(\"MoodsCool\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to dreamy.\n        /// </summary>\n        public static string MoodsDreamy {\n            get {\n                return ResourceManager.GetString(\"MoodsDreamy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to energy.\n        /// </summary>\n        public static string MoodsEnergy {\n            get {\n                return ResourceManager.GetString(\"MoodsEnergy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to epic.\n        /// </summary>\n        public static string MoodsEpic {\n            get {\n                return ResourceManager.GetString(\"MoodsEpic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to extreme.\n        /// </summary>\n        public static string MoodsExtreme {\n            get {\n                return ResourceManager.GetString(\"MoodsExtreme\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to freedom.\n        /// </summary>\n        public static string MoodsFreedom {\n            get {\n                return ResourceManager.GetString(\"MoodsFreedom\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to happy.\n        /// </summary>\n        public static string MoodsHappy {\n            get {\n                return ResourceManager.GetString(\"MoodsHappy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to loneliness.\n        /// </summary>\n        public static string MoodsLoneliness {\n            get {\n                return ResourceManager.GetString(\"MoodsLoneliness\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to night.\n        /// </summary>\n        public static string MoodsNight {\n            get {\n                return ResourceManager.GetString(\"MoodsNight\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to nostalgia.\n        /// </summary>\n        public static string MoodsNostalgia {\n            get {\n                return ResourceManager.GetString(\"MoodsNostalgia\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to optimism.\n        /// </summary>\n        public static string MoodsOptimism {\n            get {\n                return ResourceManager.GetString(\"MoodsOptimism\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to psychedelic.\n        /// </summary>\n        public static string MoodsPsychedelic {\n            get {\n                return ResourceManager.GetString(\"MoodsPsychedelic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to romantic.\n        /// </summary>\n        public static string MoodsRomantic {\n            get {\n                return ResourceManager.GetString(\"MoodsRomantic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to sad.\n        /// </summary>\n        public static string MoodsSad {\n            get {\n                return ResourceManager.GetString(\"MoodsSad\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to sexy.\n        /// </summary>\n        public static string MoodsSexy {\n            get {\n                return ResourceManager.GetString(\"MoodsSexy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to sport.\n        /// </summary>\n        public static string MoodsSport {\n            get {\n                return ResourceManager.GetString(\"MoodsSport\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to urban.\n        /// </summary>\n        public static string MoodsUrban {\n            get {\n                return ResourceManager.GetString(\"MoodsUrban\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to vintage.\n        /// </summary>\n        public static string MoodsVintage {\n            get {\n                return ResourceManager.GetString(\"MoodsVintage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please wait, we are looking for music on your PC.\n        /// </summary>\n        public static string MusicScanDescription {\n            get {\n                return ResourceManager.GetString(\"MusicScanDescription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Looking for music.\n        /// </summary>\n        public static string MusicScanTitle {\n            get {\n                return ResourceManager.GetString(\"MusicScanTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to ALBUMS.\n        /// </summary>\n        public static string MyMusicAlbums {\n            get {\n                return ResourceManager.GetString(\"MyMusicAlbums\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add album.\n        /// </summary>\n        public static string MyMusicAlbumsAdd {\n            get {\n                return ResourceManager.GetString(\"MyMusicAlbumsAdd\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to All songs.\n        /// </summary>\n        public static string MyMusicAllTracks {\n            get {\n                return ResourceManager.GetString(\"MyMusicAllTracks\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to favorites.\n        /// </summary>\n        public static string MyMusicFavorites {\n            get {\n                return ResourceManager.GetString(\"MyMusicFavorites\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to news.\n        /// </summary>\n        public static string MyMusicNews {\n            get {\n                return ResourceManager.GetString(\"MyMusicNews\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to wall.\n        /// </summary>\n        public static string MyMusicWall {\n            get {\n                return ResourceManager.GetString(\"MyMusicWall\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to News.\n        /// </summary>\n        public static string NewsTab {\n            get {\n                return ResourceManager.GetString(\"NewsTab\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Next.\n        /// </summary>\n        public static string NextButton {\n            get {\n                return ResourceManager.GetString(\"NextButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Next track.\n        /// </summary>\n        public static string NextTrack {\n            get {\n                return ResourceManager.GetString(\"NextTrack\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Track added to now playing.\n        /// </summary>\n        public static string NotificationAddedToNowPlaying {\n            get {\n                return ResourceManager.GetString(\"NotificationAddedToNowPlaying\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Unable to load info about artist.\n        /// </summary>\n        public static string NotificationArtistNotFound {\n            get {\n                return ResourceManager.GetString(\"NotificationArtistNotFound\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Looking for artist.\n        /// </summary>\n        public static string NotificationLookingArtist {\n            get {\n                return ResourceManager.GetString(\"NotificationLookingArtist\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Saved.\n        /// </summary>\n        public static string NotificationSaved {\n            get {\n                return ResourceManager.GetString(\"NotificationSaved\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Saving.\n        /// </summary>\n        public static string NotificationSaving {\n            get {\n                return ResourceManager.GetString(\"NotificationSaving\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to You are listening to radio. New tracks will dynamically appear here when you switch to the next track..\n        /// </summary>\n        public static string NowPlayingRadioHint {\n            get {\n                return ResourceManager.GetString(\"NowPlayingRadioHint\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to OK.\n        /// </summary>\n        public static string OkButton {\n            get {\n                return ResourceManager.GetString(\"OkButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Play / Pause.\n        /// </summary>\n        public static string PlayPause {\n            get {\n                return ResourceManager.GetString(\"PlayPause\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to foreign only.\n        /// </summary>\n        public static string PopularForeignOnly {\n            get {\n                return ResourceManager.GetString(\"PopularForeignOnly\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to All genres.\n        /// </summary>\n        public static string PopularGenresAll {\n            get {\n                return ResourceManager.GetString(\"PopularGenresAll\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to GENRES.\n        /// </summary>\n        public static string PopularGenresTitle {\n            get {\n                return ResourceManager.GetString(\"PopularGenresTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Popular music from VK.\n        /// </summary>\n        public static string PopularSubHeader {\n            get {\n                return ResourceManager.GetString(\"PopularSubHeader\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Portrait mode.\n        /// </summary>\n        public static string PortraitMode {\n            get {\n                return ResourceManager.GetString(\"PortraitMode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Previous track.\n        /// </summary>\n        public static string PrevTrack {\n            get {\n                return ResourceManager.GetString(\"PrevTrack\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Create station.\n        /// </summary>\n        public static string RadioAddStationButton {\n            get {\n                return ResourceManager.GetString(\"RadioAddStationButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to STATIONS.\n        /// </summary>\n        public static string RadioStationsTitle {\n            get {\n                return ResourceManager.GetString(\"RadioStationsTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Create stations with artists you like.\n        /// </summary>\n        public static string RadioSubHeader {\n            get {\n                return ResourceManager.GetString(\"RadioSubHeader\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to GENRES.\n        /// </summary>\n        public static string RecommendationsGenresGroup {\n            get {\n                return ResourceManager.GetString(\"RecommendationsGenresGroup\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to MOODS.\n        /// </summary>\n        public static string RecommendationsMoodsGroup {\n            get {\n                return ResourceManager.GetString(\"RecommendationsMoodsGroup\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to advanced.\n        /// </summary>\n        public static string RecommendationsMusicAdvanced {\n            get {\n                return ResourceManager.GetString(\"RecommendationsMusicAdvanced\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to general.\n        /// </summary>\n        public static string RecommendationsMusicGeneral {\n            get {\n                return ResourceManager.GetString(\"RecommendationsMusicGeneral\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to MUSIC.\n        /// </summary>\n        public static string RecommendationsMusicGroup {\n            get {\n                return ResourceManager.GetString(\"RecommendationsMusicGroup\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Discover new music by artists, genres, moods and more.\n        /// </summary>\n        public static string RecommendationsSubHeader {\n            get {\n                return ResourceManager.GetString(\"RecommendationsSubHeader\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Repeat.\n        /// </summary>\n        public static string Repeat {\n            get {\n                return ResourceManager.GetString(\"Repeat\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Search.\n        /// </summary>\n        public static string Search {\n            get {\n                return ResourceManager.GetString(\"Search\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Searching....\n        /// </summary>\n        public static string Searching {\n            get {\n                return ResourceManager.GetString(\"Searching\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Results for.\n        /// </summary>\n        public static string SearchResultsTitle {\n            get {\n                return ResourceManager.GetString(\"SearchResultsTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to SECTION.\n        /// </summary>\n        public static string SearchSection {\n            get {\n                return ResourceManager.GetString(\"SearchSection\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to albums.\n        /// </summary>\n        public static string SearchSectionAlbums {\n            get {\n                return ResourceManager.GetString(\"SearchSectionAlbums\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to artists.\n        /// </summary>\n        public static string SearchSectionArtists {\n            get {\n                return ResourceManager.GetString(\"SearchSectionArtists\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to tracks.\n        /// </summary>\n        public static string SearchSectionTracks {\n            get {\n                return ResourceManager.GetString(\"SearchSectionTracks\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Settings.\n        /// </summary>\n        public static string Settings {\n            get {\n                return ResourceManager.GetString(\"Settings\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Last.FM.\n        /// </summary>\n        public static string SettingsAccountsLastFm {\n            get {\n                return ResourceManager.GetString(\"SettingsAccountsLastFm\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Connect your Last.FM account to enable scrobbling..\n        /// </summary>\n        public static string SettingsAccountsLastFmDescription {\n            get {\n                return ResourceManager.GetString(\"SettingsAccountsLastFmDescription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Signed as.\n        /// </summary>\n        public static string SettingsAccountsSignedAs {\n            get {\n                return ResourceManager.GetString(\"SettingsAccountsSignedAs\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sign Out.\n        /// </summary>\n        public static string SettingsAccountsSignOut {\n            get {\n                return ResourceManager.GetString(\"SettingsAccountsSignOut\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to VK.\n        /// </summary>\n        public static string SettingsAccountsVk {\n            get {\n                return ResourceManager.GetString(\"SettingsAccountsVk\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add / Remove current track.\n        /// </summary>\n        public static string SettingsHotkeyAddRemove {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyAddRemove\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Decrease volume.\n        /// </summary>\n        public static string SettingsHotkeyDecreaseVolume {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyDecreaseVolume\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Fast forward.\n        /// </summary>\n        public static string SettingsHotkeyFastForward {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyFastForward\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Increase volume.\n        /// </summary>\n        public static string SettingsHotkeyIncreaseVolume {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyIncreaseVolume\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Next track.\n        /// </summary>\n        public static string SettingsHotkeyNext {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyNext\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Play / Pause.\n        /// </summary>\n        public static string SettingsHotkeyPlayPause {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyPlayPause\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Previous track.\n        /// </summary>\n        public static string SettingsHotkeyPrev {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyPrev\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable / Disable repeat mode.\n        /// </summary>\n        public static string SettingsHotkeyRepeat {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyRepeat\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Rewind.\n        /// </summary>\n        public static string SettingsHotkeyRewind {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyRewind\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show / Hide Meridian.\n        /// </summary>\n        public static string SettingsHotkeyShowHide {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyShowHide\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable / Disable shuffle mode.\n        /// </summary>\n        public static string SettingsHotkeyShuffle {\n            get {\n                return ResourceManager.GetString(\"SettingsHotkeyShuffle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to About.\n        /// </summary>\n        public static string SettingsMenuAbout {\n            get {\n                return ResourceManager.GetString(\"SettingsMenuAbout\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Accounts.\n        /// </summary>\n        public static string SettingsMenuAccounts {\n            get {\n                return ResourceManager.GetString(\"SettingsMenuAccounts\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to General.\n        /// </summary>\n        public static string SettingsMenuGeneral {\n            get {\n                return ResourceManager.GetString(\"SettingsMenuGeneral\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Hotkeys.\n        /// </summary>\n        public static string SettingsMenuHotkeys {\n            get {\n                return ResourceManager.GetString(\"SettingsMenuHotkeys\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to UI.\n        /// </summary>\n        public static string SettingsMenuUI {\n            get {\n                return ResourceManager.GetString(\"SettingsMenuUI\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Updates.\n        /// </summary>\n        public static string SettingsMenuUpdates {\n            get {\n                return ResourceManager.GetString(\"SettingsMenuUpdates\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to RemotePlay.\n        /// </summary>\n        public static string SettingsRemotePlay {\n            get {\n                return ResourceManager.GetString(\"SettingsRemotePlay\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Address.\n        /// </summary>\n        public static string SettingsRemotePlayAddress {\n            get {\n                return ResourceManager.GetString(\"SettingsRemotePlayAddress\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to RemotePlay allows you to control Meridian from your mobile device like phone or tablet. Remote devices should be in the same network with this PC..\n        /// </summary>\n        public static string SettingsRemotePlayDescription {\n            get {\n                return ResourceManager.GetString(\"SettingsRemotePlayDescription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable RemotePlay.\n        /// </summary>\n        public static string SettingsRemotePlayEnable {\n            get {\n                return ResourceManager.GetString(\"SettingsRemotePlayEnable\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to To start using RemotePlay on your iOS or Android device open {0} in browser on that device. To use RemotePlay on Windows Phone install Meridian app from the Store and go to the RemotePlay section in the app&apos;s menu..\n        /// </summary>\n        public static string SettingsRemotePlayHelp {\n            get {\n                return ResourceManager.GetString(\"SettingsRemotePlayHelp\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Port.\n        /// </summary>\n        public static string SettingsRemotePlayPort {\n            get {\n                return ResourceManager.GetString(\"SettingsRemotePlayPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Some changes will be applied after restart..\n        /// </summary>\n        public static string SettingsRestartMessage {\n            get {\n                return ResourceManager.GetString(\"SettingsRestartMessage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Save changes.\n        /// </summary>\n        public static string SettingsSave {\n            get {\n                return ResourceManager.GetString(\"SettingsSave\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Save &amp; Restart.\n        /// </summary>\n        public static string SettingsSaveRestart {\n            get {\n                return ResourceManager.GetString(\"SettingsSaveRestart\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Accent color.\n        /// </summary>\n        public static string SettingsUIAccentColor {\n            get {\n                return ResourceManager.GetString(\"SettingsUIAccentColor\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Artist and album art.\n        /// </summary>\n        public static string SettingsUIBackgroundArtTitle {\n            get {\n                return ResourceManager.GetString(\"SettingsUIBackgroundArtTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Background color.\n        /// </summary>\n        public static string SettingsUIBackgroundColor {\n            get {\n                return ResourceManager.GetString(\"SettingsUIBackgroundColor\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Cache size:.\n        /// </summary>\n        public static string SettingsUICacheSize {\n            get {\n                return ResourceManager.GetString(\"SettingsUICacheSize\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clear.\n        /// </summary>\n        public static string SettingsUIClearCache {\n            get {\n                return ResourceManager.GetString(\"SettingsUIClearCache\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Download album covers.\n        /// </summary>\n        public static string SettingsUIDownloadAlbumArt {\n            get {\n                return ResourceManager.GetString(\"SettingsUIDownloadAlbumArt\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Download artist art.\n        /// </summary>\n        public static string SettingsUIDownloadArtistArt {\n            get {\n                return ResourceManager.GetString(\"SettingsUIDownloadArtistArt\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Blur background (reduces performance).\n        /// </summary>\n        public static string SettingsUIEnabledBlur {\n            get {\n                return ResourceManager.GetString(\"SettingsUIEnabledBlur\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Language.\n        /// </summary>\n        public static string SettingsUILanguage {\n            get {\n                return ResourceManager.GetString(\"SettingsUILanguage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show notification when track changes.\n        /// </summary>\n        public static string SettingsUINotifications {\n            get {\n                return ResourceManager.GetString(\"SettingsUINotifications\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Notifications.\n        /// </summary>\n        public static string SettingsUINotificationsTitle {\n            get {\n                return ResourceManager.GetString(\"SettingsUINotificationsTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Play using.\n        /// </summary>\n        public static string SettingsUIPlayUsing {\n            get {\n                return ResourceManager.GetString(\"SettingsUIPlayUsing\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show current artist image on background.\n        /// </summary>\n        public static string SettingsUIShowBackgroundArt {\n            get {\n                return ResourceManager.GetString(\"SettingsUIShowBackgroundArt\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show current artist image in compact mode.\n        /// </summary>\n        public static string SettingsUIShowBackgroundArtCompactMode {\n            get {\n                return ResourceManager.GetString(\"SettingsUIShowBackgroundArtCompactMode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show icon in the tray instead of taskbar.\n        /// </summary>\n        public static string SettingsUIShowTrayIcon {\n            get {\n                return ResourceManager.GetString(\"SettingsUIShowTrayIcon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Taskbar.\n        /// </summary>\n        public static string SettingsUITaskBarTitle {\n            get {\n                return ResourceManager.GetString(\"SettingsUITaskBarTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Check now.\n        /// </summary>\n        public static string SettingsUpdatesCheck {\n            get {\n                return ResourceManager.GetString(\"SettingsUpdatesCheck\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Automatically check and install updates on start.\n        /// </summary>\n        public static string SettingsUpdatesCheckForUpdates {\n            get {\n                return ResourceManager.GetString(\"SettingsUpdatesCheckForUpdates\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Test updates may contain new features and can be released more often but also can be unstable..\n        /// </summary>\n        public static string SettingsUpdatesDevUpdatesDescription {\n            get {\n                return ResourceManager.GetString(\"SettingsUpdatesDevUpdatesDescription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Install test updates.\n        /// </summary>\n        public static string SettingsUpdatesInstallDevUpdates {\n            get {\n                return ResourceManager.GetString(\"SettingsUpdatesInstallDevUpdates\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Restart.\n        /// </summary>\n        public static string SettingsUpdatesRestart {\n            get {\n                return ResourceManager.GetString(\"SettingsUpdatesRestart\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Meridian was updated. Restart to apply changes..\n        /// </summary>\n        public static string SettingsUpdatesUpdated {\n            get {\n                return ResourceManager.GetString(\"SettingsUpdatesUpdated\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use HTTPS.\n        /// </summary>\n        public static string SettingsUseHttps {\n            get {\n                return ResourceManager.GetString(\"SettingsUseHttps\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to as society.\n        /// </summary>\n        public static string ShareAsSociety {\n            get {\n                return ResourceManager.GetString(\"ShareAsSociety\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Drag tracks here to attach them to the message.\n        /// </summary>\n        public static string ShareBarTitle {\n            get {\n                return ResourceManager.GetString(\"ShareBarTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Publish.\n        /// </summary>\n        public static string SharePublishButton {\n            get {\n                return ResourceManager.GetString(\"SharePublishButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Publishing.\n        /// </summary>\n        public static string SharePublishing {\n            get {\n                return ResourceManager.GetString(\"SharePublishing\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to signed.\n        /// </summary>\n        public static string ShareSigned {\n            get {\n                return ResourceManager.GetString(\"ShareSigned\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Share.\n        /// </summary>\n        public static string ShareTitle {\n            get {\n                return ResourceManager.GetString(\"ShareTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to share to my wall.\n        /// </summary>\n        public static string ShareToMyWall {\n            get {\n                return ResourceManager.GetString(\"ShareToMyWall\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to share with your friends and subscribers.\n        /// </summary>\n        public static string ShareToMyWallHint {\n            get {\n                return ResourceManager.GetString(\"ShareToMyWallHint\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to share to society.\n        /// </summary>\n        public static string ShareToSociety {\n            get {\n                return ResourceManager.GetString(\"ShareToSociety\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to share to friend.\n        /// </summary>\n        public static string ShareToUserWall {\n            get {\n                return ResourceManager.GetString(\"ShareToUserWall\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Shuffle.\n        /// </summary>\n        public static string Shuffle {\n            get {\n                return ResourceManager.GetString(\"Shuffle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please tell your friends about Meridian. This will really help us to make it better!.\n        /// </summary>\n        public static string TellFriendsRequestContent {\n            get {\n                return ResourceManager.GetString(\"TellFriendsRequestContent\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Tell friends.\n        /// </summary>\n        public static string TellFriendsRequestTellButton {\n            get {\n                return ResourceManager.GetString(\"TellFriendsRequestTellButton\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Do you like Meridian?.\n        /// </summary>\n        public static string TellFriendsRequestTitle {\n            get {\n                return ResourceManager.GetString(\"TellFriendsRequestTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to View post.\n        /// </summary>\n        public static string TellViewGoToPost {\n            get {\n                return ResourceManager.GetString(\"TellViewGoToPost\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Thanks!.\n        /// </summary>\n        public static string TellViewTitle {\n            get {\n                return ResourceManager.GetString(\"TellViewTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Songs.\n        /// </summary>\n        public static string TracksTab {\n            get {\n                return ResourceManager.GetString(\"TracksTab\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show what I&apos;m listening in my VK status.\n        /// </summary>\n        public static string VkStatusBroadcasting {\n            get {\n                return ResourceManager.GetString(\"VkStatusBroadcasting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Volume.\n        /// </summary>\n        public static string Volume {\n            get {\n                return ResourceManager.GetString(\"Volume\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Wall.\n        /// </summary>\n        public static string WallTab {\n            get {\n                return ResourceManager.GetString(\"WallTab\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Resources/Localization/MainResources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"ArtistAlbums\" xml:space=\"preserve\">\n    <value>ALBUMS</value>\n  </data>\n  <data name=\"ArtistRelatedArtists\" xml:space=\"preserve\">\n    <value>RELATED ARTISTS</value>\n  </data>\n  <data name=\"ArtistShowAll\" xml:space=\"preserve\">\n    <value>Show all</value>\n  </data>\n  <data name=\"ArtistTopTracks\" xml:space=\"preserve\">\n    <value>TOP TRACKS</value>\n  </data>\n  <data name=\"BackButton\" xml:space=\"preserve\">\n    <value>Go back</value>\n  </data>\n  <data name=\"CancelButton\" xml:space=\"preserve\">\n    <value>Cancel</value>\n  </data>\n  <data name=\"CaptchaEnterSymbols\" xml:space=\"preserve\">\n    <value>Enter symbols from the picture</value>\n  </data>\n  <data name=\"CaptchaTitle\" xml:space=\"preserve\">\n    <value>Confirmation</value>\n  </data>\n  <data name=\"Close\" xml:space=\"preserve\">\n    <value>Close</value>\n  </data>\n  <data name=\"ContextMenuAdd\" xml:space=\"preserve\">\n    <value>Add to my music</value>\n  </data>\n  <data name=\"ContextMenuAddToNowPlaying\" xml:space=\"preserve\">\n    <value>Add to now playing</value>\n  </data>\n  <data name=\"ContextMenuCopyInfo\" xml:space=\"preserve\">\n    <value>Copy title and artist</value>\n  </data>\n  <data name=\"ContextMenuEdit\" xml:space=\"preserve\">\n    <value>Edit</value>\n  </data>\n  <data name=\"ContextMenuLyrics\" xml:space=\"preserve\">\n    <value>View lyrics</value>\n  </data>\n  <data name=\"ContextMenuPlayNext\" xml:space=\"preserve\">\n    <value>Play next</value>\n  </data>\n  <data name=\"ContextMenuRemove\" xml:space=\"preserve\">\n    <value>Remove from my music</value>\n  </data>\n  <data name=\"ContextMenuRemoveFromNowPlaying\" xml:space=\"preserve\">\n    <value>Remove from now playing</value>\n  </data>\n  <data name=\"ContextMenuRemoveRadio\" xml:space=\"preserve\">\n    <value>Remove</value>\n  </data>\n  <data name=\"ContextMenuShare\" xml:space=\"preserve\">\n    <value>Share</value>\n  </data>\n  <data name=\"CreateStationAdd\" xml:space=\"preserve\">\n    <value>Add</value>\n  </data>\n  <data name=\"CreateStationArtist\" xml:space=\"preserve\">\n    <value>Artist</value>\n  </data>\n  <data name=\"CreateStationEdit\" xml:space=\"preserve\">\n    <value>Edit station</value>\n  </data>\n  <data name=\"CreateStationSave\" xml:space=\"preserve\">\n    <value>Save station</value>\n  </data>\n  <data name=\"CreateStationTitle\" xml:space=\"preserve\">\n    <value>New station</value>\n  </data>\n  <data name=\"EditAlbumName\" xml:space=\"preserve\">\n    <value>Title</value>\n  </data>\n  <data name=\"EditAlbumNewTitle\" xml:space=\"preserve\">\n    <value>New album</value>\n  </data>\n  <data name=\"EditAlbumSave\" xml:space=\"preserve\">\n    <value>Save changes</value>\n  </data>\n  <data name=\"EditAlbumTitle\" xml:space=\"preserve\">\n    <value>Edit album</value>\n  </data>\n  <data name=\"EditAudioArtist\" xml:space=\"preserve\">\n    <value>Artist</value>\n  </data>\n  <data name=\"EditAudioLyrics\" xml:space=\"preserve\">\n    <value>Lyrics</value>\n  </data>\n  <data name=\"EditAudioName\" xml:space=\"preserve\">\n    <value>Title</value>\n  </data>\n  <data name=\"EditAudioSave\" xml:space=\"preserve\">\n    <value>Save changes</value>\n  </data>\n  <data name=\"EditAudioTitle\" xml:space=\"preserve\">\n    <value>Edit audio</value>\n  </data>\n  <data name=\"HeaderMenuClear\" xml:space=\"preserve\">\n    <value>Clear</value>\n  </data>\n  <data name=\"HeaderMenuRefresh\" xml:space=\"preserve\">\n    <value>Refresh</value>\n  </data>\n  <data name=\"HeaderMenuSave\" xml:space=\"preserve\">\n    <value>Save to my music</value>\n  </data>\n  <data name=\"HeaderMenuShare\" xml:space=\"preserve\">\n    <value>Share</value>\n  </data>\n  <data name=\"LastFmScrobbling\" xml:space=\"preserve\">\n    <value>Scrobble to Last.FM</value>\n  </data>\n  <data name=\"LoginLoading\" xml:space=\"preserve\">\n    <value>Please wait, we are just loading your profile</value>\n  </data>\n  <data name=\"LoginLoginButton\" xml:space=\"preserve\">\n    <value>Sign in</value>\n  </data>\n  <data name=\"LoginLoginTitle\" xml:space=\"preserve\">\n    <value>Login, e-mail or phone number</value>\n  </data>\n  <data name=\"LoginPasswordTitle\" xml:space=\"preserve\">\n    <value>Password</value>\n  </data>\n  <data name=\"LoginRegisterButton\" xml:space=\"preserve\">\n    <value>New to VK? Sign Up now!</value>\n  </data>\n  <data name=\"LoginStartLoginButton\" xml:space=\"preserve\">\n    <value>Login with VK</value>\n  </data>\n  <data name=\"LoginWelcome\" xml:space=\"preserve\">\n    <value>Let's start</value>\n  </data>\n  <data name=\"MainMenuFriends\" xml:space=\"preserve\">\n    <value>Friends</value>\n  </data>\n  <data name=\"MainMenuMainTitle\" xml:space=\"preserve\">\n    <value>MAIN</value>\n  </data>\n  <data name=\"MainMenuMyMusic\" xml:space=\"preserve\">\n    <value>My music</value>\n  </data>\n  <data name=\"MainMenuNowPlaying\" xml:space=\"preserve\">\n    <value>Now playing</value>\n  </data>\n  <data name=\"MainMenuPeopleTitle\" xml:space=\"preserve\">\n    <value>PEOPLE</value>\n  </data>\n  <data name=\"MainMenuPopular\" xml:space=\"preserve\">\n    <value>Popular</value>\n  </data>\n  <data name=\"MainMenuRadio\" xml:space=\"preserve\">\n    <value>Radio</value>\n  </data>\n  <data name=\"MainMenuRecommendations\" xml:space=\"preserve\">\n    <value>Recommendations</value>\n  </data>\n  <data name=\"MainMenuSocieties\" xml:space=\"preserve\">\n    <value>Societies</value>\n  </data>\n  <data name=\"MainMenuSubscriptions\" xml:space=\"preserve\">\n    <value>Subscriptions</value>\n  </data>\n  <data name=\"Maximize\" xml:space=\"preserve\">\n    <value>Maximize</value>\n  </data>\n  <data name=\"Minimize\" xml:space=\"preserve\">\n    <value>Minimize</value>\n  </data>\n  <data name=\"MoodsCool\" xml:space=\"preserve\">\n    <value>cool</value>\n  </data>\n  <data name=\"MoodsDreamy\" xml:space=\"preserve\">\n    <value>dreamy</value>\n  </data>\n  <data name=\"MoodsEnergy\" xml:space=\"preserve\">\n    <value>energy</value>\n  </data>\n  <data name=\"MoodsEpic\" xml:space=\"preserve\">\n    <value>epic</value>\n  </data>\n  <data name=\"MoodsExtreme\" xml:space=\"preserve\">\n    <value>extreme</value>\n  </data>\n  <data name=\"MoodsFreedom\" xml:space=\"preserve\">\n    <value>freedom</value>\n  </data>\n  <data name=\"MoodsHappy\" xml:space=\"preserve\">\n    <value>happy</value>\n  </data>\n  <data name=\"MoodsLoneliness\" xml:space=\"preserve\">\n    <value>loneliness</value>\n  </data>\n  <data name=\"MoodsNight\" xml:space=\"preserve\">\n    <value>night</value>\n  </data>\n  <data name=\"MoodsNostalgia\" xml:space=\"preserve\">\n    <value>nostalgia</value>\n  </data>\n  <data name=\"MoodsOptimism\" xml:space=\"preserve\">\n    <value>optimism</value>\n  </data>\n  <data name=\"MoodsPsychedelic\" xml:space=\"preserve\">\n    <value>psychedelic</value>\n  </data>\n  <data name=\"MoodsRomantic\" xml:space=\"preserve\">\n    <value>romantic</value>\n  </data>\n  <data name=\"MoodsSad\" xml:space=\"preserve\">\n    <value>sad</value>\n  </data>\n  <data name=\"MoodsSexy\" xml:space=\"preserve\">\n    <value>sexy</value>\n  </data>\n  <data name=\"MoodsSport\" xml:space=\"preserve\">\n    <value>sport</value>\n  </data>\n  <data name=\"MoodsUrban\" xml:space=\"preserve\">\n    <value>urban</value>\n  </data>\n  <data name=\"MoodsVintage\" xml:space=\"preserve\">\n    <value>vintage</value>\n  </data>\n  <data name=\"MyMusicAlbums\" xml:space=\"preserve\">\n    <value>ALBUMS</value>\n  </data>\n  <data name=\"MyMusicAlbumsAdd\" xml:space=\"preserve\">\n    <value>Add album</value>\n  </data>\n  <data name=\"MyMusicAllTracks\" xml:space=\"preserve\">\n    <value>All songs</value>\n  </data>\n  <data name=\"MyMusicFavorites\" xml:space=\"preserve\">\n    <value>favorites</value>\n  </data>\n  <data name=\"MyMusicNews\" xml:space=\"preserve\">\n    <value>news</value>\n  </data>\n  <data name=\"MyMusicWall\" xml:space=\"preserve\">\n    <value>wall</value>\n  </data>\n  <data name=\"NextButton\" xml:space=\"preserve\">\n    <value>Next</value>\n  </data>\n  <data name=\"NextTrack\" xml:space=\"preserve\">\n    <value>Next track</value>\n  </data>\n  <data name=\"OkButton\" xml:space=\"preserve\">\n    <value>OK</value>\n  </data>\n  <data name=\"PlayPause\" xml:space=\"preserve\">\n    <value>Play / Pause</value>\n  </data>\n  <data name=\"PrevTrack\" xml:space=\"preserve\">\n    <value>Previous track</value>\n  </data>\n  <data name=\"RadioAddStationButton\" xml:space=\"preserve\">\n    <value>Create station</value>\n  </data>\n  <data name=\"RadioStationsTitle\" xml:space=\"preserve\">\n    <value>STATIONS</value>\n  </data>\n  <data name=\"RadioSubHeader\" xml:space=\"preserve\">\n    <value>Create stations with artists you like</value>\n  </data>\n  <data name=\"RecommendationsGenresGroup\" xml:space=\"preserve\">\n    <value>GENRES</value>\n  </data>\n  <data name=\"RecommendationsMoodsGroup\" xml:space=\"preserve\">\n    <value>MOODS</value>\n  </data>\n  <data name=\"RecommendationsMusicAdvanced\" xml:space=\"preserve\">\n    <value>advanced</value>\n  </data>\n  <data name=\"RecommendationsMusicGeneral\" xml:space=\"preserve\">\n    <value>general</value>\n  </data>\n  <data name=\"RecommendationsMusicGroup\" xml:space=\"preserve\">\n    <value>MUSIC</value>\n  </data>\n  <data name=\"Repeat\" xml:space=\"preserve\">\n    <value>Repeat</value>\n  </data>\n  <data name=\"Search\" xml:space=\"preserve\">\n    <value>Search</value>\n  </data>\n  <data name=\"SearchResultsTitle\" xml:space=\"preserve\">\n    <value>Results for</value>\n  </data>\n  <data name=\"SearchSection\" xml:space=\"preserve\">\n    <value>SECTION</value>\n  </data>\n  <data name=\"SearchSectionAlbums\" xml:space=\"preserve\">\n    <value>albums</value>\n  </data>\n  <data name=\"SearchSectionArtists\" xml:space=\"preserve\">\n    <value>artists</value>\n  </data>\n  <data name=\"SearchSectionTracks\" xml:space=\"preserve\">\n    <value>tracks</value>\n  </data>\n  <data name=\"Settings\" xml:space=\"preserve\">\n    <value>Settings</value>\n  </data>\n  <data name=\"SettingsAccountsLastFm\" xml:space=\"preserve\">\n    <value>Last.FM</value>\n  </data>\n  <data name=\"SettingsAccountsLastFmDescription\" xml:space=\"preserve\">\n    <value>Connect your Last.FM account to enable scrobbling.</value>\n  </data>\n  <data name=\"SettingsAccountsSignedAs\" xml:space=\"preserve\">\n    <value>Signed as</value>\n  </data>\n  <data name=\"SettingsAccountsSignOut\" xml:space=\"preserve\">\n    <value>Sign Out</value>\n  </data>\n  <data name=\"SettingsAccountsVk\" xml:space=\"preserve\">\n    <value>VK</value>\n  </data>\n  <data name=\"SettingsHotkeyAddRemove\" xml:space=\"preserve\">\n    <value>Add / Remove current track</value>\n  </data>\n  <data name=\"SettingsHotkeyDecreaseVolume\" xml:space=\"preserve\">\n    <value>Decrease volume</value>\n  </data>\n  <data name=\"SettingsHotkeyIncreaseVolume\" xml:space=\"preserve\">\n    <value>Increase volume</value>\n  </data>\n  <data name=\"SettingsHotkeyNext\" xml:space=\"preserve\">\n    <value>Next track</value>\n  </data>\n  <data name=\"SettingsHotkeyPlayPause\" xml:space=\"preserve\">\n    <value>Play / Pause</value>\n  </data>\n  <data name=\"SettingsHotkeyPrev\" xml:space=\"preserve\">\n    <value>Previous track</value>\n  </data>\n  <data name=\"SettingsHotkeyRepeat\" xml:space=\"preserve\">\n    <value>Enable / Disable repeat mode</value>\n  </data>\n  <data name=\"SettingsHotkeyShowHide\" xml:space=\"preserve\">\n    <value>Show / Hide Meridian</value>\n  </data>\n  <data name=\"SettingsHotkeyShuffle\" xml:space=\"preserve\">\n    <value>Enable / Disable shuffle mode</value>\n  </data>\n  <data name=\"SettingsMenuAbout\" xml:space=\"preserve\">\n    <value>About</value>\n  </data>\n  <data name=\"SettingsMenuAccounts\" xml:space=\"preserve\">\n    <value>Accounts</value>\n  </data>\n  <data name=\"SettingsMenuHotkeys\" xml:space=\"preserve\">\n    <value>Hotkeys</value>\n  </data>\n  <data name=\"SettingsMenuUI\" xml:space=\"preserve\">\n    <value>UI</value>\n  </data>\n  <data name=\"SettingsMenuUpdates\" xml:space=\"preserve\">\n    <value>Updates</value>\n  </data>\n  <data name=\"SettingsRestartMessage\" xml:space=\"preserve\">\n    <value>Some changes will be applied after restart.</value>\n  </data>\n  <data name=\"SettingsSave\" xml:space=\"preserve\">\n    <value>Save changes</value>\n  </data>\n  <data name=\"SettingsSaveRestart\" xml:space=\"preserve\">\n    <value>Save &amp; Restart</value>\n  </data>\n  <data name=\"SettingsUIAccentColor\" xml:space=\"preserve\">\n    <value>Accent color</value>\n  </data>\n  <data name=\"SettingsUIBackgroundColor\" xml:space=\"preserve\">\n    <value>Background color</value>\n  </data>\n  <data name=\"SettingsUILanguage\" xml:space=\"preserve\">\n    <value>Language</value>\n  </data>\n  <data name=\"ShareAsSociety\" xml:space=\"preserve\">\n    <value>as society</value>\n  </data>\n  <data name=\"ShareBarTitle\" xml:space=\"preserve\">\n    <value>Drag tracks here to attach them to the message</value>\n  </data>\n  <data name=\"SharePublishButton\" xml:space=\"preserve\">\n    <value>Publish</value>\n  </data>\n  <data name=\"SharePublishing\" xml:space=\"preserve\">\n    <value>Publishing</value>\n  </data>\n  <data name=\"ShareSigned\" xml:space=\"preserve\">\n    <value>signed</value>\n  </data>\n  <data name=\"ShareTitle\" xml:space=\"preserve\">\n    <value>Share</value>\n  </data>\n  <data name=\"ShareToMyWall\" xml:space=\"preserve\">\n    <value>share to my wall</value>\n  </data>\n  <data name=\"ShareToMyWallHint\" xml:space=\"preserve\">\n    <value>share with your friends and subscribers</value>\n  </data>\n  <data name=\"ShareToSociety\" xml:space=\"preserve\">\n    <value>share to society</value>\n  </data>\n  <data name=\"ShareToUserWall\" xml:space=\"preserve\">\n    <value>share to friend</value>\n  </data>\n  <data name=\"Shuffle\" xml:space=\"preserve\">\n    <value>Shuffle</value>\n  </data>\n  <data name=\"VkStatusBroadcasting\" xml:space=\"preserve\">\n    <value>Show what I'm listening in my VK status</value>\n  </data>\n  <data name=\"Volume\" xml:space=\"preserve\">\n    <value>Volume</value>\n  </data>\n  <data name=\"LastFmLoginTitle\" xml:space=\"preserve\">\n    <value>Login</value>\n  </data>\n  <data name=\"LastFmScrobblingGoSettings\" xml:space=\"preserve\">\n    <value>Go to settings</value>\n  </data>\n  <data name=\"LastFmScrobblingMessage\" xml:space=\"preserve\">\n    <value>To enable scrobbling you need to connect your Last.FM account in settings. Would you like to do it now?</value>\n  </data>\n  <data name=\"LastFmScrobblingTitle\" xml:space=\"preserve\">\n    <value>Last.FM scrobbling</value>\n  </data>\n  <data name=\"Loading\" xml:space=\"preserve\">\n    <value>Loading</value>\n  </data>\n  <data name=\"SettingsUpdatesCheck\" xml:space=\"preserve\">\n    <value>Check now</value>\n  </data>\n  <data name=\"SettingsUpdatesCheckForUpdates\" xml:space=\"preserve\">\n    <value>Automatically check and install updates on start</value>\n  </data>\n  <data name=\"SettingsUpdatesDevUpdatesDescription\" xml:space=\"preserve\">\n    <value>Test updates may contain new features and can be released more often but also can be unstable.</value>\n  </data>\n  <data name=\"SettingsUpdatesInstallDevUpdates\" xml:space=\"preserve\">\n    <value>Install test updates</value>\n  </data>\n  <data name=\"SettingsUpdatesRestart\" xml:space=\"preserve\">\n    <value>Restart</value>\n  </data>\n  <data name=\"SettingsUpdatesUpdated\" xml:space=\"preserve\">\n    <value>Meridian was updated. Restart to apply changes.</value>\n  </data>\n  <data name=\"NotificationSaving\" xml:space=\"preserve\">\n    <value>Saving</value>\n  </data>\n  <data name=\"NotificationSaved\" xml:space=\"preserve\">\n    <value>Saved</value>\n  </data>\n  <data name=\"SettingsHotkeyFastForward\" xml:space=\"preserve\">\n    <value>Fast forward</value>\n  </data>\n  <data name=\"SettingsHotkeyRewind\" xml:space=\"preserve\">\n    <value>Rewind</value>\n  </data>\n  <data name=\"ContextMenuSearchArtist\" xml:space=\"preserve\">\n    <value>Show more of this</value>\n  </data>\n  <data name=\"SettingsUINotifications\" xml:space=\"preserve\">\n    <value>Show notification when track changes</value>\n  </data>\n  <data name=\"SettingsUINotificationsTitle\" xml:space=\"preserve\">\n    <value>Notifications</value>\n  </data>\n  <data name=\"CompactMode\" xml:space=\"preserve\">\n    <value>Compact mode</value>\n  </data>\n  <data name=\"CompactModePin\" xml:space=\"preserve\">\n    <value>Pin on top of other windows</value>\n  </data>\n  <data name=\"CompactModeTracklist\" xml:space=\"preserve\">\n    <value>tracklist</value>\n  </data>\n  <data name=\"FullMode\" xml:space=\"preserve\">\n    <value>Normal mode</value>\n  </data>\n  <data name=\"SettingsUIShowTrayIcon\" xml:space=\"preserve\">\n    <value>Show icon in the tray instead of taskbar</value>\n  </data>\n  <data name=\"SettingsUITaskBarTitle\" xml:space=\"preserve\">\n    <value>Taskbar</value>\n  </data>\n  <data name=\"ContextMenuStartRadio\" xml:space=\"preserve\">\n    <value>Start radio</value>\n  </data>\n  <data name=\"SettingsUIBackgroundArtTitle\" xml:space=\"preserve\">\n    <value>Artist and album art</value>\n  </data>\n  <data name=\"SettingsUIShowBackgroundArt\" xml:space=\"preserve\">\n    <value>Show current artist image on background</value>\n  </data>\n  <data name=\"CreateStationSubtitle\" xml:space=\"preserve\">\n    <value>You can add up to 5 artists</value>\n  </data>\n  <data name=\"NowPlayingRadioHint\" xml:space=\"preserve\">\n    <value>You are listening to radio. New tracks will dynamically appear here when you switch to the next track.</value>\n  </data>\n  <data name=\"SettingsUICacheSize\" xml:space=\"preserve\">\n    <value>Cache size:</value>\n  </data>\n  <data name=\"SettingsUIClearCache\" xml:space=\"preserve\">\n    <value>Clear</value>\n  </data>\n  <data name=\"ContextMenuShowArtistInfo\" xml:space=\"preserve\">\n    <value>Show artist info</value>\n  </data>\n  <data name=\"NotificationArtistNotFound\" xml:space=\"preserve\">\n    <value>Unable to load info about artist</value>\n  </data>\n  <data name=\"NotificationLookingArtist\" xml:space=\"preserve\">\n    <value>Looking for artist</value>\n  </data>\n  <data name=\"Searching\" xml:space=\"preserve\">\n    <value>Searching...</value>\n  </data>\n  <data name=\"AboutTellFriends\" xml:space=\"preserve\">\n    <value>Tell friends</value>\n  </data>\n  <data name=\"AboutTellFriendsTitle\" xml:space=\"preserve\">\n    <value>Would you like to help us? Then please tell friends about Meridian.</value>\n  </data>\n  <data name=\"AboutTellMessage\" xml:space=\"preserve\">\n    <value>Meridian is the best way to listen to music from Vkontakte.</value>\n  </data>\n  <data name=\"TellViewGoToPost\" xml:space=\"preserve\">\n    <value>View post</value>\n  </data>\n  <data name=\"TellViewTitle\" xml:space=\"preserve\">\n    <value>Thanks!</value>\n  </data>\n  <data name=\"TellFriendsRequestContent\" xml:space=\"preserve\">\n    <value>Please tell your friends about Meridian. This will really help us to make it better!</value>\n  </data>\n  <data name=\"TellFriendsRequestTellButton\" xml:space=\"preserve\">\n    <value>Tell friends</value>\n  </data>\n  <data name=\"TellFriendsRequestTitle\" xml:space=\"preserve\">\n    <value>Do you like Meridian?</value>\n  </data>\n  <data name=\"CommonErrorViewContent\" xml:space=\"preserve\">\n    <value>We are sorry but something goes wrong. We will try to fix this as soon as possible.</value>\n  </data>\n  <data name=\"CommonErrorViewTitle\" xml:space=\"preserve\">\n    <value>Oh... something happened :(</value>\n  </data>\n  <data name=\"CommonErrorViewRestart\" xml:space=\"preserve\">\n    <value>Restart</value>\n  </data>\n  <data name=\"HeaderMenuLocalSearch\" xml:space=\"preserve\">\n    <value>Find in list</value>\n  </data>\n  <data name=\"ContextMenuAddToAlbum\" xml:space=\"preserve\">\n    <value>Add to album</value>\n  </data>\n  <data name=\"ContextMenuPlay\" xml:space=\"preserve\">\n    <value>Play</value>\n  </data>\n  <data name=\"ArtistsTab\" xml:space=\"preserve\">\n    <value>Artists</value>\n  </data>\n  <data name=\"TracksTab\" xml:space=\"preserve\">\n    <value>Songs</value>\n  </data>\n  <data name=\"ContextMenuCopyToMyAlbums\" xml:space=\"preserve\">\n    <value>Copy to my albums</value>\n  </data>\n  <data name=\"SettingsUIDownloadAlbumArt\" xml:space=\"preserve\">\n    <value>Download album covers</value>\n  </data>\n  <data name=\"SettingsUIDownloadArtistArt\" xml:space=\"preserve\">\n    <value>Download artist art</value>\n  </data>\n  <data name=\"MainMenuCollection\" xml:space=\"preserve\">\n    <value>Collection</value>\n  </data>\n  <data name=\"MainMenuLocalTitle\" xml:space=\"preserve\">\n    <value>THIS PC</value>\n  </data>\n  <data name=\"MainMenuVkTitle\" xml:space=\"preserve\">\n    <value>VK</value>\n  </data>\n  <data name=\"AlbumsTab\" xml:space=\"preserve\">\n    <value>Albums</value>\n  </data>\n  <data name=\"MainMenuFeed\" xml:space=\"preserve\">\n    <value>Feed</value>\n  </data>\n  <data name=\"MusicScanDescription\" xml:space=\"preserve\">\n    <value>Please wait, we are looking for music on your PC</value>\n  </data>\n  <data name=\"MusicScanTitle\" xml:space=\"preserve\">\n    <value>Looking for music</value>\n  </data>\n  <data name=\"SettingsUIEnabledBlur\" xml:space=\"preserve\">\n    <value>Blur background (reduces performance)</value>\n  </data>\n  <data name=\"FavoritesTab\" xml:space=\"preserve\">\n    <value>Favorites</value>\n  </data>\n  <data name=\"NewsTab\" xml:space=\"preserve\">\n    <value>News</value>\n  </data>\n  <data name=\"WallTab\" xml:space=\"preserve\">\n    <value>Wall</value>\n  </data>\n  <data name=\"LandscapeMode\" xml:space=\"preserve\">\n    <value>Landscape mode</value>\n  </data>\n  <data name=\"PortraitMode\" xml:space=\"preserve\">\n    <value>Portrait mode</value>\n  </data>\n  <data name=\"SettingsUIPlayUsing\" xml:space=\"preserve\">\n    <value>Play using</value>\n  </data>\n  <data name=\"FeedAdd\" xml:space=\"preserve\">\n    <value>Add society</value>\n  </data>\n  <data name=\"FeedSocieties\" xml:space=\"preserve\">\n    <value>SOCIETIES</value>\n  </data>\n  <data name=\"Delete\" xml:space=\"preserve\">\n    <value>Delete</value>\n  </data>\n  <data name=\"FeedAddSocietyTitle\" xml:space=\"preserve\">\n    <value>Add society</value>\n  </data>\n  <data name=\"AllSocieties\" xml:space=\"preserve\">\n    <value>All societies</value>\n  </data>\n  <data name=\"NotificationAddedToNowPlaying\" xml:space=\"preserve\">\n    <value>Track added to now playing</value>\n  </data>\n  <data name=\"SettingsUIShowBackgroundArtCompactMode\" xml:space=\"preserve\">\n    <value>Show current artist image in compact mode</value>\n  </data>\n  <data name=\"FeedSubHeader\" xml:space=\"preserve\">\n    <value>New music from your favorite societies</value>\n  </data>\n  <data name=\"PopularSubHeader\" xml:space=\"preserve\">\n    <value>Popular music from VK</value>\n  </data>\n  <data name=\"RecommendationsSubHeader\" xml:space=\"preserve\">\n    <value>Discover new music by artists, genres, moods and more</value>\n  </data>\n  <data name=\"SettingsRemotePlay\" xml:space=\"preserve\">\n    <value>RemotePlay</value>\n  </data>\n  <data name=\"SettingsRemotePlayAddress\" xml:space=\"preserve\">\n    <value>Address</value>\n  </data>\n  <data name=\"SettingsRemotePlayDescription\" xml:space=\"preserve\">\n    <value>RemotePlay allows you to control Meridian from your mobile device like phone or tablet. Remote devices should be in the same network with this PC.</value>\n  </data>\n  <data name=\"SettingsRemotePlayEnable\" xml:space=\"preserve\">\n    <value>Enable RemotePlay</value>\n  </data>\n  <data name=\"SettingsRemotePlayHelp\" xml:space=\"preserve\">\n    <value>To start using RemotePlay on your iOS or Android device open {0} in browser on that device. To use RemotePlay on Windows Phone install Meridian app from the Store and go to the RemotePlay section in the app's menu.</value>\n  </data>\n  <data name=\"SettingsRemotePlayPort\" xml:space=\"preserve\">\n    <value>Port</value>\n  </data>\n  <data name=\"PopularGenresAll\" xml:space=\"preserve\">\n    <value>All genres</value>\n  </data>\n  <data name=\"PopularGenresTitle\" xml:space=\"preserve\">\n    <value>GENRES</value>\n  </data>\n  <data name=\"PopularForeignOnly\" xml:space=\"preserve\">\n    <value>foreign only</value>\n  </data>\n  <data name=\"SettingsUseHttps\" xml:space=\"preserve\">\n    <value>Use HTTPS</value>\n  </data>\n  <data name=\"SettingsMenuGeneral\" xml:space=\"preserve\">\n    <value>General</value>\n  </data>\n  <data name=\"LoginGoToSettings\" xml:space=\"preserve\">\n    <value>Go to settings.</value>\n  </data>\n</root>"
  },
  {
    "path": "Meridian/Resources/Localization/MainResources.ru.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"ArtistAlbums\" xml:space=\"preserve\">\n    <value>АЛЬБОМЫ</value>\n  </data>\n  <data name=\"ArtistRelatedArtists\" xml:space=\"preserve\">\n    <value>ПОХОЖИЕ ИСПОЛНИТЕЛИ</value>\n  </data>\n  <data name=\"ArtistShowAll\" xml:space=\"preserve\">\n    <value>Показать все</value>\n  </data>\n  <data name=\"ArtistTopTracks\" xml:space=\"preserve\">\n    <value>ПОПУЛЯРНЫЕ ТРЕКИ</value>\n  </data>\n  <data name=\"BackButton\" xml:space=\"preserve\">\n    <value>Назад</value>\n  </data>\n  <data name=\"CancelButton\" xml:space=\"preserve\">\n    <value>Отмена</value>\n  </data>\n  <data name=\"CaptchaEnterSymbols\" xml:space=\"preserve\">\n    <value>Введите символы с картинки</value>\n  </data>\n  <data name=\"CaptchaTitle\" xml:space=\"preserve\">\n    <value>Подтверждение</value>\n  </data>\n  <data name=\"Close\" xml:space=\"preserve\">\n    <value>Закрыть</value>\n  </data>\n  <data name=\"ContextMenuAdd\" xml:space=\"preserve\">\n    <value>Добавить в мою музыку</value>\n  </data>\n  <data name=\"ContextMenuAddToNowPlaying\" xml:space=\"preserve\">\n    <value>Добавить в список \"Сейчас играет\"</value>\n  </data>\n  <data name=\"ContextMenuCopyInfo\" xml:space=\"preserve\">\n    <value>Копировать название</value>\n  </data>\n  <data name=\"ContextMenuEdit\" xml:space=\"preserve\">\n    <value>Редактировать</value>\n  </data>\n  <data name=\"ContextMenuLyrics\" xml:space=\"preserve\">\n    <value>Посмотреть текст песни</value>\n  </data>\n  <data name=\"ContextMenuPlayNext\" xml:space=\"preserve\">\n    <value>Воспроизвести следующим</value>\n  </data>\n  <data name=\"ContextMenuRemove\" xml:space=\"preserve\">\n    <value>Удалить из моей музыки</value>\n  </data>\n  <data name=\"ContextMenuRemoveFromNowPlaying\" xml:space=\"preserve\">\n    <value>Удалить из списка</value>\n  </data>\n  <data name=\"ContextMenuRemoveRadio\" xml:space=\"preserve\">\n    <value>Удалить</value>\n  </data>\n  <data name=\"ContextMenuShare\" xml:space=\"preserve\">\n    <value>Поделиться</value>\n  </data>\n  <data name=\"CreateStationAdd\" xml:space=\"preserve\">\n    <value>Добавить</value>\n  </data>\n  <data name=\"CreateStationArtist\" xml:space=\"preserve\">\n    <value>Исполнитель</value>\n  </data>\n  <data name=\"CreateStationEdit\" xml:space=\"preserve\">\n    <value>Редактировать станцию</value>\n  </data>\n  <data name=\"CreateStationSave\" xml:space=\"preserve\">\n    <value>Сохранить станцию</value>\n  </data>\n  <data name=\"CreateStationTitle\" xml:space=\"preserve\">\n    <value>Новая станция</value>\n  </data>\n  <data name=\"EditAlbumName\" xml:space=\"preserve\">\n    <value>Название</value>\n  </data>\n  <data name=\"EditAlbumNewTitle\" xml:space=\"preserve\">\n    <value>Новый альбом</value>\n  </data>\n  <data name=\"EditAlbumSave\" xml:space=\"preserve\">\n    <value>Сохранить изменения</value>\n  </data>\n  <data name=\"EditAlbumTitle\" xml:space=\"preserve\">\n    <value>Редактировать альбом</value>\n  </data>\n  <data name=\"EditAudioArtist\" xml:space=\"preserve\">\n    <value>Исполнитель</value>\n  </data>\n  <data name=\"EditAudioLyrics\" xml:space=\"preserve\">\n    <value>Текст</value>\n  </data>\n  <data name=\"EditAudioName\" xml:space=\"preserve\">\n    <value>Название</value>\n  </data>\n  <data name=\"EditAudioSave\" xml:space=\"preserve\">\n    <value>Сохранить изменения</value>\n  </data>\n  <data name=\"EditAudioTitle\" xml:space=\"preserve\">\n    <value>Редактровать трек</value>\n  </data>\n  <data name=\"HeaderMenuClear\" xml:space=\"preserve\">\n    <value>Очистить</value>\n  </data>\n  <data name=\"HeaderMenuRefresh\" xml:space=\"preserve\">\n    <value>Обновить</value>\n  </data>\n  <data name=\"HeaderMenuSave\" xml:space=\"preserve\">\n    <value>Сохранить</value>\n  </data>\n  <data name=\"HeaderMenuShare\" xml:space=\"preserve\">\n    <value>Поделиться</value>\n  </data>\n  <data name=\"LastFmScrobbling\" xml:space=\"preserve\">\n    <value>Скробблить на Last.FM</value>\n  </data>\n  <data name=\"LoginLoading\" xml:space=\"preserve\">\n    <value>Пожалуйста подождите, мы загружаем ваш профиль</value>\n  </data>\n  <data name=\"LoginLoginButton\" xml:space=\"preserve\">\n    <value>Войти</value>\n  </data>\n  <data name=\"LoginLoginTitle\" xml:space=\"preserve\">\n    <value>Логин, e-mail или номер телефона</value>\n  </data>\n  <data name=\"LoginPasswordTitle\" xml:space=\"preserve\">\n    <value>Пароль</value>\n  </data>\n  <data name=\"LoginRegisterButton\" xml:space=\"preserve\">\n    <value>Зарегистрироваться ВКонтакте</value>\n  </data>\n  <data name=\"LoginStartLoginButton\" xml:space=\"preserve\">\n    <value>Войти через ВКонтакте</value>\n  </data>\n  <data name=\"LoginWelcome\" xml:space=\"preserve\">\n    <value>Давайте начнем</value>\n  </data>\n  <data name=\"MainMenuFriends\" xml:space=\"preserve\">\n    <value>Друзья</value>\n  </data>\n  <data name=\"MainMenuMainTitle\" xml:space=\"preserve\">\n    <value>ГЛАВНОЕ</value>\n  </data>\n  <data name=\"MainMenuMyMusic\" xml:space=\"preserve\">\n    <value>Моя музыка</value>\n  </data>\n  <data name=\"MainMenuNowPlaying\" xml:space=\"preserve\">\n    <value>Сейчас играет</value>\n  </data>\n  <data name=\"MainMenuPeopleTitle\" xml:space=\"preserve\">\n    <value>ЛЮДИ</value>\n  </data>\n  <data name=\"MainMenuPopular\" xml:space=\"preserve\">\n    <value>Популярное</value>\n  </data>\n  <data name=\"MainMenuRadio\" xml:space=\"preserve\">\n    <value>Радио</value>\n  </data>\n  <data name=\"MainMenuRecommendations\" xml:space=\"preserve\">\n    <value>Рекомендации</value>\n  </data>\n  <data name=\"MainMenuSocieties\" xml:space=\"preserve\">\n    <value>Сообщества</value>\n  </data>\n  <data name=\"MainMenuSubscriptions\" xml:space=\"preserve\">\n    <value>Подписки</value>\n  </data>\n  <data name=\"Maximize\" xml:space=\"preserve\">\n    <value>Развернуть</value>\n  </data>\n  <data name=\"Minimize\" xml:space=\"preserve\">\n    <value>Свернуть</value>\n  </data>\n  <data name=\"MoodsCool\" xml:space=\"preserve\">\n    <value>клевое</value>\n  </data>\n  <data name=\"MoodsDreamy\" xml:space=\"preserve\">\n    <value>мечтательное</value>\n  </data>\n  <data name=\"MoodsEnergy\" xml:space=\"preserve\">\n    <value>энергичное</value>\n  </data>\n  <data name=\"MoodsEpic\" xml:space=\"preserve\">\n    <value>эпичное</value>\n  </data>\n  <data name=\"MoodsExtreme\" xml:space=\"preserve\">\n    <value>экстрим</value>\n  </data>\n  <data name=\"MoodsFreedom\" xml:space=\"preserve\">\n    <value>свобода</value>\n  </data>\n  <data name=\"MoodsHappy\" xml:space=\"preserve\">\n    <value>счастливое</value>\n  </data>\n  <data name=\"MoodsLoneliness\" xml:space=\"preserve\">\n    <value>одиночество</value>\n  </data>\n  <data name=\"MoodsNight\" xml:space=\"preserve\">\n    <value>спокойное</value>\n  </data>\n  <data name=\"MoodsNostalgia\" xml:space=\"preserve\">\n    <value>ностальгия</value>\n  </data>\n  <data name=\"MoodsOptimism\" xml:space=\"preserve\">\n    <value>оптимизм</value>\n  </data>\n  <data name=\"MoodsPsychedelic\" xml:space=\"preserve\">\n    <value>психоделика</value>\n  </data>\n  <data name=\"MoodsRomantic\" xml:space=\"preserve\">\n    <value>романтика</value>\n  </data>\n  <data name=\"MoodsSad\" xml:space=\"preserve\">\n    <value>грусть</value>\n  </data>\n  <data name=\"MoodsSexy\" xml:space=\"preserve\">\n    <value>сексуальное</value>\n  </data>\n  <data name=\"MoodsSport\" xml:space=\"preserve\">\n    <value>спортивное</value>\n  </data>\n  <data name=\"MoodsUrban\" xml:space=\"preserve\">\n    <value>городское</value>\n  </data>\n  <data name=\"MoodsVintage\" xml:space=\"preserve\">\n    <value>винтажное</value>\n  </data>\n  <data name=\"MyMusicAlbums\" xml:space=\"preserve\">\n    <value>АЛЬБОМЫ</value>\n  </data>\n  <data name=\"MyMusicAlbumsAdd\" xml:space=\"preserve\">\n    <value>Добавить альбом</value>\n  </data>\n  <data name=\"MyMusicAllTracks\" xml:space=\"preserve\">\n    <value>Все треки</value>\n  </data>\n  <data name=\"MyMusicFavorites\" xml:space=\"preserve\">\n    <value>закладки</value>\n  </data>\n  <data name=\"MyMusicNews\" xml:space=\"preserve\">\n    <value>новости</value>\n  </data>\n  <data name=\"MyMusicWall\" xml:space=\"preserve\">\n    <value>стена</value>\n  </data>\n  <data name=\"NextButton\" xml:space=\"preserve\">\n    <value>Далее</value>\n  </data>\n  <data name=\"NextTrack\" xml:space=\"preserve\">\n    <value>Следующий трек</value>\n  </data>\n  <data name=\"OkButton\" xml:space=\"preserve\">\n    <value>ОК</value>\n  </data>\n  <data name=\"PlayPause\" xml:space=\"preserve\">\n    <value>Воспроизвести / Пауза</value>\n  </data>\n  <data name=\"PrevTrack\" xml:space=\"preserve\">\n    <value>Предыдущий трек</value>\n  </data>\n  <data name=\"RadioAddStationButton\" xml:space=\"preserve\">\n    <value>Создать станцию</value>\n  </data>\n  <data name=\"RadioStationsTitle\" xml:space=\"preserve\">\n    <value>СТАНЦИИ</value>\n  </data>\n  <data name=\"RadioSubHeader\" xml:space=\"preserve\">\n    <value>Создавайте станции с любимыми исполнителями</value>\n  </data>\n  <data name=\"RecommendationsGenresGroup\" xml:space=\"preserve\">\n    <value>ЖАНРЫ</value>\n  </data>\n  <data name=\"RecommendationsMoodsGroup\" xml:space=\"preserve\">\n    <value>НАСТРОЕНИЯ</value>\n  </data>\n  <data name=\"RecommendationsMusicAdvanced\" xml:space=\"preserve\">\n    <value>расширенные</value>\n  </data>\n  <data name=\"RecommendationsMusicGeneral\" xml:space=\"preserve\">\n    <value>общие</value>\n  </data>\n  <data name=\"RecommendationsMusicGroup\" xml:space=\"preserve\">\n    <value>МУЗЫКА</value>\n  </data>\n  <data name=\"Repeat\" xml:space=\"preserve\">\n    <value>Режим повтора</value>\n  </data>\n  <data name=\"Search\" xml:space=\"preserve\">\n    <value>Поиск</value>\n  </data>\n  <data name=\"SearchResultsTitle\" xml:space=\"preserve\">\n    <value>Поиск</value>\n  </data>\n  <data name=\"SearchSection\" xml:space=\"preserve\">\n    <value>РАЗДЕЛ</value>\n  </data>\n  <data name=\"SearchSectionAlbums\" xml:space=\"preserve\">\n    <value>альбомы</value>\n  </data>\n  <data name=\"SearchSectionArtists\" xml:space=\"preserve\">\n    <value>исполнители</value>\n  </data>\n  <data name=\"SearchSectionTracks\" xml:space=\"preserve\">\n    <value>треки</value>\n  </data>\n  <data name=\"Settings\" xml:space=\"preserve\">\n    <value>Настройки</value>\n  </data>\n  <data name=\"SettingsAccountsLastFm\" xml:space=\"preserve\">\n    <value>Last.FM</value>\n  </data>\n  <data name=\"SettingsAccountsLastFmDescription\" xml:space=\"preserve\">\n    <value>Подключите ваш Last.FM аккаунт, чтобы включить скробблинг.</value>\n  </data>\n  <data name=\"SettingsAccountsSignedAs\" xml:space=\"preserve\">\n    <value>Вы вошли как</value>\n  </data>\n  <data name=\"SettingsAccountsSignOut\" xml:space=\"preserve\">\n    <value>Выйти</value>\n  </data>\n  <data name=\"SettingsAccountsVk\" xml:space=\"preserve\">\n    <value>ВКонтакте</value>\n  </data>\n  <data name=\"SettingsHotkeyAddRemove\" xml:space=\"preserve\">\n    <value>Добавить / Удалить текущий трек</value>\n  </data>\n  <data name=\"SettingsHotkeyDecreaseVolume\" xml:space=\"preserve\">\n    <value>Понизить громкость</value>\n  </data>\n  <data name=\"SettingsHotkeyIncreaseVolume\" xml:space=\"preserve\">\n    <value>Увеличить громкость</value>\n  </data>\n  <data name=\"SettingsHotkeyNext\" xml:space=\"preserve\">\n    <value>Следующий трек</value>\n  </data>\n  <data name=\"SettingsHotkeyPlayPause\" xml:space=\"preserve\">\n    <value>Воспроизвести / Пауза</value>\n  </data>\n  <data name=\"SettingsHotkeyPrev\" xml:space=\"preserve\">\n    <value>Предыдущий трек</value>\n  </data>\n  <data name=\"SettingsHotkeyRepeat\" xml:space=\"preserve\">\n    <value>Режим повтора</value>\n  </data>\n  <data name=\"SettingsHotkeyShowHide\" xml:space=\"preserve\">\n    <value>Показать / Скрыть Meridian</value>\n  </data>\n  <data name=\"SettingsHotkeyShuffle\" xml:space=\"preserve\">\n    <value>Режим случайного воспроизведения</value>\n  </data>\n  <data name=\"SettingsMenuAbout\" xml:space=\"preserve\">\n    <value>О программе</value>\n  </data>\n  <data name=\"SettingsMenuAccounts\" xml:space=\"preserve\">\n    <value>Аккаунты</value>\n  </data>\n  <data name=\"SettingsMenuHotkeys\" xml:space=\"preserve\">\n    <value>Горячие клавиши</value>\n  </data>\n  <data name=\"SettingsMenuUI\" xml:space=\"preserve\">\n    <value>Интерфейс</value>\n  </data>\n  <data name=\"SettingsMenuUpdates\" xml:space=\"preserve\">\n    <value>Обновления</value>\n  </data>\n  <data name=\"SettingsRestartMessage\" xml:space=\"preserve\">\n    <value>Некоторые изменения вступят в силу после перезапуска.</value>\n  </data>\n  <data name=\"SettingsSave\" xml:space=\"preserve\">\n    <value>Сохранить изменения</value>\n  </data>\n  <data name=\"SettingsSaveRestart\" xml:space=\"preserve\">\n    <value>Сохранить и перезапустить</value>\n  </data>\n  <data name=\"SettingsUIAccentColor\" xml:space=\"preserve\">\n    <value>Цветовая схема</value>\n  </data>\n  <data name=\"SettingsUIBackgroundColor\" xml:space=\"preserve\">\n    <value>Цвет фона</value>\n  </data>\n  <data name=\"SettingsUILanguage\" xml:space=\"preserve\">\n    <value>Язык</value>\n  </data>\n  <data name=\"ShareAsSociety\" xml:space=\"preserve\">\n    <value>от имени сообщества</value>\n  </data>\n  <data name=\"ShareBarTitle\" xml:space=\"preserve\">\n    <value>Перетащите треки сюда, чтобы прикрепить к сообщению</value>\n  </data>\n  <data name=\"SharePublishButton\" xml:space=\"preserve\">\n    <value>Опубликовать</value>\n  </data>\n  <data name=\"SharePublishing\" xml:space=\"preserve\">\n    <value>Публикация</value>\n  </data>\n  <data name=\"ShareSigned\" xml:space=\"preserve\">\n    <value>подпись</value>\n  </data>\n  <data name=\"ShareTitle\" xml:space=\"preserve\">\n    <value>Поделиться</value>\n  </data>\n  <data name=\"ShareToMyWall\" xml:space=\"preserve\">\n    <value>опубликовать у меня на стене</value>\n  </data>\n  <data name=\"ShareToMyWallHint\" xml:space=\"preserve\">\n    <value>поделиться записью с друзьями и подписчиками</value>\n  </data>\n  <data name=\"ShareToSociety\" xml:space=\"preserve\">\n    <value>опубликовать в сообществе</value>\n  </data>\n  <data name=\"ShareToUserWall\" xml:space=\"preserve\">\n    <value>поделиться с другом</value>\n  </data>\n  <data name=\"Shuffle\" xml:space=\"preserve\">\n    <value>Режим случайного воспроизведения</value>\n  </data>\n  <data name=\"VkStatusBroadcasting\" xml:space=\"preserve\">\n    <value>Отображать, что я слушаю в статусе ВКонтакте</value>\n  </data>\n  <data name=\"Volume\" xml:space=\"preserve\">\n    <value>Громкость</value>\n  </data>\n  <data name=\"LastFmLoginTitle\" xml:space=\"preserve\">\n    <value>Логин</value>\n  </data>\n  <data name=\"LastFmScrobblingGoSettings\" xml:space=\"preserve\">\n    <value>Перейти в настройки</value>\n  </data>\n  <data name=\"LastFmScrobblingMessage\" xml:space=\"preserve\">\n    <value>Для включения скробблинга, вам необходимо подключить ваш аккаунт Last.FM в настройках. Хотите сделать это сейчас?</value>\n  </data>\n  <data name=\"LastFmScrobblingTitle\" xml:space=\"preserve\">\n    <value>Last.FM скробблинг</value>\n  </data>\n  <data name=\"Loading\" xml:space=\"preserve\">\n    <value>Загрузка</value>\n  </data>\n  <data name=\"SettingsUpdatesCheck\" xml:space=\"preserve\">\n    <value>Проверить сейчас</value>\n  </data>\n  <data name=\"SettingsUpdatesCheckForUpdates\" xml:space=\"preserve\">\n    <value>Автоматически проверять и устанавливать обновления при запуске</value>\n  </data>\n  <data name=\"SettingsUpdatesDevUpdatesDescription\" xml:space=\"preserve\">\n    <value>Тестовые обновления могут содержать новые функции и выходить чаще, но также могут работать нестабильно.</value>\n  </data>\n  <data name=\"SettingsUpdatesInstallDevUpdates\" xml:space=\"preserve\">\n    <value>Устанавливать тестовые обновления</value>\n  </data>\n  <data name=\"SettingsUpdatesRestart\" xml:space=\"preserve\">\n    <value>Перезапустить</value>\n  </data>\n  <data name=\"SettingsUpdatesUpdated\" xml:space=\"preserve\">\n    <value>Meridian обновлен. Изменения вступят в силу после перезапуска.</value>\n  </data>\n  <data name=\"NotificationSaved\" xml:space=\"preserve\">\n    <value>Сохранено</value>\n  </data>\n  <data name=\"NotificationSaving\" xml:space=\"preserve\">\n    <value>Сохранение</value>\n  </data>\n  <data name=\"SettingsHotkeyFastForward\" xml:space=\"preserve\">\n    <value>Перемотать вперед</value>\n  </data>\n  <data name=\"SettingsHotkeyRewind\" xml:space=\"preserve\">\n    <value>Перемотать назад</value>\n  </data>\n  <data name=\"ContextMenuSearchArtist\" xml:space=\"preserve\">\n    <value>Найти еще треки</value>\n  </data>\n  <data name=\"SettingsUINotifications\" xml:space=\"preserve\">\n    <value>Отображать уведомление при смене трека</value>\n  </data>\n  <data name=\"SettingsUINotificationsTitle\" xml:space=\"preserve\">\n    <value>Уведомления</value>\n  </data>\n  <data name=\"CompactMode\" xml:space=\"preserve\">\n    <value>Компактный режим</value>\n  </data>\n  <data name=\"CompactModePin\" xml:space=\"preserve\">\n    <value>Закрепить поверх остальных окон</value>\n  </data>\n  <data name=\"CompactModeTracklist\" xml:space=\"preserve\">\n    <value>список треков</value>\n  </data>\n  <data name=\"FullMode\" xml:space=\"preserve\">\n    <value>Полный режим</value>\n  </data>\n  <data name=\"SettingsUIShowTrayIcon\" xml:space=\"preserve\">\n    <value>Отображать иконку в трее, вместо панели задач</value>\n  </data>\n  <data name=\"SettingsUITaskBarTitle\" xml:space=\"preserve\">\n    <value>Панель задач</value>\n  </data>\n  <data name=\"ContextMenuStartRadio\" xml:space=\"preserve\">\n    <value>Запустить радио</value>\n  </data>\n  <data name=\"SettingsUIBackgroundArtTitle\" xml:space=\"preserve\">\n    <value>Обложки альбомов и изображения исполнителей</value>\n  </data>\n  <data name=\"SettingsUIShowBackgroundArt\" xml:space=\"preserve\">\n    <value>Отображать изображение текущего исполнителя на фоне</value>\n  </data>\n  <data name=\"CreateStationSubtitle\" xml:space=\"preserve\">\n    <value>Вы можете добавить до 5 исполнителей</value>\n  </data>\n  <data name=\"NowPlayingRadioHint\" xml:space=\"preserve\">\n    <value>Вы слушаете радио. Новые треки будут появляться здесь динамически, когда вы переключаете следующий трек.</value>\n  </data>\n  <data name=\"SettingsUICacheSize\" xml:space=\"preserve\">\n    <value>Размер кэша:</value>\n  </data>\n  <data name=\"SettingsUIClearCache\" xml:space=\"preserve\">\n    <value>Очистить</value>\n  </data>\n  <data name=\"ContextMenuShowArtistInfo\" xml:space=\"preserve\">\n    <value>Об исполнителе</value>\n  </data>\n  <data name=\"NotificationArtistNotFound\" xml:space=\"preserve\">\n    <value>Не удалось загрузить информацию об исполнителе</value>\n  </data>\n  <data name=\"NotificationLookingArtist\" xml:space=\"preserve\">\n    <value>Получение информации об исполнителе</value>\n  </data>\n  <data name=\"Searching\" xml:space=\"preserve\">\n    <value>Поиск...</value>\n  </data>\n  <data name=\"AboutTellFriends\" xml:space=\"preserve\">\n    <value>Рассказать друзьям</value>\n  </data>\n  <data name=\"AboutTellFriendsTitle\" xml:space=\"preserve\">\n    <value>Хотите помочь нам? Тогда расскажите, пожалуйста, друзьям о Meridian.</value>\n  </data>\n  <data name=\"AboutTellMessage\" xml:space=\"preserve\">\n    <value>Meridian - это лучший способ слушать музыку ВКонтакте.</value>\n  </data>\n  <data name=\"TellViewGoToPost\" xml:space=\"preserve\">\n    <value>Перейти к записи</value>\n  </data>\n  <data name=\"TellViewTitle\" xml:space=\"preserve\">\n    <value>Спасибо!</value>\n  </data>\n  <data name=\"TellFriendsRequestContent\" xml:space=\"preserve\">\n    <value>Пожалуйста, расскажите друзьям о Meridian. Это очень поможет проекту стать еще лучше!</value>\n  </data>\n  <data name=\"TellFriendsRequestTellButton\" xml:space=\"preserve\">\n    <value>Рассказать друзьям</value>\n  </data>\n  <data name=\"TellFriendsRequestTitle\" xml:space=\"preserve\">\n    <value>Вам нравится Meridian?</value>\n  </data>\n  <data name=\"CommonErrorViewContent\" xml:space=\"preserve\">\n    <value>Сожалеем, но что-то пошло не так. Не расстраивайтесь, мы постараемся все починить.</value>\n  </data>\n  <data name=\"CommonErrorViewTitle\" xml:space=\"preserve\">\n    <value>Что-то пошло не так :(</value>\n  </data>\n  <data name=\"CommonErrorViewRestart\" xml:space=\"preserve\">\n    <value>Перезапустить</value>\n  </data>\n  <data name=\"HeaderMenuLocalSearch\" xml:space=\"preserve\">\n    <value>Найти в списке</value>\n  </data>\n  <data name=\"ContextMenuAddToAlbum\" xml:space=\"preserve\">\n    <value>Добавить в альбом</value>\n  </data>\n  <data name=\"ContextMenuPlay\" xml:space=\"preserve\">\n    <value>Воспроизвести</value>\n  </data>\n  <data name=\"ArtistsTab\" xml:space=\"preserve\">\n    <value>Исполнители</value>\n  </data>\n  <data name=\"TracksTab\" xml:space=\"preserve\">\n    <value>Треки</value>\n  </data>\n  <data name=\"ContextMenuCopyToMyAlbums\" xml:space=\"preserve\">\n    <value>Сохранить в свои альбомы</value>\n  </data>\n  <data name=\"SettingsUIDownloadAlbumArt\" xml:space=\"preserve\">\n    <value>Загружать обложки альбомов</value>\n  </data>\n  <data name=\"SettingsUIDownloadArtistArt\" xml:space=\"preserve\">\n    <value>Загружать изображения исполнителей</value>\n  </data>\n  <data name=\"MainMenuLocalTitle\" xml:space=\"preserve\">\n    <value>ЭТОТ ПК</value>\n  </data>\n  <data name=\"MainMenuVkTitle\" xml:space=\"preserve\">\n    <value>ВКОНТАКТЕ</value>\n  </data>\n  <data name=\"MainMenuCollection\" xml:space=\"preserve\">\n    <value>Коллекция</value>\n  </data>\n  <data name=\"AlbumsTab\" xml:space=\"preserve\">\n    <value>Альбомы</value>\n  </data>\n  <data name=\"MainMenuFeed\" xml:space=\"preserve\">\n    <value>Лента</value>\n  </data>\n  <data name=\"MusicScanDescription\" xml:space=\"preserve\">\n    <value>Пожалуйста подождите, мы ищем музыку на вашем ПК</value>\n  </data>\n  <data name=\"MusicScanTitle\" xml:space=\"preserve\">\n    <value>Поиск музыки</value>\n  </data>\n  <data name=\"SettingsUIEnabledBlur\" xml:space=\"preserve\">\n    <value>Включить размытие фона (снижает производительность)</value>\n  </data>\n  <data name=\"FavoritesTab\" xml:space=\"preserve\">\n    <value>Закладки</value>\n  </data>\n  <data name=\"NewsTab\" xml:space=\"preserve\">\n    <value>Новости</value>\n  </data>\n  <data name=\"WallTab\" xml:space=\"preserve\">\n    <value>Стена</value>\n  </data>\n  <data name=\"LandscapeMode\" xml:space=\"preserve\">\n    <value>Горизонтальный режим</value>\n  </data>\n  <data name=\"PortraitMode\" xml:space=\"preserve\">\n    <value>Вертикальный режим</value>\n  </data>\n  <data name=\"SettingsUIPlayUsing\" xml:space=\"preserve\">\n    <value>Воспроизводить с помощью</value>\n  </data>\n  <data name=\"FeedAdd\" xml:space=\"preserve\">\n    <value>Добавить сообщество</value>\n  </data>\n  <data name=\"FeedSocieties\" xml:space=\"preserve\">\n    <value>СООБЩЕСТВА</value>\n  </data>\n  <data name=\"Delete\" xml:space=\"preserve\">\n    <value>Удалить</value>\n  </data>\n  <data name=\"FeedAddSocietyTitle\" xml:space=\"preserve\">\n    <value>Добавить сообщество</value>\n  </data>\n  <data name=\"AllSocieties\" xml:space=\"preserve\">\n    <value>Все сообщества</value>\n  </data>\n  <data name=\"NotificationAddedToNowPlaying\" xml:space=\"preserve\">\n    <value>Трек добавлен в очередь</value>\n  </data>\n  <data name=\"SettingsUIShowBackgroundArtCompactMode\" xml:space=\"preserve\">\n    <value>Отображать изображение текущего исполнителя в компактном режиме</value>\n  </data>\n  <data name=\"FeedSubHeader\" xml:space=\"preserve\">\n    <value>Новая музыка из ваших любимых сообществ</value>\n  </data>\n  <data name=\"PopularSubHeader\" xml:space=\"preserve\">\n    <value>Популярная музыка ВКонтакте</value>\n  </data>\n  <data name=\"RecommendationsSubHeader\" xml:space=\"preserve\">\n    <value>Откройте для себя новую музыку с рекомендациями</value>\n  </data>\n  <data name=\"SettingsRemotePlay\" xml:space=\"preserve\">\n    <value>RemotePlay</value>\n  </data>\n  <data name=\"SettingsRemotePlayDescription\" xml:space=\"preserve\">\n    <value>RemotePlay позволяет вам управлять Meridian с помощью мобильных устройств, таких как смартфон или планшет. Для работы RemotePlay необходимо, чтобы все устройства были в одной сети.</value>\n  </data>\n  <data name=\"SettingsRemotePlayEnable\" xml:space=\"preserve\">\n    <value>Включить RemotePlay</value>\n  </data>\n  <data name=\"SettingsRemotePlayHelp\" xml:space=\"preserve\">\n    <value>Чтобы начать использовать RemotePlay на вашем iOS или Android устройстве, перейдите по адресу {0} в браузере на устройстве. Чтобы использовать RemotePlay на Windows Phone, установите приложения Meridian из магазина и перейдите в раздел RemotePlay в меню приложения.</value>\n  </data>\n  <data name=\"PopularGenresAll\" xml:space=\"preserve\">\n    <value>Все жанры</value>\n  </data>\n  <data name=\"PopularGenresTitle\" xml:space=\"preserve\">\n    <value>ЖАНРЫ</value>\n  </data>\n  <data name=\"PopularForeignOnly\" xml:space=\"preserve\">\n    <value>только зарубежные</value>\n  </data>\n  <data name=\"SettingsUseHttps\" xml:space=\"preserve\">\n    <value>Использовать HTTPS</value>\n  </data>\n  <data name=\"SettingsMenuGeneral\" xml:space=\"preserve\">\n    <value>Общие</value>\n  </data>\n  <data name=\"LoginGoToSettings\" xml:space=\"preserve\">\n    <value>Перейти в настройки.</value>\n  </data>\n</root>"
  },
  {
    "path": "Meridian/Resources/Styles/Animations.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n\n    <Storyboard x:Key=\"AudioLoadAnim\" x:Shared=\"False\" FillBehavior=\"Stop\">\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"20\"/>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimation Storyboard.TargetProperty=\"Opacity\" To=\"1\" Duration=\"0:0:0.2\"/>\n        </Storyboard>\n    </Storyboard>\n\n    <Storyboard x:Key=\"AlbumLoadAnim\" x:Shared=\"False\" FillBehavior=\"Stop\">\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"15\"/>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.6\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimation Storyboard.TargetProperty=\"Opacity\" To=\"1\" Duration=\"0:0:0.1\"/>\n        </Storyboard>\n    </Storyboard>\n\n    <Storyboard x:Key=\"MainMenuLoadAnim\" x:Shared=\"False\" FillBehavior=\"Stop\">\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"15\"/>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.9\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimation Storyboard.TargetProperty=\"Opacity\" To=\"1\" Duration=\"0:0:0.1\"/>\n        </Storyboard>\n    </Storyboard>\n\n    <Storyboard x:Key=\"FriendLoadAnim\" x:Shared=\"False\" FillBehavior=\"Stop\">\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"25\"/>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.7\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n    </Storyboard>\n\n    <Storyboard x:Key=\"LocalAlbumLoadAnim\" x:Shared=\"False\" FillBehavior=\"Stop\">\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"25\"/>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.7\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n    </Storyboard>\n\n    <Storyboard x:Key=\"ShareBarTransitionIn\" x:Shared=\"False\">\n        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Height\">\n            <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n            <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"150\">\n                <EasingDoubleKeyFrame.EasingFunction>\n                    <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                </EasingDoubleKeyFrame.EasingFunction>\n            </EasingDoubleKeyFrame>\n        </DoubleAnimationUsingKeyFrames>\n    </Storyboard>\n\n    <Storyboard x:Key=\"ShareBarTransitionOut\" x:Shared=\"False\">\n        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Height\">\n            <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"0\">\n                <EasingDoubleKeyFrame.EasingFunction>\n                    <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                </EasingDoubleKeyFrame.EasingFunction>\n            </EasingDoubleKeyFrame>\n        </DoubleAnimationUsingKeyFrames>\n    </Storyboard>\n\n    <Storyboard x:Key=\"PageLoadAnim\" x:Shared=\"False\" FillBehavior=\"Stop\">\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"40\"/>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard BeginTime=\"0:0:0.1\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.7\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimation Storyboard.TargetProperty=\"Opacity\" To=\"1\" Duration=\"0:0:0.2\"/>\n        </Storyboard>\n    </Storyboard>\n\n    <Storyboard x:Key=\"PageHeaderLoadAnim\" x:Shared=\"False\" FillBehavior=\"Stop\">\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"40\"/>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n    </Storyboard>\n\n    <Storyboard x:Key=\"LocalSearchBoxTransitionIn\" x:Shared=\"False\">\n        <Storyboard>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.Y)\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"-10\"/>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.Y)\">\n            <EasingDoubleKeyFrame KeyTime=\"0:0:0.3\" Value=\"0\">\n                <EasingDoubleKeyFrame.EasingFunction>\n                    <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                </EasingDoubleKeyFrame.EasingFunction>\n            </EasingDoubleKeyFrame>\n        </DoubleAnimationUsingKeyFrames>\n        <DoubleAnimation Storyboard.TargetProperty=\"Opacity\" To=\"1\" Duration=\"0:0:0.15\"/>\n    </Storyboard>\n\n    <Storyboard x:Key=\"LocalSearchBoxTransitionOut\" x:Shared=\"False\">\n        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.Y)\">\n            <EasingDoubleKeyFrame KeyTime=\"0:0:0.3\" Value=\"-10\">\n                <EasingDoubleKeyFrame.EasingFunction>\n                    <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                </EasingDoubleKeyFrame.EasingFunction>\n            </EasingDoubleKeyFrame>\n        </DoubleAnimationUsingKeyFrames>\n        <DoubleAnimation Storyboard.TargetProperty=\"Opacity\" To=\"0\" Duration=\"0:0:0.1\"/>\n    </Storyboard>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/AudioControlStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Style x:Key=\"PlayPauseButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ToggleButton\">\n                    <Grid Name=\"RootGrid\" Background=\"Transparent\">\n                        <Viewbox>\n                            <Path x:Name=\"Icon\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Margin=\"20,15,15,15\" HorizontalAlignment=\"Center\" Data=\"{StaticResource PlayIcon}\"/>\n                        </Viewbox>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Data\" Value=\"{StaticResource PauseIcon}\"/>\n                            <Setter TargetName=\"Icon\" Property=\"Margin\" Value=\"15\"/>\n                        </Trigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"True\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.7\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"False\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                            <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"RootGrid\" Property=\"Opacity\" Value=\"0.2\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"PrevButtonStyle\" TargetType=\"Button\">\n        <Setter Property=\"Foreground\" Value=\"Black\"/>\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"Button\">\n                    <Grid Name=\"RootGrid\" Background=\"Transparent\">\n                        <Viewbox>\n                            <Path x:Name=\"Icon\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Margin=\"15\" HorizontalAlignment=\"Center\" Data=\"{StaticResource PrevIcon}\"/>\n                        </Viewbox>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"True\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.7\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"False\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                            <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"RootGrid\" Property=\"Opacity\" Value=\"0.2\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"NextButtonStyle\" TargetType=\"Button\">\n        <Setter Property=\"Foreground\" Value=\"Black\"/>\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"Button\">\n                    <Grid Name=\"RootGrid\" Background=\"Transparent\">\n                        <Viewbox>\n                            <Path x:Name=\"Icon\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Margin=\"15\" HorizontalAlignment=\"Center\" Data=\"{StaticResource NextIcon}\"\n                                  Opacity=\"1\"/>\n                        </Viewbox>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"True\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.7\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"False\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                            <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"RootGrid\" Property=\"Opacity\" Value=\"0.2\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"ShuffleButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Padding\" Value=\"10\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource SidebarForegroundBrush}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ToggleButton\">\n                    <Grid x:Name=\"RootGrid\" Background=\"Transparent\">\n                        <Path x:Name=\"Icon\" Fill=\"{TemplateBinding Foreground}\" Opacity=\"0.5\" Stretch=\"Uniform\" HorizontalAlignment=\"Center\" Margin=\"{TemplateBinding Padding}\" Data=\"{StaticResource ShuffleIcon}\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                            <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"RepeatButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Padding\" Value=\"10\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource SidebarForegroundBrush}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ToggleButton\">\n                    <Grid x:Name=\"RootGrid\" Background=\"Transparent\">\n                        <Path x:Name=\"Icon\" Fill=\"{TemplateBinding Foreground}\" Opacity=\"0.5\" Stretch=\"Uniform\" HorizontalAlignment=\"Center\" Margin=\"{TemplateBinding Padding}\" Data=\"{StaticResource RepeatIcon}\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                            <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"VkStatusButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Padding\" Value=\"10\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ToggleButton\">\n                    <Grid x:Name=\"RootGrid\" Background=\"Transparent\">\n                        <Path x:Name=\"Icon\" Fill=\"{DynamicResource SidebarForegroundBrush}\" Opacity=\"0.5\" Stretch=\"Uniform\" HorizontalAlignment=\"Center\" Margin=\"{TemplateBinding Padding}\" Data=\"{StaticResource VkIcon}\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                            <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"LastFmScrobbleButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Padding\" Value=\"10\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ToggleButton\">\n                    <Grid x:Name=\"RootGrid\" Background=\"Transparent\">\n                        <Path x:Name=\"Icon\" Fill=\"{DynamicResource SidebarForegroundBrush}\" Opacity=\"0.5\" Stretch=\"Uniform\" HorizontalAlignment=\"Center\" Margin=\"{TemplateBinding Padding}\" Data=\"{StaticResource LastFmIcon}\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                            <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"Red\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <ControlTemplate x:Key=\"MuteButton\" TargetType=\"Button\">\n        <Grid Background=\"#00000000\">\n            <Path Name=\"Icon\" Data=\"{StaticResource VolumeMuteIcon}\" Fill=\"{DynamicResource SidebarForegroundBrush}\" Stretch=\"Uniform\" Opacity=\"0.7\"/>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n            </Trigger>\n            <!--<Trigger Property=\"IsChecked\" Value=\"True\">\n                <Setter TargetName=\"Icon\" Property=\"Data\" Value=\"{StaticResource VolumeMuteIcon}\"/>\n                <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"LightGray\"/>\n            </Trigger>-->\n            <Trigger Property=\"IsEnabled\" Value=\"False\">\n                <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n\n    <ControlTemplate x:Key=\"VolumeButton\" TargetType=\"Button\">\n        <Grid Background=\"#00000000\">\n            <Path Name=\"Icon\" Data=\"{StaticResource VolumeIcon}\" Fill=\"{DynamicResource SidebarForegroundBrush}\" Stretch=\"Uniform\" Opacity=\"0.7\"/>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n            </Trigger>\n            <!--<Trigger Property=\"IsChecked\" Value=\"True\">\n                <Setter TargetName=\"Icon\" Property=\"Data\" Value=\"{StaticResource VolumeMuteIcon}\"/>\n                <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"LightGray\"/>\n            </Trigger>-->\n            <Trigger Property=\"IsEnabled\" Value=\"False\">\n                <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n\n    <Style x:Key=\"LikeDislikeButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ToggleButton\">\n                    <Grid Name=\"RootGrid\" Background=\"Transparent\">\n                        <Path x:Name=\"Icon\" Fill=\"{DynamicResource AccentBrush}\" Opacity=\"0.7\" Stretch=\"Uniform\" HorizontalAlignment=\"Center\" Margin=\"{TemplateBinding Padding}\" Data=\"{StaticResource LikeIcon}\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Data\" Value=\"{StaticResource DislikeIcon}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"LyricsButtonStyle\" TargetType=\"Button\">\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"Button\">\n                    <Grid Name=\"RootGrid\" Background=\"Transparent\">\n                        <Path x:Name=\"Icon\" Fill=\"{DynamicResource AccentBrush}\" Opacity=\"0.7\" Stretch=\"Uniform\" HorizontalAlignment=\"Center\" Margin=\"{TemplateBinding Padding}\" Data=\"{StaticResource LyricsIcon}\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"EditButtonStyle\" TargetType=\"Button\">\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"Button\">\n                    <Grid Name=\"RootGrid\" Background=\"Transparent\">\n                        <Path x:Name=\"Icon\" Fill=\"{DynamicResource AccentBrush}\" Opacity=\"0.7\" Stretch=\"Uniform\" HorizontalAlignment=\"Center\" Margin=\"{TemplateBinding Padding}\" Data=\"{StaticResource EditIcon}\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"ShareIconButtonStyle\" TargetType=\"Button\">\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"Button\">\n                    <Grid Name=\"RootGrid\" Background=\"Transparent\">\n                        <Path x:Name=\"Icon\" Fill=\"{DynamicResource AccentBrush}\" Opacity=\"0.7\" Stretch=\"Uniform\" HorizontalAlignment=\"Center\" Margin=\"{TemplateBinding Padding}\" Data=\"{StaticResource ShareIcon}\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"PlayButtonStyle\" TargetType=\"Button\">\n        <Setter Property=\"Foreground\" Value=\"Black\"/>\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"Button\">\n                    <Grid Name=\"RootGrid\">\n                        <Ellipse x:Name=\"Base\" Stretch=\"Fill\" Fill=\"Transparent\" Stroke=\"{TemplateBinding Foreground}\" StrokeThickness=\"2\"/>\n                        <Viewbox>\n                            <Path x:Name=\"Icon\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Margin=\"15\" HorizontalAlignment=\"Center\" Data=\"{StaticResource PrevIcon}\"/>\n                        </Viewbox>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"True\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"Icon\" Property=\"Fill\" Value=\"{DynamicResource ControlButtonBackground}\"/>\n                            <Setter TargetName=\"Base\" Property=\"Fill\" Value=\"{DynamicResource ControlButtonForeground}\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"False\" />\n                            </MultiTrigger.Conditions>\n                            <Setter TargetName=\"Base\" Property=\"Fill\" Value=\"{DynamicResource ControlButtonOverBackground}\"/>\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"RootGrid\" Property=\"Opacity\" Value=\"0.2\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/ButtonStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Style x:Key=\"CommonButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Background\" Value=\"{DynamicResource ButtonBackgroundBrush}\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{DynamicResource ButtonBorderBrush}\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ButtonForegroundBrush}\"/>\n        <Setter Property=\"FontSize\" Value=\"12\"/>\n        <Setter Property=\"Padding\" Value=\"25,3,25,3\"/>\n        <Setter Property=\"BorderThickness\" Value=\"1\"/>\n        <Setter Property=\"FontWeight\" Value=\"SemiBold\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsDefaulted\" Value=\"true\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{DynamicResource ButtonHotBackgroundBrush}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsPressed\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{DynamicResource ButtonPressBackgroundBrush}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"Transparent\"/>\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"contentPresenter\" Value=\"{DynamicResource ButtonPressForegroundBrush}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"HighlightedButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Background\" Value=\"{DynamicResource AccentBrush}\"/>\n        <Setter Property=\"Foreground\" Value=\"White\"/>\n        <Setter Property=\"FontSize\" Value=\"12\"/>\n        <Setter Property=\"Padding\" Value=\"25,3,25,3\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"FontWeight\" Value=\"SemiBold\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"True\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsDefaulted\" Value=\"true\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{DynamicResource ButtonHighlightedDisabledBackgroundBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{DynamicResource ButtonHighlightedHotBackgroundBrush}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsPressed\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{DynamicResource ButtonPressBackgroundBrush}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource ButtonPressBackgroundBrush}\"/>\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"contentPresenter\" Value=\"{DynamicResource ButtonPressForegroundBrush}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"LastFmHighlightedButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Background\" Value=\"#e51400\"/>\n        <Setter Property=\"Foreground\" Value=\"White\"/>\n        <Setter Property=\"FontSize\" Value=\"12\"/>\n        <Setter Property=\"Padding\" Value=\"25,3,25,3\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"FontWeight\" Value=\"SemiBold\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"True\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsDefaulted\" Value=\"true\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"LightGray\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"#ff1600\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"#e51400\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsPressed\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{DynamicResource ButtonPressBackgroundBrush}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource ButtonPressBackgroundBrush}\"/>\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"contentPresenter\" Value=\"{DynamicResource ButtonPressForegroundBrush}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"HeaderButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Background\" Value=\"Transparent\" />\n        <Setter Property=\"BorderThickness\" Value=\"0\" />\n        <Setter Property=\"FontSize\" Value=\"28\" />\n        <Setter Property=\"FontWeight\" Value=\"Thin\" />\n        <Setter Property=\"Margin\" Value=\"5,10,0,10\"/>\n        <Setter Property=\"Opacity\" Value=\"1\" />\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\" />\n        <Setter Property=\"HorizontalAlignment\" Value=\"Left\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ToggleButton}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                        <StackPanel Orientation=\"Horizontal\">\n                            <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                            <Path x:Name=\"DropDownIcon\" Data=\"{StaticResource ChevronDown}\" Height=\"8\" Width=\"14\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Fill\" VerticalAlignment=\"Center\" Margin=\"7,8,5,0\" SnapsToDevicePixels=\"False\"/>\n                        </StackPanel>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"DropDownIcon\" Property=\"Visibility\" Value=\"Collapsed\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"CurrentAudioMenuButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Background\" Value=\"Transparent\" />\n        <Setter Property=\"BorderThickness\" Value=\"0\" />\n        <Setter Property=\"FontSize\" Value=\"28\" />\n        <Setter Property=\"FontWeight\" Value=\"Thin\" />\n        <Setter Property=\"Padding\" Value=\"25,3,0,3\"/>\n        <Setter Property=\"Margin\" Value=\"-25,7,0,0\"/>\n        <Setter Property=\"Opacity\" Value=\"1\" />\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\" />\n        <Setter Property=\"HorizontalAlignment\" Value=\"Stretch\" />\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Left\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ToggleButton}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\" Opacity=\"0.90\">\n                        <StackPanel Orientation=\"Horizontal\">\n                            <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                            <Path x:Name=\"DropDownIcon\" Data=\"{StaticResource ChevronDown}\" Height=\"8\" Width=\"12\" Fill=\"{DynamicResource SidebarForegroundBrush}\" Stretch=\"Fill\" VerticalAlignment=\"Top\" Margin=\"10,10,0,0\" SnapsToDevicePixels=\"False\" HorizontalAlignment=\"Left\"\n                                  Visibility=\"Collapsed\"/>\n                        </StackPanel>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <!--<Setter Property=\"Background\" Value=\"{DynamicResource MainMenuHotPlaylistItemBackgroundBrush}\"/>-->\n                            <Setter Property=\"Visibility\" TargetName=\"DropDownIcon\" Value=\"Visible\" />\n                            <Setter Property=\"Opacity\" TargetName=\"border\" Value=\"1\" />\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"DropDownIcon\" Property=\"Visibility\" Value=\"Collapsed\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/CheckBoxStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <SolidColorBrush x:Key=\"OptionMark.Static.Background\" Color=\"#FFFFFFFF\"/>\n    <SolidColorBrush x:Key=\"OptionMark.Static.Border\" Color=\"#FF707070\"/>\n    <Style x:Key=\"OptionMarkFocusVisual\">\n        <Setter Property=\"Control.Template\">\n            <Setter.Value>\n                <ControlTemplate>\n                    <Rectangle Margin=\"14,0,0,0\" SnapsToDevicePixels=\"true\" Stroke=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\" StrokeThickness=\"1\" StrokeDashArray=\"1 2\"/>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <SolidColorBrush x:Key=\"OptionMark.MouseOver.Background\" Color=\"#FFF3F9FF\"/>\n    <SolidColorBrush x:Key=\"OptionMark.MouseOver.Border\" Color=\"{DynamicResource AccentColor}\"/>\n    <SolidColorBrush x:Key=\"OptionMark.MouseOver.Glyph\" Color=\"#FF212121\"/>\n    <SolidColorBrush x:Key=\"OptionMark.Disabled.Background\" Color=\"#FFE6E6E6\"/>\n    <SolidColorBrush x:Key=\"OptionMark.Disabled.Border\" Color=\"#FFBCBCBC\"/>\n    <SolidColorBrush x:Key=\"OptionMark.Disabled.Glyph\" Color=\"#FF707070\"/>\n    <SolidColorBrush x:Key=\"OptionMark.Pressed.Background\" Color=\"#FFD9ECFF\"/>\n    <SolidColorBrush x:Key=\"OptionMark.Pressed.Border\" Color=\"{DynamicResource AccentColor}\"/>\n    <SolidColorBrush x:Key=\"OptionMark.Pressed.Glyph\" Color=\"#FF212121\"/>\n    <SolidColorBrush x:Key=\"OptionMark.Static.Glyph\" Color=\"#FF212121\"/>\n\n    <Style x:Key=\"CommonCheckBoxStyle\" TargetType=\"{x:Type CheckBox}\">\n        <Setter Property=\"FocusVisualStyle\" Value=\"{StaticResource FocusVisual}\"/>\n        <Setter Property=\"Background\" Value=\"{StaticResource OptionMark.Static.Background}\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{StaticResource OptionMark.Static.Border}\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\"/>\n        <Setter Property=\"BorderThickness\" Value=\"1\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type CheckBox}\">\n                    <Grid x:Name=\"templateRoot\" Background=\"Transparent\" SnapsToDevicePixels=\"True\">\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"Auto\"/>\n                            <ColumnDefinition Width=\"*\"/>\n                        </Grid.ColumnDefinitions>\n                        <Border x:Name=\"checkBoxBorder\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"1\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\">\n                            <Grid x:Name=\"markGrid\">\n                                <Path x:Name=\"optionMark\" Data=\"F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z \" Fill=\"{StaticResource OptionMark.Static.Glyph}\" Margin=\"1\" Opacity=\"0\" Stretch=\"None\"/>\n                                <Rectangle x:Name=\"indeterminateMark\" Fill=\"{StaticResource OptionMark.Static.Glyph}\" Margin=\"2\" Opacity=\"0\"/>\n                            </Grid>\n                        </Border>\n                        <ContentPresenter x:Name=\"contentPresenter\" Grid.Column=\"1\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"HasContent\" Value=\"true\">\n                            <Setter Property=\"FocusVisualStyle\" Value=\"{StaticResource OptionMarkFocusVisual}\"/>\n                            <Setter Property=\"Padding\" Value=\"4,-1,0,0\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"checkBoxBorder\" Value=\"{StaticResource OptionMark.MouseOver.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"checkBoxBorder\" Value=\"{StaticResource OptionMark.MouseOver.Border}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"optionMark\" Value=\"{StaticResource OptionMark.MouseOver.Glyph}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"indeterminateMark\" Value=\"{StaticResource OptionMark.MouseOver.Glyph}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"false\">\n                            <Setter Property=\"Background\" TargetName=\"checkBoxBorder\" Value=\"{StaticResource OptionMark.Disabled.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"checkBoxBorder\" Value=\"{StaticResource OptionMark.Disabled.Border}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"optionMark\" Value=\"{StaticResource OptionMark.Disabled.Glyph}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"indeterminateMark\" Value=\"{StaticResource OptionMark.Disabled.Glyph}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsPressed\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"checkBoxBorder\" Value=\"{StaticResource OptionMark.Pressed.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"checkBoxBorder\" Value=\"{StaticResource OptionMark.Pressed.Border}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"optionMark\" Value=\"{StaticResource OptionMark.Pressed.Glyph}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"indeterminateMark\" Value=\"{StaticResource OptionMark.Pressed.Glyph}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsChecked\" Value=\"true\">\n                            <Setter Property=\"Opacity\" TargetName=\"optionMark\" Value=\"1\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"indeterminateMark\" Value=\"0\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsChecked\" Value=\"{x:Null}\">\n                            <Setter Property=\"Opacity\" TargetName=\"optionMark\" Value=\"0\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"indeterminateMark\" Value=\"1\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/ComboBoxStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <SolidColorBrush x:Key=\"ComboBox.Static.Background\" Color=\"#FFE5E5E5\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Static.Border\" Color=\"#FFACACAC\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Static.Editable.Background\" Color=\"#FFFFFFFF\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Static.Editable.Border\" Color=\"#FFABADB3\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Static.Editable.Button.Background\" Color=\"Transparent\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Static.Editable.Button.Border\" Color=\"Transparent\"/>\n    <SolidColorBrush x:Key=\"ComboBox.MouseOver.Glyph\" Color=\"#FF000000\"/>\n    <SolidColorBrush x:Key=\"ComboBox.MouseOver.Background\" Color=\"#FFDCECFC\" />\n\n    <SolidColorBrush x:Key=\"ComboBox.MouseOver.Border\" Color=\"#FF7EB4EA\"/>\n    <SolidColorBrush x:Key=\"ComboBox.MouseOver.Editable.Background\" Color=\"#FFFFFFFF\"/>\n    <SolidColorBrush x:Key=\"ComboBox.MouseOver.Editable.Border\" Color=\"#FF7EB4EA\"/>\n    <LinearGradientBrush x:Key=\"ComboBox.MouseOver.Editable.Button.Background\" EndPoint=\"0,1\" StartPoint=\"0,0\">\n        <GradientStop Color=\"#FFEBF4FC\" Offset=\"0.0\"/>\n        <GradientStop Color=\"#FFDCECFC\" Offset=\"1.0\"/>\n    </LinearGradientBrush>\n    <SolidColorBrush x:Key=\"ComboBox.MouseOver.Editable.Button.Border\" Color=\"#FF7EB4EA\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Pressed.Glyph\" Color=\"#FF000000\"/>\n    <LinearGradientBrush x:Key=\"ComboBox.Pressed.Background\" EndPoint=\"0,1\" StartPoint=\"0,0\">\n        <GradientStop Color=\"#FFDAECFC\" Offset=\"0.0\"/>\n        <GradientStop Color=\"#FFC4E0FC\" Offset=\"1.0\"/>\n    </LinearGradientBrush>\n    <SolidColorBrush x:Key=\"ComboBox.Pressed.Border\" Color=\"#FF569DE5\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Pressed.Editable.Background\" Color=\"#FFFFFFFF\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Pressed.Editable.Border\" Color=\"#FF569DE5\"/>\n    <LinearGradientBrush x:Key=\"ComboBox.Pressed.Editable.Button.Background\" EndPoint=\"0,1\" StartPoint=\"0,0\">\n        <GradientStop Color=\"#FFDAEBFC\" Offset=\"0.0\"/>\n        <GradientStop Color=\"#FFC4E0FC\" Offset=\"1.0\"/>\n    </LinearGradientBrush>\n    <SolidColorBrush x:Key=\"ComboBox.Pressed.Editable.Button.Border\" Color=\"#FF569DE5\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Disabled.Glyph\" Color=\"#FFBFBFBF\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Disabled.Background\" Color=\"#FFF0F0F0\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Disabled.Border\" Color=\"#FFD9D9D9\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Disabled.Editable.Background\" Color=\"#FFFFFFFF\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Disabled.Editable.Border\" Color=\"#FFBFBFBF\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Disabled.Editable.Button.Background\" Color=\"Transparent\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Disabled.Editable.Button.Border\" Color=\"Transparent\"/>\n    <SolidColorBrush x:Key=\"ComboBox.Static.Glyph\" Color=\"#FF606060\"/>\n    <Style x:Key=\"ComboBoxToggleButton\" TargetType=\"{x:Type ToggleButton}\">\n        <Setter Property=\"OverridesDefaultStyle\" Value=\"true\"/>\n        <Setter Property=\"IsTabStop\" Value=\"false\"/>\n        <Setter Property=\"Focusable\" Value=\"false\"/>\n        <Setter Property=\"ClickMode\" Value=\"Press\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ToggleButton}\">\n                    <Border x:Name=\"templateRoot\" BorderBrush=\"Transparent\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{DynamicResource ComboBoxBackgroundBrush}\" SnapsToDevicePixels=\"true\">\n                        <Border x:Name=\"splitBorder\" BorderBrush=\"Transparent\" BorderThickness=\"1\" HorizontalAlignment=\"Right\" Margin=\"0\" SnapsToDevicePixels=\"true\" Width=\"{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}\">\n                            <Path x:Name=\"arrow\" Data=\"F1 M 0,0 L 2.667,2.66665 L 5.3334,0 L 5.3334,-1.78168 L 2.6667,0.88501 L0,-1.78168 L0,0 Z\" Fill=\"{StaticResource ComboBox.Static.Glyph}\" HorizontalAlignment=\"Center\" Margin=\"0\" VerticalAlignment=\"Center\"/>\n                        </Border>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <!--<MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding IsMouseOver, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding IsPressed, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding IsEnabled, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"templateRoot\" Value=\"{StaticResource ComboBox.Static.Editable.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"templateRoot\" Value=\"{StaticResource ComboBox.Static.Editable.Border}\"/>\n                            <Setter Property=\"Background\" TargetName=\"splitBorder\" Value=\"{StaticResource ComboBox.Static.Editable.Button.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"splitBorder\" Value=\"{StaticResource ComboBox.Static.Editable.Button.Border}\"/>\n                        </MultiDataTrigger>-->\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Fill\" TargetName=\"arrow\" Value=\"{DynamicResource ComboBoxForegroundBrush}\"/>\n                        </Trigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsMouseOver, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}\" Value=\"false\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"BorderBrush\" TargetName=\"templateRoot\" Value=\"{DynamicResource ComboBoxHotBrush}\"/>\n                        </MultiDataTrigger>\n                        <Trigger Property=\"IsPressed\" Value=\"true\">\n                            <Setter Property=\"Fill\" TargetName=\"arrow\" Value=\"{StaticResource ComboBox.Pressed.Glyph}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsChecked\" Value=\"true\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"templateRoot\" Value=\"{DynamicResource ComboBoxHotBrush}\"/>\n                            <Setter Property=\"Background\" TargetName=\"templateRoot\" Value=\"{DynamicResource ComboBoxHotBackgroundBrush}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <ControlTemplate x:Key=\"ComboBoxTemplate\" TargetType=\"{x:Type ComboBox}\">\n        <Grid x:Name=\"templateRoot\" SnapsToDevicePixels=\"true\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"*\"/>\n                <ColumnDefinition MinWidth=\"{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}\" Width=\"0\"/>\n            </Grid.ColumnDefinitions>\n            <Popup x:Name=\"PART_Popup\" AllowsTransparency=\"true\" Grid.ColumnSpan=\"2\" VerticalOffset=\"-2\" IsOpen=\"{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}\" Margin=\"1\" PopupAnimation=\"{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}\" Placement=\"Bottom\">\n                <Border x:Name=\"shadow\" MaxHeight=\"{TemplateBinding MaxDropDownHeight}\" MinWidth=\"{Binding ActualWidth, ElementName=templateRoot}\">\n                    <Border x:Name=\"dropDownBorder\" BorderBrush=\"{DynamicResource ComboBoxHotBrush}\" BorderThickness=\"1,0,1,1\" Background=\"{DynamicResource ComboBoxHotBackgroundBrush}\">\n                        <ScrollViewer x:Name=\"DropDownScrollViewer\" Margin=\"0,2,0,0\">\n                            <Grid x:Name=\"grid\" RenderOptions.ClearTypeHint=\"Enabled\">\n                                <Canvas x:Name=\"canvas\" HorizontalAlignment=\"Left\" Height=\"0\" VerticalAlignment=\"Top\" Width=\"0\">\n                                    <Rectangle x:Name=\"opaqueRect\" Fill=\"{Binding Background, ElementName=dropDownBorder}\" Height=\"{Binding ActualHeight, ElementName=dropDownBorder}\" Width=\"{Binding ActualWidth, ElementName=dropDownBorder}\"/>\n                                </Canvas>\n                                <ItemsPresenter x:Name=\"ItemsPresenter\" KeyboardNavigation.DirectionalNavigation=\"Contained\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\"/>\n                            </Grid>\n                        </ScrollViewer>\n                    </Border>\n                </Border>\n            </Popup>\n            <ToggleButton x:Name=\"toggleButton\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Grid.ColumnSpan=\"2\" IsChecked=\"{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}\" Style=\"{StaticResource ComboBoxToggleButton}\"/>\n            <ContentPresenter x:Name=\"contentPresenter\" ContentTemplate=\"{TemplateBinding SelectionBoxItemTemplate}\" ContentTemplateSelector=\"{TemplateBinding ItemTemplateSelector}\" Content=\"{TemplateBinding SelectionBoxItem}\" ContentStringFormat=\"{TemplateBinding SelectionBoxItemStringFormat}\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" IsHitTestVisible=\"false\" Margin=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n        </Grid>\n        <ControlTemplate.Resources>\n            <Style TargetType=\"{x:Type ComboBoxItem}\">\n                <Setter Property=\"Focusable\" Value=\"False\" />\n                <Setter Property=\"Template\">\n                    <Setter.Value>\n                        <ControlTemplate TargetType=\"{x:Type ComboBoxItem}\">\n                            <Border x:Name=\"Border\" Background=\"{DynamicResource ComboBoxHotBackgroundBrush}\" Padding=\"6,4\">\n                                <ContentPresenter RenderOptions.ClearTypeHint=\"Enabled\" />\n                            </Border>\n                            <ControlTemplate.Triggers>\n                                <Trigger Property=\"IsHighlighted\" Value=\"True\">\n                                    <Setter TargetName=\"Border\" Property=\"Background\" Value=\"{DynamicResource ComboBoxItemHotBackgroundBrush}\"/>\n                                </Trigger>\n                                <Trigger Property=\"IsEnabled\" Value=\"False\">\n                                    <Setter TargetName=\"Border\" Property=\"Opacity\" Value=\"0.5\"/>\n                                </Trigger>\n                            </ControlTemplate.Triggers>\n                        </ControlTemplate>\n                    </Setter.Value>\n                </Setter>\n            </Style>\n        </ControlTemplate.Resources>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"HasItems\" Value=\"false\">\n                <Setter Property=\"Height\" TargetName=\"dropDownBorder\" Value=\"95\"/>\n            </Trigger>\n            <MultiTrigger>\n                <MultiTrigger.Conditions>\n                    <Condition Property=\"IsGrouping\" Value=\"true\"/>\n                    <Condition Property=\"VirtualizingPanel.IsVirtualizingWhenGrouping\" Value=\"false\"/>\n                </MultiTrigger.Conditions>\n                <Setter Property=\"ScrollViewer.CanContentScroll\" Value=\"false\"/>\n            </MultiTrigger>\n            <Trigger Property=\"ScrollViewer.CanContentScroll\" SourceName=\"DropDownScrollViewer\" Value=\"false\">\n                <Setter Property=\"Canvas.Top\" TargetName=\"opaqueRect\" Value=\"{Binding VerticalOffset, ElementName=DropDownScrollViewer}\"/>\n                <Setter Property=\"Canvas.Left\" TargetName=\"opaqueRect\" Value=\"{Binding HorizontalOffset, ElementName=DropDownScrollViewer}\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n    <SolidColorBrush x:Key=\"TextBox.Static.Background\" Color=\"#FFFFFFFF\"/>\n    <Style x:Key=\"ComboBoxEditableTextBox\" TargetType=\"{x:Type TextBox}\">\n        <Setter Property=\"OverridesDefaultStyle\" Value=\"true\"/>\n        <Setter Property=\"AllowDrop\" Value=\"true\"/>\n        <Setter Property=\"MinWidth\" Value=\"0\"/>\n        <Setter Property=\"MinHeight\" Value=\"0\"/>\n        <Setter Property=\"FocusVisualStyle\" Value=\"{x:Null}\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"VerticalFirst\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"CaretBrush\" Value=\"{DynamicResource ForegroundBrush}\" />\n        <Setter Property=\"SelectionBrush\" Value=\"{DynamicResource AccentBrush}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type TextBox}\">\n                    <ScrollViewer x:Name=\"PART_ContentHost\" Background=\"Transparent\" Focusable=\"false\" HorizontalScrollBarVisibility=\"Hidden\" VerticalScrollBarVisibility=\"Hidden\"/>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <ControlTemplate x:Key=\"ComboBoxEditableTemplate\" TargetType=\"{x:Type ComboBox}\">\n        <Grid x:Name=\"templateRoot\" SnapsToDevicePixels=\"true\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"*\"/>\n                <ColumnDefinition MinWidth=\"{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}\" Width=\"0\"/>\n            </Grid.ColumnDefinitions>\n            <Popup x:Name=\"PART_Popup\" AllowsTransparency=\"true\" Grid.ColumnSpan=\"2\" IsOpen=\"{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}\" PopupAnimation=\"{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}\" Placement=\"Bottom\">\n                <Border x:Name=\"shadow\" MaxHeight=\"{TemplateBinding MaxDropDownHeight}\" MinWidth=\"{Binding ActualWidth, ElementName=templateRoot}\">\n                    <Border x:Name=\"dropDownBorder\" BorderBrush=\"{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}\" BorderThickness=\"1\" Background=\"{DynamicResource ComboBoxHotBackgroundBrush}\">\n                        <ScrollViewer x:Name=\"DropDownScrollViewer\">\n                            <Grid x:Name=\"grid\" RenderOptions.ClearTypeHint=\"Enabled\">\n                                <Canvas x:Name=\"canvas\" HorizontalAlignment=\"Left\" Height=\"0\" VerticalAlignment=\"Top\" Width=\"0\">\n                                    <Rectangle x:Name=\"opaqueRect\" Fill=\"{Binding Background, ElementName=dropDownBorder}\" Height=\"{Binding ActualHeight, ElementName=dropDownBorder}\" Width=\"{Binding ActualWidth, ElementName=dropDownBorder}\"/>\n                                </Canvas>\n                                <ItemsPresenter x:Name=\"ItemsPresenter\" KeyboardNavigation.DirectionalNavigation=\"Contained\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\"/>\n                            </Grid>\n                        </ScrollViewer>\n                    </Border>\n                </Border>\n            </Popup>\n            <ToggleButton x:Name=\"toggleButton\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Grid.ColumnSpan=\"2\" IsChecked=\"{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}\" Style=\"{StaticResource ComboBoxToggleButton}\"/>\n            <Border x:Name=\"border\" Margin=\"{TemplateBinding BorderThickness}\">\n                <TextBox x:Name=\"PART_EditableTextBox\" HorizontalContentAlignment=\"{TemplateBinding HorizontalContentAlignment}\" IsReadOnly=\"{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}\" Margin=\"{TemplateBinding Padding}\" Style=\"{StaticResource ComboBoxEditableTextBox}\" VerticalContentAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n            </Border>\n        </Grid>\n        <ControlTemplate.Resources>\n            <Style TargetType=\"{x:Type ComboBoxItem}\">\n                <Setter Property=\"Focusable\" Value=\"False\" />\n                <Setter Property=\"Template\">\n                    <Setter.Value>\n                        <ControlTemplate TargetType=\"{x:Type ComboBoxItem}\">\n                            <Border x:Name=\"Border\" Background=\"{DynamicResource ComboBoxHotBackgroundBrush}\" Padding=\"6,4\">\n                                <ContentPresenter RenderOptions.ClearTypeHint=\"Enabled\" />\n                            </Border>\n                            <ControlTemplate.Triggers>\n                                <Trigger Property=\"IsHighlighted\" Value=\"True\">\n                                    <Setter TargetName=\"Border\" Property=\"Background\" Value=\"{DynamicResource ComboBoxItemHotBackgroundBrush}\"/>\n                                </Trigger>\n                                <Trigger Property=\"IsEnabled\" Value=\"False\">\n                                    <Setter TargetName=\"Border\" Property=\"Opacity\" Value=\"0.5\"/>\n                                </Trigger>\n                            </ControlTemplate.Triggers>\n                        </ControlTemplate>\n                    </Setter.Value>\n                </Setter>\n            </Style>\n        </ControlTemplate.Resources>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsEnabled\" Value=\"false\">\n                <Setter Property=\"Opacity\" TargetName=\"border\" Value=\"0.56\"/>\n            </Trigger>\n            <Trigger Property=\"IsKeyboardFocusWithin\" Value=\"true\">\n                <Setter Property=\"Foreground\" Value=\"Black\"/>\n            </Trigger>\n            <Trigger Property=\"HasItems\" Value=\"false\">\n                <Setter Property=\"Height\" TargetName=\"dropDownBorder\" Value=\"95\"/>\n            </Trigger>\n            <MultiTrigger>\n                <MultiTrigger.Conditions>\n                    <Condition Property=\"IsGrouping\" Value=\"true\"/>\n                    <Condition Property=\"VirtualizingPanel.IsVirtualizingWhenGrouping\" Value=\"false\"/>\n                </MultiTrigger.Conditions>\n                <Setter Property=\"ScrollViewer.CanContentScroll\" Value=\"false\"/>\n            </MultiTrigger>\n            <Trigger Property=\"ScrollViewer.CanContentScroll\" SourceName=\"DropDownScrollViewer\" Value=\"false\">\n                <Setter Property=\"Canvas.Top\" TargetName=\"opaqueRect\" Value=\"{Binding VerticalOffset, ElementName=DropDownScrollViewer}\"/>\n                <Setter Property=\"Canvas.Left\" TargetName=\"opaqueRect\" Value=\"{Binding HorizontalOffset, ElementName=DropDownScrollViewer}\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n    <Style x:Key=\"CommonComboBoxStyle\" TargetType=\"{x:Type ComboBox}\">\n        <Setter Property=\"FocusVisualStyle\" Value=\"{StaticResource FocusVisual}\"/>\n        <Setter Property=\"Background\" Value=\"{DynamicResource BackgroundBrush}\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{StaticResource ComboBox.Static.Border}\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ComboBoxForegroundBrush}\"/>\n        <Setter Property=\"BorderThickness\" Value=\"1\"/>\n        <Setter Property=\"ScrollViewer.HorizontalScrollBarVisibility\" Value=\"Auto\"/>\n        <Setter Property=\"ScrollViewer.VerticalScrollBarVisibility\" Value=\"Auto\"/>\n        <Setter Property=\"Padding\" Value=\"7,5,5,5\"/>\n        <Setter Property=\"ScrollViewer.CanContentScroll\" Value=\"true\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"Both\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"Template\" Value=\"{StaticResource ComboBoxTemplate}\"/>\n        <Style.Triggers>\n            <Trigger Property=\"IsEditable\" Value=\"true\">\n                <Setter Property=\"IsTabStop\" Value=\"false\"/>\n                <Setter Property=\"Padding\" Value=\"2\"/>\n                <Setter Property=\"Template\" Value=\"{StaticResource ComboBoxEditableTemplate}\"/>\n            </Trigger>\n        </Style.Triggers>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/ContextMenuStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n\n\n    <Style TargetType=\"{x:Type MenuItem}\">\n        <Setter Property=\"OverridesDefaultStyle\" Value=\"True\"/>\n        <Setter Property=\"Foreground\" Value=\"Black\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"FontFamily\" Value=\"Segoe UI\"/>\n        <Setter Property=\"FontSize\" Value=\"14\"/>\n        <Setter Property=\"FontWeight\" Value=\"Regular\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"Both\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"Margin\" Value=\"0,1,0,1\"/>\n        <Setter Property=\"Padding\" Value=\"0,5,0,5\"/>\n        <Setter Property=\"Focusable\" Value=\"False\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type MenuItem}\">\n                    <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"True\" Uid=\"Border_38\">\n                        <Grid x:Name=\"Grid\" Uid=\"Grid_49\">\n                            <Grid.ColumnDefinitions>\n                                <ColumnDefinition MinWidth=\"17\" SharedSizeGroup=\"MenuItemIconColumnGroup\" Width=\"Auto\"/>\n                                <ColumnDefinition Width=\"*\"/>\n                                <ColumnDefinition SharedSizeGroup=\"MenuItemIGTColumnGroup\" Width=\"Auto\"/>\n                                <ColumnDefinition Width=\"14\"/>\n                            </Grid.ColumnDefinitions>\n                            <Path x:Name=\"GlyphPanel\" Data=\"M0,2L0,4.8 2.5,7.4 7.1,2.8 7.1,0 2.5,4.6z\" Fill=\"{TemplateBinding Foreground}\" FlowDirection=\"LeftToRight\" Margin=\"4,0,6,0\" Uid=\"Path_12\" Visibility=\"Hidden\" VerticalAlignment=\"Center\"/>\n                            <ContentPresenter x:Name=\"ContentPresenter\" ContentTemplate=\"{TemplateBinding HeaderTemplate}\" Content=\"{TemplateBinding Header}\" Grid.Column=\"1\" ContentSource=\"Header\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" Uid=\"ContentPresenter_33\"/>\n                            <TextBlock x:Name=\"InputGestureText\" Grid.Column=\"2\" DockPanel.Dock=\"Right\" Margin=\"5,2,0,2\" Text=\"{TemplateBinding InputGestureText}\" Uid=\"TextBlock_10\"/>\n                        </Grid>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                    <!--<ControlTemplate.Triggers>\n                                <Trigger Property=\"IsChecked\" Value=\"True\">\n                                    <Setter Property=\"Visibility\" TargetName=\"GlyphPanel\" Value=\"Visible\"/>\n                                </Trigger>\n                                <DataTrigger Value=\"False\">\n                                    <DataTrigger.Binding>\n                                        <Binding ElementName=\"MenuItemIcon\" Path=\"Source\"/>\n                                    </DataTrigger.Binding>\n                                    <Setter Property=\"VerticalAlignment\" TargetName=\"ContentPresenter\" Value=\"Center\"/>\n                                </DataTrigger>\n                            </ControlTemplate.Triggers>-->\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n        <Style.Triggers>\n            <Trigger Property=\"Role\" Value=\"TopLevelHeader\">\n                <Setter Property=\"Margin\" Value=\"0,1\"/>\n                <Setter Property=\"Padding\" Value=\"6,0\"/>\n                <Setter Property=\"Template\">\n                    <Setter.Value>\n                        <ControlTemplate TargetType=\"{x:Type MenuItem}\">\n                            <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"True\" Uid=\"Border_39\">\n                                <DockPanel x:Name=\"DockPanel\" Uid=\"DockPanel_4\">\n                                    <Path x:Name=\"GlyphPanel\" Data=\"M0,2L0,4.8 2.5,7.4 7.1,2.8 7.1,0 2.5,4.6z\" Fill=\"{TemplateBinding Foreground}\" FlowDirection=\"LeftToRight\" Margin=\"4,0,6,0\" Uid=\"Path_13\" Visibility=\"Collapsed\" VerticalAlignment=\"Center\"/>\n                                    <ContentPresenter x:Name=\"ContentPresenter\" ContentTemplate=\"{TemplateBinding HeaderTemplate}\" Content=\"{TemplateBinding Header}\" ContentSource=\"Header\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" Uid=\"ContentPresenter_35\"/>\n                                </DockPanel>\n                            </Border>\n                            <ControlTemplate.Triggers>\n                                <!--<Trigger Property=\"IsSuspendingPopupAnimation\" Value=\"True\">\n                                            <Setter Property=\"PopupAnimation\" TargetName=\"PART_Popup\" Value=\"None\"/>\n                                        </Trigger>-->\n                                <Trigger Property=\"IsChecked\" Value=\"True\">\n                                    <Setter Property=\"Visibility\" TargetName=\"GlyphPanel\" Value=\"Visible\"/>\n                                </Trigger>\n                            </ControlTemplate.Triggers>\n                        </ControlTemplate>\n                    </Setter.Value>\n                </Setter>\n            </Trigger>\n            <Trigger Property=\"Role\" Value=\"TopLevelItem\">\n                <Setter Property=\"Margin\" Value=\"0,1\"/>\n                <Setter Property=\"Padding\" Value=\"6,3\"/>\n                <Setter Property=\"Template\">\n                    <Setter.Value>\n                        <ControlTemplate TargetType=\"{x:Type MenuItem}\">\n                            <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"True\" Uid=\"Border_41\">\n                                <DockPanel x:Name=\"DockPanel\" Uid=\"DockPanel_5\">\n                                    <Path x:Name=\"GlyphPanel\" Data=\"M0,2L0,4.8 2.5,7.4 7.1,2.8 7.1,0 2.5,4.6z\" Fill=\"{TemplateBinding Foreground}\" FlowDirection=\"LeftToRight\" Margin=\"4,0,6,0\" Uid=\"Path_14\" Visibility=\"Collapsed\" VerticalAlignment=\"Center\"/>\n                                    <ContentPresenter x:Name=\"ContentPresenter\" ContentTemplate=\"{TemplateBinding HeaderTemplate}\" Content=\"{TemplateBinding Header}\" ContentSource=\"Header\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" Uid=\"ContentPresenter_37\"/>\n                                </DockPanel>\n                            </Border>\n                            <ControlTemplate.Triggers>\n                                <Trigger Property=\"IsChecked\" Value=\"True\">\n                                    <Setter Property=\"Visibility\" TargetName=\"GlyphPanel\" Value=\"Visible\"/>\n                                </Trigger>\n                            </ControlTemplate.Triggers>\n                        </ControlTemplate>\n                    </Setter.Value>\n                </Setter>\n            </Trigger>\n            <Trigger Property=\"Role\" Value=\"SubmenuHeader\">\n                <Setter Property=\"DockPanel.Dock\" Value=\"Top\"/>\n                <Setter Property=\"Padding\" Value=\"0,2\"/>\n                <Setter Property=\"Template\">\n                    <Setter.Value>\n                        <ControlTemplate TargetType=\"{x:Type MenuItem}\">\n                            <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"True\" Uid=\"Border_42\">\n                                <Grid x:Name=\"Grid\" Uid=\"Grid_50\">\n                                    <Grid.ColumnDefinitions>\n                                        <ColumnDefinition MinWidth=\"17\" SharedSizeGroup=\"MenuItemIconColumnGroup\" Width=\"Auto\"/>\n                                        <ColumnDefinition Width=\"*\"/>\n                                        <ColumnDefinition MinWidth=\"5\" SharedSizeGroup=\"MenuItemIGTColumnGroup\" Width=\"Auto\"/>\n                                        <ColumnDefinition Width=\"14\"/>\n                                    </Grid.ColumnDefinitions>\n                                    <Path x:Name=\"GlyphPanel\" Data=\"M0,2L0,4.8 2.5,7.4 7.1,2.8 7.1,0 2.5,4.6z\" Fill=\"{TemplateBinding Foreground}\" FlowDirection=\"LeftToRight\" Margin=\"4,0,6,0\" Uid=\"Path_15\" Visibility=\"Hidden\" VerticalAlignment=\"Center\"/>\n                                    <ContentPresenter x:Name=\"ContentPresenter\" ContentTemplate=\"{TemplateBinding HeaderTemplate}\" Content=\"{TemplateBinding Header}\" Grid.Column=\"1\" ContentSource=\"Header\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" Uid=\"ContentPresenter_39\"/>\n                                    <Path x:Name=\"Path\" Grid.Column=\"3\" DockPanel.Dock=\"Right\" Data=\"M0,0L4,3.5 0,7z\" Fill=\"{TemplateBinding Foreground}\" Margin=\"4,0,6,0\" Uid=\"Path_16\" VerticalAlignment=\"Center\"/>\n                                </Grid>\n                            </Border>\n                            <ControlTemplate.Triggers>\n                                <!--<Trigger Property=\"IsSuspendingPopupAnimation\" Value=\"True\">\n                                            <Setter Property=\"PopupAnimation\" TargetName=\"PART_Popup\" Value=\"None\"/>\n                                        </Trigger>-->\n                                <Trigger Property=\"IsChecked\" Value=\"True\">\n                                    <Setter Property=\"Visibility\" TargetName=\"GlyphPanel\" Value=\"Visible\"/>\n                                </Trigger>\n                            </ControlTemplate.Triggers>\n                        </ControlTemplate>\n                    </Setter.Value>\n                </Setter>\n            </Trigger>\n            <Trigger Property=\"Role\" Value=\"SubmenuItem\">\n                <Setter Property=\"DockPanel.Dock\" Value=\"Top\"/>\n                <Setter Property=\"Padding\" Value=\"0,2\"/>\n            </Trigger>\n            <Trigger Property=\"IsHighlighted\" Value=\"True\">\n                <Setter Property=\"Background\" Value=\"{DynamicResource HotContextMenuItemBackgroundBrush}\"/>\n            </Trigger>\n            <!--<Trigger Property=\"IsEnabled\" Value=\"False\">\n                        <Setter Property=\"Foreground\" Value=\"{DynamicResource ListItemDisabledForegroundBrush}\"/>\n                    </Trigger>-->\n        </Style.Triggers>\n    </Style>\n\n    <Style x:Key=\"CommonSeparatorStyle\" TargetType=\"{x:Type Separator}\">\n        <Style.BasedOn>\n            <Style TargetType=\"{x:Type Separator}\">\n                <Setter Property=\"OverridesDefaultStyle\" Value=\"True\"/>\n                <Setter Property=\"Height\" Value=\"1\"/>\n                <Setter Property=\"Margin\" Value=\"18,2\"/>\n                <Setter Property=\"Focusable\" Value=\"False\"/>\n                <Setter Property=\"UseLayoutRounding\" Value=\"True\"/>\n                <Setter Property=\"SnapsToDevicePixels\" Value=\"True\" />\n                <Setter Property=\"Template\">\n                    <Setter.Value>\n                        <ControlTemplate TargetType=\"{x:Type Separator}\">\n                            <Border Background=\"Black\" Uid=\"Border_28\" Opacity=\"0.2\"/>\n                        </ControlTemplate>\n                    </Setter.Value>\n                </Setter>\n            </Style>\n        </Style.BasedOn>\n    </Style>\n\n    <Style x:Key=\"CommonContextMenuStyle\" TargetType=\"{x:Type ContextMenu}\">\n        <Setter Property=\"OverridesDefaultStyle\" Value=\"True\"/>\n        <Setter Property=\"Background\" Value=\"White\"/>\n        <Setter Property=\"BorderThickness\" Value=\"1\"/>\n        <Setter Property=\"BorderBrush\" Value=\"#a0a0a0\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Center\"/>\n        <Setter Property=\"Padding\" Value=\"0,2,0,2\"/>\n        <Setter Property=\"Grid.IsSharedSizeScope\" Value=\"True\"/>\n        <Setter Property=\"HasDropShadow\" Value=\"{DynamicResource {x:Static SystemParameters.DropShadowKey}}\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"Both\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"FontFamily\" Value=\"{DynamicResource {x:Static SystemFonts.MessageFontFamilyKey}}\"/>\n        <Setter Property=\"FontSize\" Value=\"{DynamicResource {x:Static SystemFonts.MessageFontSizeKey}}\"/>\n        <Setter Property=\"FontWeight\" Value=\"{DynamicResource {x:Static SystemFonts.MessageFontWeightKey}}\"/>\n        <Setter Property=\"MinWidth\" Value=\"185\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ContextMenu}\">\n                    <Border Uid=\"Border_93\">\n                        <Border.Style>\n                            <Style TargetType=\"{x:Type Border}\">\n                                <Setter Property=\"Tag\" Value=\"{DynamicResource {x:Static SystemParameters.DropShadowKey}}\"/>\n                                <Style.Triggers>\n                                    <DataTrigger Binding=\"{Binding Tag, RelativeSource={RelativeSource Self}}\" Value=\"True\">\n                                        <Setter Property=\"Background\" Value=\"Transparent\"/>\n                                        <Setter Property=\"Padding\" Value=\"0,0,0,0\"/>\n                                    </DataTrigger>\n                                </Style.Triggers>\n                            </Style>\n                        </Border.Style>\n                        <Border BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Uid=\"Border_50\">\n                            <ScrollViewer CanContentScroll=\"True\" Style=\"{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}\" Uid=\"ScrollViewer_9\">\n                                <ItemsPresenter KeyboardNavigation.DirectionalNavigation=\"Cycle\" Margin=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" Uid=\"ItemsPresenter_5\"/>\n                            </ScrollViewer>\n                        </Border>\n                    </Border>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/DataTemplates.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n                    xmlns:converters=\"clr-namespace:Neptune.UI.Converters;assembly=Neptune.Desktop\">\n\n    <converters:BooleanToObjectConverter x:Key=\"LikeDislikeTooltipConverter\" FalseObject=\"{x:Static localization:MainResources.ContextMenuAdd}\"\n                                         TrueObject=\"{x:Static localization:MainResources.ContextMenuRemove}\"/>\n\n    <DataTemplate x:Key=\"AudioItemTemplate\">\n        <Button x:Name=\"RootElement\" Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.PlayAudioCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\"\n                Padding=\"0,5,0,5\" Height=\"32\">\n            <Button.RenderTransform>\n                <TranslateTransform />\n            </Button.RenderTransform>\n            <Button.Triggers>\n                <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                    <BeginStoryboard Storyboard=\"{StaticResource AudioLoadAnim}\" />\n                </EventTrigger>\n            </Button.Triggers>\n            <Button.ContextMenu>\n                <ContextMenu Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAdd}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuEdit}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}}\" Command=\"{Binding Main.EditAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuRemove}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuShare}\" Command=\"{Binding Main.ShareAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuLyrics}\" IsEnabled=\"{Binding HasLyrics}\" Command=\"{Binding Main.ShowLyricsCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <!--<MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAddToAlbum}\" Command=\"{Binding Main.AddToAlbumCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>-->\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuShowArtistInfo}\" Command=\"{Binding Main.ShowArtistInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" />\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuSearchArtist}\" Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" />\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding Main.AddToNowPlayingCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuPlayNext}\" Command=\"{Binding Main.PlayAudioNextCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuCopyInfo}\" Command=\"{Binding Main.CopyInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                </ContextMenu>\n            </Button.ContextMenu>\n            <Grid Background=\"Transparent\" VerticalAlignment=\"Center\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"12\"/>\n                    <ColumnDefinition Width=\"0.5*\" MaxWidth=\"500\"/>\n                    <ColumnDefinition Width=\"0.3*\"/>\n                    <ColumnDefinition Width=\"0.2*\"/>\n                </Grid.ColumnDefinitions>\n\n                <TextBlock Grid.Column=\"1\" x:Name=\"Title\" Text=\"{Binding Title}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"13\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Title}\" Margin=\"0,0,5,0\"/>\n                <Button Style=\"{StaticResource SimpleButtonStyle}\" Grid.Column=\"2\" HorizontalAlignment=\"Left\" Opacity=\"0.6\" Margin=\"0,0,0,0\" Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\"\n                        CommandParameter=\"{Binding Artist}\">\n                    <TextBlock x:Name=\"Artist\" Text=\"{Binding Artist}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"13\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Artist}\"/>\n                </Button>\n                <TextBlock x:Name=\"Duration\" Grid.Column=\"3\" Text=\"{Binding Duration, Converter={StaticResource AudioTimeSpanConverter}}\" Foreground=\"{DynamicResource ForegroundBrush}\" Visibility=\"{Binding Duration.TotalSeconds, Converter={StaticResource NullToVisibilityConverter}}\"\n                           HorizontalAlignment=\"Right\" Opacity=\"0.6\" FontSize=\"12\" VerticalAlignment=\"Center\" Margin=\"0,0,24,0\" TextTrimming=\"CharacterEllipsis\"/>\n                <StackPanel x:Name=\"ToolbarPanel\"  Grid.Column=\"3\" HorizontalAlignment=\"Right\" Margin=\"0,-2,24,-2\" Opacity=\"0\" Orientation=\"Horizontal\" VerticalAlignment=\"Center\">\n                    <Button Style=\"{StaticResource AddButtonStyle}\" Width=\"22\" Height=\"20\" Padding=\"4\"\n                            Command=\"{Binding Main.AddToNowPlayingCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\" Margin=\"0,0,0,0\"\n                            ToolTip=\"{x:Static localization:MainResources.ContextMenuAddToNowPlaying}\" Foreground=\"{DynamicResource AccentBrush}\"/>\n\n                    <Button Style=\"{StaticResource LyricsButtonStyle}\" Width=\"22\" Height=\"20\" Padding=\"4\" Visibility=\"{Binding HasLyrics, Converter={StaticResource BoolToVisibilityConverter}}\"\n                            Command=\"{Binding Main.ShowLyricsCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\" Margin=\"5,0,0,0\"\n                            ToolTip=\"{x:Static localization:MainResources.ContextMenuLyrics}\"/>\n\n                    <Button Style=\"{StaticResource EditButtonStyle}\" Width=\"22\" Height=\"20\" Padding=\"4\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}}\"\n                            Command=\"{Binding Main.EditAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\" Margin=\"5,0,0,0\"\n                            ToolTip=\"{x:Static localization:MainResources.ContextMenuEdit}\"/>\n\n                    <ToggleButton x:Name=\"LikeDislikeButton\" Style=\"{StaticResource LikeDislikeButtonStyle}\" Width=\"22\" Height=\"20\" Padding=\"4\" Margin=\"5,0,0,0\"\n                              IsChecked=\"{Binding IsAddedByCurrentUser, Mode=OneWay}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              ToolTip=\"{Binding IsAddedByCurrentUser, Converter={StaticResource LikeDislikeTooltipConverter}}\" SnapsToDevicePixels=\"False\"/>\n                </StackPanel>\n            </Grid>\n        </Button>\n        <DataTemplate.Triggers>\n            <DataTrigger Binding=\"{Binding IsPlaying, Mode=OneWay}\" Value=\"True\">\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Title\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Artist\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Duration\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Title\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Artist\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Duration\"/>\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Artist\" />\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Duration\" />\n            </DataTrigger>\n            <DataTrigger Binding=\"{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},Path=IsMouseOver}\" Value=\"True\">\n                <Setter TargetName=\"Duration\" Property=\"Opacity\" Value=\"0\" />\n                <Setter TargetName=\"ToolbarPanel\" Property=\"Opacity\" Value=\"1\" />\n            </DataTrigger>\n            <DataTrigger Binding=\"{Binding ElementName='Artist',Path=IsMouseOver}\" Value=\"True\">\n                <Setter TargetName=\"Artist\" Property=\"Cursor\" Value=\"Hand\" />\n                <Setter TargetName=\"Artist\" Property=\"TextDecorations\" Value=\"Underline\" />\n            </DataTrigger>\n        </DataTemplate.Triggers>\n    </DataTemplate>\n\n    <DataTemplate x:Key=\"LocalAudioItemTemplate\">\n        <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.PlayAudioCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\"\n                Padding=\"0,5,0,5\" MaxHeight=\"32\">\n            <Button.RenderTransform>\n                <TranslateTransform />\n            </Button.RenderTransform>\n            <Button.Triggers>\n                <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                    <BeginStoryboard Storyboard=\"{StaticResource AudioLoadAnim}\" />\n                </EventTrigger>\n            </Button.Triggers>\n            <Button.ContextMenu>\n                <ContextMenu Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                    <!--<MenuItem Header=\"{x:Static localization:MainResources.ContextMenuStartRadio}\" Command=\"{Binding Main.StartTrackRadioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>-->\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuShowArtistInfo}\" Command=\"{Binding Main.ShowArtistInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" />\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuSearchArtist}\" Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" />\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding Main.AddToNowPlayingCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuPlayNext}\" Command=\"{Binding Main.PlayAudioNextCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuCopyInfo}\" Command=\"{Binding Main.CopyInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                </ContextMenu>\n            </Button.ContextMenu>\n            <Grid Background=\"Transparent\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"12\"/>\n                    <ColumnDefinition Width=\"0.5*\" MaxWidth=\"500\"/>\n                    <ColumnDefinition Width=\"0.2*\"/>\n                    <ColumnDefinition Width=\"0.2*\"/>\n                    <ColumnDefinition Width=\"0.1*\"/>\n                </Grid.ColumnDefinitions>\n                <TextBlock Grid.Column=\"1\" x:Name=\"Title\" Text=\"{Binding Title}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"13\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Title}\" Margin=\"0,0,5,0\"/>\n                <Button Style=\"{StaticResource SimpleButtonStyle}\" Grid.Column=\"2\" HorizontalAlignment=\"Left\" Opacity=\"0.6\" Margin=\"0,0,0,0\" Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\"\n                        CommandParameter=\"{Binding Artist}\">\n                    <TextBlock x:Name=\"Artist\" Text=\"{Binding Artist}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"13\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Artist}\"/>\n                </Button>\n                <TextBlock x:Name=\"Album\" Grid.Column=\"3\" Text=\"{Binding Album}\" Foreground=\"{DynamicResource ForegroundBrush}\" HorizontalAlignment=\"Left\" Opacity=\"0.6\" FontSize=\"13\" Margin=\"10,0,10,0\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Album}\"/>\n                <TextBlock x:Name=\"Duration\" Grid.Column=\"4\" Text=\"{Binding Duration, Converter={StaticResource AudioTimeSpanConverter}}\" Foreground=\"{DynamicResource ForegroundBrush}\" Visibility=\"{Binding Duration.TotalSeconds, Converter={StaticResource NullToVisibilityConverter}}\" HorizontalAlignment=\"Right\" Opacity=\"0.6\" FontSize=\"12\" VerticalAlignment=\"Center\" Margin=\"0,0,24,0\" TextTrimming=\"CharacterEllipsis\"/>\n                <StackPanel x:Name=\"ToolbarPanel\"  Grid.Column=\"4\" HorizontalAlignment=\"Right\" Margin=\"0,-2,24,-2\" Opacity=\"0\" Orientation=\"Horizontal\" VerticalAlignment=\"Center\">\n                    <Button Style=\"{StaticResource AddButtonStyle}\" Width=\"22\" Height=\"20\" Padding=\"4\"\n                            Command=\"{Binding Main.AddToNowPlayingCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\" Margin=\"0,0,0,0\"\n                            ToolTip=\"{x:Static localization:MainResources.ContextMenuAddToNowPlaying}\" Foreground=\"{DynamicResource AccentBrush}\"/>\n                </StackPanel>\n            </Grid>\n        </Button>\n        <DataTemplate.Triggers>\n            <DataTrigger Binding=\"{Binding IsPlaying, Mode=OneWay}\" Value=\"True\">\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Title\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Artist\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Duration\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Title\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Artist\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Duration\"/>\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Artist\" />\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Duration\" />\n            </DataTrigger>\n            <DataTrigger Binding=\"{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},Path=IsMouseOver}\" Value=\"True\">\n                <Setter TargetName=\"Duration\" Property=\"Opacity\" Value=\"0\" />\n                <Setter TargetName=\"ToolbarPanel\" Property=\"Opacity\" Value=\"1\" />\n            </DataTrigger>\n            <DataTrigger Binding=\"{Binding ElementName='Artist', Path=IsMouseOver}\" Value=\"True\">\n                <Setter TargetName=\"Artist\" Property=\"Cursor\" Value=\"Hand\" />\n                <Setter TargetName=\"Artist\" Property=\"TextDecorations\" Value=\"Underline\" />\n            </DataTrigger>\n        </DataTemplate.Triggers>\n    </DataTemplate>\n\n    <DataTemplate x:Key=\"NowPlayingAudioItemTemplate\">\n        <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.PlayAudioCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\"\n                Padding=\"0,5,0,5\" MaxHeight=\"32\">\n            <Button.RenderTransform>\n                <TranslateTransform />\n            </Button.RenderTransform>\n            <Button.Triggers>\n                <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                    <BeginStoryboard Storyboard=\"{StaticResource AudioLoadAnim}\" />\n                </EventTrigger>\n            </Button.Triggers>\n            <Button.ContextMenu>\n                <ContextMenu Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAdd}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuEdit}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}}\" Command=\"{Binding Main.EditAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuRemove}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuShare}\" Command=\"{Binding Main.ShareAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuLyrics}\" IsEnabled=\"{Binding HasLyrics}\" Command=\"{Binding Main.ShowLyricsCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <!--<MenuItem Header=\"{x:Static localization:MainResources.ContextMenuStartRadio}\" Command=\"{Binding Main.StartTrackRadioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>-->\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuSearchArtist}\" Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" />\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuRemoveFromNowPlaying}\" Command=\"{Binding Main.RemoveFromNowPlayingCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuPlayNext}\" Command=\"{Binding Main.PlayAudioNextCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuCopyInfo}\" Command=\"{Binding Main.CopyInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                </ContextMenu>\n            </Button.ContextMenu>\n            <Grid>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"12\"/>\n                    <ColumnDefinition Width=\"0.5*\" MaxWidth=\"500\"/>\n                    <ColumnDefinition Width=\"0.3*\"/>\n                    <ColumnDefinition Width=\"0.2*\"/>\n                </Grid.ColumnDefinitions>\n                <TextBlock Grid.Column=\"1\" x:Name=\"Title\" Text=\"{Binding Title}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"13\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Title}\" Margin=\"0,0,5,0\"/>\n                <TextBlock x:Name=\"Artist\" Grid.Column=\"2\" Text=\"{Binding Artist}\" Foreground=\"{DynamicResource ForegroundBrush}\" HorizontalAlignment=\"Left\" Opacity=\"0.6\" FontSize=\"13\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Artist}\"/>\n                <TextBlock x:Name=\"Duration\" Grid.Column=\"3\" Text=\"{Binding Duration, Converter={StaticResource AudioTimeSpanConverter}}\" Foreground=\"{DynamicResource ForegroundBrush}\" Visibility=\"{Binding Duration.TotalSeconds, Converter={StaticResource NullToVisibilityConverter}}\" HorizontalAlignment=\"Right\" Opacity=\"0.6\" FontSize=\"12\" VerticalAlignment=\"Center\" Margin=\"0,0,24,0\" TextTrimming=\"CharacterEllipsis\"/>\n\n                <StackPanel x:Name=\"ToolbarPanel\"  Grid.Column=\"3\" HorizontalAlignment=\"Right\" Margin=\"0,-2,24,-2\" Opacity=\"0\" Orientation=\"Horizontal\">\n\n                    <Button Style=\"{StaticResource LyricsButtonStyle}\" Width=\"22\" Height=\"20\" Padding=\"4\" Visibility=\"{Binding HasLyrics, Converter={StaticResource BoolToVisibilityConverter}}\"\n                            Command=\"{Binding Main.ShowLyricsCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\" Margin=\"0,0,0,0\"\n                            ToolTip=\"{x:Static localization:MainResources.ContextMenuLyrics}\"/>\n\n                    <Button Style=\"{StaticResource EditButtonStyle}\" Width=\"22\" Height=\"20\" Padding=\"4\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}}\"\n                            Command=\"{Binding Main.EditAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\" Margin=\"5,0,0,0\"\n                            ToolTip=\"{x:Static localization:MainResources.ContextMenuEdit}\"/>\n\n                    <ToggleButton x:Name=\"LikeDislikeButton\" Style=\"{StaticResource LikeDislikeButtonStyle}\" Width=\"22\" Height=\"20\" Padding=\"4\" Margin=\"5,0,0,0\"\n                              IsChecked=\"{Binding IsAddedByCurrentUser, Mode=OneWay}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"\n                              ToolTip=\"{Binding IsAddedByCurrentUser, Converter={StaticResource LikeDislikeTooltipConverter}}\" SnapsToDevicePixels=\"False\"/>\n                </StackPanel>\n            </Grid>\n        </Button>\n        <DataTemplate.Triggers>\n            <DataTrigger Binding=\"{Binding IsPlaying, Mode=OneWay}\" Value=\"True\">\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Title\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Artist\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Duration\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Title\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Artist\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Duration\"/>\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Artist\" />\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Duration\" />\n            </DataTrigger>\n            <DataTrigger Binding=\"{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},Path=IsMouseOver}\" Value=\"True\">\n                <Setter TargetName=\"Duration\" Property=\"Opacity\" Value=\"0\" />\n                <Setter TargetName=\"ToolbarPanel\" Property=\"Opacity\" Value=\"1\" />\n            </DataTrigger>\n        </DataTemplate.Triggers>\n    </DataTemplate>\n\n    <DataTemplate x:Key=\"NowPlayingLocalAudioItemTemplate\">\n        <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.PlayAudioCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\"\n                Padding=\"0,5,0,5\" MaxHeight=\"32\">\n            <Button.RenderTransform>\n                <TranslateTransform />\n            </Button.RenderTransform>\n            <Button.Triggers>\n                <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                    <BeginStoryboard Storyboard=\"{StaticResource AudioLoadAnim}\" />\n                </EventTrigger>\n            </Button.Triggers>\n            <Button.ContextMenu>\n                <ContextMenu Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                    <!--<MenuItem Header=\"{x:Static localization:MainResources.ContextMenuStartRadio}\" Command=\"{Binding Main.StartTrackRadioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>-->\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuShowArtistInfo}\" Command=\"{Binding Main.ShowArtistInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" />\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuSearchArtist}\" Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" />\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding Main.AddToNowPlayingCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuPlayNext}\" Command=\"{Binding Main.PlayAudioNextCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuCopyInfo}\" Command=\"{Binding Main.CopyInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                </ContextMenu>\n            </Button.ContextMenu>\n            <Grid Background=\"Transparent\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"12\"/>\n                    <ColumnDefinition Width=\"0.5*\" MaxWidth=\"500\"/>\n                    <ColumnDefinition Width=\"0.2*\"/>\n                    <ColumnDefinition Width=\"0.2*\"/>\n                    <ColumnDefinition Width=\"0.1*\"/>\n                </Grid.ColumnDefinitions>\n                <TextBlock Grid.Column=\"1\" x:Name=\"Title\" Text=\"{Binding Title}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"13\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Title}\" Margin=\"0,0,5,0\"/>\n                <Button Style=\"{StaticResource SimpleButtonStyle}\" Grid.Column=\"2\" HorizontalAlignment=\"Left\" Opacity=\"0.6\" Margin=\"0,0,0,0\" Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\"\n                        CommandParameter=\"{Binding Artist}\">\n                    <TextBlock x:Name=\"Artist\" Text=\"{Binding Artist}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"13\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Artist}\"/>\n                </Button>\n                <TextBlock x:Name=\"Album\" Grid.Column=\"3\" Text=\"{Binding Album}\" Foreground=\"{DynamicResource ForegroundBrush}\" HorizontalAlignment=\"Left\" Opacity=\"0.6\" FontSize=\"13\" Margin=\"10,0,10,0\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Album}\"/>\n                <TextBlock x:Name=\"Duration\" Grid.Column=\"4\" Text=\"{Binding Duration, Converter={StaticResource AudioTimeSpanConverter}}\" Foreground=\"{DynamicResource ForegroundBrush}\" Visibility=\"{Binding Duration.TotalSeconds, Converter={StaticResource NullToVisibilityConverter}}\" HorizontalAlignment=\"Right\" Opacity=\"0.6\" FontSize=\"12\" VerticalAlignment=\"Center\" Margin=\"0,0,24,0\" TextTrimming=\"CharacterEllipsis\"/>\n            </Grid>\n        </Button>\n        <DataTemplate.Triggers>\n            <DataTrigger Binding=\"{Binding IsPlaying, Mode=OneWay}\" Value=\"True\">\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Title\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Artist\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Duration\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Title\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Artist\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Duration\"/>\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Artist\" />\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Duration\" />\n            </DataTrigger>\n            <DataTrigger Binding=\"{Binding ElementName='Artist',Path=IsMouseOver}\" Value=\"True\">\n                <Setter TargetName=\"Artist\" Property=\"Cursor\" Value=\"Hand\" />\n                <Setter TargetName=\"Artist\" Property=\"TextDecorations\" Value=\"Underline\" />\n            </DataTrigger>\n        </DataTemplate.Triggers>\n    </DataTemplate>\n\n    <DataTemplate x:Key=\"CompactAudioItemTemplate\">\n        <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.PlayAudioCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\"\n                Padding=\"15,5,5,5\" MaxHeight=\"40\">\n            <Button.RenderTransform>\n                <TranslateTransform />\n            </Button.RenderTransform>\n            <Button.Triggers>\n                <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                    <BeginStoryboard Storyboard=\"{StaticResource AudioLoadAnim}\" />\n                </EventTrigger>\n            </Button.Triggers>\n            <Button.ContextMenu>\n                <ContextMenu Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAdd}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuRemove}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <!--<MenuItem Header=\"{x:Static localization:MainResources.ContextMenuStartRadio}\" Command=\"{Binding Main.StartTrackRadioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>-->\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuRemoveFromNowPlaying}\" Command=\"{Binding Main.RemoveFromNowPlayingCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuPlayNext}\" Command=\"{Binding Main.PlayAudioNextCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuCopyInfo}\" Command=\"{Binding Main.CopyInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                </ContextMenu>\n            </Button.ContextMenu>\n            <Grid>\n                <Grid.RowDefinitions>\n                    <RowDefinition />\n                    <RowDefinition />\n                </Grid.RowDefinitions>\n                <TextBlock x:Name=\"Title\" Text=\"{Binding Title}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"12\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Title}\"/>\n                <TextBlock x:Name=\"Artist\" Grid.Row=\"1\" Text=\"{Binding Artist}\" Foreground=\"{DynamicResource ForegroundBrush}\" HorizontalAlignment=\"Left\" Opacity=\"0.6\" FontSize=\"12\" Margin=\"0,0,0,0\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Artist}\"/>\n            </Grid>\n        </Button>\n        <DataTemplate.Triggers>\n            <DataTrigger Binding=\"{Binding IsPlaying, Mode=OneWay}\" Value=\"True\">\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Title\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Artist\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Title\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Artist\"/>\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Artist\" />\n            </DataTrigger>\n        </DataTemplate.Triggers>\n    </DataTemplate>\n\n    <DataTemplate x:Key=\"OrderedAudioItemTemplate\">\n        <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.PlayAudioCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\"\n                Padding=\"0,5,0,5\" MaxHeight=\"32\">\n            <Button.RenderTransform>\n                <TranslateTransform />\n            </Button.RenderTransform>\n            <Button.Triggers>\n                <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                    <BeginStoryboard Storyboard=\"{StaticResource AudioLoadAnim}\" />\n                </EventTrigger>\n            </Button.Triggers>\n            <Button.ContextMenu>\n                <ContextMenu Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAdd}\" Visibility=\"{Binding IsAddedByCurrentUser, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\" Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuShare}\" Command=\"{Binding Main.ShareAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuLyrics}\" IsEnabled=\"{Binding HasLyrics}\" Command=\"{Binding Main.ShowLyricsCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <!--<MenuItem Header=\"{x:Static localization:MainResources.ContextMenuStartRadio}\" Command=\"{Binding Main.StartTrackRadioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>-->\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuSearchArtist}\" Command=\"{Binding Main.SearchCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Artist}\" />\n                    <Separator Style=\"{StaticResource CommonSeparatorStyle}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding Main.AddToNowPlayingCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuPlayNext}\" Command=\"{Binding Main.PlayAudioNextCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                    <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuCopyInfo}\" Command=\"{Binding Main.CopyInfoCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding}\"/>\n                </ContextMenu>\n            </Button.ContextMenu>\n            <Grid>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"12\"/>\n                    <ColumnDefinition Width=\"Auto\"/>\n                    <ColumnDefinition Width=\"0.5*\" MaxWidth=\"500\"/>\n                    <ColumnDefinition Width=\"0.3*\"/>\n                    <ColumnDefinition Width=\"0.2*\"/>\n                </Grid.ColumnDefinitions>\n                <TextBlock Grid.Column=\"1\" x:Name=\"Order\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"14\" Margin=\"0,0,5,0\">\n                    <Run Text=\"{Binding Order}\"/>.\n                </TextBlock>\n                <TextBlock x:Name=\"Title\" Grid.Column=\"2\" Text=\"{Binding Title}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"13\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Title}\"/>\n                <TextBlock x:Name=\"Artist\" Grid.Column=\"3\" Text=\"{Binding Artist}\" Foreground=\"{DynamicResource ForegroundBrush}\" HorizontalAlignment=\"Left\" Opacity=\"0.6\" FontSize=\"13\" Margin=\"20,0,0,0\" TextTrimming=\"CharacterEllipsis\"\n                           ToolTip=\"{Binding Artist}\"/>\n                <TextBlock x:Name=\"Duration\" Grid.Column=\"4\" Text=\"{Binding Duration, Converter={StaticResource AudioTimeSpanConverter}}\" Foreground=\"{DynamicResource ForegroundBrush}\" HorizontalAlignment=\"Right\" Opacity=\"0.6\" FontSize=\"12\" VerticalAlignment=\"Center\" Margin=\"0,0,24,0\" TextTrimming=\"CharacterEllipsis\"/>\n            </Grid>\n        </Button>\n        <DataTemplate.Triggers>\n            <DataTrigger Binding=\"{Binding IsPlaying, Mode=OneWay}\" Value=\"True\">\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Order\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Title\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Artist\"/>\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" TargetName=\"Duration\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Order\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Title\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Artist\"/>\n                <Setter Property=\"FontWeight\" Value=\"SemiBold\" TargetName=\"Duration\"/>\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Artist\" />\n                <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"Duration\" />\n            </DataTrigger>\n        </DataTemplate.Triggers>\n    </DataTemplate>\n\n    <DataTemplate x:Key=\"PostItemDataTemplate\">\n        <StackPanel>\n            <ItemsControl ItemsSource=\"{Binding Audios}\" ItemTemplate=\"{StaticResource AudioItemTemplate}\" />\n            <Rectangle Fill=\"{DynamicResource ForegroundBrush}\" Height=\"1\" Margin=\"0,5,0,5\" Opacity=\"0.3\"/>\n        </StackPanel>\n    </DataTemplate>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/ExpanderStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <SolidColorBrush x:Key=\"Expander.MouseOver.Circle.Stroke\" Color=\"#FF5593FF\"/>\n    <SolidColorBrush x:Key=\"Expander.MouseOver.Circle.Fill\" Color=\"#FFF3F9FF\"/>\n    <SolidColorBrush x:Key=\"Expander.MouseOver.Arrow.Stroke\" Color=\"#FF000000\"/>\n    <SolidColorBrush x:Key=\"Expander.Pressed.Circle.Stroke\" Color=\"#FF3C77DD\"/>\n    <SolidColorBrush x:Key=\"Expander.Pressed.Circle.Fill\" Color=\"#FFD9ECFF\"/>\n    <SolidColorBrush x:Key=\"Expander.Pressed.Arrow.Stroke\" Color=\"#FF000000\"/>\n    <SolidColorBrush x:Key=\"Expander.Disabled.Circle.Stroke\" Color=\"#FFBCBCBC\"/>\n    <SolidColorBrush x:Key=\"Expander.Disabled.Circle.Fill\" Color=\"#FFE6E6E6\"/>\n    <SolidColorBrush x:Key=\"Expander.Disabled.Arrow.Stroke\" Color=\"#FF707070\"/>\n    <SolidColorBrush x:Key=\"Expander.Static.Circle.Fill\" Color=\"#FFFFFFFF\"/>\n    <SolidColorBrush x:Key=\"Expander.Static.Circle.Stroke\" Color=\"#FF333333\"/>\n    <SolidColorBrush x:Key=\"Expander.Static.Arrow.Stroke\" Color=\"#FF333333\"/>\n    <Style x:Key=\"ExpanderRightHeaderStyle\" TargetType=\"{x:Type ToggleButton}\">\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ToggleButton}\">\n                    <Border Padding=\"{TemplateBinding Padding}\">\n                        <Grid Background=\"Transparent\" SnapsToDevicePixels=\"False\">\n                            <Grid.RowDefinitions>\n                                <RowDefinition Height=\"19\"/>\n                                <RowDefinition Height=\"*\"/>\n                            </Grid.RowDefinitions>\n                            <Grid>\n                                <Grid.LayoutTransform>\n                                    <TransformGroup>\n                                        <TransformGroup.Children>\n                                            <TransformCollection>\n                                                <RotateTransform Angle=\"-90\"/>\n                                            </TransformCollection>\n                                        </TransformGroup.Children>\n                                    </TransformGroup>\n                                </Grid.LayoutTransform>\n                                <Ellipse x:Name=\"circle\" Fill=\"{StaticResource Expander.Static.Circle.Fill}\" HorizontalAlignment=\"Center\" Height=\"19\" Stroke=\"{StaticResource Expander.Static.Circle.Stroke}\" VerticalAlignment=\"Center\" Width=\"19\"/>\n                                <Path x:Name=\"arrow\" Data=\"M 1,1.5 L 4.5,5 L 8,1.5\" HorizontalAlignment=\"Center\" SnapsToDevicePixels=\"false\" Stroke=\"{StaticResource Expander.Static.Arrow.Stroke}\" StrokeThickness=\"2\" VerticalAlignment=\"Center\"/>\n                            </Grid>\n                            <ContentPresenter HorizontalAlignment=\"Center\" Margin=\"0,4,0,0\" Grid.Row=\"1\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"True\" VerticalAlignment=\"Top\"/>\n                        </Grid>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\" Value=\"true\">\n                            <Setter Property=\"Data\" TargetName=\"arrow\" Value=\"M 1,4.5  L 4.5,1  L 8,4.5\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Stroke\" TargetName=\"circle\" Value=\"{StaticResource Expander.MouseOver.Circle.Stroke}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"circle\" Value=\"{StaticResource Expander.MouseOver.Circle.Fill}\"/>\n                            <Setter Property=\"Stroke\" TargetName=\"arrow\" Value=\"{StaticResource Expander.MouseOver.Arrow.Stroke}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsPressed\" Value=\"true\">\n                            <Setter Property=\"Stroke\" TargetName=\"circle\" Value=\"{StaticResource Expander.Pressed.Circle.Stroke}\"/>\n                            <Setter Property=\"StrokeThickness\" TargetName=\"circle\" Value=\"1.5\"/>\n                            <Setter Property=\"Fill\" TargetName=\"circle\" Value=\"{StaticResource Expander.Pressed.Circle.Fill}\"/>\n                            <Setter Property=\"Stroke\" TargetName=\"arrow\" Value=\"{StaticResource Expander.Pressed.Arrow.Stroke}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"false\">\n                            <Setter Property=\"Stroke\" TargetName=\"circle\" Value=\"{StaticResource Expander.Disabled.Circle.Stroke}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"circle\" Value=\"{StaticResource Expander.Disabled.Circle.Fill}\"/>\n                            <Setter Property=\"Stroke\" TargetName=\"arrow\" Value=\"{StaticResource Expander.Disabled.Arrow.Stroke}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"ExpanderUpHeaderStyle\" TargetType=\"{x:Type ToggleButton}\">\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ToggleButton}\">\n                    <Border Padding=\"{TemplateBinding Padding}\">\n                        <Grid Background=\"Transparent\" SnapsToDevicePixels=\"False\">\n                            <Grid.ColumnDefinitions>\n                                <ColumnDefinition Width=\"19\"/>\n                                <ColumnDefinition Width=\"*\"/>\n                            </Grid.ColumnDefinitions>\n                            <Grid>\n                                <Grid.LayoutTransform>\n                                    <TransformGroup>\n                                        <TransformGroup.Children>\n                                            <TransformCollection>\n                                                <RotateTransform Angle=\"180\"/>\n                                            </TransformCollection>\n                                        </TransformGroup.Children>\n                                    </TransformGroup>\n                                </Grid.LayoutTransform>\n                                <Ellipse x:Name=\"circle\" Fill=\"{StaticResource Expander.Static.Circle.Fill}\" HorizontalAlignment=\"Center\" Height=\"19\" Stroke=\"{StaticResource Expander.Static.Circle.Stroke}\" VerticalAlignment=\"Center\" Width=\"19\"/>\n                                <Path x:Name=\"arrow\" Data=\"M 1,1.5 L 4.5,5 L 8,1.5\" HorizontalAlignment=\"Center\" SnapsToDevicePixels=\"false\" Stroke=\"{StaticResource Expander.Static.Arrow.Stroke}\" StrokeThickness=\"2\" VerticalAlignment=\"Center\"/>\n                            </Grid>\n                            <ContentPresenter Grid.Column=\"1\" HorizontalAlignment=\"Left\" Margin=\"4,0,0,0\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"True\" VerticalAlignment=\"Center\"/>\n                        </Grid>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\" Value=\"true\">\n                            <Setter Property=\"Data\" TargetName=\"arrow\" Value=\"M 1,4.5  L 4.5,1  L 8,4.5\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Stroke\" TargetName=\"circle\" Value=\"{StaticResource Expander.MouseOver.Circle.Stroke}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"circle\" Value=\"{StaticResource Expander.MouseOver.Circle.Fill}\"/>\n                            <Setter Property=\"Stroke\" TargetName=\"arrow\" Value=\"{StaticResource Expander.MouseOver.Arrow.Stroke}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsPressed\" Value=\"true\">\n                            <Setter Property=\"Stroke\" TargetName=\"circle\" Value=\"{StaticResource Expander.Pressed.Circle.Stroke}\"/>\n                            <Setter Property=\"StrokeThickness\" TargetName=\"circle\" Value=\"1.5\"/>\n                            <Setter Property=\"Fill\" TargetName=\"circle\" Value=\"{StaticResource Expander.Pressed.Circle.Fill}\"/>\n                            <Setter Property=\"Stroke\" TargetName=\"arrow\" Value=\"{StaticResource Expander.Pressed.Arrow.Stroke}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"false\">\n                            <Setter Property=\"Stroke\" TargetName=\"circle\" Value=\"{StaticResource Expander.Disabled.Circle.Stroke}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"circle\" Value=\"{StaticResource Expander.Disabled.Circle.Fill}\"/>\n                            <Setter Property=\"Stroke\" TargetName=\"arrow\" Value=\"{StaticResource Expander.Disabled.Arrow.Stroke}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"ExpanderLeftHeaderStyle\" TargetType=\"{x:Type ToggleButton}\">\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ToggleButton}\">\n                    <Border Padding=\"{TemplateBinding Padding}\">\n                        <Grid Background=\"Transparent\" SnapsToDevicePixels=\"False\">\n                            <Grid.RowDefinitions>\n                                <RowDefinition Height=\"19\"/>\n                                <RowDefinition Height=\"*\"/>\n                            </Grid.RowDefinitions>\n                            <Grid>\n                                <Grid.LayoutTransform>\n                                    <TransformGroup>\n                                        <TransformGroup.Children>\n                                            <TransformCollection>\n                                                <RotateTransform Angle=\"90\"/>\n                                            </TransformCollection>\n                                        </TransformGroup.Children>\n                                    </TransformGroup>\n                                </Grid.LayoutTransform>\n                                <Ellipse x:Name=\"circle\" Fill=\"{StaticResource Expander.Static.Circle.Fill}\" HorizontalAlignment=\"Center\" Height=\"19\" Stroke=\"{StaticResource Expander.Static.Circle.Stroke}\" VerticalAlignment=\"Center\" Width=\"19\"/>\n                                <Path x:Name=\"arrow\" Data=\"M 1,1.5 L 4.5,5 L 8,1.5\" HorizontalAlignment=\"Center\" SnapsToDevicePixels=\"false\" Stroke=\"{StaticResource Expander.Static.Arrow.Stroke}\" StrokeThickness=\"2\" VerticalAlignment=\"Center\"/>\n                            </Grid>\n                            <ContentPresenter HorizontalAlignment=\"Center\" Margin=\"0,4,0,0\" Grid.Row=\"1\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"True\" VerticalAlignment=\"Top\"/>\n                        </Grid>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsChecked\" Value=\"true\">\n                            <Setter Property=\"Data\" TargetName=\"arrow\" Value=\"M 1,4.5  L 4.5,1  L 8,4.5\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Stroke\" TargetName=\"circle\" Value=\"{StaticResource Expander.MouseOver.Circle.Stroke}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"circle\" Value=\"{StaticResource Expander.MouseOver.Circle.Fill}\"/>\n                            <Setter Property=\"Stroke\" TargetName=\"arrow\" Value=\"{StaticResource Expander.MouseOver.Arrow.Stroke}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsPressed\" Value=\"true\">\n                            <Setter Property=\"Stroke\" TargetName=\"circle\" Value=\"{StaticResource Expander.Pressed.Circle.Stroke}\"/>\n                            <Setter Property=\"StrokeThickness\" TargetName=\"circle\" Value=\"1.5\"/>\n                            <Setter Property=\"Fill\" TargetName=\"circle\" Value=\"{StaticResource Expander.Pressed.Circle.Fill}\"/>\n                            <Setter Property=\"Stroke\" TargetName=\"arrow\" Value=\"{StaticResource Expander.Pressed.Arrow.Stroke}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"false\">\n                            <Setter Property=\"Stroke\" TargetName=\"circle\" Value=\"{StaticResource Expander.Disabled.Circle.Stroke}\"/>\n                            <Setter Property=\"Fill\" TargetName=\"circle\" Value=\"{StaticResource Expander.Disabled.Circle.Fill}\"/>\n                            <Setter Property=\"Stroke\" TargetName=\"arrow\" Value=\"{StaticResource Expander.Disabled.Arrow.Stroke}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"ExpanderHeaderFocusVisual\">\n        <Setter Property=\"Control.Template\">\n            <Setter.Value>\n                <ControlTemplate>\n                    <Border>\n                        <Rectangle Margin=\"0\" SnapsToDevicePixels=\"true\" Stroke=\"Black\" StrokeThickness=\"1\" StrokeDashArray=\"1 2\"/>\n                    </Border>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"ExpanderDownHeaderStyle\" TargetType=\"{x:Type ToggleButton}\">\n        <Setter Property=\"Opacity\" Value=\"1\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ToggleButton}\">\n                    <Border Padding=\"{TemplateBinding Padding}\">\n                        <Grid Background=\"Transparent\" SnapsToDevicePixels=\"False\">\n                            <ContentPresenter HorizontalAlignment=\"Left\" Margin=\"0,0,0,0\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"True\" VerticalAlignment=\"Center\"/>\n                        </Grid>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"MainMenuGroupExpanderStyle\" TargetType=\"{x:Type Expander}\">\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"1\"/>\n        <Setter Property=\"Margin\" Value=\"0,0,0,20\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Expander}\">\n                    <Border BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" CornerRadius=\"3\" SnapsToDevicePixels=\"true\">\n                        <DockPanel>\n                            <ToggleButton x:Name=\"HeaderSite\" ContentTemplate=\"{TemplateBinding HeaderTemplate}\" ContentTemplateSelector=\"{TemplateBinding HeaderTemplateSelector}\" Content=\"{TemplateBinding Header}\" DockPanel.Dock=\"Top\" Foreground=\"{TemplateBinding Foreground}\" FontWeight=\"{TemplateBinding FontWeight}\" FocusVisualStyle=\"{StaticResource ExpanderHeaderFocusVisual}\" FontStyle=\"{TemplateBinding FontStyle}\" FontStretch=\"{TemplateBinding FontStretch}\" FontSize=\"{TemplateBinding FontSize}\" FontFamily=\"{TemplateBinding FontFamily}\" HorizontalContentAlignment=\"{TemplateBinding HorizontalContentAlignment}\" IsChecked=\"{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}\" Margin=\"1\" MinWidth=\"0\" MinHeight=\"0\" Padding=\"{TemplateBinding Padding}\" Style=\"{StaticResource ExpanderDownHeaderStyle}\" VerticalContentAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                            <ContentPresenter x:Name=\"ExpandSite\" DockPanel.Dock=\"Bottom\" Focusable=\"false\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" Visibility=\"Collapsed\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                        </DockPanel>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsExpanded\" Value=\"true\">\n                            <Setter Property=\"Visibility\" TargetName=\"ExpandSite\" Value=\"Visible\"/>\n                        </Trigger>\n                        <Trigger Property=\"ExpandDirection\" Value=\"Right\">\n                            <Setter Property=\"DockPanel.Dock\" TargetName=\"ExpandSite\" Value=\"Right\"/>\n                            <Setter Property=\"DockPanel.Dock\" TargetName=\"HeaderSite\" Value=\"Left\"/>\n                            <Setter Property=\"Style\" TargetName=\"HeaderSite\" Value=\"{StaticResource ExpanderRightHeaderStyle}\"/>\n                        </Trigger>\n                        <Trigger Property=\"ExpandDirection\" Value=\"Up\">\n                            <Setter Property=\"DockPanel.Dock\" TargetName=\"ExpandSite\" Value=\"Top\"/>\n                            <Setter Property=\"DockPanel.Dock\" TargetName=\"HeaderSite\" Value=\"Bottom\"/>\n                            <Setter Property=\"Style\" TargetName=\"HeaderSite\" Value=\"{StaticResource ExpanderUpHeaderStyle}\"/>\n                        </Trigger>\n                        <Trigger Property=\"ExpandDirection\" Value=\"Left\">\n                            <Setter Property=\"DockPanel.Dock\" TargetName=\"ExpandSite\" Value=\"Left\"/>\n                            <Setter Property=\"DockPanel.Dock\" TargetName=\"HeaderSite\" Value=\"Right\"/>\n                            <Setter Property=\"Style\" TargetName=\"HeaderSite\" Value=\"{StaticResource ExpanderLeftHeaderStyle}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"false\">\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/Icons.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Geometry x:Key=\"PlayIcon\">F1 M 0,0L 12.9999,9.75006L 12.9999,10.5001L 0,20L 0,0 Z</Geometry>\n    <Geometry x:Key=\"PauseIcon\">F1 M 0,0L 4,0L 4,18L 0,18L 0,0 Z M 10,0L 14,0L 14,18L 10,18L 10,0 Z</Geometry>\n    <Geometry x:Key=\"NextIcon\">F1 M 0,6.10352e-005L 13.4583,10.2917L 0,20.5834L 0,6.10352e-005 Z M 15.8333,0.791687L 20.5833,0.791687L 20.5833,19.7917L 15.8333,19.7917L 15.8333,0.791687 Z</Geometry>\n    <Geometry x:Key=\"PrevIcon\">F1 M 20.5833,-6.10352e-005L 20.5833,20.5833L 7.12501,10.2916L 20.5833,-6.10352e-005 Z M 4.75,0.791626L 4.75,19.7916L 0,19.7916L 0,0.791626L 4.75,0.791626 Z</Geometry>\n\n    <Geometry x:Key=\"ShuffleIcon\">M 18,30L 22,30L 22,25L 8.00001,12.9999L 7.99999,6.54999L 12,10.5L 12,6.5L 5.99998,0L 0,6.5L 0,10.5L 3.99999,6.54999L 4,14.2501L 18,26L 18,30 Z M 8,30L 4,30L 3.99998,25L 9.54166,20.25L 12.1684,22.5015L 7.99998,26L 8,30 Z M 18,13L 18,6.25L 14,10.5L 14,6.5L 20,0L 26,6.5L 26,10.5L 22,6.25L 22,14.2501L 16.5474,18.8264L 13.875,16.5357L 18,13 Z</Geometry>\n    <Geometry x:Key=\"RepeatIcon\">F1 M 19.9,10.9999C 19.9,7.1969 17.0694,4.05493 13.4,3.56604L 13.4,0.0447998C 19.0065,0.550049 23.4,5.2619 23.4,10.9999C 23.4,11.3268 23.3857,11.6505 23.3578,11.9701L 23.3611,11.9701C 23.3254,12.3662 23.2687,12.7563 23.1921,13.1393C 22.7412,15.4271 21.5809,17.4601 19.9499,18.9999L 19.937,18.9878C 17.9689,20.8372 15.3197,21.9701 12.4059,21.9701C 12.0668,21.9701 11.7313,21.9547 11.4,21.9247L 11.4,21.9551C 5.7935,21.4499 1.4,16.738 1.4,10.9999C 1.4,7.8479 3.32578,4.40552 5.45012,2.39996L 0,2.39996L 2.4,-6.10352e-005L 10.4,-6.10352e-005L 10.4,7.99994L 8,10.4L 8,4.80969C 6.46562,6.18298 4.9,8.77869 4.9,10.9999C 4.9,12.915 5.61774,14.6624 6.7989,15.9879L 6.81568,15.9701C 8.18898,17.5045 10.1847,18.4701 12.4059,18.4701C 16.0393,18.4701 19.0692,15.8865 19.7587,12.4562C 19.8514,11.9852 19.9,11.4982 19.9,10.9999 Z</Geometry>\n    <Geometry x:Key=\"LikeIcon\">F1 M 0.109378,8.16675C -1.05729,3.83337 2.27604,0.500061 5.10938,6.10352e-005C 7.94271,-0.499939 10.2761,1.83337 12.6094,4.16669C 14.9427,1.83337 17.276,-0.499939 20.1094,6.10352e-005C 22.9427,0.500061 26.276,3.83337 25.1093,8.16675C 23.9427,12.5001 18.276,17.8334 12.6094,23.1667C 6.94272,17.8334 1.27605,12.5001 0.109378,8.16675 Z</Geometry>\n    <Geometry x:Key=\"DislikeIcon\">F1 M 0.109377,8.16675C -1.05729,3.83337 2.27604,0.500061 5.10938,6.10352e-005C 7.48017,-0.418335 9.50089,1.14703 11.4645,3.03632L 9.60938,13.1667L 12.6094,12.1667L 12.6094,23.1667C 6.94272,17.8334 1.27605,12.5001 0.109377,8.16675 Z M 20.1094,6.10352e-005C 22.9427,0.500061 26.276,3.83337 25.1093,8.16675C 23.9427,12.5001 18.276,17.8334 12.6094,23.1667L 16.6094,8.16669L 13.6094,9.16669L 15.3129,1.64935C 16.7995,0.463623 18.359,-0.308838 20.1094,6.10352e-005 Z</Geometry>\n    <Geometry x:Key=\"LyricsIcon\">F1 M 21.846,29.7036L 78.154,29.7036L 78.154,37.8982L 21.846,37.8982L 21.846,29.7036 Z M 21.846,54.2826L 78.154,54.2826L 78.154,62.4774L 21.846,62.4774L 21.846,54.2826 Z M 21.846,78.8626L 78.154,78.8626L 78.154,87.0572L 21.846,87.0572L 21.846,78.8626 Z M 9.26287,8.18396L 9.26287,108.421L 90.7367,108.421L 90.7367,8.18396L 9.26287,8.18396 Z M 100,108.421L 100,109.057L 100,116.605L 0,116.605L 0,109.057L 0,108.421L 0,8.18396L 0,7.30688L 0,-3.05176e-005L 100,-3.05176e-005L 100,7.30688L 100,8.18396L 100,108.421 Z</Geometry>\n    <Geometry x:Key=\"ShareIcon\">F1 M 6.33333,15.8334C 9.83114,15.8334 12.6667,18.6689 12.6667,22.1667C 12.6667,24.1684 11.7381,25.9532 10.2881,27.1138C 12.2869,33.1971 17.8717,37.6561 24.5417,38C 24.5417,40.4554 25.5578,42.6734 27.1926,44.2565L 25.3333,44.3334C 15.1233,44.3334 6.5256,37.4305 3.95237,28.0372C 1.6345,27.0963 0,24.8223 0,22.1667C 0,18.6689 2.83553,15.8334 6.33333,15.8334 Z M 32.4583,0C 35.9561,0 38.7917,2.83557 38.7917,6.33337C 38.7917,9.83118 35.9561,12.6667 32.4583,12.6667C 28.967,12.6667 26.1355,9.84167 26.125,6.35284C 25.8628,6.3399 25.5988,6.33337 25.3333,6.33337C 19.1827,6.33337 13.8511,9.84045 11.2294,14.964C 9.8342,14.0138 8.14863,13.4584 6.33333,13.4584L 4.89235,13.577C 8.24825,5.60052 16.1367,0 25.3333,0C 26.9357,0 28.4984,0.170044 30.0043,0.493042C 30.759,0.175537 31.5882,0 32.4583,0 Z M 33.25,31.6667C 34.6474,31.6667 35.9391,32.1193 36.9865,32.8859C 39.5818,30.0658 41.1666,26.3013 41.1666,22.1667C 41.1666,18.7075 40.0573,15.5074 38.175,12.9027C 39.9346,11.3703 41.0726,9.14252 41.1611,6.64758C 45.0821,10.6461 47.5,16.124 47.5,22.1667C 47.5,29.0405 44.3712,35.1836 39.4601,39.2495C 38.88,42.1489 36.3201,44.3334 33.25,44.3334C 29.7522,44.3334 26.9167,41.4978 26.9167,38C 26.9167,34.5022 29.7522,31.6667 33.25,31.6667 Z</Geometry>\n    <Geometry x:Key=\"EditIcon\">F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z</Geometry>\n\n    <Geometry x:Key=\"VkIcon\">M 509.399,327.645C 508.782,327.645 481.922,328.359 468.183,328.413C 450.482,328.484 434.874,322.381 422.355,310.325C 408.303,296.795 395.567,281.904 381.985,267.872C 377.389,263.121 372.301,258.669 366.821,254.997C 359.475,250.069 353.153,251.312 347.331,257.923C 340.257,265.955 338.275,275.963 337.053,286.123C 336.131,293.796 336.366,301.66 334.898,309.208C 332.769,320.156 324.842,326.44 312.353,326.996C 276.261,328.601 240.762,326.231 207.101,311.036C 176.625,297.28 150.778,277.619 128.901,252.451C 87.9272,205.315 57.5979,151.428 29.6246,96.0694C 20.6379,78.2827 12.4473,60.0934 3.89526,42.0867C 3.32458,40.8867 2.73527,39.692 2.23661,38.4627C -3.62476,24.0427 2.17525,15.108 17.9033,14.448C 22.7859,14.244 27.6793,14.348 32.5659,14.272C 52.7659,13.9587 72.9633,13.5214 93.1646,13.34C 110.402,13.1866 118.391,18.428 124.922,34.1013C 140.51,71.508 159.513,107.017 184.061,139.344C 188.821,145.613 194.715,151.284 200.963,156.091C 207.314,160.979 213.865,159.252 216.559,151.701C 219.638,143.076 222.37,133.812 222.562,124.769C 223.038,102.205 222.518,79.5813 221.382,57.0333C 220.507,39.696 211.887,30.928 194.619,27.1373C 187.483,25.5694 186.479,22.4387 191.257,16.52C 199.693,6.07336 211.566,1.99466 224.078,1.31732C 246.889,0.0840149 269.775,-0.225311 292.622,3.05176e-005C 301.117,0.0840149 309.73,2.20398 318.033,4.37469C 328.639,7.14667 334.145,15.2 335.471,25.6214C 336.558,34.164 336.886,42.8747 336.702,51.4933C 336.209,74.344 334.954,97.1814 334.646,120.033C 334.533,128.368 335.423,136.915 337.298,145.032C 340.41,158.505 349.323,161.789 358.678,151.921C 370.197,139.773 380.371,126.189 389.977,112.424C 407.561,87.2267 420.473,59.4733 431.891,31.0253C 437.193,17.8187 441.869,14.4627 455.789,14.4094C 486.227,14.2906 516.667,14.172 547.106,14.2413C 551.706,14.252 556.505,14.6281 560.866,15.9654C 569.818,18.712 573.186,25.396 570.918,34.7187C 566.099,54.5214 555.245,71.368 543.705,87.6187C 525.977,112.587 507.326,136.899 489.266,161.635C 473.951,182.613 474.709,190.057 493.094,208.536C 511.254,226.793 529.845,244.659 547.266,263.597C 555.427,272.471 562.085,283.021 567.983,293.616C 575.979,307.979 571.329,319.92 555.557,323.927C 544.603,326.708 532.822,326.288 521.398,327.121C 517.421,327.412 510.017,327.645 509.399,327.645 Z</Geometry>\n    <Geometry x:Key=\"LastFmIcon\">F1 M 14.7107,16.5067L 13.488,13.1827C 13.488,13.1827 11.5013,15.3986 8.52133,15.3986C 5.884,15.3986 4.01333,13.1066 4.01333,9.43866C 4.01333,4.73865 6.38133,3.05731 8.712,3.05731C 12.0733,3.05731 13.144,5.23596 14.0613,8.02533L 15.284,11.8453C 16.5067,15.552 18.7987,18.532 25.408,18.532C 30.1467,18.532 33.356,17.08 33.356,13.2587C 33.356,10.164 31.5987,8.55865 28.3133,7.79596L 25.868,7.25995C 24.1853,6.87866 23.6893,6.19067 23.6893,5.04401C 23.6893,3.7453 24.7213,2.98132 26.4027,2.98132C 28.236,2.98132 29.2293,3.66797 29.3827,5.31195L 33.204,4.85333C 32.8973,1.41467 30.528,0 26.6307,0C 23.192,0 19.8307,1.29999 19.8307,5.46533C 19.8307,8.06262 21.092,9.70532 24.2627,10.4706L 26.8613,11.0813C 28.8093,11.5386 29.4587,12.3413 29.4587,13.4506C 29.4587,14.864 28.084,15.4373 25.4853,15.4373C 21.6267,15.4373 20.0213,13.412 19.104,10.6226L 17.844,6.80267C 16.2387,1.83466 13.6787,0 8.59733,0C 2.98133,0 0,3.55328 0,9.59064C 0,15.3986 2.98133,18.532 8.32933,18.532C 12.648,18.532 14.7107,16.5067 14.7107,16.5067 Z</Geometry>\n    <Geometry x:Key=\"DeviceIcon\">F1 M 20,23.0002L 55.9998,23.0002C 57.1044,23.0002 57.9998,23.8956 57.9998,25.0002L 57.9999,46C 57.9999,47.1046 57.1045,48 55.9999,48L 41,48L 41,53L 45,53C 46.1046,53 47,53.8954 47,55L 47,57L 29,57L 29,55C 29,53.8954 29.8955,53 31,53L 35,53L 35,48L 20,48C 18.8954,48 18,47.1046 18,46L 18,25.0002C 18,23.8956 18.8954,23.0002 20,23.0002 Z M 21,26.0002L 21,45L 54.9999,45L 54.9998,26.0002L 21,26.0002 Z</Geometry>\n    \n    <Geometry x:Key=\"CloseIcon\">F1 M 0.471333,20.3887L 20.3887,0.471375M 0.471333,0.471375L 20.3887,20.3887</Geometry>\n    <Geometry x:Key=\"MinimizeIcon\">F1 M 0,1.33331L 20,1.33331L 20,0L 0,0L 0,1.33331 Z</Geometry>\n    <Geometry x:Key=\"MinimodeIcon\">M 17.3693,9.18268L 17.3693,0.666687L 0.666667,0.666687L 0.666667,17.6987L 11.6773,17.6987L 11.6773,9.18268L 17.3693,9.18268 Z M 11.6773,17.6991L 11.6773,19.3337L 19.3333,19.3337L 19.3333,9.18311L 17.3693,9.18311</Geometry>\n    <Geometry x:Key=\"MaximizeIcon\">F1 M 19.3333,19.3333L 0.666667,19.3333L 0.666667,0.666687L 19.3333,0.666687L 19.3333,19.3333 Z</Geometry>\n    <Geometry x:Key=\"RestoreIcon\">M 4.63867,4.77777L 0.666667,4.77777L 0.666667,19.5004L 15.3893,19.5004L 15.3893,15.3884M 19.3609,0.666687L 4.63827,0.666687L 4.63827,4.7774L 15.3889,4.7774L 15.3889,15.3894L 19.3609,15.3894L 19.3609,0.666687 Z</Geometry>\n    <Geometry x:Key=\"LandscapeModeIcon\">F1 M 42,0.169312L 42,37.1693L 21,37.1693L 21,0.169312L 42,0.169312 Z M 38,4.16937L 25,4.16937L 25,33.1693L 38,33.1693L 38,4.16937 Z M 19,37.1693L 14,37.1693L 14,33.1693L 19,33.1693L 19,37.1693 Z M 7,33.1693L 13,33.1693L 13,37.1693L 7,37.1693L 7,33.1693 Z M 6,33.1693L 6,37.1693L 0,37.1693L 0,33.1693L 6,33.1693 Z M 0,24.1693L 0,17.1693L 4.00002,17.1693L 4.00002,24.1694L 0,24.1693 Z M 12,21.1694L 5.00001,21.1693L 5.00001,17.1693L 12,17.1693L 12,21.1694 Z M 19,21.1693L 13,21.1693L 13,17.1693L 19,17.1693L 19,21.1693 Z M 6.10352e-005,25.1694L 4.00008,25.1694L 4.00004,32.1694L 2.09808e-005,32.1693L 6.10352e-005,25.1694 Z M 5.32918,6.10352e-005L 15.9167,6.10352e-005L 15.9167,2.55566L 7.8848,2.55566L 7.8848,9.40106L 11.9008,5.38507L 11.9008,9.21851L 6.42445,14.6948L 1.31322,9.58362L 1.31322,5.38507L 5.32918,9.40106L 5.32918,6.10352e-005 Z</Geometry>\n    <Geometry x:Key=\"PortraitModeIcon\">F1 M 0.169273,41.9999L 37.1693,41.9999L 37.1693,21L 0.169273,21L 0.169273,41.9999 Z M 4.1693,37.9999L 4.1693,25L 33.1693,25L 33.1693,37.9999L 4.1693,37.9999 Z M 37.1693,19L 37.1693,14L 33.1693,14L 33.1693,19L 37.1693,19 Z M 33.1693,7L 33.1693,13L 37.1693,13L 37.1693,7L 33.1693,7 Z M 33.1693,6L 37.1693,6L 37.1693,0L 33.1693,0L 33.1693,6 Z M 24.1693,0L 17.1693,0L 17.1693,4L 24.1693,4L 24.1693,0 Z M 21.1693,12L 21.1693,5L 17.1693,5L 17.1693,12L 21.1693,12 Z M 21.1693,19L 21.1693,13L 17.1693,13L 17.1693,19L 21.1693,19 Z M 25.1693,6.10352e-005L 25.1693,4.00006L 32.1693,4.00006L 32.1693,0L 25.1693,6.10352e-005 Z M 1.90735e-006,5.32916L 1.90735e-006,15.9167L 2.55562,15.9167L 2.55562,7.88477L 9.40101,7.88477L 5.38505,11.9008L 9.21847,11.9008L 14.6948,6.42444L 9.58356,1.31323L 5.38505,1.31323L 9.40101,5.32916L 1.90735e-006,5.32916 Z</Geometry>\n    <Geometry x:Key=\"AddIcon\">F1 M 16,0L 22,0L 22,16L 38,16L 38,22L 22,22L 22,38L 16,38L 16,22L 0,22L 0,16L 16,16L 16,0 Z</Geometry>\n\n    <Geometry x:Key=\"SettingsIcon\">F1 M 15.5566,12.3899C 17.3055,12.3899 18.7232,13.8077 18.7232,15.5566C 18.7232,17.3055 17.3055,18.7233 15.5566,18.7233C 13.8077,18.7233 12.3899,17.3055 12.3899,15.5566C 12.3899,13.8077 13.8077,12.3899 15.5566,12.3899 Z M 16.6491,5.35065L 21.7464,0.978882C 22.7033,1.38568 23.612,1.88397 24.4614,2.46277L 23.5458,9.11249L 30.2416,9.62549C 30.6245,10.5728 30.9185,11.5656 31.1131,12.5936L 25.7625,16.6492L 30.1342,21.7465C 29.7274,22.7034 29.2291,23.612 28.6504,24.4614L 22.0007,23.5458L 21.4876,30.2416C 20.5403,30.6246 19.5475,30.9185 18.5195,31.1131L 14.464,25.7625L 9.36667,30.1343C 8.40978,29.7274 7.50115,29.2291 6.65176,28.6504L 7.56733,22.0007L 0.871544,21.4876C 0.488571,20.5403 0.194601,19.5475 0,18.5195L 5.35067,14.464L 0.978872,9.3667C 1.38569,8.40979 1.88398,7.50116 2.46276,6.65179L 9.11247,7.56732L 9.6255,0.871582C 10.5728,0.488586 11.5656,0.194641 12.5936,0L 16.6491,5.35065 Z M 15.5566,9.22327C 12.0587,9.22327 9.22322,12.0588 9.22322,15.5566C 9.22322,19.0544 12.0587,21.8899 15.5566,21.8899C 19.0544,21.8899 21.8899,19.0544 21.8899,15.5566C 21.8899,12.0588 19.0544,9.22327 15.5566,9.22327 Z</Geometry>\n    <Geometry x:Key=\"BackIcon\">F1 M 3.74533,12.388C 7.17067,16.64 9.724,19.8093 12.2773,22.9774C 11.6907,23.4827 11.1053,23.9867 10.5187,24.4907C 7.13333,20.6027 3.74933,16.7147 0,12.4094C 3.616,8.09735 7.01067,4.04803 10.4053,0C 11.04,0.486694 11.6747,0.971985 12.3093,1.45868C 9.41467,5.15204 6.52133,8.84668 3.74533,12.388 Z</Geometry>\n    <Geometry x:Key=\"SearchIcon\">F1 M 0.585785,17.114L 5.84589,11.9957C 5.16676,10.8199 5.02814,9.45538 5.02814,8C 5.02814,3.58173 8.35986,0 12.7781,0C 17.1964,0 20.7781,3.58173 20.7781,8C 20.7781,12.4183 17.1964,15.75 12.7781,15.75C 11.3975,15.75 10.0985,15.6503 8.96497,15.0345L 3.6642,20.1924C 2.88315,20.9734 1.36683,20.9734 0.585785,20.1924C -0.195262,19.4113 -0.195262,17.895 0.585785,17.114 Z M 12.7781,3C 10.0167,3 7.77814,5.23859 7.77814,8C 7.77814,10.7614 10.0167,13 12.7781,13C 15.5396,13 17.7781,10.7614 17.7781,8C 17.7781,5.23859 15.5396,3 12.7781,3 Z</Geometry>\n\n    <Geometry x:Key=\"VolumeIcon\">F1 M 2.00027,5.00073L 6.00084,5.00073L 12.0017,6.10352e-005L 12.0017,17.0024L 6.00084,11.0016L 2.00027,11.0016C 0.895554,11.0016 0,10.106 0,9.00128L 0,7.00104C 0,5.8963 0.895554,5.00073 2.00027,5.00073 Z M 21.0029,8.00116C 21.0029,10.1891 19.9992,12.1427 18.4272,13.4265L 17.0026,12.002C 18.2171,11.0896 19.0026,9.63715 19.0026,8.00116C 19.0026,6.36523 18.2171,4.91278 17.0026,4.00043L 18.4272,2.57587C 19.9992,3.85968 21.0029,5.81317 21.0029,8.00116 Z M 17.0024,8.00116C 17.0024,9.33472 16.1324,10.465 14.9291,10.8556L 14.002,9.00128C 14.5543,9.00128 15.0021,8.55353 15.0021,8.00116C 15.0021,7.44879 14.5543,7.00104 14.002,7.00104L 14.9291,5.14673C 16.1324,5.53729 17.0024,6.66766 17.0024,8.00116 Z</Geometry>\n    <Geometry x:Key=\"VolumeMuteIcon\">F1 M 2.00027,5.00073L 6.00083,5.00073L 12.0017,6.10352e-005L 12.0017,17.0024L 6.00083,11.0016L 2.00027,11.0016C 0.895551,11.0016 0,10.106 0,9.00128L 0,7.00104C 0,5.8963 0.895551,5.00073 2.00027,5.00073 Z M 14.8453,12.0372L 18.3814,8.50116L 14.8453,4.96515L 16.9669,2.84357L 20.503,6.37958L 24.0389,2.84363L 26.1605,4.96527L 22.6246,8.50116L 26.1606,12.0372L 24.039,14.1588L 20.503,10.6228L 16.9669,14.1588L 14.8453,12.0372 Z</Geometry>\n\n    <Geometry x:Key=\"MixIcon\">F1 M 6.33333,28.5L 7.91667,28.6497L 7.91666,4.75L 33.25,0L 33.25,28.5C 33.25,31.1234 30.4145,33.25 26.9167,33.25C 23.4189,33.25 20.5833,31.1234 20.5833,28.5C 20.5833,25.8766 23.4188,23.75 26.9167,23.75C 27.4634,23.75 27.9939,23.8019 28.5,23.8997L 28.5,5.64063L 12.6667,8.60938L 12.6667,33.25C 12.6667,35.8734 9.83114,38 6.33333,38C 2.83553,38 0,35.8734 0,33.25C 0,30.6266 2.83553,28.5 6.33333,28.5 Z</Geometry>\n    <Geometry x:Key=\"CheckIcon\">F1 M 4.74998,11.0831L 15.8333,22.1664L 33.2498,-6.10352e-005L 37.9998,4.74994L 15.8333,31.6664L 1.90735e-006,15.8331L 4.74998,11.0831 Z</Geometry>\n    <Geometry x:Key=\"SaveIcon\">F1 M 0,0L 34.8333,0L 34.8333,34.8334L 25.3333,34.8334L 25.3333,23.75L 9.5,23.75L 9.5,34.8334L 0,34.8334L 0,0 Z M 12.6667,34.8334L 12.6667,30.0834L 19,30.0834L 19,34.8334L 12.6667,34.8334 Z M 6.33332,3.16669L 6.33332,12.6667L 28.5,12.6667L 28.5,3.16669L 6.33332,3.16669 Z</Geometry>\n\n    <Geometry x:Key=\"ChevronDown\">F1 M 114.043,-224.836L 114.043,-204.003L 57.793,-147.94L 1.54299,-203.753L 1.54299,-224.836L 57.793,-167.982L 114.043,-224.836 Z</Geometry>\n\n    <Geometry x:Key=\"Pin315dIcon\">F1 M 3.53583,19.625L 6.36465,16.7961L 0.176576,10.6081C 1.35525,9.90088 2.53392,9.19366 3.59473,9.31158C 4.53475,9.41602 5.38222,10.1683 6.21914,10.9944L 12.7295,6.18811C 12.0223,5.4809 11.4919,4.95044 11.6097,3.88965C 11.7276,2.82886 12.6705,1.41443 13.6135,0L 24.9288,11.3153C 23.5144,12.2582 22.0999,13.2012 21.0391,13.319C 19.9783,13.4369 19.4479,12.9065 18.7407,12.1993L 13.9344,18.7097C 14.7605,19.5466 15.5128,20.394 15.6172,21.334C 15.7351,22.3948 15.0279,23.5735 14.3207,24.7522L 8.13271,18.5642L 5.30389,21.3931L 0,24.9288L 3.53583,19.625 Z</Geometry>\n    <Geometry x:Key=\"PinIcon\">F1 M 22.7532,33.0046L 22.7532,29.004L 14.002,29.004C 14.3353,27.6705 14.6687,26.337 15.5022,25.6703C 16.2407,25.0794 17.3719,25.0121 18.5479,25.0045L 19.7528,17.0024C 18.7526,17.0024 18.0025,17.0024 17.3358,16.1689C 16.669,15.3355 16.3356,13.6686 16.0022,12.0017L 32.0045,12.0017C 31.6711,13.6686 31.3377,15.3355 30.6709,16.1689C 30.0042,17.0024 29.254,17.0024 28.2539,17.0024L 29.4588,25.0045C 30.6348,25.0121 31.766,25.0794 32.5045,25.6703C 33.338,26.337 33.6714,27.6705 34.0047,29.004L 25.2536,29.004L 25.2536,33.0046L 24.0033,39.2552L 22.7532,33.0046 Z</Geometry>\n\n    <Geometry x:Key=\"NowPlayingIcon\">M 0,16L 2.66667,16L 2.66667,10.6667L 0,10.6667L 0,16 Z M 5.27733,16L 7.944,16L 7.944,5.33331L 5.27733,5.33331L 5.27733,16 Z M 10.612,16L 13.2787,16L 13.2787,0L 10.612,0L 10.612,16 Z M 16,16L 18.668,16L 18.668,5.33331L 16,5.33331L 16,16 Z</Geometry>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/ListBoxStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Style x:Key=\"CommonListBoxStyle\" TargetType=\"{x:Type ListBox}\">\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\"/>\n        <Setter Property=\"ScrollViewer.HorizontalScrollBarVisibility\" Value=\"Auto\"/>\n        <Setter Property=\"ScrollViewer.VerticalScrollBarVisibility\" Value=\"Auto\"/>\n        <Setter Property=\"ScrollViewer.CanContentScroll\" Value=\"true\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"Both\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Center\"/>\n        <Setter Property=\"AlternationCount\" Value=\"2\" />\n        <Setter Property=\"Padding\" Value=\"15,10,15,0\"></Setter>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListBox}\">\n                    <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                        <ScrollViewer Focusable=\"False\">\n                            <ItemsPresenter SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" Margin=\"{TemplateBinding Padding}\"/>\n                        </ScrollViewer>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsGrouping\" Value=\"true\"/>\n                                <Condition Property=\"VirtualizingPanel.IsVirtualizingWhenGrouping\" Value=\"false\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"ScrollViewer.CanContentScroll\" Value=\"false\"/>\n                        </MultiTrigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"AlbumsListBoxStyle\" TargetType=\"{x:Type ListBox}\">\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\"/>\n        <Setter Property=\"ScrollViewer.HorizontalScrollBarVisibility\" Value=\"Auto\"/>\n        <Setter Property=\"ScrollViewer.VerticalScrollBarVisibility\" Value=\"Auto\"/>\n        <Setter Property=\"ScrollViewer.CanContentScroll\" Value=\"true\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"Both\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Center\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListBox}\">\n                    <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                        <ItemsPresenter SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" Margin=\"{TemplateBinding Padding}\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsGrouping\" Value=\"true\"/>\n                                <Condition Property=\"VirtualizingPanel.IsVirtualizingWhenGrouping\" Value=\"false\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"ScrollViewer.CanContentScroll\" Value=\"false\"/>\n                        </MultiTrigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"MainMenuListBoxItemStyle\" TargetType=\"{x:Type ListBoxItem}\">\n        <Setter Property=\"SnapsToDevicePixels\" Value=\"True\"/>\n        <Setter Property=\"Padding\" Value=\"0\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"FontWeight\" Value=\"Light\" />\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource SidebarInactiveForegroundBrush}\" />\n        <Setter Property=\"RenderTransform\">\n            <Setter.Value>\n                <TranslateTransform/>\n            </Setter.Value>\n        </Setter>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListBoxItem}\">\n                    <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Margin=\"18,5,10,5\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\" \n                                          Opacity=\"1\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"Bd\" Value=\"{DynamicResource MainMenuHotPlaylistItemBackgroundBrush}\"/>\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource SidebarForegroundBrush}\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"Selector.IsSelectionActive\" Value=\"False\"/>\n                                <Condition Property=\"IsSelected\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"Bd\" Value=\"{DynamicResource AccentBrush}\"/>\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource SelectedPlaylistItemForegroundBrush}\"/>\n                            <!--<Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"1\"/>-->\n                            <Setter Property=\"FontWeight\" Value=\"Regular\" />\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"Selector.IsSelectionActive\" Value=\"True\"/>\n                                <Condition Property=\"IsSelected\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"Bd\" Value=\"{DynamicResource AccentBrush}\"/>\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource SelectedPlaylistItemForegroundBrush}\"/>\n                            <!--<Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"1\"/>-->\n                            <Setter Property=\"FontWeight\" Value=\"Regular\" />\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"Bd\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"RecommendationsListBoxItemStyle\" TargetType=\"{x:Type ListBoxItem}\">\n        <Setter Property=\"SnapsToDevicePixels\" Value=\"True\"/>\n        <Setter Property=\"Padding\" Value=\"0\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource PlaylistItemForegroundBrush}\" />\n        <Setter Property=\"FontFamily\" Value=\"Segoe UI SemiLight\" />\n        <Setter Property=\"RenderTransform\">\n            <Setter.Value>\n                <TranslateTransform/>\n            </Setter.Value>\n        </Setter>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListBoxItem}\">\n                    <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Margin=\"12,5,12,5\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\" Opacity=\"1\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"Bd\" Value=\"{DynamicResource HotPlaylistItemBackgroundBrush}\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"Selector.IsSelectionActive\" Value=\"False\"/>\n                                <Condition Property=\"IsSelected\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"1\"/>\n                            <Setter Property=\"FontFamily\" Value=\"Segoe UI\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"Selector.IsSelectionActive\" Value=\"True\"/>\n                                <Condition Property=\"IsSelected\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Foreground\" Value=\"{StaticResource AccentBrush}\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"1\"/>\n                            <Setter Property=\"FontFamily\" Value=\"Segoe UI\"/>\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"Bd\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"AudioListBoxItemStyle\" TargetType=\"{x:Type ListBoxItem}\">\n        <Setter Property=\"SnapsToDevicePixels\" Value=\"True\"/>\n        <Setter Property=\"Padding\" Value=\"0,0,0,0\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListBoxItem}\">\n                    <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter Margin=\"{TemplateBinding Padding}\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"Bd\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter Property=\"Background\" TargetName=\"Bd\" Value=\"{DynamicResource HotPlaylistItemBackgroundBrush}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n        <Style.Triggers>\n            <Trigger Property=\"ItemsControl.AlternationIndex\" Value=\"0\">\n                <Setter Property=\"Background\" Value=\"{DynamicResource AudioAlternationBackgroundBrush}\" />\n            </Trigger>\n        </Style.Triggers>\n    </Style>\n\n    <!-- Стиль для стандартных альбомов (\"все аудиозаписи\", \"со стены\" и т.п.) -->\n    <Style x:Key=\"AlbumListBoxItemStyle\" TargetType=\"{x:Type ListBoxItem}\">\n        <Setter Property=\"SnapsToDevicePixels\" Value=\"True\"/>\n        <Setter Property=\"Padding\" Value=\"12,5,12,6\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource PlaylistItemForegroundBrush}\" />\n        <Setter Property=\"FontFamily\" Value=\"Segoe UI SemiLight\" />\n        <Setter Property=\"RenderTransform\">\n            <Setter.Value>\n                <TranslateTransform/>\n            </Setter.Value>\n        </Setter>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListBoxItem}\">\n                    <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Margin=\"{TemplateBinding Padding}\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\" Opacity=\"1\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"Bd\" Value=\"{DynamicResource HotPlaylistItemBackgroundBrush}\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"Selector.IsSelectionActive\" Value=\"False\"/>\n                                <Condition Property=\"IsSelected\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"1\"/>\n                            <Setter Property=\"FontFamily\" Value=\"Segoe UI\"/>\n                            <Setter Property=\"Background\" TargetName=\"Bd\" Value=\"{DynamicResource SelectedPlaylistItemBackgroundBrush}\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"Selector.IsSelectionActive\" Value=\"True\"/>\n                                <Condition Property=\"IsSelected\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"1\"/>\n                            <Setter Property=\"FontFamily\" Value=\"Segoe UI\"/>\n                            <Setter Property=\"Background\" TargetName=\"Bd\" Value=\"{DynamicResource SelectedPlaylistItemBackgroundBrush}\"/>\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"Bd\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"LastFmAlbumListBoxItemStyle\" TargetType=\"{x:Type ListBoxItem}\">\n        <Setter Property=\"SnapsToDevicePixels\" Value=\"True\"/>\n        <Setter Property=\"Padding\" Value=\"0\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource PlaylistItemForegroundBrush}\" />\n        <Setter Property=\"FontFamily\" Value=\"Segoe UI SemiLight\" />\n        <Setter Property=\"RenderTransform\">\n            <Setter.Value>\n                <TranslateTransform/>\n            </Setter.Value>\n        </Setter>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListBoxItem}\">\n                    <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Margin=\"5\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\" Opacity=\"1\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"Bd\" Value=\"{DynamicResource HotPlaylistItemBackgroundBrush}\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"Selector.IsSelectionActive\" Value=\"False\"/>\n                                <Condition Property=\"IsSelected\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"1\"/>\n                            <Setter Property=\"FontFamily\" Value=\"Segoe UI\"/>\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"Selector.IsSelectionActive\" Value=\"True\"/>\n                                <Condition Property=\"IsSelected\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"1\"/>\n                            <Setter Property=\"FontFamily\" Value=\"Segoe UI\"/>\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"Bd\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <!-- Стиль для пользовательских альбомов -->\n    <Style x:Key=\"UserAlbumListBoxItemStyle\" TargetType=\"{x:Type ListBoxItem}\" BasedOn=\"{StaticResource AlbumListBoxItemStyle}\">\n        <Setter Property=\"FontSize\" Value=\"14\" />\n    </Style>\n\n    <!-- Стиль для разделителя в списке альбомов -->\n    <Style x:Key=\"SeparatorItemStyle\" TargetType=\"ListBoxItem\">\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"Margin\" Value=\"7,5,7,5\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"IsEnabled\" Value=\"False\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ListBoxItem\">\n                    <Grid Margin=\"{TemplateBinding Padding}\" HorizontalAlignment=\"Stretch\">\n                        <Rectangle Height=\"0.5\" Fill=\"{DynamicResource ForegroundBrush}\" Opacity=\"0.3\" SnapsToDevicePixels=\"False\"/>\n                    </Grid>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"FriendListBoxItemStyle\" TargetType=\"{x:Type ListBoxItem}\">\n        <Setter Property=\"SnapsToDevicePixels\" Value=\"False\"/>\n        <Setter Property=\"Padding\" Value=\"0,0,0,0\"/>\n        <Setter Property=\"Margin\" Value=\"0,0,5,5\" />\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"3\"/>\n        <Setter Property=\"FocusVisualStyle\" Value=\"{StaticResource FocusVisual}\"/>\n        <Setter Property=\"RenderTransform\">\n            <Setter.Value>\n                <TranslateTransform/>\n            </Setter.Value>\n        </Setter>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListBoxItem}\">\n                    <Border x:Name=\"Bd\" Opacity=\"1\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"\n                                          Margin=\"-1\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\"/>\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"BorderBrush\" TargetName=\"Bd\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"Bd\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"GroupListBoxItemStyle\" TargetType=\"{x:Type ListBoxItem}\">\n        <Setter Property=\"SnapsToDevicePixels\" Value=\"False\"/>\n        <Setter Property=\"Padding\" Value=\"0,0,0,0\"/>\n        <Setter Property=\"Margin\" Value=\"0,0,5,5\" />\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"3\"/>\n        <Setter Property=\"FocusVisualStyle\" Value=\"{StaticResource FocusVisual}\"/>\n        <Setter Property=\"RenderTransform\">\n            <Setter.Value>\n                <TranslateTransform/>\n            </Setter.Value>\n        </Setter>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ListBoxItem}\">\n                    <Border x:Name=\"Bd\" Opacity=\"1\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"\n                                          Margin=\"-1\"/>\n                    </Border>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/ProgressBarStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <ControlTemplate x:Key=\"PhoneProgressBarSliderThumb\" TargetType=\"Thumb\">\n        <Rectangle IsHitTestVisible=\"False\" Width=\"3\" Height=\"3\" Fill=\"{TemplateBinding Foreground}\"/>\n    </ControlTemplate>\n    <Style x:Key=\"PhoneProgressBarSliderStyle\" TargetType=\"{x:Type Slider}\">\n        <Setter Property=\"Maximum\" Value=\"3000\"/>\n        <Setter Property=\"Minimum\" Value=\"0\"/>\n        <Setter Property=\"Opacity\" Value=\"1\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Slider}\">\n                    <Grid x:Name=\"GridRoot\">\n                        <Grid.RowDefinitions>\n                            <RowDefinition Height=\"Auto\"/>\n                            <RowDefinition Height=\"Auto\" MinHeight=\"{TemplateBinding MinHeight}\"/>\n                            <RowDefinition Height=\"Auto\"/>\n                        </Grid.RowDefinitions>\n\n                        <!-- The Track lays out the repeat buttons and thumb -->\n                        <Track Grid.Row=\"1\" x:Name=\"PART_Track\">\n                            <Track.Thumb>\n                                <Thumb x:Name=\"Thumb\" Template=\"{StaticResource PhoneProgressBarSliderThumb}\" Foreground=\"{TemplateBinding Foreground}\"/>\n                            </Track.Thumb>\n                            <Track.IncreaseRepeatButton>\n                                <RepeatButton Command=\"Slider.IncreaseLarge\" Template=\"{x:Null}\"/>\n                            </Track.IncreaseRepeatButton>\n                            <Track.DecreaseRepeatButton>\n                                <RepeatButton Command=\"Slider.DecreaseLarge\" Template=\"{x:Null}\"/>\n                            </Track.DecreaseRepeatButton>\n                        </Track>\n                    </Grid>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"CommonProgressBarStyle\" TargetType=\"{x:Type ProgressBar}\">\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\"/>\n        <Setter Property=\"IsHitTestVisible\" Value=\"False\"/>\n        <Setter Property=\"Padding\" Value=\"12\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ProgressBar\">\n                    <Grid>\n                        <VisualStateManager.VisualStateGroups>\n                            <VisualStateGroup x:Name=\"CommonStates\">\n                                <VisualState x:Name=\"Determinate\"/>\n                                <VisualState x:Name=\"Indeterminate\">\n                                    <Storyboard RepeatBehavior=\"Forever\" Duration=\"00:00:04.4\">\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName=\"IndeterminateRoot\" Storyboard.TargetProperty=\"Visibility\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Visible</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName=\"DeterminateRoot\" Storyboard.TargetProperty=\"Visibility\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"0\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Collapsed</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider1\" Storyboard.TargetProperty=\"Value\">\n                                            <EasingDoubleKeyFrame Value=\"1000\" \tKeyTime=\"00:00:00.5\">\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                            <LinearDoubleKeyFrame Value=\"2000\" \tKeyTime=\"00:00:02.0\" />\n                                            <EasingDoubleKeyFrame Value=\"3000\" \tKeyTime=\"00:00:02.5\" >\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseIn\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                        </DoubleAnimationUsingKeyFrames>\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider2\" Storyboard.TargetProperty=\"Value\" BeginTime=\"00:00:00.2\">\n                                            <EasingDoubleKeyFrame Value=\"1000\" \tKeyTime=\"00:00:00.5\">\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                            <LinearDoubleKeyFrame Value=\"2000\" \tKeyTime=\"00:00:02.0\" />\n                                            <EasingDoubleKeyFrame Value=\"3000\" \tKeyTime=\"00:00:02.5\" >\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseIn\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                        </DoubleAnimationUsingKeyFrames>\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider3\" Storyboard.TargetProperty=\"Value\" BeginTime=\"00:00:00.4\">\n                                            <EasingDoubleKeyFrame Value=\"1000\" \tKeyTime=\"00:00:00.5\">\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                            <LinearDoubleKeyFrame Value=\"2000\" \tKeyTime=\"00:00:02.0\" />\n                                            <EasingDoubleKeyFrame Value=\"3000\" \tKeyTime=\"00:00:02.5\" >\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseIn\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                        </DoubleAnimationUsingKeyFrames>\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider4\" Storyboard.TargetProperty=\"Value\" BeginTime=\"00:00:00.6\">\n                                            <EasingDoubleKeyFrame Value=\"1000\" \tKeyTime=\"00:00:00.5\">\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                            <LinearDoubleKeyFrame Value=\"2000\" \tKeyTime=\"00:00:02.0\" />\n                                            <EasingDoubleKeyFrame Value=\"3000\" \tKeyTime=\"00:00:02.5\" >\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseIn\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                        </DoubleAnimationUsingKeyFrames>\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider5\" Storyboard.TargetProperty=\"Value\" BeginTime=\"00:00:00.8\">\n                                            <EasingDoubleKeyFrame Value=\"1000\" \tKeyTime=\"00:00:00.5\">\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                            <LinearDoubleKeyFrame Value=\"2000\" \tKeyTime=\"00:00:02.0\" />\n                                            <EasingDoubleKeyFrame Value=\"3000\" \tKeyTime=\"00:00:02.5\" >\n                                                <EasingDoubleKeyFrame.EasingFunction>\n                                                    <ExponentialEase EasingMode=\"EaseIn\" Exponent=\"1\"/>\n                                                </EasingDoubleKeyFrame.EasingFunction>\n                                            </EasingDoubleKeyFrame>\n                                        </DoubleAnimationUsingKeyFrames>\n\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider1\" Storyboard.TargetProperty=\"Opacity\">\n                                            <DiscreteDoubleKeyFrame Value=\"1\"\tKeyTime=\"0\" />\n                                            <DiscreteDoubleKeyFrame Value=\"0\"\tKeyTime=\"00:00:02.5\" />\n                                        </DoubleAnimationUsingKeyFrames>\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider2\" Storyboard.TargetProperty=\"Opacity\" BeginTime=\"00:00:00.2\">\n                                            <DiscreteDoubleKeyFrame Value=\"1\"\tKeyTime=\"0\" />\n                                            <DiscreteDoubleKeyFrame Value=\"0\"\tKeyTime=\"00:00:02.5\" />\n                                        </DoubleAnimationUsingKeyFrames>\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider3\" Storyboard.TargetProperty=\"Opacity\" BeginTime=\"00:00:00.4\">\n                                            <DiscreteDoubleKeyFrame Value=\"1\"\tKeyTime=\"0\" />\n                                            <DiscreteDoubleKeyFrame Value=\"0\"\tKeyTime=\"00:00:02.5\" />\n                                        </DoubleAnimationUsingKeyFrames>\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider4\" Storyboard.TargetProperty=\"Opacity\" BeginTime=\"00:00:00.6\">\n                                            <DiscreteDoubleKeyFrame Value=\"1\"\tKeyTime=\"0\" />\n                                            <DiscreteDoubleKeyFrame Value=\"0\"\tKeyTime=\"00:00:02.5\" />\n                                        </DoubleAnimationUsingKeyFrames>\n                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName=\"Slider5\" Storyboard.TargetProperty=\"Opacity\" BeginTime=\"00:00:00.8\">\n                                            <DiscreteDoubleKeyFrame Value=\"1\"\tKeyTime=\"0\" />\n                                            <DiscreteDoubleKeyFrame Value=\"0\"\tKeyTime=\"00:00:02.5\" />\n                                        </DoubleAnimationUsingKeyFrames>\n                                    </Storyboard>\n                                </VisualState>\n                            </VisualStateGroup>\n                        </VisualStateManager.VisualStateGroups>\n                        <Grid x:Name=\"DeterminateRoot\" Visibility=\"Visible\" Margin=\"{TemplateBinding Padding}\" Background=\"{TemplateBinding Background}\">\n                            <Rectangle x:Name=\"PART_Track\" Opacity=\"0.1\" Height=\"4\"/>\n                            <Rectangle x:Name=\"PART_Indicator\" Fill=\"{TemplateBinding Foreground}\" HorizontalAlignment=\"Left\"  Height=\"4\" />\n                        </Grid>\n                        <Border x:Name=\"IndeterminateRoot\" Visibility=\"Collapsed\" Margin=\"{TemplateBinding Padding}\" ClipToBounds=\"True\">\n                            <Grid Margin=\"-5,0,0,0\">\n                                <Slider x:Name=\"Slider1\" Style=\"{StaticResource PhoneProgressBarSliderStyle}\" Foreground=\"{TemplateBinding Foreground}\"/>\n                                <Slider x:Name=\"Slider2\" Style=\"{StaticResource PhoneProgressBarSliderStyle}\" Foreground=\"{TemplateBinding Foreground}\"/>\n                                <Slider x:Name=\"Slider3\" Style=\"{StaticResource PhoneProgressBarSliderStyle}\" Foreground=\"{TemplateBinding Foreground}\"/>\n                                <Slider x:Name=\"Slider4\" Style=\"{StaticResource PhoneProgressBarSliderStyle}\" Foreground=\"{TemplateBinding Foreground}\"/>\n                                <Slider x:Name=\"Slider5\" Style=\"{StaticResource PhoneProgressBarSliderStyle}\" Foreground=\"{TemplateBinding Foreground}\"/>\n                            </Grid>\n                        </Border>\n                    </Grid>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"HeaderProgressBarStyle\" BasedOn=\"{StaticResource CommonProgressBarStyle}\" TargetType=\"{x:Type ProgressBar}\">\n        <Setter Property=\"VerticalAlignment\" Value=\"Top\" />\n        <Setter Property=\"HorizontalAlignment\" Value=\"Left\" />\n        <Setter Property=\"Width\" Value=\"200\" />\n        <Setter Property=\"Margin\" Value=\"24,2,0,0\" />\n        <Setter Property=\"Padding\" Value=\"0\" />\n        <Setter Property=\"Height\" Value=\"5\" />\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/ScrollbarStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:system=\"clr-namespace:System;assembly=mscorlib\">\n    <SolidColorBrush x:Key=\"ScrollBar.Static.Background\" Color=\"Transparent\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Static.Border\" Color=\"#F0F0F0\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Pressed.Glyph\" Color=\"#FFFFFF\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.MouseOver.Glyph\" Color=\"#000000\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Disabled.Glyph\" Color=\"#BFBFBF\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Static.Glyph\" Color=\"#606060\"/>\n    <Style x:Key=\"FocusVisual\">\n        <Setter Property=\"Control.Template\">\n            <Setter.Value>\n                <ControlTemplate>\n                    <Rectangle Margin=\"2\" SnapsToDevicePixels=\"true\" Stroke=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\" StrokeThickness=\"1\" StrokeDashArray=\"1 2\"/>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <SolidColorBrush x:Key=\"ScrollBar.MouseOver.Background\" Color=\"#DADADA\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.MouseOver.Border\" Color=\"#DADADA\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Pressed.Background\" Color=\"#606060\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Pressed.Border\" Color=\"#606060\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Disabled.Background\" Color=\"#F0F0F0\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Disabled.Border\" Color=\"#F0F0F0\"/>\n    <Style x:Key=\"ScrollBarButton\" TargetType=\"{x:Type RepeatButton}\">\n        <Setter Property=\"FocusVisualStyle\" Value=\"{StaticResource FocusVisual}\"/>\n        <Setter Property=\"BorderThickness\" Value=\"1\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Center\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Center\"/>\n        <Setter Property=\"Padding\" Value=\"1\"/>\n        <Setter Property=\"Focusable\" Value=\"false\"/>\n        <Setter Property=\"IsTabStop\" Value=\"false\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type RepeatButton}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{StaticResource ScrollBar.Static.Border}\" BorderThickness=\"1\" Background=\"{StaticResource ScrollBar.Static.Background}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{StaticResource ScrollBar.MouseOver.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{StaticResource ScrollBar.MouseOver.Border}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsPressed\" Value=\"true\">\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{StaticResource ScrollBar.Pressed.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{StaticResource ScrollBar.Pressed.Border}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"false\">\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"0.56\"/>\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{StaticResource ScrollBar.Disabled.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{StaticResource ScrollBar.Disabled.Border}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"RepeatButtonTransparent\" TargetType=\"{x:Type RepeatButton}\">\n        <Setter Property=\"OverridesDefaultStyle\" Value=\"true\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"Focusable\" Value=\"false\"/>\n        <Setter Property=\"IsTabStop\" Value=\"false\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type RepeatButton}\">\n                    <Rectangle Fill=\"{TemplateBinding Background}\" Height=\"{TemplateBinding Height}\" Width=\"{TemplateBinding Width}\"/>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <SolidColorBrush x:Key=\"ScrollBar.MouseOver.Thumb\" Color=\"#A6A6A6\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Pressed.Thumb\" Color=\"#606060\"/>\n    <SolidColorBrush x:Key=\"ScrollBar.Static.Thumb\" Color=\"{DynamicResource ForegroundColor}\"/>\n    <Style x:Key=\"ScrollBarThumbVertical\" TargetType=\"{x:Type Thumb}\">\n        <Setter Property=\"OverridesDefaultStyle\" Value=\"true\"/>\n        <Setter Property=\"IsTabStop\" Value=\"false\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Thumb}\">\n                    <Grid Background=\"Transparent\">\n                        <Rectangle x:Name=\"rectangle\" Fill=\"{StaticResource ScrollBar.Static.Thumb}\" Height=\"{TemplateBinding Height}\" Opacity=\"0.4\" SnapsToDevicePixels=\"True\" Width=\"7\" HorizontalAlignment=\"Right\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Opacity\" TargetName=\"rectangle\" Value=\"0.7\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsDragging\" Value=\"true\">\n                            <Setter Property=\"Opacity\" TargetName=\"rectangle\" Value=\"0.7\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"ScrollBarThumbHorizontal\" TargetType=\"{x:Type Thumb}\">\n        <Setter Property=\"OverridesDefaultStyle\" Value=\"true\"/>\n        <Setter Property=\"IsTabStop\" Value=\"false\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Thumb}\">\n                    <Grid Background=\"Transparent\">\n                        <Rectangle x:Name=\"rectangle\" Fill=\"{StaticResource ScrollBar.Static.Thumb}\" Opacity=\"0.4\" Height=\"7\" SnapsToDevicePixels=\"True\" Width=\"{TemplateBinding Width}\" VerticalAlignment=\"Bottom\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"Opacity\" TargetName=\"rectangle\" Value=\"0.7\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsDragging\" Value=\"true\">\n                            <Setter Property=\"Opacity\" TargetName=\"rectangle\" Value=\"0.7\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style TargetType=\"{x:Type ScrollBar}\">\n        <Setter Property=\"Stylus.IsPressAndHoldEnabled\" Value=\"false\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"false\"/>\n        <Setter Property=\"Background\" Value=\"{StaticResource ScrollBar.Static.Background}\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{StaticResource ScrollBar.Static.Border}\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"Width\" Value=\"10\"/>\n        <Setter Property=\"Opacity\" Value=\"0\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ScrollBar}\">\n                    <Grid x:Name=\"Bg\" SnapsToDevicePixels=\"true\">\n                        <Track x:Name=\"PART_Track\" IsDirectionReversed=\"true\" IsEnabled=\"{TemplateBinding IsMouseOver}\" Grid.Row=\"1\">\n                            <Track.Resources>\n                                <!-- Set the Thumb's minimum height to 50.\n                                The Thumb's minimum height is half the\n                                value of VerticalScrollBarButtonHeightKey. -->\n                                <system:Double x:Key=\"{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}\">\n                                    100\n                                </system:Double>\n                            </Track.Resources>\n                            <Track.DecreaseRepeatButton>\n                                <RepeatButton Command=\"{x:Static ScrollBar.PageUpCommand}\" Style=\"{StaticResource RepeatButtonTransparent}\"/>\n                            </Track.DecreaseRepeatButton>\n                            <Track.IncreaseRepeatButton>\n                                <RepeatButton Command=\"{x:Static ScrollBar.PageDownCommand}\" Style=\"{StaticResource RepeatButtonTransparent}\"/>\n                            </Track.IncreaseRepeatButton>\n                            <Track.Thumb>\n                                <Thumb Style=\"{StaticResource ScrollBarThumbVertical}\"/>\n                            </Track.Thumb>\n                        </Track>\n                    </Grid>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n        <Style.Triggers>\n            <Trigger Property=\"Orientation\" Value=\"Horizontal\">\n                <Setter Property=\"Width\" Value=\"Auto\"/>\n                <Setter Property=\"MinWidth\" Value=\"0\"/>\n                <Setter Property=\"Height\" Value=\"10\"/>\n                <Setter Property=\"BorderThickness\" Value=\"0\"/>\n                <Setter Property=\"Template\">\n                    <Setter.Value>\n                        <ControlTemplate TargetType=\"{x:Type ScrollBar}\">\n                            <Grid x:Name=\"Bg\" SnapsToDevicePixels=\"true\">\n                                <Track x:Name=\"PART_Track\" IsEnabled=\"{TemplateBinding IsMouseOver}\">\n                                    <Track.Resources>\n                                        <!-- Set the Thumb's minimum height to 50.\n                                The Thumb's minimum height is half the\n                                value of VerticalScrollBarButtonHeightKey. -->\n                                        <system:Double x:Key=\"{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}\">\n                                            100\n                                        </system:Double>\n                                    </Track.Resources>\n                                    <Track.DecreaseRepeatButton>\n                                        <RepeatButton Command=\"{x:Static ScrollBar.PageLeftCommand}\" Style=\"{StaticResource RepeatButtonTransparent}\"/>\n                                    </Track.DecreaseRepeatButton>\n                                    <Track.IncreaseRepeatButton>\n                                        <RepeatButton Command=\"{x:Static ScrollBar.PageRightCommand}\" Style=\"{StaticResource RepeatButtonTransparent}\"/>\n                                    </Track.IncreaseRepeatButton>\n                                    <Track.Thumb>\n                                        <Thumb Style=\"{StaticResource ScrollBarThumbHorizontal}\"/>\n                                    </Track.Thumb>\n                                </Track>\n                            </Grid>\n                        </ControlTemplate>\n                    </Setter.Value>\n                </Setter>\n            </Trigger>\n        </Style.Triggers>\n    </Style>\n\n    <Style TargetType=\"{x:Type ScrollViewer}\">\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ScrollViewer}\">\n                    <Grid x:Name=\"Grid\" Background=\"{TemplateBinding Background}\">\n                        <Grid.Triggers>\n                            <EventTrigger RoutedEvent=\"MouseEnter\">\n                                <BeginStoryboard>\n                                    <Storyboard>\n                                        <DoubleAnimation Storyboard.TargetName=\"PART_VerticalScrollBar\" Storyboard.TargetProperty=\"Opacity\" To=\"1\" Duration=\"0:0:0.2\"/>\n                                        <DoubleAnimation Storyboard.TargetName=\"PART_HorizontalScrollBar\" Storyboard.TargetProperty=\"Opacity\" To=\"1\" Duration=\"0:0:0.2\"/>\n                                    </Storyboard>\n                                </BeginStoryboard>\n                            </EventTrigger>\n                            <EventTrigger RoutedEvent=\"MouseLeave\">\n                                <BeginStoryboard>\n                                    <Storyboard BeginTime=\"0:0:0.5\">\n                                        <DoubleAnimation Storyboard.TargetName=\"PART_VerticalScrollBar\" Storyboard.TargetProperty=\"Opacity\" To=\"0\" Duration=\"0:0:0.2\"/>\n                                        <DoubleAnimation Storyboard.TargetName=\"PART_HorizontalScrollBar\" Storyboard.TargetProperty=\"Opacity\" To=\"0\" Duration=\"0:0:0.2\"/>\n                                    </Storyboard>\n                                </BeginStoryboard>\n                            </EventTrigger>\n                        </Grid.Triggers>\n                        <ScrollContentPresenter x:Name=\"PART_ScrollContentPresenter\" CanContentScroll=\"{TemplateBinding CanContentScroll}\" CanHorizontallyScroll=\"False\" CanVerticallyScroll=\"False\" ContentTemplate=\"{TemplateBinding ContentTemplate}\" Content=\"{TemplateBinding Content}\" Grid.Column=\"0\" Margin=\"{TemplateBinding Padding}\" Grid.Row=\"0\"/>\n                        <ScrollBar x:Name=\"PART_VerticalScrollBar\" HorizontalAlignment=\"Right\" AutomationProperties.AutomationId=\"VerticalScrollBar\" Cursor=\"Arrow\" Grid.Column=\"1\" Maximum=\"{TemplateBinding ScrollableHeight}\" Minimum=\"0\" Grid.Row=\"0\" Visibility=\"{TemplateBinding ComputedVerticalScrollBarVisibility}\" Value=\"{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}\" ViewportSize=\"{TemplateBinding ViewportHeight}\"/>\n                        <ScrollBar x:Name=\"PART_HorizontalScrollBar\" VerticalAlignment=\"Bottom\" AutomationProperties.AutomationId=\"HorizontalScrollBar\" Cursor=\"Arrow\" Grid.Column=\"0\" Maximum=\"{TemplateBinding ScrollableWidth}\" Minimum=\"0\" Orientation=\"Horizontal\" Grid.Row=\"1\" Visibility=\"{TemplateBinding ComputedHorizontalScrollBarVisibility}\" Value=\"{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}\" ViewportSize=\"{TemplateBinding ViewportWidth}\"/>\n                    </Grid>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/SliderStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <SolidColorBrush x:Key=\"SliderThumb.Static.Foreground\" Color=\"#FFE5E5E5\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.MouseOver.Background\" Color=\"#FFDCECFC\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.MouseOver.Border\" Color=\"#FF7Eb4EA\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.Pressed.Background\" Color=\"#FFDAECFC\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.Pressed.Border\" Color=\"#FF569DE5\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.Disabled.Background\" Color=\"#FFF0F0F0\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.Disabled.Border\" Color=\"#FFD9D9D9\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.Static.Background\" Color=\"#FFFFFF\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.Static.Border\" Color=\"#231f20\" Opacity=\"0.2\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.Track.Border\" Color=\"Transparent\"/>\n    <SolidColorBrush x:Key=\"SliderThumb.Track.Background\" Color=\"{StaticResource AccentColor}\"/>\n\n    <ControlTemplate x:Key=\"SliderThumbHorizontalTop\" TargetType=\"{x:Type Thumb}\">\n        <Grid HorizontalAlignment=\"Center\" UseLayoutRounding=\"True\" VerticalAlignment=\"Center\">\n            <Path x:Name=\"grip\" Data=\"M 0,6 C0,6 5.5,0 5.5,0 5.5,0 11,6 11,6 11,6 11,18 11,18 11,18 0,18 0,18 0,18 0,6 0,6 z\" Fill=\"{StaticResource SliderThumb.Static.Background}\" Stretch=\"Fill\" SnapsToDevicePixels=\"True\" Stroke=\"{StaticResource SliderThumb.Static.Border}\" StrokeThickness=\"1\" UseLayoutRounding=\"True\" VerticalAlignment=\"Center\"/>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.MouseOver.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.MouseOver.Border}\"/>\n            </Trigger>\n            <Trigger Property=\"IsDragging\" Value=\"true\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Pressed.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Pressed.Border}\"/>\n            </Trigger>\n            <Trigger Property=\"IsEnabled\" Value=\"false\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Border}\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n    <ControlTemplate x:Key=\"SliderThumbHorizontalBottom\" TargetType=\"{x:Type Thumb}\">\n        <Grid HorizontalAlignment=\"Center\" UseLayoutRounding=\"True\" VerticalAlignment=\"Center\">\n            <Path x:Name=\"grip\" Data=\"M 0,12 C0,12 5.5,18 5.5,18 5.5,18 11,12 11,12 11,12 11,0 11,0 11,0 0,0 0,0 0,0 0,12 0,12 z\" Fill=\"{StaticResource SliderThumb.Static.Background}\" Stretch=\"Fill\" SnapsToDevicePixels=\"True\" Stroke=\"{StaticResource SliderThumb.Static.Border}\" StrokeThickness=\"1\" UseLayoutRounding=\"True\" VerticalAlignment=\"Center\"/>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.MouseOver.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.MouseOver.Border}\"/>\n            </Trigger>\n            <Trigger Property=\"IsDragging\" Value=\"true\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Pressed.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Pressed.Border}\"/>\n            </Trigger>\n            <Trigger Property=\"IsEnabled\" Value=\"false\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Border}\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n\n    <Style x:Key=\"RepeatButtonTransparent\" TargetType=\"{x:Type RepeatButton}\">\n        <Setter Property=\"OverridesDefaultStyle\" Value=\"true\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"Focusable\" Value=\"false\"/>\n        <Setter Property=\"IsTabStop\" Value=\"false\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type RepeatButton}\">\n                    <Rectangle Fill=\"{TemplateBinding Background}\" Height=\"{TemplateBinding Height}\" Width=\"{TemplateBinding Width}\"/>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <ControlTemplate x:Key=\"SliderThumbHorizontalDefault\" TargetType=\"{x:Type Thumb}\">\n        <Grid HorizontalAlignment=\"Center\" UseLayoutRounding=\"False\" VerticalAlignment=\"Center\">\n            <Rectangle x:Name=\"grip\" Width=\"14\" Height=\"14\" RadiusX=\"12\" RadiusY=\"12\" Margin=\"0\" Fill=\"{StaticResource SliderThumb.Static.Background}\" Stretch=\"Fill\" SnapsToDevicePixels=\"True\" Stroke=\"#22000000\" StrokeThickness=\"1\" UseLayoutRounding=\"True\" VerticalAlignment=\"Center\">\n                <Rectangle.Effect>\n                    <DropShadowEffect Direction=\"-90\" BlurRadius=\"2\" ShadowDepth=\"2\" Opacity=\"0.2\"/>\n                </Rectangle.Effect>\n            </Rectangle>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                <Setter Property=\"Width\" TargetName=\"grip\" Value=\"14\"/>\n                <Setter Property=\"Height\" TargetName=\"grip\" Value=\"14\"/>\n            </Trigger>\n            <Trigger Property=\"IsEnabled\" Value=\"false\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Border}\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n    <ControlTemplate x:Key=\"SliderHorizontal\" TargetType=\"{x:Type Slider}\">\n        <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"Transparent\" SnapsToDevicePixels=\"False\" Padding=\"0,4,0,4\" Margin=\"0,-4,0,0\">\n            <Grid>\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\"/>\n                    <RowDefinition Height=\"Auto\" MinHeight=\"{TemplateBinding MinHeight}\"/>\n                    <RowDefinition Height=\"Auto\"/>\n                </Grid.RowDefinitions>\n                <TickBar x:Name=\"TopTick\" Fill=\"{TemplateBinding Foreground}\" Height=\"4\" Margin=\"0,0,0,2\" Placement=\"Top\" Grid.Row=\"0\" Visibility=\"Collapsed\"/>\n                <TickBar x:Name=\"BottomTick\" Fill=\"{TemplateBinding Foreground}\" Height=\"4\" Margin=\"0,2,0,0\" Placement=\"Bottom\" Grid.Row=\"2\" Visibility=\"Collapsed\"/>\n                <Border x:Name=\"TrackBackground\" BorderBrush=\"{StaticResource SliderThumb.Track.Border}\" BorderThickness=\"1\" Background=\"{TemplateBinding Background}\" Height=\"5\" Margin=\"0,0\" Grid.Row=\"1\" VerticalAlignment=\"center\">\n                    <Canvas Margin=\"-6,-1\">\n                        <Rectangle x:Name=\"PART_SelectionRange\" Fill=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\" Height=\"4.0\" Visibility=\"Hidden\"/>\n                    </Canvas>\n                </Border>\n                <Track x:Name=\"PART_Track\" Grid.Row=\"1\">\n                    <Track.DecreaseRepeatButton>\n                        <RepeatButton Command=\"{x:Static Slider.DecreaseLarge}\" Style=\"{StaticResource RepeatButtonTransparent}\" Background=\"{DynamicResource AccentBrush}\" Height=\"3\"/>\n                    </Track.DecreaseRepeatButton>\n                    <Track.IncreaseRepeatButton>\n                        <RepeatButton Command=\"{x:Static Slider.IncreaseLarge}\" Style=\"{StaticResource RepeatButtonTransparent}\"/>\n                    </Track.IncreaseRepeatButton>\n                    <Track.Thumb>\n                        <Thumb x:Name=\"Thumb\" Focusable=\"False\" OverridesDefaultStyle=\"True\" Template=\"{StaticResource SliderThumbHorizontalDefault}\" VerticalAlignment=\"Center\"/>\n                    </Track.Thumb>\n                </Track>\n            </Grid>\n        </Border>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"TickPlacement\" Value=\"TopLeft\">\n                <Setter Property=\"Visibility\" TargetName=\"TopTick\" Value=\"Visible\"/>\n                <Setter Property=\"Template\" TargetName=\"Thumb\" Value=\"{StaticResource SliderThumbHorizontalTop}\"/>\n                <Setter Property=\"Margin\" TargetName=\"TrackBackground\" Value=\"5,2,5,0\"/>\n            </Trigger>\n            <Trigger Property=\"TickPlacement\" Value=\"BottomRight\">\n                <Setter Property=\"Visibility\" TargetName=\"BottomTick\" Value=\"Visible\"/>\n                <Setter Property=\"Template\" TargetName=\"Thumb\" Value=\"{StaticResource SliderThumbHorizontalBottom}\"/>\n                <Setter Property=\"Margin\" TargetName=\"TrackBackground\" Value=\"5,0,5,2\"/>\n            </Trigger>\n            <Trigger Property=\"TickPlacement\" Value=\"Both\">\n                <Setter Property=\"Visibility\" TargetName=\"TopTick\" Value=\"Visible\"/>\n                <Setter Property=\"Visibility\" TargetName=\"BottomTick\" Value=\"Visible\"/>\n            </Trigger>\n            <Trigger Property=\"IsSelectionRangeEnabled\" Value=\"true\">\n                <Setter Property=\"Visibility\" TargetName=\"PART_SelectionRange\" Value=\"Visible\"/>\n            </Trigger>\n            <Trigger Property=\"IsKeyboardFocused\" Value=\"true\">\n                <Setter Property=\"Foreground\" TargetName=\"Thumb\" Value=\"Blue\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n    <ControlTemplate x:Key=\"SliderThumbVerticalLeft\" TargetType=\"{x:Type Thumb}\">\n        <Grid HorizontalAlignment=\"Center\" UseLayoutRounding=\"True\" VerticalAlignment=\"Center\">\n            <Path x:Name=\"grip\" Data=\"M 6,11 C6,11 0,5.5 0,5.5 0,5.5 6,0 6,0 6,0 18,0 18,0 18,0 18,11 18,11 18,11 6,11 6,11 z\" Fill=\"{StaticResource SliderThumb.Static.Background}\" Stretch=\"Fill\" Stroke=\"{StaticResource SliderThumb.Static.Border}\"/>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.MouseOver.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.MouseOver.Border}\"/>\n            </Trigger>\n            <Trigger Property=\"IsDragging\" Value=\"true\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Pressed.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Pressed.Border}\"/>\n            </Trigger>\n            <Trigger Property=\"IsEnabled\" Value=\"false\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Border}\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n    <ControlTemplate x:Key=\"SliderThumbVerticalRight\" TargetType=\"{x:Type Thumb}\">\n        <Grid HorizontalAlignment=\"Center\" UseLayoutRounding=\"True\" VerticalAlignment=\"Center\">\n            <Path x:Name=\"grip\" Data=\"M 12,11 C12,11 18,5.5 18,5.5 18,5.5 12,0 12,0 12,0 0,0 0,0 0,0 0,11 0,11 0,11 12,11 12,11 z\" Fill=\"{StaticResource SliderThumb.Static.Background}\" Stretch=\"Fill\" Stroke=\"{StaticResource SliderThumb.Static.Border}\"/>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.MouseOver.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.MouseOver.Border}\"/>\n            </Trigger>\n            <Trigger Property=\"IsDragging\" Value=\"true\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Pressed.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Pressed.Border}\"/>\n            </Trigger>\n            <Trigger Property=\"IsEnabled\" Value=\"false\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Border}\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n    <ControlTemplate x:Key=\"SliderThumbVerticalDefault\" TargetType=\"{x:Type Thumb}\">\n        <Grid HorizontalAlignment=\"Center\" UseLayoutRounding=\"False\" VerticalAlignment=\"Center\">\n            <Rectangle x:Name=\"grip\" Width=\"8\" Height=\"8\" RadiusX=\"10\" RadiusY=\"10\" Margin=\"-15\"  Fill=\"{StaticResource SliderThumb.Static.Background}\" Stretch=\"Fill\" SnapsToDevicePixels=\"False\" Stroke=\"{StaticResource SliderThumb.Static.Border}\" StrokeThickness=\"0\" UseLayoutRounding=\"True\" VerticalAlignment=\"Center\"/>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                <Setter Property=\"Width\" TargetName=\"grip\" Value=\"11\"/>\n                <Setter Property=\"Height\" TargetName=\"grip\" Value=\"11\"/>\n            </Trigger>\n            <Trigger Property=\"IsEnabled\" Value=\"false\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Border}\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n    <ControlTemplate x:Key=\"SliderVertical\" TargetType=\"{x:Type Slider}\">\n        <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"False\">\n            <Grid>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\"/>\n                    <ColumnDefinition MinWidth=\"{TemplateBinding MinWidth}\" Width=\"Auto\"/>\n                    <ColumnDefinition Width=\"Auto\"/>\n                </Grid.ColumnDefinitions>\n                <TickBar x:Name=\"TopTick\" Grid.Column=\"0\" Fill=\"{TemplateBinding Foreground}\" Margin=\"0,0,2,0\" Placement=\"Left\" Visibility=\"Collapsed\" Width=\"4\"/>\n                <TickBar x:Name=\"BottomTick\" Grid.Column=\"2\" Fill=\"{TemplateBinding Foreground}\" Margin=\"2,0,0,0\" Placement=\"Right\" Visibility=\"Collapsed\" Width=\"4\"/>\n                <Border x:Name=\"TrackBackground\" BorderBrush=\"{StaticResource SliderThumb.Track.Border}\" BorderThickness=\"1\" Background=\"{DynamicResource ProgressBarBackgroundBrush}\" Grid.Column=\"1\" HorizontalAlignment=\"center\" Margin=\"0,5\" Width=\"5.0\">\n                    <Canvas Margin=\"-1,-6\">\n                        <Rectangle x:Name=\"PART_SelectionRange\" Fill=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\" Visibility=\"Hidden\" Width=\"4.0\"/>\n                    </Canvas>\n                </Border>\n                <Track x:Name=\"PART_Track\" Grid.Column=\"1\">\n                    <Track.DecreaseRepeatButton>\n                        <RepeatButton Command=\"{x:Static Slider.DecreaseLarge}\" Style=\"{StaticResource RepeatButtonTransparent}\" Background=\"{StaticResource SliderThumb.Track.Background}\" Width=\"3\"/>\n                    </Track.DecreaseRepeatButton>\n                    <Track.IncreaseRepeatButton>\n                        <RepeatButton Command=\"{x:Static Slider.IncreaseLarge}\" Style=\"{StaticResource RepeatButtonTransparent}\"/>\n                    </Track.IncreaseRepeatButton>\n                    <Track.Thumb>\n                        <Thumb x:Name=\"Thumb\" Focusable=\"False\" OverridesDefaultStyle=\"True\" Template=\"{StaticResource SliderThumbVerticalDefault}\" VerticalAlignment=\"Top\"/>\n                    </Track.Thumb>\n                </Track>\n            </Grid>\n        </Border>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"TickPlacement\" Value=\"TopLeft\">\n                <Setter Property=\"Visibility\" TargetName=\"TopTick\" Value=\"Visible\"/>\n                <Setter Property=\"Template\" TargetName=\"Thumb\" Value=\"{StaticResource SliderThumbVerticalLeft}\"/>\n                <Setter Property=\"Margin\" TargetName=\"TrackBackground\" Value=\"2,5,0,5\"/>\n            </Trigger>\n            <Trigger Property=\"TickPlacement\" Value=\"BottomRight\">\n                <Setter Property=\"Visibility\" TargetName=\"BottomTick\" Value=\"Visible\"/>\n                <Setter Property=\"Template\" TargetName=\"Thumb\" Value=\"{StaticResource SliderThumbVerticalRight}\"/>\n                <Setter Property=\"Margin\" TargetName=\"TrackBackground\" Value=\"0,5,2,5\"/>\n            </Trigger>\n            <Trigger Property=\"TickPlacement\" Value=\"Both\">\n                <Setter Property=\"Visibility\" TargetName=\"TopTick\" Value=\"Visible\"/>\n                <Setter Property=\"Visibility\" TargetName=\"BottomTick\" Value=\"Visible\"/>\n            </Trigger>\n            <Trigger Property=\"IsSelectionRangeEnabled\" Value=\"true\">\n                <Setter Property=\"Visibility\" TargetName=\"PART_SelectionRange\" Value=\"Visible\"/>\n            </Trigger>\n            <Trigger Property=\"IsKeyboardFocused\" Value=\"true\">\n                <Setter Property=\"Foreground\" TargetName=\"Thumb\" Value=\"Blue\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n    <Style x:Key=\"CommonSliderStyle\" TargetType=\"{x:Type Slider}\">\n        <Setter Property=\"Stylus.IsPressAndHoldEnabled\" Value=\"false\"/>\n        <Setter Property=\"Background\" Value=\"{DynamicResource ProgressBarBackgroundBrush}\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"Foreground\" Value=\"{StaticResource SliderThumb.Static.Foreground}\"/>\n        <Setter Property=\"Template\" Value=\"{StaticResource SliderHorizontal}\"/>\n        <Style.Triggers>\n            <Trigger Property=\"Orientation\" Value=\"Vertical\">\n                <Setter Property=\"Template\" Value=\"{StaticResource SliderVertical}\"/>\n            </Trigger>\n        </Style.Triggers>\n    </Style>\n    \n    <!-- Volume -->\n    <ControlTemplate x:Key=\"VolumeSliderThumbHorizontal\" TargetType=\"{x:Type Thumb}\">\n        <Grid HorizontalAlignment=\"Center\" UseLayoutRounding=\"False\" VerticalAlignment=\"Center\">\n            <Rectangle x:Name=\"grip\" Width=\"10\" Height=\"10\" RadiusX=\"12\" RadiusY=\"12\" Margin=\"0\" Fill=\"{StaticResource SliderThumb.Static.Background}\" Stretch=\"Fill\" SnapsToDevicePixels=\"False\" Stroke=\"{StaticResource SliderThumb.Static.Border}\" StrokeThickness=\"0\" UseLayoutRounding=\"True\" VerticalAlignment=\"Center\">\n                <Rectangle.Effect>\n                    <DropShadowEffect Direction=\"-90\" BlurRadius=\"2.5\" ShadowDepth=\"1\" Opacity=\"0.35\"/>\n                </Rectangle.Effect>\n            </Rectangle>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                <Setter Property=\"Width\" TargetName=\"grip\" Value=\"10\"/>\n                <Setter Property=\"Height\" TargetName=\"grip\" Value=\"10\"/>\n            </Trigger>\n            <Trigger Property=\"IsEnabled\" Value=\"false\">\n                <Setter Property=\"Fill\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Background}\"/>\n                <Setter Property=\"Stroke\" TargetName=\"grip\" Value=\"{StaticResource SliderThumb.Disabled.Border}\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n\n    <ControlTemplate x:Key=\"VolumeSliderHorizontal\" TargetType=\"{x:Type Slider}\">\n        <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"Transparent\" SnapsToDevicePixels=\"False\" Padding=\"0,4,0,4\" Margin=\"0,-4,0,0\">\n            <Grid>\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\"/>\n                    <RowDefinition Height=\"Auto\" MinHeight=\"{TemplateBinding MinHeight}\"/>\n                    <RowDefinition Height=\"Auto\"/>\n                </Grid.RowDefinitions>\n                <TickBar x:Name=\"TopTick\" Fill=\"{TemplateBinding Foreground}\" Height=\"4\" Margin=\"0,0,0,2\" Placement=\"Top\" Grid.Row=\"0\" Visibility=\"Collapsed\"/>\n                <TickBar x:Name=\"BottomTick\" Fill=\"{TemplateBinding Foreground}\" Height=\"4\" Margin=\"0,2,0,0\" Placement=\"Bottom\" Grid.Row=\"2\" Visibility=\"Collapsed\"/>\n                <Border x:Name=\"TrackBackground\" BorderBrush=\"{StaticResource SliderThumb.Track.Border}\" BorderThickness=\"1\" Background=\"{TemplateBinding Background}\" Height=\"5\" Margin=\"0,0\" Grid.Row=\"1\" VerticalAlignment=\"center\">\n                    <Canvas Margin=\"-6,-1\">\n                        <Rectangle x:Name=\"PART_SelectionRange\" Fill=\"{DynamicResource {x:Static SystemColors.HighlightBrushKey}}\" Height=\"4.0\" Visibility=\"Hidden\"/>\n                    </Canvas>\n                </Border>\n                <Track x:Name=\"PART_Track\" Grid.Row=\"1\">\n                    <Track.DecreaseRepeatButton>\n                        <RepeatButton Command=\"{x:Static Slider.DecreaseLarge}\" Style=\"{StaticResource RepeatButtonTransparent}\" Background=\"{DynamicResource VolumeBarBackgroundBrush}\" Height=\"1.5\"/>\n                    </Track.DecreaseRepeatButton>\n                    <Track.IncreaseRepeatButton>\n                        <RepeatButton Command=\"{x:Static Slider.IncreaseLarge}\" Style=\"{StaticResource RepeatButtonTransparent}\"/>\n                    </Track.IncreaseRepeatButton>\n                    <Track.Thumb>\n                        <Thumb x:Name=\"Thumb\" Focusable=\"False\" OverridesDefaultStyle=\"True\" Template=\"{StaticResource VolumeSliderThumbHorizontal}\" VerticalAlignment=\"Center\"/>\n                    </Track.Thumb>\n                </Track>\n            </Grid>\n        </Border>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"TickPlacement\" Value=\"TopLeft\">\n                <Setter Property=\"Visibility\" TargetName=\"TopTick\" Value=\"Visible\"/>\n                <Setter Property=\"Template\" TargetName=\"Thumb\" Value=\"{StaticResource SliderThumbHorizontalTop}\"/>\n                <Setter Property=\"Margin\" TargetName=\"TrackBackground\" Value=\"5,2,5,0\"/>\n            </Trigger>\n            <Trigger Property=\"TickPlacement\" Value=\"BottomRight\">\n                <Setter Property=\"Visibility\" TargetName=\"BottomTick\" Value=\"Visible\"/>\n                <Setter Property=\"Template\" TargetName=\"Thumb\" Value=\"{StaticResource SliderThumbHorizontalBottom}\"/>\n                <Setter Property=\"Margin\" TargetName=\"TrackBackground\" Value=\"5,0,5,2\"/>\n            </Trigger>\n            <Trigger Property=\"TickPlacement\" Value=\"Both\">\n                <Setter Property=\"Visibility\" TargetName=\"TopTick\" Value=\"Visible\"/>\n                <Setter Property=\"Visibility\" TargetName=\"BottomTick\" Value=\"Visible\"/>\n            </Trigger>\n            <Trigger Property=\"IsSelectionRangeEnabled\" Value=\"true\">\n                <Setter Property=\"Visibility\" TargetName=\"PART_SelectionRange\" Value=\"Visible\"/>\n            </Trigger>\n            <Trigger Property=\"IsKeyboardFocused\" Value=\"true\">\n                <Setter Property=\"Foreground\" TargetName=\"Thumb\" Value=\"Blue\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n\n    <Style x:Key=\"VolumeSliderStyle\" TargetType=\"{x:Type Slider}\">\n        <Setter Property=\"Stylus.IsPressAndHoldEnabled\" Value=\"false\"/>\n        <Setter Property=\"Background\" Value=\"{DynamicResource ProgressBarBackgroundBrush}\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"Foreground\" Value=\"{StaticResource SliderThumb.Static.Foreground}\"/>\n        <Setter Property=\"Template\" Value=\"{StaticResource VolumeSliderHorizontal}\"/>\n        <Style.Triggers>\n            <Trigger Property=\"Orientation\" Value=\"Vertical\">\n                <Setter Property=\"Template\" Value=\"{StaticResource SliderVertical}\"/>\n            </Trigger>\n        </Style.Triggers>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/Styles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:converters=\"clr-namespace:Meridian.Converters\"\n                    xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n                    xmlns:controls=\"clr-namespace:Meridian.Controls\"\n                    xmlns:system=\"clr-namespace:System;assembly=mscorlib\">\n\n    <converters:AlbumListItemContainerStyleSelector x:Key=\"AlbumItemStyleSelector\" \n                                                        DefaultItemStyle=\"{StaticResource AlbumListBoxItemStyle}\" ItemStyle=\"{StaticResource UserAlbumListBoxItemStyle}\" \n                                                        SeparatorStyle=\"{StaticResource SeparatorItemStyle}\"/>\n\n    <Style x:Key=\"SimpleButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"Padding\" Value=\"1\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Border>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style TargetType=\"{x:Type controls:BusyIndicator}\">\n        <Setter Property=\"IsTabStop\" Value=\"False\" />\n        <Setter Property=\"Focusable\" Value=\"False\" />\n        <Setter Property=\"HorizontalAlignment\" Value=\"Stretch\" />\n        <Setter Property=\"VerticalAlignment\" Value=\"Stretch\" />\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Stretch\" />\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Stretch\" />\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\" />\n        <Setter Property=\"BusyContent\" Value=\"{x:Static localization:MainResources.Loading}\" />\n        <Setter Property=\"BusyContentStyle\">\n            <Setter.Value>\n                <Style TargetType=\"ContentPresenter\">\n                    <Setter Property=\"Margin\" Value=\"24,5,5,0\" />\n                </Style>\n            </Setter.Value>\n        </Setter>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type controls:BusyIndicator}\">\n                    <Grid>\n                        <VisualStateManager.VisualStateGroups>\n                            <VisualStateGroup x:Name=\"VisibilityStates\">\n                                <VisualState x:Name=\"Hidden\">\n                                    <Storyboard>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"busycontent\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Collapsed</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"overlay\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Collapsed</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                    </Storyboard>\n                                </VisualState>\n                                <VisualState x:Name=\"Visible\">\n                                    <Storyboard>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"busycontent\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Visible</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"overlay\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Visible</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                    </Storyboard>\n                                </VisualState>\n                            </VisualStateGroup>\n                            <VisualStateGroup x:Name=\"BusyStatusStates\">\n                                <VisualState x:Name=\"Idle\">\n                                    <Storyboard>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"content\" Storyboard.TargetProperty=\"(Control.IsEnabled)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <system:Boolean>True</system:Boolean>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"errorcontent\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Collapsed</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"content\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Visible</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                    </Storyboard>\n                                </VisualState>\n                                <VisualState x:Name=\"Busy\">\n                                    <Storyboard>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"content\" Storyboard.TargetProperty=\"(Control.IsEnabled)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <system:Boolean>False</system:Boolean>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"errorcontent\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Collapsed</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"content\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Collapsed</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                    </Storyboard>\n                                </VisualState>\n                                <VisualState x:Name=\"Error\">\n                                    <Storyboard>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"errorcontent\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Visible</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"busycontent\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Collapsed</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"content\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Collapsed</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                        <ObjectAnimationUsingKeyFrames BeginTime=\"00:00:00\" Duration=\"00:00:00.001\" Storyboard.TargetName=\"overlay\" Storyboard.TargetProperty=\"(UIElement.Visibility)\">\n                                            <DiscreteObjectKeyFrame KeyTime=\"00:00:00\">\n                                                <DiscreteObjectKeyFrame.Value>\n                                                    <Visibility>Visible</Visibility>\n                                                </DiscreteObjectKeyFrame.Value>\n                                            </DiscreteObjectKeyFrame>\n                                        </ObjectAnimationUsingKeyFrames>\n                                    </Storyboard>\n                                </VisualState>\n                            </VisualStateGroup>\n                        </VisualStateManager.VisualStateGroups>\n                        <ContentControl x:Name=\"content\" Content=\"{TemplateBinding Content}\" ContentTemplate=\"{TemplateBinding ContentTemplate}\"\n                                        HorizontalContentAlignment=\"{TemplateBinding HorizontalContentAlignment}\" \n                                        VerticalContentAlignment=\"{TemplateBinding VerticalContentAlignment}\" IsTabStop=\"False\" Focusable=\"False\" />\n                        <Rectangle x:Name=\"overlay\" />\n                        <ContentPresenter x:Name=\"busycontent\" Style=\"{TemplateBinding BusyContentStyle}\">\n                            <ContentPresenter.Content>\n                                <StackPanel HorizontalAlignment=\"Left\">\n                                    <TextBlock Text=\"{TemplateBinding BusyContent}\" Foreground=\"{TemplateBinding Foreground}\" Opacity=\"0.7\" TextWrapping=\"Wrap\"/>\n                                    <ProgressBar Style=\"{StaticResource CommonProgressBarStyle}\" IsIndeterminate=\"{TemplateBinding IsBusy}\" Width=\"200\"/>\n                                </StackPanel>\n                            </ContentPresenter.Content>\n                        </ContentPresenter>\n                        <ContentPresenter x:Name=\"errorcontent\" Style=\"{TemplateBinding BusyContentStyle}\" Visibility=\"Collapsed\">\n                            <ContentPresenter.Content>\n                                <TextBlock Text=\"{TemplateBinding Error}\" Foreground=\"{TemplateBinding Foreground}\" Opacity=\"0.7\" TextWrapping=\"Wrap\"/>\n                            </ContentPresenter.Content>\n                        </ContentPresenter>\n                    </Grid>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"AddButtonStyle\" TargetType=\"{x:Type Button}\" BasedOn=\"{StaticResource SimpleButtonStyle}\">\n        <Setter Property=\"Opacity\" Value=\"0.7\" />\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\" />\n        <Setter Property=\"SnapsToDevicePixels\" Value=\"False\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                        <Path Data=\"{StaticResource AddIcon}\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"UniformToFill\" Width=\"10\" Height=\"10\" Margin=\"2,3,2,2\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter Property=\"Opacity\" Value=\"1\" />\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\" />\n                        </Trigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"True\" />\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Opacity\" Value=\"1\" />\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\" />\n                        </MultiTrigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"CurrentAudioButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"Padding\" Value=\"1\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"True\" />\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"#05e2e2e2\" />\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"False\" />\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"border\" Value=\"{DynamicResource HotCurrentTrackBackgroundBrush}\" />\n                        </MultiTrigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"MainBackButtonStyle\" TargetType=\"Button\">\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\" />\n        <Setter Property=\"Width\" Value=\"20\"/>\n        <Setter Property=\"Height\" Value=\"20\"/>\n        <Setter Property=\"Opacity\" Value=\"0.5\" />\n        <Setter Property=\"Padding\" Value=\"5\" />\n        <Setter Property=\"Margin\" Value=\"3,1,-3,-1\" />\n        <Setter Property=\"ToolTip\" Value=\"{x:Static localization:MainResources.BackButton}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"Button\">\n                    <Grid Name=\"RootGrid\" Background=\"{TemplateBinding Background}\">\n                        <Viewbox>\n                            <Path x:Name=\"Icon\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Margin=\"{TemplateBinding Padding}\" HorizontalAlignment=\"Center\" Data=\"{StaticResource BackIcon}\"/>\n                        </Viewbox>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"True\" />\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Opacity\" Value=\"0.9\" />\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"False\" />\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Opacity\" Value=\"1\" />\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"Opacity\" Value=\"0.2\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"CompactBackButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\"/>\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Opacity\" Value=\"0.7\" />\n        <Setter Property=\"Padding\" Value=\"15\" />\n        <Setter Property=\"ToolTip\" Value=\"{x:Static localization:MainResources.BackButton}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ToggleButton\">\n                    <Grid Name=\"RootGrid\" Background=\"Transparent\">\n                        <Viewbox>\n                            <Path x:Name=\"Icon\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Margin=\"{TemplateBinding Padding}\" HorizontalAlignment=\"Center\" Data=\"{StaticResource BackIcon}\"/>\n                        </Viewbox>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"True\" />\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Opacity\" Value=\"0.9\" />\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"False\" />\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Opacity\" Value=\"1\" />\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"Opacity\" Value=\"0.2\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"PinButtonStyle\" TargetType=\"ToggleButton\">\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\"/>\n        <Setter Property=\"Width\" Value=\"56\"/>\n        <Setter Property=\"Height\" Value=\"56\"/>\n        <Setter Property=\"Opacity\" Value=\"0.7\" />\n        <Setter Property=\"Padding\" Value=\"15\" />\n        <Setter Property=\"ToolTip\" Value=\"{x:Static localization:MainResources.BackButton}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"ToggleButton\">\n                    <Grid Name=\"RootGrid\" Background=\"Transparent\">\n                        <Viewbox>\n                            <Path x:Name=\"Icon\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Margin=\"{TemplateBinding Padding}\" HorizontalAlignment=\"Center\" Data=\"{StaticResource Pin315dIcon}\"/>\n                        </Viewbox>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"True\" />\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Opacity\" Value=\"0.9\" />\n                        </MultiTrigger>\n                        <MultiTrigger>\n                            <MultiTrigger.Conditions>\n                                <Condition Property=\"IsMouseOver\" Value=\"True\" />\n                                <Condition Property=\"IsPressed\" Value=\"False\" />\n                            </MultiTrigger.Conditions>\n                            <Setter Property=\"Opacity\" Value=\"1\" />\n                        </MultiTrigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"Opacity\" Value=\"0.2\" />\n                        </Trigger>\n                        <Trigger Property=\"IsChecked\" Value=\"True\">\n                            <Setter Property=\"Data\" TargetName=\"Icon\" Value=\"{StaticResource PinIcon}\" />\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <ControlTemplate x:Key=\"SearchBoxButton\" TargetType=\"Button\">\n        <Grid Background=\"#00000000\">\n            <Path Name=\"Icon\" Data=\"{StaticResource SearchIcon}\" Fill=\"{DynamicResource ForegroundBrush}\" Stretch=\"Uniform\" Opacity=\"0.3\"/>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n            </Trigger>\n            <Trigger Property=\"IsEnabled\" Value=\"False\">\n                <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n\n    <ControlTemplate x:Key=\"CancelSearchBoxButton\" TargetType=\"Button\">\n        <Grid Background=\"#00000000\">\n            <Path Name=\"Icon\" Data=\"{StaticResource CloseIcon}\" Fill=\"{DynamicResource AccentBrush}\" Stretch=\"Uniform\" Opacity=\"0.7\"/>\n        </Grid>\n        <ControlTemplate.Triggers>\n            <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n            </Trigger>\n            <Trigger Property=\"IsEnabled\" Value=\"False\">\n                <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n            </Trigger>\n        </ControlTemplate.Triggers>\n    </ControlTemplate>\n\n    <Style x:Key=\"ShowAllButton\" TargetType=\"Button\" BasedOn=\"{StaticResource SimpleButtonStyle}\">\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\"\n                            Opacity=\"0.7\">\n                        <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" Margin=\"{TemplateBinding Padding}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"border\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsPressed\" Value=\"True\">\n                            <Setter Property=\"Opacity\" Value=\"0.6\" TargetName=\"border\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/TabControlStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <SolidColorBrush x:Key=\"TabItem.Selected.Background\" Color=\"#FFFFFF\"/>\n    <SolidColorBrush x:Key=\"TabItem.Selected.Border\" Color=\"#ACACAC\"/>\n    \n    <Style x:Key=\"CommonTabControlStyle\" TargetType=\"{x:Type TabControl}\">\n        <Setter Property=\"Padding\" Value=\"0,0,0,0\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Center\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Center\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{StaticResource TabItem.Selected.Border}\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type TabControl}\">\n                    <Grid x:Name=\"templateRoot\" ClipToBounds=\"true\" SnapsToDevicePixels=\"true\" KeyboardNavigation.TabNavigation=\"Local\">\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition x:Name=\"ColumnDefinition0\"/>\n                            <ColumnDefinition x:Name=\"ColumnDefinition1\" Width=\"0\"/>\n                        </Grid.ColumnDefinitions>\n                        <Grid.RowDefinitions>\n                            <RowDefinition x:Name=\"RowDefinition0\" Height=\"Auto\"/>\n                            <RowDefinition Height=\"Auto\"/>\n                            <RowDefinition x:Name=\"RowDefinition1\" Height=\"*\"/>\n                        </Grid.RowDefinitions>\n                        <TabPanel x:Name=\"headerPanel\" Background=\"Transparent\" Grid.Column=\"0\" IsItemsHost=\"true\" Margin=\"25,0,0,0\" Grid.Row=\"0\" KeyboardNavigation.TabIndex=\"1\" Panel.ZIndex=\"1\"/>\n                        <Rectangle Grid.Row=\"1\" Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource MainBackgroundSplitterBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,10,0,0\"/>\n                        <Border x:Name=\"contentPanel\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Grid.Column=\"0\" KeyboardNavigation.DirectionalNavigation=\"Contained\" Grid.Row=\"2\" KeyboardNavigation.TabIndex=\"2\" KeyboardNavigation.TabNavigation=\"Local\">\n                            <ContentPresenter x:Name=\"PART_SelectedContentHost\" ContentSource=\"SelectedContent\" Margin=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\"/>\n                        </Border>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"TabStripPlacement\" Value=\"Bottom\">\n                            <Setter Property=\"Grid.Row\" TargetName=\"headerPanel\" Value=\"1\"/>\n                            <Setter Property=\"Grid.Row\" TargetName=\"contentPanel\" Value=\"0\"/>\n                            <Setter Property=\"Height\" TargetName=\"RowDefinition0\" Value=\"*\"/>\n                            <Setter Property=\"Height\" TargetName=\"RowDefinition1\" Value=\"Auto\"/>\n                            <Setter Property=\"Margin\" TargetName=\"headerPanel\" Value=\"2,0,2,2\"/>\n                        </Trigger>\n                        <Trigger Property=\"TabStripPlacement\" Value=\"Left\">\n                            <Setter Property=\"Grid.Row\" TargetName=\"headerPanel\" Value=\"0\"/>\n                            <Setter Property=\"Grid.Row\" TargetName=\"contentPanel\" Value=\"0\"/>\n                            <Setter Property=\"Grid.Column\" TargetName=\"headerPanel\" Value=\"0\"/>\n                            <Setter Property=\"Grid.Column\" TargetName=\"contentPanel\" Value=\"1\"/>\n                            <Setter Property=\"Width\" TargetName=\"ColumnDefinition0\" Value=\"Auto\"/>\n                            <Setter Property=\"Width\" TargetName=\"ColumnDefinition1\" Value=\"*\"/>\n                            <Setter Property=\"Height\" TargetName=\"RowDefinition0\" Value=\"*\"/>\n                            <Setter Property=\"Height\" TargetName=\"RowDefinition1\" Value=\"0\"/>\n                            <Setter Property=\"Margin\" TargetName=\"headerPanel\" Value=\"2,2,0,2\"/>\n                        </Trigger>\n                        <Trigger Property=\"TabStripPlacement\" Value=\"Right\">\n                            <Setter Property=\"Grid.Row\" TargetName=\"headerPanel\" Value=\"0\"/>\n                            <Setter Property=\"Grid.Row\" TargetName=\"contentPanel\" Value=\"0\"/>\n                            <Setter Property=\"Grid.Column\" TargetName=\"headerPanel\" Value=\"1\"/>\n                            <Setter Property=\"Grid.Column\" TargetName=\"contentPanel\" Value=\"0\"/>\n                            <Setter Property=\"Width\" TargetName=\"ColumnDefinition0\" Value=\"*\"/>\n                            <Setter Property=\"Width\" TargetName=\"ColumnDefinition1\" Value=\"Auto\"/>\n                            <Setter Property=\"Height\" TargetName=\"RowDefinition0\" Value=\"*\"/>\n                            <Setter Property=\"Height\" TargetName=\"RowDefinition1\" Value=\"0\"/>\n                            <Setter Property=\"Margin\" TargetName=\"headerPanel\" Value=\"0,2,2,2\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"false\">\n                            <Setter Property=\"TextElement.Foreground\" TargetName=\"templateRoot\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    \n    <LinearGradientBrush x:Key=\"TabItem.Static.Background\" EndPoint=\"0,1\" StartPoint=\"0,0\">\n        <GradientStop Color=\"#F0F0F0\" Offset=\"0.0\"/>\n        <GradientStop Color=\"#E5E5E5\" Offset=\"1.0\"/>\n    </LinearGradientBrush>\n    <SolidColorBrush x:Key=\"TabItem.Static.Border\" Color=\"#ACACAC\"/>\n    <LinearGradientBrush x:Key=\"TabItem.MouseOver.Background\" EndPoint=\"0,1\" StartPoint=\"0,0\">\n        <GradientStop Color=\"#ECF4FC\" Offset=\"0.0\"/>\n        <GradientStop Color=\"#DCECFC\" Offset=\"1.0\"/>\n    </LinearGradientBrush>\n    <SolidColorBrush x:Key=\"TabItem.MouseOver.Border\" Color=\"#7EB4EA\"/>\n    <SolidColorBrush x:Key=\"TabItem.Disabled.Background\" Color=\"#F0F0F0\"/>\n    <SolidColorBrush x:Key=\"TabItem.Disabled.Border\" Color=\"#D9D9D9\"/>\n    \n    <Style x:Key=\"CommonTabItemStyle\" TargetType=\"{x:Type TabItem}\">\n        <Setter Property=\"FocusVisualStyle\" Value=\"{StaticResource FocusVisual}\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{StaticResource TabItem.Static.Border}\"/>\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"Margin\" Value=\"0\"/>\n        <Setter Property=\"Padding\" Value=\"15,3,15,4\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"VerticalContentAlignment\" Value=\"Stretch\"/>\n        <Setter Property=\"FontSize\" Value=\"13\" />\n        <Setter Property=\"FontWeight\" Value=\"Normal\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type TabItem}\">\n                    <Grid x:Name=\"templateRoot\" SnapsToDevicePixels=\"true\" Margin=\"0,0,15,0\">\n                        <Border x:Name=\"mainBorder\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"0\" Background=\"{TemplateBinding Background}\" Margin=\"0\">\n                            <Border x:Name=\"innerBorder\" BorderBrush=\"{StaticResource TabItem.Selected.Border}\" BorderThickness=\"0\" Background=\"{StaticResource TabItem.Selected.Background}\" Margin=\"-1\" Opacity=\"0\"/>\n                        </Border>\n                        <ContentPresenter x:Name=\"contentPresenter\" ContentSource=\"Header\" Focusable=\"False\" HorizontalAlignment=\"{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\" \n                                          Margin=\"{TemplateBinding Padding}\" \n                                          RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" \n                                          VerticalAlignment=\"{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"\n                                          Opacity=\"0.6\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsMouseOver, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Left\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.MouseOver.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.MouseOver.Border}\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,1,0,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,1,0,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsMouseOver, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Bottom\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.MouseOver.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.MouseOver.Border}\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,0,1,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,0,1,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsMouseOver, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Right\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Background\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.MouseOver.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.MouseOver.Border}\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"0,1,1,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"0,1,1,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsMouseOver, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Top\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"0.85\"/>\n                            <!--<Setter Property=\"Background\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.MouseOver.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.MouseOver.Border}\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,1,1,0\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,1,1,0\"/>-->\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsEnabled, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Left\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"0.56\"/>\n                            <Setter Property=\"Background\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.Disabled.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.Disabled.Border}\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,1,0,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,1,0,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsEnabled, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Bottom\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"0.56\"/>\n                            <Setter Property=\"Background\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.Disabled.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.Disabled.Border}\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,0,1,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,0,1,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsEnabled, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Right\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"0.56\"/>\n                            <Setter Property=\"Background\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.Disabled.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.Disabled.Border}\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"0,1,1,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"0,1,1,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsEnabled, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Top\"/>\n                            </MultiDataTrigger.Conditions>\n                            <!--<Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"0.56\"/>\n                            <Setter Property=\"Background\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.Disabled.Background}\"/>\n                            <Setter Property=\"BorderBrush\" TargetName=\"mainBorder\" Value=\"{StaticResource TabItem.Disabled.Border}\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,1,1,0\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,1,1,0\"/>-->\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsSelected, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Left\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,1,0,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,1,0,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsSelected, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Left\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Panel.ZIndex\" Value=\"1\"/>\n                            <Setter Property=\"Margin\" Value=\"-2,-2,0,-2\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"innerBorder\" Value=\"1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,1,0,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,1,0,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsSelected, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Bottom\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,0,1,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,0,1,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsSelected, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Bottom\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Panel.ZIndex\" Value=\"1\"/>\n                            <Setter Property=\"Margin\" Value=\"-2,0,-2,-2\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"innerBorder\" Value=\"1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,0,1,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,0,1,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsSelected, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Right\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"0,1,1,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"0,1,1,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsSelected, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Right\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Panel.ZIndex\" Value=\"1\"/>\n                            <Setter Property=\"Margin\" Value=\"0,-2,-2,-2\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"innerBorder\" Value=\"1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"0,1,1,1\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"0,1,1,1\"/>\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsSelected, RelativeSource={RelativeSource Self}}\" Value=\"false\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Top\"/>\n                            </MultiDataTrigger.Conditions>\n                            <!--<Setter Property=\"BorderThickness\" TargetName=\"innerBorder\" Value=\"1,1,1,0\"/>\n                            <Setter Property=\"BorderThickness\" TargetName=\"mainBorder\" Value=\"1,1,1,0\"/>-->\n                        </MultiDataTrigger>\n                        <MultiDataTrigger>\n                            <MultiDataTrigger.Conditions>\n                                <Condition Binding=\"{Binding IsSelected, RelativeSource={RelativeSource Self}}\" Value=\"true\"/>\n                                <Condition Binding=\"{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}\" Value=\"Top\"/>\n                            </MultiDataTrigger.Conditions>\n                            <Setter Property=\"Panel.ZIndex\" Value=\"1\"/>\n                            <Setter Property=\"Opacity\" TargetName=\"contentPresenter\" Value=\"1\"/>\n                            <Setter Property=\"FontWeight\"  Value=\"Normal\"/>\n                            <Setter Property=\"Background\" TargetName=\"mainBorder\" Value=\"{DynamicResource AccentBrush}\"/>\n                            <Setter Property=\"Foreground\" Value=\"White\"/>\n                        </MultiDataTrigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/TextBoxStyles.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n                    xmlns:controls=\"clr-namespace:Meridian.Controls\">\n    <Style x:Key=\"CommonTextBoxStyle\" TargetType=\"{x:Type TextBox}\">\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{DynamicResource TextBoxBorderBrush}\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource TextBoxForegroundBrush}\"/>\n        <Setter Property=\"BorderThickness\" Value=\"1\"/>\n        <Setter Property=\"KeyboardNavigation.TabNavigation\" Value=\"None\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Left\"/>\n        <Setter Property=\"FocusVisualStyle\" Value=\"{x:Null}\"/>\n        <Setter Property=\"AllowDrop\" Value=\"true\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"VerticalFirst\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"MaxLength\" Value=\"50\" />\n        <Setter Property=\"SelectionBrush\" Value=\"{DynamicResource AccentBrush}\" />\n        <Setter Property=\"CaretBrush\" Value=\"{DynamicResource TextBoxForegroundBrush}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type TextBox}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"3,2,0,2\" SnapsToDevicePixels=\"True\">\n                        <ScrollViewer x:Name=\"PART_ContentHost\" Focusable=\"False\" HorizontalScrollBarVisibility=\"Hidden\" VerticalScrollBarVisibility=\"Hidden\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"Opacity\" TargetName=\"border\" Value=\"0.56\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource TextBoxHotBorderBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsKeyboardFocused\" Value=\"True\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n        <Style.Triggers>\n            <MultiTrigger>\n                <MultiTrigger.Conditions>\n                    <Condition Property=\"IsInactiveSelectionHighlightEnabled\" Value=\"true\"/>\n                    <Condition Property=\"IsSelectionActive\" Value=\"false\"/>\n                </MultiTrigger.Conditions>\n                <Setter Property=\"SelectionBrush\" Value=\"{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}\"/>\n            </MultiTrigger>\n        </Style.Triggers>\n    </Style>\n\n    <Style x:Key=\"CommonPasswordBoxStyle\" TargetType=\"{x:Type PasswordBox}\">\n        <Setter Property=\"PasswordChar\" Value=\"●\"/>\n        <Setter Property=\"Background\" Value=\"Transparent\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{DynamicResource TextBoxBorderBrush}\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource TextBoxForegroundBrush}\"/>\n        <Setter Property=\"BorderThickness\" Value=\"1\"/>\n        <Setter Property=\"KeyboardNavigation.TabNavigation\" Value=\"None\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Left\"/>\n        <Setter Property=\"FocusVisualStyle\" Value=\"{x:Null}\"/>\n        <Setter Property=\"AllowDrop\" Value=\"true\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"VerticalFirst\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"MaxLength\" Value=\"50\" />\n        <Setter Property=\"SelectionBrush\" Value=\"{DynamicResource AccentBrush}\" />\n        <Setter Property=\"CaretBrush\" Value=\"{DynamicResource TextBoxForegroundBrush}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type PasswordBox}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"True\" Padding=\"3,3,0,3\">\n                        <ScrollViewer x:Name=\"PART_ContentHost\" Focusable=\"false\" HorizontalScrollBarVisibility=\"Hidden\" VerticalScrollBarVisibility=\"Hidden\"/>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsEnabled\" Value=\"false\">\n                            <Setter Property=\"Opacity\" TargetName=\"border\" Value=\"0.56\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource TextBoxHotBorderBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsKeyboardFocused\" Value=\"true\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n        <Style.Triggers>\n            <MultiTrigger>\n                <MultiTrigger.Conditions>\n                    <Condition Property=\"IsInactiveSelectionHighlightEnabled\" Value=\"true\"/>\n                    <Condition Property=\"IsSelectionActive\" Value=\"false\"/>\n                </MultiTrigger.Conditions>\n                <Setter Property=\"SelectionBrush\" Value=\"{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}\"/>\n            </MultiTrigger>\n        </Style.Triggers>\n    </Style>\n\n    <Style x:Key=\"SearchBoxStyle\" TargetType=\"{x:Type controls:TextBoxWithHint}\">\n        <Setter Property=\"Background\" Value=\"{DynamicResource SearchBarBackgroundBrush}\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{DynamicResource TextBoxBorderBrush}\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\"/>\n        <Setter Property=\"CaretBrush\" Value=\"{DynamicResource ForegroundBrush}\" />\n        <Setter Property=\"BorderThickness\" Value=\"0\"/>\n        <Setter Property=\"KeyboardNavigation.TabNavigation\" Value=\"None\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Left\"/>\n        <Setter Property=\"FocusVisualStyle\" Value=\"{x:Null}\"/>\n        <Setter Property=\"AllowDrop\" Value=\"true\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"VerticalFirst\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"MaxLength\" Value=\"50\" />\n        <Setter Property=\"FontFamily\" Value=\"Segoe UI SemiLight\" />\n        <Setter Property=\"SelectionBrush\" Value=\"{DynamicResource AccentBrush}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type controls:TextBoxWithHint}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"0,2,0,2\" SnapsToDevicePixels=\"True\">\n                        <Grid>\n                            <ContentControl x:Name=\"HintContent\" Style=\"{TemplateBinding HintStyle}\" Content=\"{TemplateBinding Hint}\" Margin=\"{TemplateBinding Padding}\"/>\n                            <ScrollViewer x:Name=\"PART_ContentHost\" Focusable=\"False\" HorizontalScrollBarVisibility=\"Hidden\" VerticalScrollBarVisibility=\"Hidden\" Margin=\"-2,3,0,0\"\n                                          Opacity=\"0.7\"/>\n                        </Grid>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"Opacity\" TargetName=\"border\" Value=\"0.5\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource TextBoxHotBorderBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsKeyboardFocused\" Value=\"True\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n        <Style.Triggers>\n            <MultiTrigger>\n                <MultiTrigger.Conditions>\n                    <Condition Property=\"IsInactiveSelectionHighlightEnabled\" Value=\"true\"/>\n                    <Condition Property=\"IsSelectionActive\" Value=\"false\"/>\n                </MultiTrigger.Conditions>\n                <Setter Property=\"SelectionBrush\" Value=\"{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}\"/>\n            </MultiTrigger>\n        </Style.Triggers>\n    </Style>\n\n    <Style x:Key=\"LocalSearchBoxStyle\" TargetType=\"{x:Type controls:TextBoxWithHint}\">\n        <Setter Property=\"Background\" Value=\"{DynamicResource MainBackgroundBrush}\"/>\n        <Setter Property=\"BorderBrush\" Value=\"{DynamicResource TextBoxBorderBrush}\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\"/>\n        <Setter Property=\"CaretBrush\" Value=\"{DynamicResource ForegroundBrush}\" />\n        <Setter Property=\"BorderThickness\" Value=\"1\"/>\n        <Setter Property=\"KeyboardNavigation.TabNavigation\" Value=\"None\"/>\n        <Setter Property=\"HorizontalContentAlignment\" Value=\"Left\"/>\n        <Setter Property=\"FocusVisualStyle\" Value=\"{x:Null}\"/>\n        <Setter Property=\"AllowDrop\" Value=\"true\"/>\n        <Setter Property=\"ScrollViewer.PanningMode\" Value=\"VerticalFirst\"/>\n        <Setter Property=\"Stylus.IsFlicksEnabled\" Value=\"False\"/>\n        <Setter Property=\"MaxLength\" Value=\"50\" />\n        <Setter Property=\"SelectionBrush\" Value=\"{DynamicResource AccentBrush}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type controls:TextBoxWithHint}\">\n                    <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"3,0,0,1\" SnapsToDevicePixels=\"True\">\n                        <Grid>\n                            <ContentControl x:Name=\"HintContent\" Style=\"{TemplateBinding HintStyle}\" Content=\"{TemplateBinding Hint}\" Margin=\"3,1,0,1\" FontSize=\"{TemplateBinding FontSize}\"/>\n                            <ScrollViewer x:Name=\"PART_ContentHost\" Focusable=\"False\" HorizontalScrollBarVisibility=\"Hidden\" VerticalScrollBarVisibility=\"Hidden\" Margin=\"0,3,0,0\"\n                                          Opacity=\"0.7\"/>\n                        </Grid>\n                    </Border>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter Property=\"Opacity\" TargetName=\"border\" Value=\"0.5\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource TextBoxHotBorderBrush}\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsKeyboardFocused\" Value=\"True\">\n                            <Setter Property=\"BorderBrush\" TargetName=\"border\" Value=\"{DynamicResource AccentBrush}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n        <Style.Triggers>\n            <MultiTrigger>\n                <MultiTrigger.Conditions>\n                    <Condition Property=\"IsInactiveSelectionHighlightEnabled\" Value=\"true\"/>\n                    <Condition Property=\"IsSelectionActive\" Value=\"false\"/>\n                </MultiTrigger.Conditions>\n                <Setter Property=\"SelectionBrush\" Value=\"{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}\"/>\n            </MultiTrigger>\n        </Style.Triggers>\n    </Style>\n\n\n    <Style x:Key=\"TextBoxHintStyle\" TargetType=\"ContentControl\">\n        <Setter Property=\"HorizontalAlignment\" Value=\"Left\"/>\n        <Setter Property=\"Opacity\" Value=\"0.4\"/>\n        <Setter Property=\"FontFamily\" Value=\"Segoe UI SemiLight\" />\n        <Setter Property=\"FontSize\" Value=\"14\" />\n        <Setter Property=\"VerticalAlignment\" Value=\"Center\" />\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Styles/WindowButtons.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Style x:Key=\"CloseButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Width\" Value=\"22\"/>\n        <Setter Property=\"Height\" Value=\"22\"/>\n        <Setter Property=\"Background\" Value=\"#00000000\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ControlButtonForeground}\"/>\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Grid x:Name=\"RootGrid\" Background=\"{TemplateBinding Background}\">\n                        <Path Name=\"Icon\" Data=\"{StaticResource CloseIcon}\" Stroke=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Opacity=\"0.5\" Margin=\"5\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"MaximizeButtonStyle\" TargetType=\"{x:Type ToggleButton}\">\n        <Setter Property=\"Width\" Value=\"22\"/>\n        <Setter Property=\"Height\" Value=\"22\"/>\n        <Setter Property=\"Background\" Value=\"#00000000\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ControlButtonForeground}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type ToggleButton}\">\n                    <Grid Background=\"{TemplateBinding Background}\">\n                        <Path Name=\"Icon\" Data=\"{StaticResource MaximizeIcon}\" Stroke=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Opacity=\"0.5\" Margin=\"5\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsChecked\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Data\" Value=\"{StaticResource RestoreIcon}\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n\n    <Style x:Key=\"MinimizeButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Width\" Value=\"22\"/>\n        <Setter Property=\"Height\" Value=\"22\"/>\n        <Setter Property=\"Background\" Value=\"#00000000\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ControlButtonForeground}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Grid Background=\"{TemplateBinding Background}\">\n                        <Path Name=\"Icon\" Data=\"{StaticResource MinimizeIcon}\" Stroke=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Opacity=\"0.5\" VerticalAlignment=\"Center\" Margin=\"5\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    \n    <Style x:Key=\"MiniModeButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Width\" Value=\"22\"/>\n        <Setter Property=\"Height\" Value=\"22\"/>\n        <Setter Property=\"Background\" Value=\"#00000000\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ControlButtonForeground}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Grid Background=\"{TemplateBinding Background}\">\n                        <Path Name=\"Icon\" Data=\"{StaticResource MinimodeIcon}\" Stroke=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Opacity=\"0.5\" Margin=\"5\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    \n    <Style x:Key=\"LandscapeModeButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Width\" Value=\"10\"/>\n        <Setter Property=\"Height\" Value=\"10\"/>\n        <Setter Property=\"Background\" Value=\"#00000000\"/>\n        <Setter Property=\"Foreground\" Value=\"{StaticResource ControlButtonForeground}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Grid Background=\"{TemplateBinding Background}\">\n                        <Path Name=\"Icon\" Data=\"{StaticResource LandscapeModeIcon}\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Opacity=\"0.5\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n    <Style x:Key=\"PortraitModeButtonStyle\" TargetType=\"{x:Type Button}\">\n        <Setter Property=\"Width\" Value=\"10\"/>\n        <Setter Property=\"Height\" Value=\"10\"/>\n        <Setter Property=\"Background\" Value=\"#00000000\"/>\n        <Setter Property=\"Foreground\" Value=\"{DynamicResource ControlButtonForeground}\" />\n        <Setter Property=\"Template\">\n            <Setter.Value>\n                <ControlTemplate TargetType=\"{x:Type Button}\">\n                    <Grid Background=\"{TemplateBinding Background}\">\n                        <Path Name=\"Icon\" Data=\"{StaticResource PortraitModeIcon}\" Fill=\"{TemplateBinding Foreground}\" Stretch=\"Uniform\" Opacity=\"0.5\"/>\n                    </Grid>\n                    <ControlTemplate.Triggers>\n                        <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"1\"/>\n                        </Trigger>\n                        <Trigger Property=\"IsEnabled\" Value=\"False\">\n                            <Setter TargetName=\"Icon\" Property=\"Opacity\" Value=\"0.2\"/>\n                        </Trigger>\n                    </ControlTemplate.Triggers>\n                </ControlTemplate>\n            </Setter.Value>\n        </Setter>\n    </Style>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accent.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <!-- Colors -->\n    <Color x:Key=\"ForegroundColor\">#414042</Color>\n    <Color x:Key=\"BackgroundColor\">White</Color>\n    <Color x:Key=\"ContrastColor\">#f2f2f2</Color>\n\n    <SolidColorBrush x:Key=\"ForegroundBrush\" Color=\"{StaticResource ForegroundColor}\" />\n    <SolidColorBrush x:Key=\"BackgroundBrush\" Color=\"{StaticResource BackgroundColor}\" />\n\n    <SolidColorBrush x:Key=\"MainBackgroundBrush\" Color=\"{StaticResource BackgroundColor}\"/>\n\n    <SolidColorBrush x:Key=\"MainTabActiveForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n\n    <SolidColorBrush x:Key=\"MainBackgroundSplitterBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.15\"/>\n\n    <SolidColorBrush x:Key=\"AudioAlternationBackgroundBrush\" Color=\"Black\" Opacity=\"0.03\" />\n    \n    <!-- Main menu -->\n    <SolidColorBrush x:Key=\"MainMenuHotPlaylistItemBackgroundBrush\" Color=\"{StaticResource BackgroundColor}\" Opacity=\"0.05\"/>\n\n    <!-- Buttons -->\n    <SolidColorBrush x:Key=\"ButtonBorderBrush\" Color=\"Gray\"/>\n    <SolidColorBrush x:Key=\"ButtonForegroundBrush\" Color=\"#333333\"/>\n    <SolidColorBrush x:Key=\"ButtonBackgroundBrush\" Color=\"#eeeeee\"/>\n    <SolidColorBrush x:Key=\"ButtonHotBackgroundBrush\" Color=\"#dedede\"/>\n    <SolidColorBrush x:Key=\"ButtonPressForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"ButtonPressBackgroundBrush\" Color=\"#333333\"/>\n    <SolidColorBrush x:Key=\"ButtonHighlightedHotBackgroundBrush\" Color=\"{StaticResource AccentColor}\" Opacity=\"0.8\"/>\n    <SolidColorBrush x:Key=\"ButtonHighlightedDisabledBackgroundBrush\" Color=\"LightGray\" Opacity=\"1\"/>\n\n    <!-- Control Icons -->\n    <SolidColorBrush x:Key=\"ControlButtonForeground\" Color=\"{StaticResource ForegroundColor}\"/>\n    <SolidColorBrush x:Key=\"ControlButtonBackground\" Color=\"{StaticResource BackgroundColor}\"/>\n    <SolidColorBrush x:Key=\"ControlButtonOverBackground\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n\n    <!-- Albums -->\n    <SolidColorBrush x:Key=\"PlaylistItemForegroundBrush\" Color=\"#707070\"/>\n    <SolidColorBrush x:Key=\"HotPlaylistItemBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n    <SolidColorBrush x:Key=\"SelectedPlaylistItemForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"SelectedPlaylistItemBackgroundBrush\" Color=\"{StaticResource AccentColor}\" Opacity=\"0.08\"/>\n\n    <!-- Current track -->\n    <SolidColorBrush x:Key=\"HotCurrentTrackBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n\n    <!-- Context menu -->\n    <SolidColorBrush x:Key=\"HotContextMenuItemBackgroundBrush\" Color=\"Black\" Opacity=\"0.1\"/>\n\n    <!-- TextBoxes -->\n    <SolidColorBrush x:Key=\"TextBoxBorderBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.3\"/>\n    <SolidColorBrush x:Key=\"TextBoxHotBorderBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.7\"/>\n    <SolidColorBrush x:Key=\"TextBoxForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n    <SolidColorBrush x:Key=\"TextBoxBackgroundBrush\" Color=\"#33FFFFFF\"/>\n\n    <SolidColorBrush x:Key=\"ShadowTopBrush\" Color=\"Black\" Opacity=\"0.2\"/>\n    <SolidColorBrush x:Key=\"ShadowBottomBrush\" Color=\"Black\" Opacity=\"0.2\"/>\n\n    <SolidColorBrush x:Key=\"AlbumsListBackgroundBrush\" Color=\"{StaticResource ContrastColor}\" Opacity=\"0.7\"/>\n    <SolidColorBrush x:Key=\"SplitterBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n\n    <!-- Progress bar -->\n    <SolidColorBrush x:Key=\"ProgressBarBackgroundBrush\" Color=\"#22000000\"/>\n\n    <!-- Volume bar -->\n    <SolidColorBrush x:Key=\"VolumeBarBackgroundBrush\" Color=\"White\"/>\n\n    <SolidColorBrush x:Key=\"SearchBarBackgroundBrush\" Color=\"#ecebec\" Opacity=\"0.7\"/>\n\n    <!-- Comboboxes -->\n    <!-- ComboBoxBg-->\n    <SolidColorBrush x:Key=\"ComboBoxBackgroundBrush\" Color=\"#FFEEEEEE\" />\n    <!-- ComboBoxForeground-->\n    <SolidColorBrush x:Key=\"ComboBoxForegroundBrush\" Color=\"Black\"/>\n    <!-- ComboBoxBorder-->\n    <SolidColorBrush x:Key=\"ComboBoxBorderBrush\" Color=\"#FFEEEEEE\"/>\n    <!-- ComboBoxArrow-->\n    <SolidColorBrush x:Key=\"ComboBoxArrowBrush\" Color=\"#FF999999\"/>\n    <!-- ComboBoxBorderHover && ComboBoxArrowHover-->\n    <SolidColorBrush x:Key=\"ComboBoxHotBrush\" Color=\"#FF333333\" />\n    <!-- ComboBoxBgHover-->\n    <SolidColorBrush x:Key=\"ComboBoxHotBackgroundBrush\" Color=\"#FFFFFFFF\"/>\n    <!-- ComboBoxItemHighlighted-->\n    <SolidColorBrush x:Key=\"ComboBoxItemHotBackgroundBrush\" Color=\"#FFDFDFDF\" />\n\n    <!-- Sidebar -->\n    <SolidColorBrush x:Key=\"SidebarBackgroundBrush\" Color=\"{StaticResource AccentColor}\" Opacity=\"0.65\"/>\n    <FontFamily x:Key=\"SidebarForegroundFont\">Segoe UI SemiLight</FontFamily>\n    <SolidColorBrush x:Key=\"SidebarForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"SidebarInactiveForegroundBrush\" Color=\"White\" Opacity=\"0.5\"/>\n    <SolidColorBrush x:Key=\"SidebarGroupForegroundBrush\" Color=\"White\" Opacity=\"0.9\"/>\n    <SolidColorBrush x:Key=\"SidebarSliderBackgroundBrush\" Color=\"White\" Opacity=\"0.1\"/>\n\n    <SolidColorBrush x:Key=\"SidebarNowPlayingImageBackgroundBrush\" Color=\"Transparent\"/>\n    \n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accents/Blue.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Color x:Key=\"AccentColor\">#006ac1</Color>\n    <SolidColorBrush x:Key=\"AccentBrush\" Color=\"{StaticResource AccentColor}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accents/Emerald.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Color x:Key=\"AccentColor\">#059f01</Color>\n    <SolidColorBrush x:Key=\"AccentBrush\" Color=\"{StaticResource AccentColor}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accents/Magenta.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Color x:Key=\"AccentColor\">#d80073</Color>\n    <SolidColorBrush x:Key=\"AccentBrush\" Color=\"{StaticResource AccentColor}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accents/Mango.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Color x:Key=\"AccentColor\">#fe6f11</Color>\n    <SolidColorBrush x:Key=\"AccentBrush\" Color=\"{StaticResource AccentColor}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accents/Pink.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Color x:Key=\"AccentColor\">#e671b8</Color>\n    <SolidColorBrush x:Key=\"AccentBrush\" Color=\"{StaticResource AccentColor}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accents/Purple.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Color x:Key=\"AccentColor\">#6800d3</Color>\n    <SolidColorBrush x:Key=\"AccentBrush\" Color=\"{StaticResource AccentColor}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accents/Red.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Color x:Key=\"AccentColor\">#e51400</Color>\n    <SolidColorBrush x:Key=\"AccentBrush\" Color=\"{StaticResource AccentColor}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accents/Sea.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Color x:Key=\"AccentColor\">#009f9f</Color>\n    <SolidColorBrush x:Key=\"AccentBrush\" Color=\"{StaticResource AccentColor}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Accents/Sky.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <Color x:Key=\"AccentColor\">#1ba1e2</Color>\n    <SolidColorBrush x:Key=\"AccentBrush\" Color=\"{StaticResource AccentColor}\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Dark.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <!-- Colors -->\n    <Color x:Key=\"ForegroundColor\">White</Color>\n    <Color x:Key=\"BackgroundColor\">#282b2f</Color>\n    <Color x:Key=\"ContrastColor\">#2d2d2d</Color>\n\n    <SolidColorBrush x:Key=\"ForegroundBrush\" Color=\"{StaticResource ForegroundColor}\" />\n    <SolidColorBrush x:Key=\"BackgroundBrush\" Color=\"{StaticResource BackgroundColor}\" />\n\n    <!--<SolidColorBrush x:Key=\"MainBackgroundBrush\" Color=\"#484c53\"/>-->\n    <SolidColorBrush x:Key=\"MainBackgroundBrush\" Color=\"#282b2f\"/>\n\n    <SolidColorBrush x:Key=\"MainTabActiveForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n\n    <SolidColorBrush x:Key=\"MainBackgroundSplitterBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.15\"/>\n\n    <SolidColorBrush x:Key=\"AudioAlternationBackgroundBrush\" Color=\"Black\" Opacity=\"0.05\" />\n\n    <!-- Main menu -->\n    <SolidColorBrush x:Key=\"MainMenuHotPlaylistItemBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n\n    <!-- Buttons -->\n    <SolidColorBrush x:Key=\"ButtonBorderBrush\" Color=\"Gray\"/>\n    <SolidColorBrush x:Key=\"ButtonForegroundBrush\" Color=\"#eeeeee\"/>\n    <SolidColorBrush x:Key=\"ButtonBackgroundBrush\" Color=\"#333333\"/>\n    <SolidColorBrush x:Key=\"ButtonHotBackgroundBrush\" Color=\"#2d2d2d\"/>\n    <SolidColorBrush x:Key=\"ButtonPressForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"ButtonPressBackgroundBrush\" Color=\"#333333\"/>\n    <SolidColorBrush x:Key=\"ButtonHighlightedHotBackgroundBrush\" Color=\"{StaticResource AccentColor}\" Opacity=\"0.8\"/>\n    <SolidColorBrush x:Key=\"ButtonHighlightedDisabledBackgroundBrush\" Color=\"#eeeeee\" Opacity=\"0.1\"/>\n\n    <!-- Control Icons -->\n    <SolidColorBrush x:Key=\"ControlButtonForeground\" Color=\"{StaticResource ForegroundColor}\"/>\n    <SolidColorBrush x:Key=\"ControlButtonBackground\" Color=\"{StaticResource BackgroundColor}\"/>\n    <SolidColorBrush x:Key=\"ControlButtonOverBackground\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n\n    <!-- Albums -->\n    <SolidColorBrush x:Key=\"PlaylistItemForegroundBrush\" Color=\"#ededed\"/>\n    <SolidColorBrush x:Key=\"HotPlaylistItemBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n    <SolidColorBrush x:Key=\"SelectedPlaylistItemForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"SelectedPlaylistItemBackgroundBrush\" Color=\"{StaticResource AccentColor}\" Opacity=\"0.08\"/>\n\n    <!-- Current track -->\n    <SolidColorBrush x:Key=\"HotCurrentTrackBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.2\"/>\n\n    <!-- Context menu -->\n    <SolidColorBrush x:Key=\"HotContextMenuItemBackgroundBrush\" Color=\"Black\" Opacity=\"0.1\"/>\n    \n    <!-- TextBoxes -->\n    <SolidColorBrush x:Key=\"TextBoxBorderBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.3\"/>\n    <SolidColorBrush x:Key=\"TextBoxHotBorderBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.7\"/>\n    <SolidColorBrush x:Key=\"TextBoxForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n    <SolidColorBrush x:Key=\"TextBoxBackgroundBrush\" Color=\"#33FFFFFF\"/>\n\n    <SolidColorBrush x:Key=\"ShadowTopBrush\" Color=\"#525252\" Opacity=\"0.9\"/>\n    <SolidColorBrush x:Key=\"ShadowBottomBrush\" Color=\"#525252\" Opacity=\"0.9\"/>\n\n    <SolidColorBrush x:Key=\"AlbumsListBackgroundBrush\" Color=\"{StaticResource ContrastColor}\" Opacity=\"0.9\"/>\n    <SolidColorBrush x:Key=\"SplitterBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n\n    <SolidColorBrush x:Key=\"SearchBarBackgroundBrush\" Color=\"#3e4144\" Opacity=\"0.7\"/>\n\n    <!-- Volume bar -->\n    <SolidColorBrush x:Key=\"VolumeBarBackgroundBrush\" Color=\"#58595b\"/>\n\n    <!-- Comboboxes -->\n    <!-- ComboBoxBg-->\n    <SolidColorBrush x:Key=\"ComboBoxBackgroundBrush\" Color=\"#2e3136\" />\n    <!-- ComboBoxForeground-->\n    <SolidColorBrush x:Key=\"ComboBoxForegroundBrush\" Color=\"LightGray\"/>\n    <!-- ComboBoxBorder-->\n    <SolidColorBrush x:Key=\"ComboBoxBorderBrush\" Color=\"#333333\"/>\n    <!-- ComboBoxArrow-->\n    <SolidColorBrush x:Key=\"ComboBoxArrowBrush\" Color=\"#FF999999\"/>\n    <!-- ComboBoxBorderHover && ComboBoxArrowHover-->\n    <SolidColorBrush x:Key=\"ComboBoxHotBrush\" Color=\"#FFCCCCCC\" />\n    <!-- ComboBoxBgHover-->\n    <SolidColorBrush x:Key=\"ComboBoxHotBackgroundBrush\" Color=\"#111111\"/>\n    <!-- ComboBoxItemHighlighted-->\n    <SolidColorBrush x:Key=\"ComboBoxItemHotBackgroundBrush\" Color=\"#FF3F3F3F\" />\n\n    <!-- Progress bar -->\n    <SolidColorBrush x:Key=\"ProgressBarBackgroundBrush\" Color=\"#2e3136\"/>\n\n    <!-- Sidebar -->\n    <SolidColorBrush x:Key=\"SidebarBackgroundBrush\" Color=\"#282b2f\"/>\n    <FontFamily x:Key=\"SidebarForegroundFont\">Segoe UI SemiLight</FontFamily>\n    <SolidColorBrush x:Key=\"SidebarForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"SidebarInactiveForegroundBrush\" Color=\"White\" Opacity=\"0.7\"/>\n    <SolidColorBrush x:Key=\"SidebarGroupForegroundBrush\" Color=\"White\" Opacity=\"0.3\"/>\n    <SolidColorBrush x:Key=\"SidebarSliderBackgroundBrush\" Color=\"White\" Opacity=\"0.1\"/>\n\n    <SolidColorBrush x:Key=\"SidebarNowPlayingImageBackgroundBrush\" Color=\"#2e3136\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Graphite.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <!-- Colors -->\n    <Color x:Key=\"ForegroundColor\">#414042</Color>\n    <Color x:Key=\"BackgroundColor\">White</Color>\n    <Color x:Key=\"ContrastColor\">#f2f2f2</Color>\n\n    <SolidColorBrush x:Key=\"ForegroundBrush\" Color=\"{StaticResource ForegroundColor}\" />\n    <SolidColorBrush x:Key=\"BackgroundBrush\" Color=\"{StaticResource BackgroundColor}\" />\n\n    <SolidColorBrush x:Key=\"MainBackgroundBrush\" Color=\"{StaticResource BackgroundColor}\"/>\n\n    <SolidColorBrush x:Key=\"MainTabActiveForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n\n    <SolidColorBrush x:Key=\"MainBackgroundSplitterBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.15\"/>\n\n    <SolidColorBrush x:Key=\"AudioAlternationBackgroundBrush\" Color=\"Black\" Opacity=\"0.03\" />\n    \n    <!-- Main menu -->\n    <SolidColorBrush x:Key=\"MainMenuHotPlaylistItemBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.3\"/>\n\n    <!-- Buttons -->\n    <SolidColorBrush x:Key=\"ButtonBorderBrush\" Color=\"Gray\"/>\n    <SolidColorBrush x:Key=\"ButtonForegroundBrush\" Color=\"#333333\"/>\n    <SolidColorBrush x:Key=\"ButtonBackgroundBrush\" Color=\"#eeeeee\"/>\n    <SolidColorBrush x:Key=\"ButtonHotBackgroundBrush\" Color=\"#dedede\"/>\n    <SolidColorBrush x:Key=\"ButtonPressForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"ButtonPressBackgroundBrush\" Color=\"#333333\"/>\n    <SolidColorBrush x:Key=\"ButtonHighlightedHotBackgroundBrush\" Color=\"{StaticResource AccentColor}\" Opacity=\"0.8\"/>\n    <SolidColorBrush x:Key=\"ButtonHighlightedDisabledBackgroundBrush\" Color=\"LightGray\" Opacity=\"1\"/>\n\n    <!-- Control Icons -->\n    <SolidColorBrush x:Key=\"ControlButtonForeground\" Color=\"{StaticResource ForegroundColor}\"/>\n    <SolidColorBrush x:Key=\"ControlButtonBackground\" Color=\"{StaticResource BackgroundColor}\"/>\n    <SolidColorBrush x:Key=\"ControlButtonOverBackground\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n\n    <!-- Albums -->\n    <SolidColorBrush x:Key=\"PlaylistItemForegroundBrush\" Color=\"#707070\"/>\n    <SolidColorBrush x:Key=\"HotPlaylistItemBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n    <SolidColorBrush x:Key=\"SelectedPlaylistItemForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"SelectedPlaylistItemBackgroundBrush\" Color=\"{StaticResource AccentColor}\" Opacity=\"0.08\"/>\n\n    <!-- Current track -->\n    <SolidColorBrush x:Key=\"HotCurrentTrackBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n\n    <!-- Context menu -->\n    <SolidColorBrush x:Key=\"HotContextMenuItemBackgroundBrush\" Color=\"Black\" Opacity=\"0.1\"/>\n\n    <!-- TextBoxes -->\n    <SolidColorBrush x:Key=\"TextBoxBorderBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.3\"/>\n    <SolidColorBrush x:Key=\"TextBoxHotBorderBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.7\"/>\n    <SolidColorBrush x:Key=\"TextBoxForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n    <SolidColorBrush x:Key=\"TextBoxBackgroundBrush\" Color=\"#33FFFFFF\"/>\n\n    <SolidColorBrush x:Key=\"ShadowTopBrush\" Color=\"Black\" Opacity=\"0.2\"/>\n    <SolidColorBrush x:Key=\"ShadowBottomBrush\" Color=\"Black\" Opacity=\"0.2\"/>\n\n    <SolidColorBrush x:Key=\"AlbumsListBackgroundBrush\" Color=\"{StaticResource ContrastColor}\" Opacity=\"0.7\"/>\n    <SolidColorBrush x:Key=\"SplitterBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n\n    <!-- Progress bar -->\n    <SolidColorBrush x:Key=\"ProgressBarBackgroundBrush\" Color=\"#22000000\"/>\n\n    <!-- Volume bar -->\n    <SolidColorBrush x:Key=\"VolumeBarBackgroundBrush\" Color=\"White\"/>\n\n    <SolidColorBrush x:Key=\"SearchBarBackgroundBrush\" Color=\"#ecebec\" Opacity=\"0.7\"/>\n\n    <!-- Comboboxes -->\n    <!-- ComboBoxBg-->\n    <SolidColorBrush x:Key=\"ComboBoxBackgroundBrush\" Color=\"#FFEEEEEE\" />\n    <!-- ComboBoxForeground-->\n    <SolidColorBrush x:Key=\"ComboBoxForegroundBrush\" Color=\"Black\"/>\n    <!-- ComboBoxBorder-->\n    <SolidColorBrush x:Key=\"ComboBoxBorderBrush\" Color=\"#FFEEEEEE\"/>\n    <!-- ComboBoxArrow-->\n    <SolidColorBrush x:Key=\"ComboBoxArrowBrush\" Color=\"#FF999999\"/>\n    <!-- ComboBoxBorderHover && ComboBoxArrowHover-->\n    <SolidColorBrush x:Key=\"ComboBoxHotBrush\" Color=\"#FF333333\" />\n    <!-- ComboBoxBgHover-->\n    <SolidColorBrush x:Key=\"ComboBoxHotBackgroundBrush\" Color=\"#FFFFFFFF\"/>\n    <!-- ComboBoxItemHighlighted-->\n    <SolidColorBrush x:Key=\"ComboBoxItemHotBackgroundBrush\" Color=\"#FFDFDFDF\" />\n\n    <!-- Sidebar -->\n    <SolidColorBrush x:Key=\"SidebarBackgroundBrush\" Color=\"#2e3136\"/>\n    <FontFamily x:Key=\"SidebarForegroundFont\">Segoe UI SemiLight</FontFamily>\n    <SolidColorBrush x:Key=\"SidebarForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"SidebarInactiveForegroundBrush\" Color=\"White\" Opacity=\"0.7\"/>\n    <SolidColorBrush x:Key=\"SidebarGroupForegroundBrush\" Color=\"White\" Opacity=\"0.3\"/>\n    <SolidColorBrush x:Key=\"SidebarSliderBackgroundBrush\" Color=\"White\" Opacity=\"0.1\"/>\n\n    <SolidColorBrush x:Key=\"SidebarNowPlayingImageBackgroundBrush\" Color=\"Transparent\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/Resources/Themes/Light.xaml",
    "content": "﻿<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <!-- Colors -->\n    <Color x:Key=\"ForegroundColor\">#414042</Color>\n    <Color x:Key=\"BackgroundColor\">White</Color>\n    <Color x:Key=\"ContrastColor\">#f2f2f2</Color>\n\n    <SolidColorBrush x:Key=\"ForegroundBrush\" Color=\"{StaticResource ForegroundColor}\" />\n    <SolidColorBrush x:Key=\"BackgroundBrush\" Color=\"{StaticResource BackgroundColor}\" />\n\n    <SolidColorBrush x:Key=\"MainBackgroundBrush\" Color=\"{StaticResource BackgroundColor}\"/>\n\n    <SolidColorBrush x:Key=\"MainTabActiveForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n\n    <SolidColorBrush x:Key=\"MainBackgroundSplitterBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.15\"/>\n\n    <SolidColorBrush x:Key=\"AudioAlternationBackgroundBrush\" Color=\"Black\" Opacity=\"0.03\" />\n\n    <!-- Main menu -->\n    <SolidColorBrush x:Key=\"MainMenuHotPlaylistItemBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.3\"/>\n\n    <!-- Buttons -->\n    <SolidColorBrush x:Key=\"ButtonBorderBrush\" Color=\"Gray\"/>\n    <SolidColorBrush x:Key=\"ButtonForegroundBrush\" Color=\"#333333\"/>\n    <SolidColorBrush x:Key=\"ButtonBackgroundBrush\" Color=\"#eeeeee\"/>\n    <SolidColorBrush x:Key=\"ButtonHotBackgroundBrush\" Color=\"#dedede\"/>\n    <SolidColorBrush x:Key=\"ButtonPressForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"ButtonPressBackgroundBrush\" Color=\"#333333\"/>\n    <SolidColorBrush x:Key=\"ButtonHighlightedHotBackgroundBrush\" Color=\"{StaticResource AccentColor}\" Opacity=\"0.8\"/>\n    <SolidColorBrush x:Key=\"ButtonHighlightedDisabledBackgroundBrush\" Color=\"LightGray\" Opacity=\"1\"/>\n\n    <!-- Control Icons -->\n    <SolidColorBrush x:Key=\"ControlButtonForeground\" Color=\"{StaticResource ForegroundColor}\"/>\n    <SolidColorBrush x:Key=\"ControlButtonBackground\" Color=\"{StaticResource BackgroundColor}\"/>\n    <SolidColorBrush x:Key=\"ControlButtonOverBackground\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n\n    <!-- Albums -->\n    <SolidColorBrush x:Key=\"PlaylistItemForegroundBrush\" Color=\"#707070\"/>\n    <SolidColorBrush x:Key=\"HotPlaylistItemBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n    <SolidColorBrush x:Key=\"SelectedPlaylistItemForegroundBrush\" Color=\"White\"/>\n    <SolidColorBrush x:Key=\"SelectedPlaylistItemBackgroundBrush\" Color=\"{StaticResource AccentColor}\" Opacity=\"0.08\"/>\n\n    <!-- Current track -->\n    <SolidColorBrush x:Key=\"HotCurrentTrackBackgroundBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.1\"/>\n\n    <!-- Context menu -->\n    <SolidColorBrush x:Key=\"HotContextMenuItemBackgroundBrush\" Color=\"Black\" Opacity=\"0.1\"/>\n\n    <!-- TextBoxes -->\n    <SolidColorBrush x:Key=\"TextBoxBorderBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.3\"/>\n    <SolidColorBrush x:Key=\"TextBoxHotBorderBrush\" Color=\"{StaticResource ForegroundColor}\" Opacity=\"0.7\"/>\n    <SolidColorBrush x:Key=\"TextBoxForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n    <SolidColorBrush x:Key=\"TextBoxBackgroundBrush\" Color=\"#33FFFFFF\"/>\n\n    <SolidColorBrush x:Key=\"ShadowTopBrush\" Color=\"Black\" Opacity=\"0.2\"/>\n    <SolidColorBrush x:Key=\"ShadowBottomBrush\" Color=\"Black\" Opacity=\"0.2\"/>\n\n    <SolidColorBrush x:Key=\"AlbumsListBackgroundBrush\" Color=\"{StaticResource ContrastColor}\" Opacity=\"0.7\"/>\n    <SolidColorBrush x:Key=\"SplitterBrush\" Color=\"{StaticResource ForegroundColor}\"/>\n\n    <!-- Progress bar -->\n    <SolidColorBrush x:Key=\"ProgressBarBackgroundBrush\" Color=\"#22000000\"/>\n\n    <!-- Volume bar -->\n    <SolidColorBrush x:Key=\"VolumeBarBackgroundBrush\" Color=\"#58595b\"/>\n\n    <SolidColorBrush x:Key=\"SearchBarBackgroundBrush\" Color=\"#ecebec\" Opacity=\"0.7\"/>\n\n    <!-- Comboboxes -->\n    <!-- ComboBoxBg-->\n    <SolidColorBrush x:Key=\"ComboBoxBackgroundBrush\" Color=\"#FFEEEEEE\" />\n    <!-- ComboBoxForeground-->\n    <SolidColorBrush x:Key=\"ComboBoxForegroundBrush\" Color=\"Black\"/>\n    <!-- ComboBoxBorder-->\n    <SolidColorBrush x:Key=\"ComboBoxBorderBrush\" Color=\"#FFEEEEEE\"/>\n    <!-- ComboBoxArrow-->\n    <SolidColorBrush x:Key=\"ComboBoxArrowBrush\" Color=\"#FF999999\"/>\n    <!-- ComboBoxBorderHover && ComboBoxArrowHover-->\n    <SolidColorBrush x:Key=\"ComboBoxHotBrush\" Color=\"#FF333333\" />\n    <!-- ComboBoxBgHover-->\n    <SolidColorBrush x:Key=\"ComboBoxHotBackgroundBrush\" Color=\"#FFFFFFFF\"/>\n    <!-- ComboBoxItemHighlighted-->\n    <SolidColorBrush x:Key=\"ComboBoxItemHotBackgroundBrush\" Color=\"#FFDFDFDF\" />\n\n    <!-- Sidebar -->\n    <SolidColorBrush x:Key=\"SidebarBackgroundBrush\" Color=\"White\"/>\n    <FontFamily x:Key=\"SidebarForegroundFont\">Segoe UI SemiLight</FontFamily>\n    <SolidColorBrush x:Key=\"SidebarForegroundBrush\" Color=\"Black\"/>\n    <SolidColorBrush x:Key=\"SidebarInactiveForegroundBrush\" Color=\"Black\" Opacity=\"0.85\"/>\n    <SolidColorBrush x:Key=\"SidebarGroupForegroundBrush\" Color=\"Black\" Opacity=\"0.4\"/>\n    <SolidColorBrush x:Key=\"SidebarSliderBackgroundBrush\" Color=\"Black\" Opacity=\"0.1\"/>\n\n    <SolidColorBrush x:Key=\"SidebarNowPlayingImageBackgroundBrush\" Color=\"Transparent\"/>\n</ResourceDictionary>"
  },
  {
    "path": "Meridian/SQLite.cs",
    "content": "//\n// Copyright (c) 2009-2012 Krueger Systems, Inc.\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n//\n#if WINDOWS_PHONE && !USE_WP8_NATIVE_SQLITE\n#define USE_CSHARP_SQLITE\n#endif\n\nusing System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing System.Linq;\nusing System.Linq.Expressions;\nusing System.Threading;\n\n#if USE_CSHARP_SQLITE\nusing Sqlite3 = Community.CsharpSqlite.Sqlite3;\nusing Sqlite3DatabaseHandle = Community.CsharpSqlite.Sqlite3.sqlite3;\nusing Sqlite3Statement = Community.CsharpSqlite.Sqlite3.Vdbe;\n#elif USE_WP8_NATIVE_SQLITE\nusing Sqlite3 = Sqlite.Sqlite3;\nusing Sqlite3DatabaseHandle = Sqlite.Database;\nusing Sqlite3Statement = Sqlite.Statement;\n#else\nusing Sqlite3DatabaseHandle = System.IntPtr;\nusing Sqlite3Statement = System.IntPtr;\nusing System.Collections;\n#endif\n\nnamespace SQLite\n{\n\tpublic class SQLiteException : Exception\n\t{\n\t\tpublic SQLite3.Result Result { get; private set; }\n\n\t\tprotected SQLiteException (SQLite3.Result r,string message) : base(message)\n\t\t{\n\t\t\tResult = r;\n\t\t}\n\n\t\tpublic static SQLiteException New (SQLite3.Result r, string message)\n\t\t{\n\t\t\treturn new SQLiteException (r, message);\n\t\t}\n\t}\n\n\tpublic class NotNullConstraintViolationException : SQLiteException\n\t{\n\t\tpublic IEnumerable<TableMapping.Column> Columns { get; protected set; }\n\n\t\tprotected NotNullConstraintViolationException (SQLite3.Result r, string message)\n\t\t\t: this (r, message, null, null)\n\t\t{\n\n\t\t}\n\n\t\tprotected NotNullConstraintViolationException (SQLite3.Result r, string message, TableMapping mapping, object obj)\n\t\t\t: base (r, message)\n\t\t{\n\t\t\tif (mapping != null && obj != null) {\n\t\t\t\tthis.Columns = from c in mapping.Columns\n\t\t\t\t\t\t\t   where c.IsNullable == false && c.GetValue (obj) == null\n\t\t\t\t\t\t\t   select c;\n\t\t\t}\n\t\t}\n\n\t\tpublic static new NotNullConstraintViolationException New (SQLite3.Result r, string message)\n\t\t{\n\t\t\treturn new NotNullConstraintViolationException (r, message);\n\t\t}\n\n\t\tpublic static NotNullConstraintViolationException New (SQLite3.Result r, string message, TableMapping mapping, object obj)\n\t\t{\n\t\t\treturn new NotNullConstraintViolationException (r, message, mapping, obj);\n\t\t}\n\n\t\tpublic static NotNullConstraintViolationException New (SQLiteException exception, TableMapping mapping, object obj)\n\t\t{\n\t\t\treturn new NotNullConstraintViolationException (exception.Result, exception.Message, mapping, obj);\n\t\t}\n\t}\n\n\t[Flags]\n\tpublic enum SQLiteOpenFlags {\n\t\tReadOnly = 1, ReadWrite = 2, Create = 4,\n\t\tNoMutex = 0x8000, FullMutex = 0x10000,\n\t\tSharedCache = 0x20000, PrivateCache = 0x40000,\n\t\tProtectionComplete = 0x00100000,\n\t\tProtectionCompleteUnlessOpen = 0x00200000,\n\t\tProtectionCompleteUntilFirstUserAuthentication = 0x00300000,\n\t\tProtectionNone = 0x00400000\n\t}\n\n    [Flags]\n    public enum CreateFlags\n    {\n        None = 0,\n        ImplicitPK = 1,    // create a primary key for field called 'Id' (Orm.ImplicitPkName)\n        ImplicitIndex = 2, // create an index for fields ending in 'Id' (Orm.ImplicitIndexSuffix)\n        AllImplicit = 3,   // do both above\n\n        AutoIncPK = 4      // force PK field to be auto inc\n    }\n\n\t/// <summary>\n\t/// Represents an open connection to a SQLite database.\n\t/// </summary>\n\tpublic partial class SQLiteConnection : IDisposable\n\t{\n\t\tprivate bool _open;\n\t\tprivate TimeSpan _busyTimeout;\n\t\tprivate Dictionary<string, TableMapping> _mappings = null;\n\t\tprivate Dictionary<string, TableMapping> _tables = null;\n\t\tprivate System.Diagnostics.Stopwatch _sw;\n\t\tprivate long _elapsedMilliseconds = 0;\n\n\t\tprivate int _transactionDepth = 0;\n\t\tprivate Random _rand = new Random ();\n\n\t\tpublic Sqlite3DatabaseHandle Handle { get; private set; }\n\t\tinternal static readonly Sqlite3DatabaseHandle NullHandle = default(Sqlite3DatabaseHandle);\n\n\t\tpublic string DatabasePath { get; private set; }\n\n\t\tpublic bool TimeExecution { get; set; }\n\n\t\tpublic bool Trace { get; set; }\n\n\t\tpublic bool StoreDateTimeAsTicks { get; private set; }\n\n        public bool CaseSensitive { get; private set; }\n\n\t\t/// <summary>\n\t\t/// Constructs a new SQLiteConnection and opens a SQLite database specified by databasePath.\n\t\t/// </summary>\n\t\t/// <param name=\"databasePath\">\n\t\t/// Specifies the path to the database file.\n\t\t/// </param>\n\t\t/// <param name=\"storeDateTimeAsTicks\">\n\t\t/// Specifies whether to store DateTime properties as ticks (true) or strings (false). You\n\t\t/// absolutely do want to store them as Ticks in all new projects. The default of false is\n\t\t/// only here for backwards compatibility. There is a *significant* speed advantage, with no\n\t\t/// down sides, when setting storeDateTimeAsTicks = true.\n\t\t/// </param>\n\t\tpublic SQLiteConnection (string databasePath, bool storeDateTimeAsTicks = false, bool caseSensitive = true)\n            : this(databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, storeDateTimeAsTicks, caseSensitive)\n\t\t{\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Constructs a new SQLiteConnection and opens a SQLite database specified by databasePath.\n\t\t/// </summary>\n\t\t/// <param name=\"databasePath\">\n\t\t/// Specifies the path to the database file.\n\t\t/// </param>\n\t\t/// <param name=\"storeDateTimeAsTicks\">\n\t\t/// Specifies whether to store DateTime properties as ticks (true) or strings (false). You\n\t\t/// absolutely do want to store them as Ticks in all new projects. The default of false is\n\t\t/// only here for backwards compatibility. There is a *significant* speed advantage, with no\n\t\t/// down sides, when setting storeDateTimeAsTicks = true.\n\t\t/// </param>\n        public SQLiteConnection(string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = false, bool caseSensitive = true)\n\t\t{\n\t\t\tif (string.IsNullOrEmpty (databasePath))\n\t\t\t\tthrow new ArgumentException (\"Must be specified\", \"databasePath\");\n\n\t\t\tDatabasePath = databasePath;\n\n#if NETFX_CORE\n\t\t\tSQLite3.SetDirectory(/*temp directory type*/2, Windows.Storage.ApplicationData.Current.TemporaryFolder.Path);\n#endif\n\n\t\t\tSqlite3DatabaseHandle handle;\n\n#if SILVERLIGHT || USE_CSHARP_SQLITE\n            var r = SQLite3.Open (databasePath, out handle, (int)openFlags, IntPtr.Zero);\n#else\n\t\t\t// open using the byte[]\n\t\t\t// in the case where the path may include Unicode\n\t\t\t// force open to using UTF-8 using sqlite3_open_v2\n\t\t\tvar databasePathAsBytes = GetNullTerminatedUtf8 (DatabasePath);\n\t\t\tvar r = SQLite3.Open (databasePathAsBytes, out handle, (int) openFlags, IntPtr.Zero);\n#endif\n\n\t\t\tHandle = handle;\n\t\t\tif (r != SQLite3.Result.OK) {\n\t\t\t\tthrow SQLiteException.New (r, String.Format (\"Could not open database file: {0} ({1})\", DatabasePath, r));\n\t\t\t}\n\t\t\t_open = true;\n\n\t\t\tStoreDateTimeAsTicks = storeDateTimeAsTicks;\n            CaseSensitive = caseSensitive;\n\t\t\t\n\t\t\tBusyTimeout = TimeSpan.FromSeconds (0.1);\n\t\t}\n\t\t\n\t\tstatic SQLiteConnection ()\n\t\t{\n\t\t\tif (_preserveDuringLinkMagic) {\n\t\t\t\tvar ti = new ColumnInfo ();\n\t\t\t\tti.Name = \"magic\";\n\t\t\t}\n\t\t}\n\n        public void EnableLoadExtension(int onoff)\n        {\n            SQLite3.Result r = SQLite3.EnableLoadExtension(Handle, onoff);\n\t\t\tif (r != SQLite3.Result.OK) {\n\t\t\t\tstring msg = SQLite3.GetErrmsg (Handle);\n\t\t\t\tthrow SQLiteException.New (r, msg);\n\t\t\t}\n        }\n\n\t\tstatic byte[] GetNullTerminatedUtf8 (string s)\n\t\t{\n\t\t\tvar utf8Length = System.Text.Encoding.UTF8.GetByteCount (s);\n\t\t\tvar bytes = new byte [utf8Length + 1];\n\t\t\tutf8Length = System.Text.Encoding.UTF8.GetBytes(s, 0, s.Length, bytes, 0);\n\t\t\treturn bytes;\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// Used to list some code that we want the MonoTouch linker\n\t\t/// to see, but that we never want to actually execute.\n\t\t/// </summary>\n\t\tstatic bool _preserveDuringLinkMagic;\n\n\t\t/// <summary>\n\t\t/// Sets a busy handler to sleep the specified amount of time when a table is locked.\n\t\t/// The handler will sleep multiple times until a total time of <see cref=\"BusyTimeout\"/> has accumulated.\n\t\t/// </summary>\n\t\tpublic TimeSpan BusyTimeout {\n\t\t\tget { return _busyTimeout; }\n\t\t\tset {\n\t\t\t\t_busyTimeout = value;\n\t\t\t\tif (Handle != NullHandle) {\n\t\t\t\t\tSQLite3.BusyTimeout (Handle, (int)_busyTimeout.TotalMilliseconds);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the mappings from types to tables that the connection\n\t\t/// currently understands.\n\t\t/// </summary>\n\t\tpublic IEnumerable<TableMapping> TableMappings {\n\t\t\tget {\n\t\t\t\treturn _tables != null ? _tables.Values : Enumerable.Empty<TableMapping> ();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Retrieves the mapping that is automatically generated for the given type.\n\t\t/// </summary>\n\t\t/// <param name=\"type\">\n\t\t/// The type whose mapping to the database is returned.\n\t\t/// </param>         \n        /// <param name=\"createFlags\">\n\t\t/// Optional flags allowing implicit PK and indexes based on naming conventions\n\t\t/// </param>     \n\t\t/// <returns>\n\t\t/// The mapping represents the schema of the columns of the database and contains \n\t\t/// methods to set and get properties of objects.\n\t\t/// </returns>\n        public TableMapping GetMapping(Type type, CreateFlags createFlags = CreateFlags.None)\n\t\t{\n\t\t\tif (_mappings == null) {\n\t\t\t\t_mappings = new Dictionary<string, TableMapping> ();\n\t\t\t}\n\t\t\tTableMapping map;\n\t\t\tif (!_mappings.TryGetValue (type.FullName, out map)) {\n\t\t\t\tmap = new TableMapping (type, createFlags);\n\t\t\t\t_mappings [type.FullName] = map;\n\t\t\t}\n\t\t\treturn map;\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// Retrieves the mapping that is automatically generated for the given type.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// The mapping represents the schema of the columns of the database and contains \n\t\t/// methods to set and get properties of objects.\n\t\t/// </returns>\n\t\tpublic TableMapping GetMapping<T> ()\n\t\t{\n\t\t\treturn GetMapping (typeof (T));\n\t\t}\n\n\t\tprivate struct IndexedColumn\n\t\t{\n\t\t\tpublic int Order;\n\t\t\tpublic string ColumnName;\n\t\t}\n\n\t\tprivate struct IndexInfo\n\t\t{\n\t\t\tpublic string IndexName;\n\t\t\tpublic string TableName;\n\t\t\tpublic bool Unique;\n\t\t\tpublic List<IndexedColumn> Columns;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Executes a \"drop table\" on the database.  This is non-recoverable.\n\t\t/// </summary>\n\t\tpublic int DropTable<T>()\n\t\t{\n\t\t\tvar map = GetMapping (typeof (T));\n\n\t\t\tvar query = string.Format(\"drop table if exists \\\"{0}\\\"\", map.TableName);\n\n\t\t\treturn Execute (query);\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// Executes a \"create table if not exists\" on the database. It also\n\t\t/// creates any specified indexes on the columns of the table. It uses\n\t\t/// a schema automatically generated from the specified type. You can\n\t\t/// later access this schema by calling GetMapping.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// The number of entries added to the database schema.\n\t\t/// </returns>\n\t\tpublic int CreateTable<T>(CreateFlags createFlags = CreateFlags.None)\n\t\t{\n\t\t\treturn CreateTable(typeof (T), createFlags);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Executes a \"create table if not exists\" on the database. It also\n\t\t/// creates any specified indexes on the columns of the table. It uses\n\t\t/// a schema automatically generated from the specified type. You can\n\t\t/// later access this schema by calling GetMapping.\n\t\t/// </summary>\n\t\t/// <param name=\"ty\">Type to reflect to a database table.</param>\n        /// <param name=\"createFlags\">Optional flags allowing implicit PK and indexes based on naming conventions.</param>  \n\t\t/// <returns>\n\t\t/// The number of entries added to the database schema.\n\t\t/// </returns>\n        public int CreateTable(Type ty, CreateFlags createFlags = CreateFlags.None)\n\t\t{\n\t\t\tif (_tables == null) {\n\t\t\t\t_tables = new Dictionary<string, TableMapping> ();\n\t\t\t}\n\t\t\tTableMapping map;\n\t\t\tif (!_tables.TryGetValue (ty.FullName, out map)) {\n\t\t\t\tmap = GetMapping (ty, createFlags);\n\t\t\t\t_tables.Add (ty.FullName, map);\n\t\t\t}\n\t\t\tvar query = \"create table if not exists \\\"\" + map.TableName + \"\\\"(\\n\";\n\n            var decls = map.Columns.Select(p => Orm.SqlDecl(p, StoreDateTimeAsTicks, CaseSensitive));\n\t\t\tvar decl = string.Join (\",\\n\", decls.ToArray ());\n\t\t\tquery += decl;\n\t\t\tquery += \")\";\n\t\t\t\n\t\t\tvar count = Execute (query);\n\t\t\t\n\t\t\tif (count == 0) { //Possible bug: This always seems to return 0?\n\t\t\t\t// Table already exists, migrate it\n\t\t\t\tMigrateTable (map);\n\t\t\t}\n\n\t\t\tvar indexes = new Dictionary<string, IndexInfo> ();\n\t\t\tforeach (var c in map.Columns) {\n\t\t\t\tforeach (var i in c.Indices) {\n\t\t\t\t\tvar iname = i.Name ?? map.TableName + \"_\" + c.Name;\n\t\t\t\t\tIndexInfo iinfo;\n\t\t\t\t\tif (!indexes.TryGetValue (iname, out iinfo)) {\n\t\t\t\t\t\tiinfo = new IndexInfo {\n\t\t\t\t\t\t\tIndexName = iname,\n\t\t\t\t\t\t\tTableName = map.TableName,\n\t\t\t\t\t\t\tUnique = i.Unique,\n\t\t\t\t\t\t\tColumns = new List<IndexedColumn> ()\n\t\t\t\t\t\t};\n\t\t\t\t\t\tindexes.Add (iname, iinfo);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (i.Unique != iinfo.Unique)\n\t\t\t\t\t\tthrow new Exception (\"All the columns in an index must have the same value for their Unique property\");\n\n\t\t\t\t\tiinfo.Columns.Add (new IndexedColumn {\n\t\t\t\t\t\tOrder = i.Order,\n\t\t\t\t\t\tColumnName = c.Name\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach (var indexName in indexes.Keys) {\n\t\t\t\tvar index = indexes[indexName];\n\t\t\t\tvar columns = index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray();\n                count += CreateIndex(indexName, index.TableName, columns, index.Unique);\n\t\t\t}\n\t\t\t\n\t\t\treturn count;\n\t\t}\n\n        /// <summary>\n        /// Creates an index for the specified table and columns.\n        /// </summary>\n        /// <param name=\"indexName\">Name of the index to create</param>\n        /// <param name=\"tableName\">Name of the database table</param>\n        /// <param name=\"columnNames\">An array of column names to index</param>\n        /// <param name=\"unique\">Whether the index should be unique</param>\n        public int CreateIndex(string indexName, string tableName, string[] columnNames, bool unique = false)\n        {\n            const string sqlFormat = \"create {2} index if not exists \\\"{3}\\\" on \\\"{0}\\\"(\\\"{1}\\\")\";\n            var sql = String.Format(sqlFormat, tableName, string.Join (\"\\\", \\\"\", columnNames), unique ? \"unique\" : \"\", indexName);\n            return Execute(sql);\n        }\n\n        /// <summary>\n        /// Creates an index for the specified table and column.\n        /// </summary>\n        /// <param name=\"indexName\">Name of the index to create</param>\n        /// <param name=\"tableName\">Name of the database table</param>\n        /// <param name=\"columnName\">Name of the column to index</param>\n        /// <param name=\"unique\">Whether the index should be unique</param>\n        public int CreateIndex(string indexName, string tableName, string columnName, bool unique = false)\n        {\n            return CreateIndex(indexName, tableName, new string[] { columnName }, unique);\n        }\n        \n        /// <summary>\n        /// Creates an index for the specified table and column.\n        /// </summary>\n        /// <param name=\"tableName\">Name of the database table</param>\n        /// <param name=\"columnName\">Name of the column to index</param>\n        /// <param name=\"unique\">Whether the index should be unique</param>\n        public int CreateIndex(string tableName, string columnName, bool unique = false)\n        {\n            return CreateIndex(tableName + \"_\" + columnName, tableName, columnName, unique);\n        }\n\n        /// <summary>\n        /// Creates an index for the specified table and columns.\n        /// </summary>\n        /// <param name=\"tableName\">Name of the database table</param>\n        /// <param name=\"columnNames\">An array of column names to index</param>\n        /// <param name=\"unique\">Whether the index should be unique</param>\n        public int CreateIndex(string tableName, string[] columnNames, bool unique = false)\n        {\n            return CreateIndex(tableName + \"_\" + string.Join (\"_\", columnNames), tableName, columnNames, unique);\n        }\n\n        /// <summary>\n        /// Creates an index for the specified object property.\n        /// e.g. CreateIndex<Client>(c => c.Name);\n        /// </summary>\n        /// <typeparam name=\"T\">Type to reflect to a database table.</typeparam>\n        /// <param name=\"property\">Property to index</param>\n        /// <param name=\"unique\">Whether the index should be unique</param>\n        public void CreateIndex<T>(Expression<Func<T, object>> property, bool unique = false)\n        {\n            MemberExpression mx;\n            if (property.Body.NodeType == ExpressionType.Convert)\n            {\n                mx = ((UnaryExpression)property.Body).Operand as MemberExpression;\n            }\n            else\n            {\n                mx= (property.Body as MemberExpression);\n            }\n            var propertyInfo = mx.Member as PropertyInfo;\n            if (propertyInfo == null)\n            {\n                throw new ArgumentException(\"The lambda expression 'property' should point to a valid Property\");\n            }\n\n            var propName = propertyInfo.Name;\n\n            var map = GetMapping<T>();\n            var colName = map.FindColumnWithPropertyName(propName).Name;\n\n            CreateIndex(map.TableName, colName, unique);\n        }\n\n\t\tpublic class ColumnInfo\n\t\t{\n//\t\t\tpublic int cid { get; set; }\n\n\t\t\t[Column (\"name\")]\n\t\t\tpublic string Name { get; set; }\n\n//\t\t\t[Column (\"type\")]\n//\t\t\tpublic string ColumnType { get; set; }\n\n\t\t\tpublic int notnull { get; set; }\n\n//\t\t\tpublic string dflt_value { get; set; }\n\n//\t\t\tpublic int pk { get; set; }\n\n\t\t\tpublic override string ToString ()\n\t\t\t{\n\t\t\t\treturn Name;\n\t\t\t}\n\t\t}\n\n\t\tpublic List<ColumnInfo> GetTableInfo (string tableName)\n\t\t{\n\t\t\tvar query = \"pragma table_info(\\\"\" + tableName + \"\\\")\";\t\t\t\n\t\t\treturn Query<ColumnInfo> (query);\n\t\t}\n\n\t\tvoid MigrateTable (TableMapping map)\n\t\t{\n\t\t\tvar existingCols = GetTableInfo (map.TableName);\n\t\t\t\n\t\t\tvar toBeAdded = new List<TableMapping.Column> ();\n\t\t\t\n\t\t\tforeach (var p in map.Columns) {\n\t\t\t\tvar found = false;\n\t\t\t\tforeach (var c in existingCols) {\n\t\t\t\t\tfound = (string.Compare (p.Name, c.Name, StringComparison.OrdinalIgnoreCase) == 0);\n\t\t\t\t\tif (found)\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (!found) {\n\t\t\t\t\ttoBeAdded.Add (p);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tforeach (var p in toBeAdded) {\n\t\t\t\tvar addCol = \"alter table \\\"\" + map.TableName + \"\\\" add column \" + Orm.SqlDecl (p, StoreDateTimeAsTicks);\n\t\t\t\tExecute (addCol);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new SQLiteCommand. Can be overridden to provide a sub-class.\n\t\t/// </summary>\n\t\t/// <seealso cref=\"SQLiteCommand.OnInstanceCreated\"/>\n\t\tprotected virtual SQLiteCommand NewCommand ()\n\t\t{\n\t\t\treturn new SQLiteCommand (this);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a new SQLiteCommand given the command text with arguments. Place a '?'\n\t\t/// in the command text for each of the arguments.\n\t\t/// </summary>\n\t\t/// <param name=\"cmdText\">\n\t\t/// The fully escaped SQL.\n\t\t/// </param>\n\t\t/// <param name=\"args\">\n\t\t/// Arguments to substitute for the occurences of '?' in the command text.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// A <see cref=\"SQLiteCommand\"/>\n\t\t/// </returns>\n\t\tpublic SQLiteCommand CreateCommand (string cmdText, params object[] ps)\n\t\t{\n\t\t\tif (!_open)\n\t\t\t\tthrow SQLiteException.New (SQLite3.Result.Error, \"Cannot create commands from unopened database\");\n\n\t\t\tvar cmd = NewCommand ();\n\t\t\tcmd.CommandText = cmdText;\n\t\t\tforeach (var o in ps) {\n\t\t\t\tcmd.Bind (o);\n\t\t\t}\n\t\t\treturn cmd;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'\n\t\t/// in the command text for each of the arguments and then executes that command.\n\t\t/// Use this method instead of Query when you don't expect rows back. Such cases include\n\t\t/// INSERTs, UPDATEs, and DELETEs.\n\t\t/// You can set the Trace or TimeExecution properties of the connection\n\t\t/// to profile execution.\n\t\t/// </summary>\n\t\t/// <param name=\"query\">\n\t\t/// The fully escaped SQL.\n\t\t/// </param>\n\t\t/// <param name=\"args\">\n\t\t/// Arguments to substitute for the occurences of '?' in the query.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows modified in the database as a result of this execution.\n\t\t/// </returns>\n\t\tpublic int Execute (string query, params object[] args)\n\t\t{\n\t\t\tvar cmd = CreateCommand (query, args);\n\t\t\t\n\t\t\tif (TimeExecution) {\n\t\t\t\tif (_sw == null) {\n\t\t\t\t\t_sw = new Stopwatch ();\n\t\t\t\t}\n\t\t\t\t_sw.Reset ();\n\t\t\t\t_sw.Start ();\n\t\t\t}\n\n\t\t\tvar r = cmd.ExecuteNonQuery ();\n\t\t\t\n\t\t\tif (TimeExecution) {\n\t\t\t\t_sw.Stop ();\n\t\t\t\t_elapsedMilliseconds += _sw.ElapsedMilliseconds;\n\t\t\t\tDebug.WriteLine (string.Format (\"Finished in {0} ms ({1:0.0} s total)\", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0));\n\t\t\t}\n\t\t\t\n\t\t\treturn r;\n\t\t}\n\n\t\tpublic T ExecuteScalar<T> (string query, params object[] args)\n\t\t{\n\t\t\tvar cmd = CreateCommand (query, args);\n\t\t\t\n\t\t\tif (TimeExecution) {\n\t\t\t\tif (_sw == null) {\n\t\t\t\t\t_sw = new Stopwatch ();\n\t\t\t\t}\n\t\t\t\t_sw.Reset ();\n\t\t\t\t_sw.Start ();\n\t\t\t}\n\t\t\t\n\t\t\tvar r = cmd.ExecuteScalar<T> ();\n\t\t\t\n\t\t\tif (TimeExecution) {\n\t\t\t\t_sw.Stop ();\n\t\t\t\t_elapsedMilliseconds += _sw.ElapsedMilliseconds;\n\t\t\t\tDebug.WriteLine (string.Format (\"Finished in {0} ms ({1:0.0} s total)\", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0));\n\t\t\t}\n\t\t\t\n\t\t\treturn r;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'\n\t\t/// in the command text for each of the arguments and then executes that command.\n\t\t/// It returns each row of the result using the mapping automatically generated for\n\t\t/// the given type.\n\t\t/// </summary>\n\t\t/// <param name=\"query\">\n\t\t/// The fully escaped SQL.\n\t\t/// </param>\n\t\t/// <param name=\"args\">\n\t\t/// Arguments to substitute for the occurences of '?' in the query.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// An enumerable with one result for each row returned by the query.\n\t\t/// </returns>\n\t\tpublic List<T> Query<T> (string query, params object[] args) where T : new()\n\t\t{\n\t\t\tvar cmd = CreateCommand (query, args);\n\t\t\treturn cmd.ExecuteQuery<T> ();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'\n\t\t/// in the command text for each of the arguments and then executes that command.\n\t\t/// It returns each row of the result using the mapping automatically generated for\n\t\t/// the given type.\n\t\t/// </summary>\n\t\t/// <param name=\"query\">\n\t\t/// The fully escaped SQL.\n\t\t/// </param>\n\t\t/// <param name=\"args\">\n\t\t/// Arguments to substitute for the occurences of '?' in the query.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// An enumerable with one result for each row returned by the query.\n\t\t/// The enumerator will call sqlite3_step on each call to MoveNext, so the database\n\t\t/// connection must remain open for the lifetime of the enumerator.\n\t\t/// </returns>\n\t\tpublic IEnumerable<T> DeferredQuery<T>(string query, params object[] args) where T : new()\n\t\t{\n\t\t\tvar cmd = CreateCommand(query, args);\n\t\t\treturn cmd.ExecuteDeferredQuery<T>();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'\n\t\t/// in the command text for each of the arguments and then executes that command.\n\t\t/// It returns each row of the result using the specified mapping. This function is\n\t\t/// only used by libraries in order to query the database via introspection. It is\n\t\t/// normally not used.\n\t\t/// </summary>\n\t\t/// <param name=\"map\">\n\t\t/// A <see cref=\"TableMapping\"/> to use to convert the resulting rows\n\t\t/// into objects.\n\t\t/// </param>\n\t\t/// <param name=\"query\">\n\t\t/// The fully escaped SQL.\n\t\t/// </param>\n\t\t/// <param name=\"args\">\n\t\t/// Arguments to substitute for the occurences of '?' in the query.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// An enumerable with one result for each row returned by the query.\n\t\t/// </returns>\n\t\tpublic List<object> Query (TableMapping map, string query, params object[] args)\n\t\t{\n\t\t\tvar cmd = CreateCommand (query, args);\n\t\t\treturn cmd.ExecuteQuery<object> (map);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'\n\t\t/// in the command text for each of the arguments and then executes that command.\n\t\t/// It returns each row of the result using the specified mapping. This function is\n\t\t/// only used by libraries in order to query the database via introspection. It is\n\t\t/// normally not used.\n\t\t/// </summary>\n\t\t/// <param name=\"map\">\n\t\t/// A <see cref=\"TableMapping\"/> to use to convert the resulting rows\n\t\t/// into objects.\n\t\t/// </param>\n\t\t/// <param name=\"query\">\n\t\t/// The fully escaped SQL.\n\t\t/// </param>\n\t\t/// <param name=\"args\">\n\t\t/// Arguments to substitute for the occurences of '?' in the query.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// An enumerable with one result for each row returned by the query.\n\t\t/// The enumerator will call sqlite3_step on each call to MoveNext, so the database\n\t\t/// connection must remain open for the lifetime of the enumerator.\n\t\t/// </returns>\n\t\tpublic IEnumerable<object> DeferredQuery(TableMapping map, string query, params object[] args)\n\t\t{\n\t\t\tvar cmd = CreateCommand(query, args);\n\t\t\treturn cmd.ExecuteDeferredQuery<object>(map);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns a queryable interface to the table represented by the given type.\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// A queryable object that is able to translate Where, OrderBy, and Take\n\t\t/// queries into native SQL.\n\t\t/// </returns>\n\t\tpublic TableQuery<T> Table<T> () where T : new()\n\t\t{\n\t\t\treturn new TableQuery<T> (this);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Attempts to retrieve an object with the given primary key from the table\n\t\t/// associated with the specified type. Use of this method requires that\n\t\t/// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute).\n\t\t/// </summary>\n\t\t/// <param name=\"pk\">\n\t\t/// The primary key.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The object with the given primary key. Throws a not found exception\n\t\t/// if the object is not found.\n\t\t/// </returns>\n\t\tpublic T Get<T> (object pk) where T : new()\n\t\t{\n\t\t\tvar map = GetMapping (typeof(T));\n\t\t\treturn Query<T> (map.GetByPrimaryKeySql, pk).First ();\n\t\t}\n\n        /// <summary>\n        /// Attempts to retrieve the first object that matches the predicate from the table\n        /// associated with the specified type. \n        /// </summary>\n        /// <param name=\"predicate\">\n        /// A predicate for which object to find.\n        /// </param>\n        /// <returns>\n        /// The object that matches the given predicate. Throws a not found exception\n        /// if the object is not found.\n        /// </returns>\n        public T Get<T> (Expression<Func<T, bool>> predicate) where T : new()\n        {\n            return Table<T> ().Where (predicate).First ();\n        }\n\n\t\t/// <summary>\n\t\t/// Attempts to retrieve an object with the given primary key from the table\n\t\t/// associated with the specified type. Use of this method requires that\n\t\t/// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute).\n\t\t/// </summary>\n\t\t/// <param name=\"pk\">\n\t\t/// The primary key.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The object with the given primary key or null\n\t\t/// if the object is not found.\n\t\t/// </returns>\n\t\tpublic T Find<T> (object pk) where T : new ()\n\t\t{\n\t\t\tvar map = GetMapping (typeof (T));\n\t\t\treturn Query<T> (map.GetByPrimaryKeySql, pk).FirstOrDefault ();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Attempts to retrieve an object with the given primary key from the table\n\t\t/// associated with the specified type. Use of this method requires that\n\t\t/// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute).\n\t\t/// </summary>\n\t\t/// <param name=\"pk\">\n\t\t/// The primary key.\n\t\t/// </param>\n\t\t/// <param name=\"map\">\n\t\t/// The TableMapping used to identify the object type.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The object with the given primary key or null\n\t\t/// if the object is not found.\n\t\t/// </returns>\n\t\tpublic object Find (object pk, TableMapping map)\n\t\t{\n\t\t\treturn Query (map, map.GetByPrimaryKeySql, pk).FirstOrDefault ();\n\t\t}\n\t\t\n\t\t/// <summary>\n        /// Attempts to retrieve the first object that matches the predicate from the table\n        /// associated with the specified type. \n        /// </summary>\n        /// <param name=\"predicate\">\n        /// A predicate for which object to find.\n        /// </param>\n        /// <returns>\n        /// The object that matches the given predicate or null\n        /// if the object is not found.\n        /// </returns>\n        public T Find<T> (Expression<Func<T, bool>> predicate) where T : new()\n        {\n            return Table<T> ().Where (predicate).FirstOrDefault ();\n        }\n\n\t\t/// <summary>\n\t\t/// Whether <see cref=\"BeginTransaction\"/> has been called and the database is waiting for a <see cref=\"Commit\"/>.\n\t\t/// </summary>\n\t\tpublic bool IsInTransaction {\n\t\t\tget { return _transactionDepth > 0; }\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Begins a new transaction. Call <see cref=\"Commit\"/> to end the transaction.\n\t\t/// </summary>\n\t\t/// <example cref=\"System.InvalidOperationException\">Throws if a transaction has already begun.</example>\n\t\tpublic void BeginTransaction ()\n\t\t{\n\t\t\t// The BEGIN command only works if the transaction stack is empty, \n\t\t\t//    or in other words if there are no pending transactions. \n\t\t\t// If the transaction stack is not empty when the BEGIN command is invoked, \n\t\t\t//    then the command fails with an error.\n\t\t\t// Rather than crash with an error, we will just ignore calls to BeginTransaction\n\t\t\t//    that would result in an error.\n\t\t\tif (Interlocked.CompareExchange (ref _transactionDepth, 1, 0) == 0) {\n\t\t\t\ttry {\n\t\t\t\t\tExecute (\"begin transaction\");\n\t\t\t\t} catch (Exception ex) {\n\t\t\t\t\tvar sqlExp = ex as SQLiteException;\n\t\t\t\t\tif (sqlExp != null) {\n\t\t\t\t\t\t// It is recommended that applications respond to the errors listed below \n\t\t\t\t\t\t//    by explicitly issuing a ROLLBACK command.\n\t\t\t\t\t\t// TODO: This rollback failsafe should be localized to all throw sites.\n\t\t\t\t\t\tswitch (sqlExp.Result) {\n\t\t\t\t\t\tcase SQLite3.Result.IOError:\n\t\t\t\t\t\tcase SQLite3.Result.Full:\n\t\t\t\t\t\tcase SQLite3.Result.Busy:\n\t\t\t\t\t\tcase SQLite3.Result.NoMem:\n\t\t\t\t\t\tcase SQLite3.Result.Interrupt:\n\t\t\t\t\t\t\tRollbackTo (null, true);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Call decrement and not VolatileWrite in case we've already \n\t\t\t\t\t\t//    created a transaction point in SaveTransactionPoint since the catch.\n\t\t\t\t\t\tInterlocked.Decrement (ref _transactionDepth);\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow;\n\t\t\t\t}\n\t\t\t} else { \n\t\t\t\t// Calling BeginTransaction on an already open transaction is invalid\n\t\t\t\tthrow new InvalidOperationException (\"Cannot begin a transaction while already in a transaction.\");\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Creates a savepoint in the database at the current point in the transaction timeline.\n\t\t/// Begins a new transaction if one is not in progress.\n\t\t/// \n\t\t/// Call <see cref=\"RollbackTo\"/> to undo transactions since the returned savepoint.\n\t\t/// Call <see cref=\"Release\"/> to commit transactions after the savepoint returned here.\n\t\t/// Call <see cref=\"Commit\"/> to end the transaction, committing all changes.\n\t\t/// </summary>\n\t\t/// <returns>A string naming the savepoint.</returns>\n\t\tpublic string SaveTransactionPoint ()\n\t\t{\n\t\t\tint depth = Interlocked.Increment (ref _transactionDepth) - 1;\n\t\t\tstring retVal = \"S\" + _rand.Next (short.MaxValue) + \"D\" + depth;\n\n\t\t\ttry {\n\t\t\t\tExecute (\"savepoint \" + retVal);\n\t\t\t} catch (Exception ex) {\n\t\t\t\tvar sqlExp = ex as SQLiteException;\n\t\t\t\tif (sqlExp != null) {\n\t\t\t\t\t// It is recommended that applications respond to the errors listed below \n\t\t\t\t\t//    by explicitly issuing a ROLLBACK command.\n\t\t\t\t\t// TODO: This rollback failsafe should be localized to all throw sites.\n\t\t\t\t\tswitch (sqlExp.Result) {\n\t\t\t\t\tcase SQLite3.Result.IOError:\n\t\t\t\t\tcase SQLite3.Result.Full:\n\t\t\t\t\tcase SQLite3.Result.Busy:\n\t\t\t\t\tcase SQLite3.Result.NoMem:\n\t\t\t\t\tcase SQLite3.Result.Interrupt:\n\t\t\t\t\t\tRollbackTo (null, true);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tInterlocked.Decrement (ref _transactionDepth);\n\t\t\t\t}\n\n\t\t\t\tthrow;\n\t\t\t}\n\n\t\t\treturn retVal;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Rolls back the transaction that was begun by <see cref=\"BeginTransaction\"/> or <see cref=\"SaveTransactionPoint\"/>.\n\t\t/// </summary>\n\t\tpublic void Rollback ()\n\t\t{\n\t\t\tRollbackTo (null, false);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Rolls back the savepoint created by <see cref=\"BeginTransaction\"/> or SaveTransactionPoint.\n\t\t/// </summary>\n\t\t/// <param name=\"savepoint\">The name of the savepoint to roll back to, as returned by <see cref=\"SaveTransactionPoint\"/>.  If savepoint is null or empty, this method is equivalent to a call to <see cref=\"Rollback\"/></param>\n\t\tpublic void RollbackTo (string savepoint)\n\t\t{\n\t\t\tRollbackTo (savepoint, false);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Rolls back the transaction that was begun by <see cref=\"BeginTransaction\"/>.\n\t\t/// </summary>\n\t\t/// <param name=\"noThrow\">true to avoid throwing exceptions, false otherwise</param>\n\t\tvoid RollbackTo (string savepoint, bool noThrow)\n\t\t{\n\t\t\t// Rolling back without a TO clause rolls backs all transactions \n\t\t\t//    and leaves the transaction stack empty.   \n\t\t\ttry {\n\t\t\t\tif (String.IsNullOrEmpty (savepoint)) {\n\t\t\t\t\tif (Interlocked.Exchange (ref _transactionDepth, 0) > 0) {\n\t\t\t\t\t\tExecute (\"rollback\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDoSavePointExecute (savepoint, \"rollback to \");\n\t\t\t\t}   \n\t\t\t} catch (SQLiteException) {\n\t\t\t\tif (!noThrow)\n\t\t\t\t\tthrow;\n            \n\t\t\t}\n\t\t\t// No need to rollback if there are no transactions open.\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Releases a savepoint returned from <see cref=\"SaveTransactionPoint\"/>.  Releasing a savepoint \n\t\t///    makes changes since that savepoint permanent if the savepoint began the transaction,\n\t\t///    or otherwise the changes are permanent pending a call to <see cref=\"Commit\"/>.\n\t\t/// \n\t\t/// The RELEASE command is like a COMMIT for a SAVEPOINT.\n\t\t/// </summary>\n\t\t/// <param name=\"savepoint\">The name of the savepoint to release.  The string should be the result of a call to <see cref=\"SaveTransactionPoint\"/></param>\n\t\tpublic void Release (string savepoint)\n\t\t{\n\t\t\tDoSavePointExecute (savepoint, \"release \");\n\t\t}\n\n\t\tvoid DoSavePointExecute (string savepoint, string cmd)\n\t\t{\n\t\t\t// Validate the savepoint\n\t\t\tint firstLen = savepoint.IndexOf ('D');\n\t\t\tif (firstLen >= 2 && savepoint.Length > firstLen + 1) {\n\t\t\t\tint depth;\n\t\t\t\tif (Int32.TryParse (savepoint.Substring (firstLen + 1), out depth)) {\n\t\t\t\t\t// TODO: Mild race here, but inescapable without locking almost everywhere.\n\t\t\t\t\tif (0 <= depth && depth < _transactionDepth) {\n#if NETFX_CORE\n                        Volatile.Write (ref _transactionDepth, depth);\n#elif SILVERLIGHT\n\t\t\t\t\t\t_transactionDepth = depth;\n#else\n                        Thread.VolatileWrite (ref _transactionDepth, depth);\n#endif\n                        Execute (cmd + savepoint);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow new ArgumentException (\"savePoint is not valid, and should be the result of a call to SaveTransactionPoint.\", \"savePoint\");\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Commits the transaction that was begun by <see cref=\"BeginTransaction\"/>.\n\t\t/// </summary>\n\t\tpublic void Commit ()\n\t\t{\n\t\t\tif (Interlocked.Exchange (ref _transactionDepth, 0) != 0) {\n\t\t\t\tExecute (\"commit\");\n\t\t\t}\n\t\t\t// Do nothing on a commit with no open transaction\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Executes <param name=\"action\"> within a (possibly nested) transaction by wrapping it in a SAVEPOINT. If an\n\t\t/// exception occurs the whole transaction is rolled back, not just the current savepoint. The exception\n\t\t/// is rethrown.\n\t\t/// </summary>\n\t\t/// <param name=\"action\">\n\t\t/// The <see cref=\"Action\"/> to perform within a transaction. <param name=\"action\"> can contain any number\n\t\t/// of operations on the connection but should never call <see cref=\"BeginTransaction\"/> or\n\t\t/// <see cref=\"Commit\"/>.\n\t\t/// </param>\n\t\tpublic void RunInTransaction (Action action)\n\t\t{\n\t\t\ttry {\n\t\t\t\tvar savePoint = SaveTransactionPoint ();\n\t\t\t\taction ();\n\t\t\t\tRelease (savePoint);\n\t\t\t} catch (Exception) {\n\t\t\t\tRollback ();\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inserts all specified objects.\n\t\t/// </summary>\n\t\t/// <param name=\"objects\">\n\t\t/// An <see cref=\"IEnumerable\"/> of the objects to insert.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows added to the table.\n\t\t/// </returns>\n\t\tpublic int InsertAll (System.Collections.IEnumerable objects)\n\t\t{\n\t\t\tvar c = 0;\n\t\t\tRunInTransaction(() => {\n\t\t\t\tforeach (var r in objects) {\n\t\t\t\t\tc += Insert (r);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn c;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inserts all specified objects.\n\t\t/// </summary>\n\t\t/// <param name=\"objects\">\n\t\t/// An <see cref=\"IEnumerable\"/> of the objects to insert.\n\t\t/// </param>\n\t\t/// <param name=\"extra\">\n\t\t/// Literal SQL code that gets placed into the command. INSERT {extra} INTO ...\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows added to the table.\n\t\t/// </returns>\n\t\tpublic int InsertAll (System.Collections.IEnumerable objects, string extra)\n\t\t{\n\t\t\tvar c = 0;\n\t\t\tRunInTransaction (() => {\n\t\t\t\tforeach (var r in objects) {\n\t\t\t\t\tc += Insert (r, extra);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn c;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inserts all specified objects.\n\t\t/// </summary>\n\t\t/// <param name=\"objects\">\n\t\t/// An <see cref=\"IEnumerable\"/> of the objects to insert.\n\t\t/// </param>\n\t\t/// <param name=\"objType\">\n\t\t/// The type of object to insert.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows added to the table.\n\t\t/// </returns>\n\t\tpublic int InsertAll (System.Collections.IEnumerable objects, Type objType)\n\t\t{\n\t\t\tvar c = 0;\n\t\t\tRunInTransaction (() => {\n\t\t\t\tforeach (var r in objects) {\n\t\t\t\t\tc += Insert (r, objType);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn c;\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// Inserts the given object and retrieves its\n\t\t/// auto incremented primary key if it has one.\n\t\t/// </summary>\n\t\t/// <param name=\"obj\">\n\t\t/// The object to insert.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows added to the table.\n\t\t/// </returns>\n\t\tpublic int Insert (object obj)\n\t\t{\n\t\t\tif (obj == null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\treturn Insert (obj, \"\", obj.GetType ());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inserts the given object and retrieves its\n\t\t/// auto incremented primary key if it has one.\n\t\t/// If a UNIQUE constraint violation occurs with\n\t\t/// some pre-existing object, this function deletes\n\t\t/// the old object.\n\t\t/// </summary>\n\t\t/// <param name=\"obj\">\n\t\t/// The object to insert.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows modified.\n\t\t/// </returns>\n\t\tpublic int InsertOrReplace (object obj)\n\t\t{\n\t\t\tif (obj == null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\treturn Insert (obj, \"OR REPLACE\", obj.GetType ());\n\t\t}\n\n        public int InsertOrIgnore(object obj)\n        {\n            if (obj == null)\n            {\n                return 0;\n            }\n            return Insert(obj, \"OR IGNORE\", obj.GetType());\n        }\n\n\n        public int InsertOrReplaceAll(IEnumerable objects)\n        {\n            var c = 0;\n            RunInTransaction(() =>\n            {\n                foreach (var r in objects)\n                {\n                    c += InsertOrReplace(r);\n                }\n            });\n            return c;\n        }\n\n        public int InsertOrIgnoreAll(IEnumerable objects)\n        {\n            var c = 0;\n            RunInTransaction(() =>\n            {\n                foreach (var r in objects)\n                {\n                    c += InsertOrIgnore(r);\n                }\n            });\n            return c;\n        }\n\n\t\t/// <summary>\n\t\t/// Inserts the given object and retrieves its\n\t\t/// auto incremented primary key if it has one.\n\t\t/// </summary>\n\t\t/// <param name=\"obj\">\n\t\t/// The object to insert.\n\t\t/// </param>\n\t\t/// <param name=\"objType\">\n\t\t/// The type of object to insert.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows added to the table.\n\t\t/// </returns>\n\t\tpublic int Insert (object obj, Type objType)\n\t\t{\n\t\t\treturn Insert (obj, \"\", objType);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Inserts the given object and retrieves its\n\t\t/// auto incremented primary key if it has one.\n\t\t/// If a UNIQUE constraint violation occurs with\n\t\t/// some pre-existing object, this function deletes\n\t\t/// the old object.\n\t\t/// </summary>\n\t\t/// <param name=\"obj\">\n\t\t/// The object to insert.\n\t\t/// </param>\n\t\t/// <param name=\"objType\">\n\t\t/// The type of object to insert.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows modified.\n\t\t/// </returns>\n\t\tpublic int InsertOrReplace (object obj, Type objType)\n\t\t{\n\t\t\treturn Insert (obj, \"OR REPLACE\", objType);\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// Inserts the given object and retrieves its\n\t\t/// auto incremented primary key if it has one.\n\t\t/// </summary>\n\t\t/// <param name=\"obj\">\n\t\t/// The object to insert.\n\t\t/// </param>\n\t\t/// <param name=\"extra\">\n\t\t/// Literal SQL code that gets placed into the command. INSERT {extra} INTO ...\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows added to the table.\n\t\t/// </returns>\n\t\tpublic int Insert (object obj, string extra)\n\t\t{\n\t\t\tif (obj == null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\treturn Insert (obj, extra, obj.GetType ());\n\t\t}\n\n\t    /// <summary>\n\t    /// Inserts the given object and retrieves its\n\t    /// auto incremented primary key if it has one.\n\t    /// </summary>\n\t    /// <param name=\"obj\">\n\t    /// The object to insert.\n\t    /// </param>\n\t    /// <param name=\"extra\">\n\t    /// Literal SQL code that gets placed into the command. INSERT {extra} INTO ...\n\t    /// </param>\n\t    /// <param name=\"objType\">\n\t    /// The type of object to insert.\n\t    /// </param>\n\t    /// <returns>\n\t    /// The number of rows added to the table.\n\t    /// </returns>\n\t    public int Insert (object obj, string extra, Type objType)\n\t\t{\n\t\t\tif (obj == null || objType == null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\t\n            \n\t\t\tvar map = GetMapping (objType);\n\n#if NETFX_CORE\n            if (map.PK != null && map.PK.IsAutoGuid)\n            {\n                // no GetProperty so search our way up the inheritance chain till we find it\n                PropertyInfo prop;\n                while (objType != null)\n                {\n                    var info = objType.GetTypeInfo();\n                    prop = info.GetDeclaredProperty(map.PK.PropertyName);\n                    if (prop != null) \n                    {\n                        if (prop.GetValue(obj, null).Equals(Guid.Empty))\n                        {\n                            prop.SetValue(obj, Guid.NewGuid(), null);\n                        }\n                        break; \n                    }\n\n                    objType = info.BaseType;\n                }\n            }\n#else\n            if (map.PK != null && map.PK.IsAutoGuid) {\n                var prop = objType.GetProperty(map.PK.PropertyName);\n                if (prop != null) {\n                    if (prop.GetValue(obj, null).Equals(Guid.Empty)) {\n                        prop.SetValue(obj, Guid.NewGuid(), null);\n                    }\n                }\n            }\n#endif\n\n\n\t\t\tvar replacing = string.Compare (extra, \"OR REPLACE\", StringComparison.OrdinalIgnoreCase) == 0;\n\t\t\t\n\t\t\tvar cols = replacing ? map.InsertOrReplaceColumns : map.InsertColumns;\n\t\t\tvar vals = new object[cols.Length];\n\t\t\tfor (var i = 0; i < vals.Length; i++) {\n\t\t\t\tvals [i] = cols [i].GetValue (obj);\n\t\t\t}\n\t\t\t\n\t\t\tvar insertCmd = map.GetInsertCommand (this, extra);\n\t\t\tint count;\n\n\t\t\ttry {\n\t\t\t\tcount = insertCmd.ExecuteNonQuery (vals);\n\t\t\t}\n\t\t\tcatch (SQLiteException ex) {\n\n\t\t\t\tif (SQLite3.ExtendedErrCode (this.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) {\n\t\t\t\t\tthrow NotNullConstraintViolationException.New (ex.Result, ex.Message, map, obj);\n\t\t\t\t}\n\t\t\t\tthrow;\n\t\t\t}\n\n            if (map.HasAutoIncPK)\n            {\n\t\t\t\tvar id = SQLite3.LastInsertRowid (Handle);\n\t\t\t\tmap.SetAutoIncPK (obj, id);\n\t\t\t}\n\t\t\t\n\t\t\treturn count;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Updates all of the columns of a table using the specified object\n\t\t/// except for its primary key.\n\t\t/// The object is required to have a primary key.\n\t\t/// </summary>\n\t\t/// <param name=\"obj\">\n\t\t/// The object to update. It must have a primary key designated using the PrimaryKeyAttribute.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows updated.\n\t\t/// </returns>\n\t\tpublic int Update (object obj)\n\t\t{\n\t\t\tif (obj == null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\treturn Update (obj, obj.GetType ());\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Updates all of the columns of a table using the specified object\n\t\t/// except for its primary key.\n\t\t/// The object is required to have a primary key.\n\t\t/// </summary>\n\t\t/// <param name=\"obj\">\n\t\t/// The object to update. It must have a primary key designated using the PrimaryKeyAttribute.\n\t\t/// </param>\n\t\t/// <param name=\"objType\">\n\t\t/// The type of object to insert.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows updated.\n\t\t/// </returns>\n\t\tpublic int Update (object obj, Type objType)\n\t\t{\n\t\t\tint rowsAffected = 0;\n\t\t\tif (obj == null || objType == null) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\t\n\t\t\tvar map = GetMapping (objType);\n\t\t\t\n\t\t\tvar pk = map.PK;\n\t\t\t\n\t\t\tif (pk == null) {\n\t\t\t\tthrow new NotSupportedException (\"Cannot update \" + map.TableName + \": it has no PK\");\n\t\t\t}\n\t\t\t\n\t\t\tvar cols = from p in map.Columns\n\t\t\t\twhere p != pk\n\t\t\t\tselect p;\n\t\t\tvar vals = from c in cols\n\t\t\t\tselect c.GetValue (obj);\n\t\t\tvar ps = new List<object> (vals);\n\t\t\tps.Add (pk.GetValue (obj));\n\t\t\tvar q = string.Format (\"update \\\"{0}\\\" set {1} where {2} = ? \", map.TableName, string.Join (\",\", (from c in cols\n\t\t\t\tselect \"\\\"\" + c.Name + \"\\\" = ? \").ToArray ()), pk.Name);\n\n\t\t\ttry {\n\t\t\t\trowsAffected = Execute (q, ps.ToArray ());\n\t\t\t}\n\t\t\tcatch (SQLiteException ex) {\n\n\t\t\t\tif (ex.Result == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode (this.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) {\n\t\t\t\t\tthrow NotNullConstraintViolationException.New (ex, map, obj);\n\t\t\t\t}\n\n\t\t\t\tthrow ex;\n\t\t\t}\n\n\t\t\treturn rowsAffected;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Updates all specified objects.\n\t\t/// </summary>\n\t\t/// <param name=\"objects\">\n\t\t/// An <see cref=\"IEnumerable\"/> of the objects to insert.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows modified.\n\t\t/// </returns>\n\t\tpublic int UpdateAll (System.Collections.IEnumerable objects)\n\t\t{\n\t\t\tvar c = 0;\n\t\t\tRunInTransaction (() => {\n\t\t\t\tforeach (var r in objects) {\n\t\t\t\t\tc += Update (r);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn c;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Deletes the given object from the database using its primary key.\n\t\t/// </summary>\n\t\t/// <param name=\"objectToDelete\">\n\t\t/// The object to delete. It must have a primary key designated using the PrimaryKeyAttribute.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of rows deleted.\n\t\t/// </returns>\n\t\tpublic int Delete (object objectToDelete)\n\t\t{\n\t\t\tvar map = GetMapping (objectToDelete.GetType ());\n\t\t\tvar pk = map.PK;\n\t\t\tif (pk == null) {\n\t\t\t\tthrow new NotSupportedException (\"Cannot delete \" + map.TableName + \": it has no PK\");\n\t\t\t}\n\t\t\tvar q = string.Format (\"delete from \\\"{0}\\\" where \\\"{1}\\\" = ?\", map.TableName, pk.Name);\n\t\t\treturn Execute (q, pk.GetValue (objectToDelete));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Deletes the object with the specified primary key.\n\t\t/// </summary>\n\t\t/// <param name=\"primaryKey\">\n\t\t/// The primary key of the object to delete.\n\t\t/// </param>\n\t\t/// <returns>\n\t\t/// The number of objects deleted.\n\t\t/// </returns>\n\t\t/// <typeparam name='T'>\n\t\t/// The type of object.\n\t\t/// </typeparam>\n\t\tpublic int Delete<T> (object primaryKey)\n\t\t{\n\t\t\tvar map = GetMapping (typeof (T));\n\t\t\tvar pk = map.PK;\n\t\t\tif (pk == null) {\n\t\t\t\tthrow new NotSupportedException (\"Cannot delete \" + map.TableName + \": it has no PK\");\n\t\t\t}\n\t\t\tvar q = string.Format (\"delete from \\\"{0}\\\" where \\\"{1}\\\" = ?\", map.TableName, pk.Name);\n\t\t\treturn Execute (q, primaryKey);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Deletes all the objects from the specified table.\n\t\t/// WARNING WARNING: Let me repeat. It deletes ALL the objects from the\n\t\t/// specified table. Do you really want to do that?\n\t\t/// </summary>\n\t\t/// <returns>\n\t\t/// The number of objects deleted.\n\t\t/// </returns>\n\t\t/// <typeparam name='T'>\n\t\t/// The type of objects to delete.\n\t\t/// </typeparam>\n\t\tpublic int DeleteAll<T> ()\n\t\t{\n\t\t\tvar map = GetMapping (typeof (T));\n\t\t\tvar query = string.Format(\"delete from \\\"{0}\\\"\", map.TableName);\n\t\t\treturn Execute (query);\n\t\t}\n\n\t\t~SQLiteConnection ()\n\t\t{\n\t\t\tDispose (false);\n\t\t}\n\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\tDispose (true);\n\t\t\tGC.SuppressFinalize (this);\n\t\t}\n\n\t\tprotected virtual void Dispose (bool disposing)\n\t\t{\n\t\t\tClose ();\n\t\t}\n\n\t\tpublic void Close ()\n\t\t{\n\t\t\tif (_open && Handle != NullHandle) {\n\t\t\t\ttry {\n\t\t\t\t\tif (_mappings != null) {\n\t\t\t\t\t\tforeach (var sqlInsertCommand in _mappings.Values) {\n\t\t\t\t\t\t\tsqlInsertCommand.Dispose();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar r = SQLite3.Close (Handle);\n\t\t\t\t\tif (r != SQLite3.Result.OK) {\n\t\t\t\t\t\tstring msg = SQLite3.GetErrmsg (Handle);\n\t\t\t\t\t\tthrow SQLiteException.New (r, msg);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally {\n\t\t\t\t\tHandle = NullHandle;\n\t\t\t\t\t_open = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Represents a parsed connection string.\n\t/// </summary>\n\tclass SQLiteConnectionString\n\t{\n\t\tpublic string ConnectionString { get; private set; }\n\t\tpublic string DatabasePath { get; private set; }\n\t\tpublic bool StoreDateTimeAsTicks { get; private set; }\n        public bool CaseSensitive { get; private set; }\n\n#if NETFX_CORE\n\t\tstatic readonly string MetroStyleDataPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path;\n#endif\n\n\t\tpublic SQLiteConnectionString (string databasePath, bool storeDateTimeAsTicks, bool caseSensitive = true)\n\t\t{\n\t\t\tConnectionString = databasePath;\n\t\t\tStoreDateTimeAsTicks = storeDateTimeAsTicks;\n            CaseSensitive = caseSensitive;\n\n#if NETFX_CORE\n\t\t\tDatabasePath = System.IO.Path.Combine (MetroStyleDataPath, databasePath);\n#else\n\t\t\tDatabasePath = databasePath;\n#endif\n\t\t}\n\t}\n\n    [AttributeUsage (AttributeTargets.Class)]\n\tpublic class TableAttribute : Attribute\n\t{\n\t\tpublic string Name { get; set; }\n\n\t\tpublic TableAttribute (string name)\n\t\t{\n\t\t\tName = name;\n\t\t}\n\t}\n\n\t[AttributeUsage (AttributeTargets.Property)]\n\tpublic class ColumnAttribute : Attribute\n\t{\n\t\tpublic string Name { get; set; }\n\n\t\tpublic ColumnAttribute (string name)\n\t\t{\n\t\t\tName = name;\n\t\t}\n\t}\n\n\t[AttributeUsage (AttributeTargets.Property)]\n\tpublic class PrimaryKeyAttribute : Attribute\n\t{\n\t}\n\n\t[AttributeUsage (AttributeTargets.Property)]\n\tpublic class AutoIncrementAttribute : Attribute\n\t{\n\t}\n\n\t[AttributeUsage (AttributeTargets.Property)]\n\tpublic class IndexedAttribute : Attribute\n\t{\n\t\tpublic string Name { get; set; }\n\t\tpublic int Order { get; set; }\n\t\tpublic virtual bool Unique { get; set; }\n\t\t\n\t\tpublic IndexedAttribute()\n\t\t{\n\t\t}\n\t\t\n\t\tpublic IndexedAttribute(string name, int order)\n\t\t{\n\t\t\tName = name;\n\t\t\tOrder = order;\n\t\t}\n\t}\n\n\t[AttributeUsage (AttributeTargets.Property)]\n\tpublic class IgnoreAttribute : Attribute\n\t{\n\t}\n\n\t[AttributeUsage (AttributeTargets.Property)]\n\tpublic class UniqueAttribute : IndexedAttribute\n\t{\n\t\tpublic override bool Unique {\n\t\t\tget { return true; }\n\t\t\tset { /* throw?  */ }\n\t\t}\n\t}\n\n\t[AttributeUsage (AttributeTargets.Property)]\n\tpublic class MaxLengthAttribute : Attribute\n\t{\n\t\tpublic int Value { get; private set; }\n\n\t\tpublic MaxLengthAttribute (int length)\n\t\t{\n\t\t\tValue = length;\n\t\t}\n\t}\n\n\t[AttributeUsage (AttributeTargets.Property)]\n\tpublic class CollationAttribute: Attribute\n\t{\n\t\tpublic string Value { get; private set; }\n\n\t\tpublic CollationAttribute (string collation)\n\t\t{\n\t\t\tValue = collation;\n\t\t}\n\t}\n\n\t[AttributeUsage (AttributeTargets.Property)]\n\tpublic class NotNullAttribute : Attribute\n\t{\n\t}\n\n\tpublic class TableMapping\n\t{\n\t\tpublic Type MappedType { get; private set; }\n\n\t\tpublic string TableName { get; private set; }\n\n\t\tpublic Column[] Columns { get; private set; }\n\n\t\tpublic Column PK { get; private set; }\n\n\t\tpublic string GetByPrimaryKeySql { get; private set; }\n\n\t\tColumn _autoPk;\n\t\tColumn[] _insertColumns;\n\t\tColumn[] _insertOrReplaceColumns;\n\n        public TableMapping(Type type, CreateFlags createFlags = CreateFlags.None)\n\t\t{\n\t\t\tMappedType = type;\n\n#if NETFX_CORE\n\t\t\tvar tableAttr = (TableAttribute)System.Reflection.CustomAttributeExtensions\n                .GetCustomAttribute(type.GetTypeInfo(), typeof(TableAttribute), true);\n#else\n\t\t\tvar tableAttr = (TableAttribute)type.GetCustomAttributes (typeof (TableAttribute), true).FirstOrDefault ();\n#endif\n\n\t\t\tTableName = tableAttr != null ? tableAttr.Name : MappedType.Name;\n\n#if !NETFX_CORE\n\t\t\tvar props = MappedType.GetProperties (BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);\n#else\n\t\t\tvar props = from p in MappedType.GetRuntimeProperties()\n\t\t\t\t\t\twhere ((p.GetMethod != null && p.GetMethod.IsPublic) || (p.SetMethod != null && p.SetMethod.IsPublic) || (p.GetMethod != null && p.GetMethod.IsStatic) || (p.SetMethod != null && p.SetMethod.IsStatic))\n\t\t\t\t\t\tselect p;\n#endif\n\t\t\tvar cols = new List<Column> ();\n\t\t\tforeach (var p in props) {\n#if !NETFX_CORE\n\t\t\t\tvar ignore = p.GetCustomAttributes (typeof(IgnoreAttribute), true).Length > 0;\n#else\n\t\t\t\tvar ignore = p.GetCustomAttributes (typeof(IgnoreAttribute), true).Count() > 0;\n#endif\n\t\t\t\tif (p.CanWrite && !ignore) {\n\t\t\t\t\tcols.Add (new Column (p, createFlags));\n\t\t\t\t}\n\t\t\t}\n\t\t\tColumns = cols.ToArray ();\n\t\t\tforeach (var c in Columns) {\n\t\t\t\tif (c.IsAutoInc && c.IsPK) {\n\t\t\t\t\t_autoPk = c;\n\t\t\t\t}\n\t\t\t\tif (c.IsPK) {\n\t\t\t\t\tPK = c;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tHasAutoIncPK = _autoPk != null;\n\n\t\t\tif (PK != null) {\n\t\t\t\tGetByPrimaryKeySql = string.Format (\"select * from \\\"{0}\\\" where \\\"{1}\\\" = ?\", TableName, PK.Name);\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// People should not be calling Get/Find without a PK\n\t\t\t\tGetByPrimaryKeySql = string.Format (\"select * from \\\"{0}\\\" limit 1\", TableName);\n\t\t\t}\n\t\t}\n\n\t\tpublic bool HasAutoIncPK { get; private set; }\n\n\t\tpublic void SetAutoIncPK (object obj, long id)\n\t\t{\n\t\t\tif (_autoPk != null) {\n\t\t\t\t_autoPk.SetValue (obj, Convert.ChangeType (id, _autoPk.ColumnType, null));\n\t\t\t}\n\t\t}\n\n\t\tpublic Column[] InsertColumns {\n\t\t\tget {\n\t\t\t\tif (_insertColumns == null) {\n\t\t\t\t\t_insertColumns = Columns.Where (c => !c.IsAutoInc).ToArray ();\n\t\t\t\t}\n\t\t\t\treturn _insertColumns;\n\t\t\t}\n\t\t}\n\n\t\tpublic Column[] InsertOrReplaceColumns {\n\t\t\tget {\n\t\t\t\tif (_insertOrReplaceColumns == null) {\n\t\t\t\t\t_insertOrReplaceColumns = Columns.ToArray ();\n\t\t\t\t}\n\t\t\t\treturn _insertOrReplaceColumns;\n\t\t\t}\n\t\t}\n\n\t\tpublic Column FindColumnWithPropertyName (string propertyName)\n\t\t{\n\t\t\tvar exact = Columns.FirstOrDefault (c => c.PropertyName == propertyName);\n\t\t\treturn exact;\n\t\t}\n\n\t\tpublic Column FindColumn (string columnName)\n\t\t{\n\t\t\tvar exact = Columns.FirstOrDefault (c => c.Name == columnName);\n\t\t\treturn exact;\n\t\t}\n\t\t\n\t\tPreparedSqlLiteInsertCommand _insertCommand;\n\t\tstring _insertCommandExtra;\n\n\t\tpublic PreparedSqlLiteInsertCommand GetInsertCommand(SQLiteConnection conn, string extra)\n\t\t{\n\t\t\tif (_insertCommand == null) {\n\t\t\t\t_insertCommand = CreateInsertCommand(conn, extra);\n\t\t\t\t_insertCommandExtra = extra;\n\t\t\t}\n\t\t\telse if (_insertCommandExtra != extra) {\n\t\t\t\t_insertCommand.Dispose();\n\t\t\t\t_insertCommand = CreateInsertCommand(conn, extra);\n\t\t\t\t_insertCommandExtra = extra;\n\t\t\t}\n\t\t\treturn _insertCommand;\n\t\t}\n\t\t\n\t\tPreparedSqlLiteInsertCommand CreateInsertCommand(SQLiteConnection conn, string extra)\n\t\t{\n\t\t\tvar cols = InsertColumns;\n\t\t    string insertSql;\n            if (!cols.Any() && Columns.Count() == 1 && Columns[0].IsAutoInc)\n            {\n                insertSql = string.Format(\"insert {1} into \\\"{0}\\\" default values\", TableName, extra);\n            }\n            else\n            {\n\t\t\t\tvar replacing = string.Compare (extra, \"OR REPLACE\", StringComparison.OrdinalIgnoreCase) == 0;\n\n\t\t\t\tif (replacing) {\n\t\t\t\t\tcols = InsertOrReplaceColumns;\n\t\t\t\t}\n\n                insertSql = string.Format(\"insert {3} into \\\"{0}\\\"({1}) values ({2})\", TableName,\n                                   string.Join(\",\", (from c in cols\n                                                     select \"\\\"\" + c.Name + \"\\\"\").ToArray()),\n                                   string.Join(\",\", (from c in cols\n                                                     select \"?\").ToArray()), extra);\n                \n            }\n\t\t\t\n\t\t\tvar insertCommand = new PreparedSqlLiteInsertCommand(conn);\n\t\t\tinsertCommand.CommandText = insertSql;\n\t\t\treturn insertCommand;\n\t\t}\n\t\t\n\t\tprotected internal void Dispose()\n\t\t{\n\t\t\tif (_insertCommand != null) {\n\t\t\t\t_insertCommand.Dispose();\n\t\t\t\t_insertCommand = null;\n\t\t\t}\n\t\t}\n\n\t\tpublic class Column\n\t\t{\n\t\t\tPropertyInfo _prop;\n\n\t\t\tpublic string Name { get; private set; }\n\n\t\t\tpublic string PropertyName { get { return _prop.Name; } }\n\n\t\t\tpublic Type ColumnType { get; private set; }\n\n\t\t\tpublic string Collation { get; private set; }\n\n            public bool IsAutoInc { get; private set; }\n            public bool IsAutoGuid { get; private set; }\n\n\t\t\tpublic bool IsPK { get; private set; }\n\n\t\t\tpublic IEnumerable<IndexedAttribute> Indices { get; set; }\n\n\t\t\tpublic bool IsNullable { get; private set; }\n\n\t\t\tpublic int? MaxStringLength { get; private set; }\n\n            public Column(PropertyInfo prop, CreateFlags createFlags = CreateFlags.None)\n            {\n                var colAttr = (ColumnAttribute)prop.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault();\n\n                _prop = prop;\n                Name = colAttr == null ? prop.Name : colAttr.Name;\n                //If this type is Nullable<T> then Nullable.GetUnderlyingType returns the T, otherwise it returns null, so get the actual type instead\n                ColumnType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;\n                Collation = Orm.Collation(prop);\n\n                IsPK = Orm.IsPK(prop) ||\n\t\t\t\t\t(((createFlags & CreateFlags.ImplicitPK) == CreateFlags.ImplicitPK) &&\n\t\t\t\t\t \tstring.Compare (prop.Name, Orm.ImplicitPkName, StringComparison.OrdinalIgnoreCase) == 0);\n\n                var isAuto = Orm.IsAutoInc(prop) || (IsPK && ((createFlags & CreateFlags.AutoIncPK) == CreateFlags.AutoIncPK));\n                IsAutoGuid = isAuto && ColumnType == typeof(Guid);\n                IsAutoInc = isAuto && !IsAutoGuid;\n\n                Indices = Orm.GetIndices(prop);\n                if (!Indices.Any()\n                    && !IsPK\n                    && ((createFlags & CreateFlags.ImplicitIndex) == CreateFlags.ImplicitIndex)\n                    && Name.EndsWith (Orm.ImplicitIndexSuffix, StringComparison.OrdinalIgnoreCase)\n                    )\n                {\n                    Indices = new IndexedAttribute[] { new IndexedAttribute() };\n                }\n                IsNullable = !(IsPK || Orm.IsMarkedNotNull(prop));\n                MaxStringLength = Orm.MaxStringLength(prop);\n            }\n\n\t\t\tpublic void SetValue (object obj, object val)\n\t\t\t{\n\t\t\t\t_prop.SetValue (obj, val, null);\n\t\t\t}\n\n\t\t\tpublic object GetValue (object obj)\n\t\t\t{\n\t\t\t\treturn _prop.GetValue (obj, null);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static class Orm\n\t{\n        public const int DefaultMaxStringLength = 140;\n        public const string ImplicitPkName = \"Id\";\n        public const string ImplicitIndexSuffix = \"Id\";\n        private const string CaseInsensitive_Sql = \"collate nocase\";\n\n        public static string SqlDecl(TableMapping.Column p, bool storeDateTimeAsTicks, bool caseSensitive = true)\n\t\t{\n            string decl = \"\\\"\" + p.Name + \"\\\" \" + SqlType(p, storeDateTimeAsTicks, caseSensitive) + \" \";\n\t\t\t\n\t\t\tif (p.IsPK) {\n\t\t\t\tdecl += \"primary key \";\n\t\t\t}\n\t\t\tif (p.IsAutoInc) {\n\t\t\t\tdecl += \"autoincrement \";\n\t\t\t}\n\t\t\tif (!p.IsNullable) {\n\t\t\t\tdecl += \"not null \";\n\t\t\t}\n\t\t\tif (!string.IsNullOrEmpty (p.Collation)) {\n\t\t\t\tdecl += \"collate \" + p.Collation + \" \";\n\t\t\t}\n\t\t\t\n\t\t\treturn decl;\n\t\t}\n\n        public static string SqlType(TableMapping.Column p, bool storeDateTimeAsTicks, bool caseSensitive = true)\n\t\t{\n\t\t\tvar clrType = p.ColumnType;\n\t\t\tif (clrType == typeof(Boolean) || clrType == typeof(Byte) || clrType == typeof(UInt16) || clrType == typeof(SByte) || clrType == typeof(Int16) || clrType == typeof(Int32)) {\n\t\t\t\treturn \"integer\";\n\t\t\t} else if (clrType == typeof(UInt32) || clrType == typeof(Int64)) {\n\t\t\t\treturn \"bigint\";\n\t\t\t} else if (clrType == typeof(Single) || clrType == typeof(Double) || clrType == typeof(Decimal)) {\n\t\t\t\treturn \"float\";\n\t\t\t} else if (clrType == typeof(String)) {\n\t\t\t\tint? len = p.MaxStringLength;\n\n\t\t\t\tif (len.HasValue)\n                    return \"varchar(\" + len + \")\" + (caseSensitive ? \"\" : \" \" + CaseInsensitive_Sql);//return \"varchar(\" + len.Value + \")\";\n\n                return \"varchar\" + (caseSensitive ? \"\" : \" \" + CaseInsensitive_Sql);\n\t\t\t} else if (clrType == typeof(TimeSpan)) {\n                return \"bigint\";\n\t\t\t} else if (clrType == typeof(DateTime)) {\n\t\t\t\treturn storeDateTimeAsTicks ? \"bigint\" : \"datetime\";\n\t\t\t} else if (clrType == typeof(DateTimeOffset)) {\n\t\t\t\treturn \"bigint\";\n#if !NETFX_CORE\n\t\t\t} else if (clrType.IsEnum) {\n#else\n\t\t\t} else if (clrType.GetTypeInfo().IsEnum) {\n#endif\n\t\t\t\treturn \"integer\";\n\t\t\t} else if (clrType == typeof(byte[])) {\n\t\t\t\treturn \"blob\";\n            } else if (clrType == typeof(Guid)) {\n                return \"varchar(36)\";\n            } else {\n\t\t\t\tthrow new NotSupportedException (\"Don't know about \" + clrType);\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool IsPK (MemberInfo p)\n\t\t{\n\t\t\tvar attrs = p.GetCustomAttributes (typeof(PrimaryKeyAttribute), true);\n#if !NETFX_CORE\n\t\t\treturn attrs.Length > 0;\n#else\n\t\t\treturn attrs.Count() > 0;\n#endif\n\t\t}\n\n\t\tpublic static string Collation (MemberInfo p)\n\t\t{\n\t\t\tvar attrs = p.GetCustomAttributes (typeof(CollationAttribute), true);\n#if !NETFX_CORE\n\t\t\tif (attrs.Length > 0) {\n\t\t\t\treturn ((CollationAttribute)attrs [0]).Value;\n#else\n\t\t\tif (attrs.Count() > 0) {\n                return ((CollationAttribute)attrs.First()).Value;\n#endif\n\t\t\t} else {\n\t\t\t\treturn string.Empty;\n\t\t\t}\n\t\t}\n\n\t\tpublic static bool IsAutoInc (MemberInfo p)\n\t\t{\n\t\t\tvar attrs = p.GetCustomAttributes (typeof(AutoIncrementAttribute), true);\n#if !NETFX_CORE\n\t\t\treturn attrs.Length > 0;\n#else\n\t\t\treturn attrs.Count() > 0;\n#endif\n\t\t}\n\n\t\tpublic static IEnumerable<IndexedAttribute> GetIndices(MemberInfo p)\n\t\t{\n\t\t\tvar attrs = p.GetCustomAttributes(typeof(IndexedAttribute), true);\n\t\t\treturn attrs.Cast<IndexedAttribute>();\n\t\t}\n\t\t\n\t\tpublic static int? MaxStringLength(PropertyInfo p)\n\t\t{\n\t\t\tvar attrs = p.GetCustomAttributes (typeof(MaxLengthAttribute), true);\n#if !NETFX_CORE\n\t\t\tif (attrs.Length > 0)\n\t\t\t\treturn ((MaxLengthAttribute)attrs [0]).Value;\n#else\n\t\t\tif (attrs.Count() > 0)\n\t\t\t\treturn ((MaxLengthAttribute)attrs.First()).Value;\n#endif\n\n\t\t\treturn null;\n\t\t}\n\n\t\tpublic static bool IsMarkedNotNull(MemberInfo p)\n\t\t{\n\t\t\tvar attrs = p.GetCustomAttributes (typeof (NotNullAttribute), true);\n#if !NETFX_CORE\n\t\t\treturn attrs.Length > 0;\n#else\n\treturn attrs.Count() > 0;\n#endif\n\t\t}\n\t}\n\n\tpublic partial class SQLiteCommand\n\t{\n\t\tSQLiteConnection _conn;\n\t\tprivate List<Binding> _bindings;\n\n\t\tpublic string CommandText { get; set; }\n\n\t\tinternal SQLiteCommand (SQLiteConnection conn)\n\t\t{\n\t\t\t_conn = conn;\n\t\t\t_bindings = new List<Binding> ();\n\t\t\tCommandText = \"\";\n\t\t}\n\n\t\tpublic int ExecuteNonQuery ()\n\t\t{\n\t\t\tif (_conn.Trace) {\n\t\t\t\tDebug.WriteLine (\"Executing: \" + this);\n\t\t\t}\n\t\t\t\n\t\t\tvar r = SQLite3.Result.OK;\n\t\t\tvar stmt = Prepare ();\n\t\t\tr = SQLite3.Step (stmt);\n\t\t\tFinalize (stmt);\n\t\t\tif (r == SQLite3.Result.Done) {\n\t\t\t\tint rowsAffected = SQLite3.Changes (_conn.Handle);\n\t\t\t\treturn rowsAffected;\n\t\t\t} else if (r == SQLite3.Result.Error) {\n\t\t\t\tstring msg = SQLite3.GetErrmsg (_conn.Handle);\n\t\t\t\tthrow SQLiteException.New (r, msg);\n\t\t\t}\n\t\t\telse if (r == SQLite3.Result.Constraint) {\n\t\t\t\tif (SQLite3.ExtendedErrCode (_conn.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) {\n\t\t\t\t\tthrow NotNullConstraintViolationException.New (r, SQLite3.GetErrmsg (_conn.Handle));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow SQLiteException.New(r, r.ToString());\n\t\t}\n\n\t\tpublic IEnumerable<T> ExecuteDeferredQuery<T> ()\n\t\t{\n\t\t\treturn ExecuteDeferredQuery<T>(_conn.GetMapping(typeof(T)));\n\t\t}\n\n\t\tpublic List<T> ExecuteQuery<T> ()\n\t\t{\n\t\t\treturn ExecuteDeferredQuery<T>(_conn.GetMapping(typeof(T))).ToList();\n\t\t}\n\n\t\tpublic List<T> ExecuteQuery<T> (TableMapping map)\n\t\t{\n\t\t\treturn ExecuteDeferredQuery<T>(map).ToList();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Invoked every time an instance is loaded from the database.\n\t\t/// </summary>\n\t\t/// <param name='obj'>\n\t\t/// The newly created object.\n\t\t/// </param>\n\t\t/// <remarks>\n\t\t/// This can be overridden in combination with the <see cref=\"SQLiteConnection.NewCommand\"/>\n\t\t/// method to hook into the life-cycle of objects.\n\t\t///\n\t\t/// Type safety is not possible because MonoTouch does not support virtual generic methods.\n\t\t/// </remarks>\n\t\tprotected virtual void OnInstanceCreated (object obj)\n\t\t{\n\t\t\t// Can be overridden.\n\t\t}\n\n\t\tpublic IEnumerable<T> ExecuteDeferredQuery<T> (TableMapping map)\n\t\t{\n\t\t\tif (_conn.Trace) {\n\t\t\t\tDebug.WriteLine (\"Executing Query: \" + this);\n\t\t\t}\n\n\t\t\tvar stmt = Prepare ();\n\t\t\ttry\n\t\t\t{\n\t\t\t\tvar cols = new TableMapping.Column[SQLite3.ColumnCount (stmt)];\n\n\t\t\t\tfor (int i = 0; i < cols.Length; i++) {\n\t\t\t\t\tvar name = SQLite3.ColumnName16 (stmt, i);\n\t\t\t\t\tcols [i] = map.FindColumn (name);\n\t\t\t\t}\n\t\t\t\n\t\t\t\twhile (SQLite3.Step (stmt) == SQLite3.Result.Row) {\n\t\t\t\t\tvar obj = Activator.CreateInstance(map.MappedType);\n\t\t\t\t\tfor (int i = 0; i < cols.Length; i++) {\n\t\t\t\t\t\tif (cols [i] == null)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tvar colType = SQLite3.ColumnType (stmt, i);\n\t\t\t\t\t\tvar val = ReadCol (stmt, i, colType, cols [i].ColumnType);\n\t\t\t\t\t\tcols [i].SetValue (obj, val);\n \t\t\t\t\t}\n\t\t\t\t\tOnInstanceCreated (obj);\n\t\t\t\t\tyield return (T)obj;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tSQLite3.Finalize(stmt);\n\t\t\t}\n\t\t}\n\n\t\tpublic T ExecuteScalar<T> ()\n\t\t{\n\t\t\tif (_conn.Trace) {\n\t\t\t\tDebug.WriteLine (\"Executing Query: \" + this);\n\t\t\t}\n\t\t\t\n\t\t\tT val = default(T);\n\t\t\t\n\t\t\tvar stmt = Prepare ();\n\n            try\n            {\n                var r = SQLite3.Step (stmt);\n                if (r == SQLite3.Result.Row) {\n                    var colType = SQLite3.ColumnType (stmt, 0);\n                    val = (T)ReadCol (stmt, 0, colType, typeof(T));\n                }\n                else if (r == SQLite3.Result.Done) {\n                }\n                else\n                {\n                    throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle));\n                }\n            }\n            finally\n            {\n                Finalize (stmt);\n            }\n\t\t\t\n\t\t\treturn val;\n\t\t}\n\n\t\tpublic void Bind (string name, object val)\n\t\t{\n\t\t\t_bindings.Add (new Binding {\n\t\t\t\tName = name,\n\t\t\t\tValue = val\n\t\t\t});\n\t\t}\n\n\t\tpublic void Bind (object val)\n\t\t{\n\t\t\tBind (null, val);\n\t\t}\n\n\t\tpublic override string ToString ()\n\t\t{\n\t\t\tvar parts = new string[1 + _bindings.Count];\n\t\t\tparts [0] = CommandText;\n\t\t\tvar i = 1;\n\t\t\tforeach (var b in _bindings) {\n\t\t\t\tparts [i] = string.Format (\"  {0}: {1}\", i - 1, b.Value);\n\t\t\t\ti++;\n\t\t\t}\n\t\t\treturn string.Join (Environment.NewLine, parts);\n\t\t}\n\n\t\tSqlite3Statement Prepare()\n\t\t{\n\t\t\tvar stmt = SQLite3.Prepare2 (_conn.Handle, CommandText);\n\t\t\tBindAll (stmt);\n\t\t\treturn stmt;\n\t\t}\n\n\t\tvoid Finalize (Sqlite3Statement stmt)\n\t\t{\n\t\t\tSQLite3.Finalize (stmt);\n\t\t}\n\n\t\tvoid BindAll (Sqlite3Statement stmt)\n\t\t{\n\t\t\tint nextIdx = 1;\n\t\t\tforeach (var b in _bindings) {\n\t\t\t\tif (b.Name != null) {\n\t\t\t\t\tb.Index = SQLite3.BindParameterIndex (stmt, b.Name);\n\t\t\t\t} else {\n\t\t\t\t\tb.Index = nextIdx++;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tBindParameter (stmt, b.Index, b.Value, _conn.StoreDateTimeAsTicks);\n\t\t\t}\n\t\t}\n\n\t\tinternal static IntPtr NegativePointer = new IntPtr (-1);\n\n\t\tinternal static void BindParameter (Sqlite3Statement stmt, int index, object value, bool storeDateTimeAsTicks)\n\t\t{\n\t\t\tif (value == null) {\n\t\t\t\tSQLite3.BindNull (stmt, index);\n\t\t\t} else {\n\t\t\t\tif (value is Int32) {\n\t\t\t\t\tSQLite3.BindInt (stmt, index, (int)value);\n\t\t\t\t} else if (value is String) {\n\t\t\t\t\tSQLite3.BindText (stmt, index, (string)value, -1, NegativePointer);\n\t\t\t\t} else if (value is Byte || value is UInt16 || value is SByte || value is Int16) {\n\t\t\t\t\tSQLite3.BindInt (stmt, index, Convert.ToInt32 (value));\n\t\t\t\t} else if (value is Boolean) {\n\t\t\t\t\tSQLite3.BindInt (stmt, index, (bool)value ? 1 : 0);\n\t\t\t\t} else if (value is UInt32 || value is Int64) {\n\t\t\t\t\tSQLite3.BindInt64 (stmt, index, Convert.ToInt64 (value));\n\t\t\t\t} else if (value is Single || value is Double || value is Decimal) {\n\t\t\t\t\tSQLite3.BindDouble (stmt, index, Convert.ToDouble (value));\n\t\t\t\t} else if (value is TimeSpan) {\n\t\t\t\t\tSQLite3.BindInt64(stmt, index, ((TimeSpan)value).Ticks);\n\t\t\t\t} else if (value is DateTime) {\n\t\t\t\t\tif (storeDateTimeAsTicks) {\n\t\t\t\t\t\tSQLite3.BindInt64 (stmt, index, ((DateTime)value).Ticks);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tSQLite3.BindText (stmt, index, ((DateTime)value).ToString (\"yyyy-MM-dd HH:mm:ss\"), -1, NegativePointer);\n\t\t\t\t\t}\n\t\t\t\t} else if (value is DateTimeOffset) {\n\t\t\t\t\tSQLite3.BindInt64 (stmt, index, ((DateTimeOffset)value).UtcTicks);\n#if !NETFX_CORE\n\t\t\t\t} else if (value.GetType().IsEnum) {\n#else\n\t\t\t\t} else if (value.GetType().GetTypeInfo().IsEnum) {\n#endif\n\t\t\t\t\tSQLite3.BindInt (stmt, index, Convert.ToInt32 (value));\n                } else if (value is byte[]){\n                    SQLite3.BindBlob(stmt, index, (byte[]) value, ((byte[]) value).Length, NegativePointer);\n                } else if (value is Guid) {\n                    SQLite3.BindText(stmt, index, ((Guid)value).ToString(), 72, NegativePointer);\n                } else {\n                    throw new NotSupportedException(\"Cannot store type: \" + value.GetType());\n                }\n\t\t\t}\n\t\t}\n\n\t\tclass Binding\n\t\t{\n\t\t\tpublic string Name { get; set; }\n\n\t\t\tpublic object Value { get; set; }\n\n\t\t\tpublic int Index { get; set; }\n\t\t}\n\n\t\tobject ReadCol (Sqlite3Statement stmt, int index, SQLite3.ColType type, Type clrType)\n\t\t{\n\t\t\tif (type == SQLite3.ColType.Null) {\n\t\t\t\treturn null;\n\t\t\t} else {\n\t\t\t\tif (clrType == typeof(String)) {\n\t\t\t\t\treturn SQLite3.ColumnString (stmt, index);\n\t\t\t\t} else if (clrType == typeof(Int32)) {\n\t\t\t\t\treturn (int)SQLite3.ColumnInt (stmt, index);\n\t\t\t\t} else if (clrType == typeof(Boolean)) {\n\t\t\t\t\treturn SQLite3.ColumnInt (stmt, index) == 1;\n\t\t\t\t} else if (clrType == typeof(double)) {\n\t\t\t\t\treturn SQLite3.ColumnDouble (stmt, index);\n\t\t\t\t} else if (clrType == typeof(float)) {\n\t\t\t\t\treturn (float)SQLite3.ColumnDouble (stmt, index);\n\t\t\t\t} else if (clrType == typeof(TimeSpan)) {\n\t\t\t\t\treturn new TimeSpan(SQLite3.ColumnInt64(stmt, index));\n\t\t\t\t} else if (clrType == typeof(DateTime)) {\n\t\t\t\t\tif (_conn.StoreDateTimeAsTicks) {\n\t\t\t\t\t\treturn new DateTime (SQLite3.ColumnInt64 (stmt, index));\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tvar text = SQLite3.ColumnString (stmt, index);\n\t\t\t\t\t\treturn DateTime.Parse (text);\n\t\t\t\t\t}\n\t\t\t\t} else if (clrType == typeof(DateTimeOffset)) {\n\t\t\t\t\treturn new DateTimeOffset(SQLite3.ColumnInt64 (stmt, index),TimeSpan.Zero);\n#if !NETFX_CORE\n\t\t\t\t} else if (clrType.IsEnum) {\n#else\n\t\t\t\t} else if (clrType.GetTypeInfo().IsEnum) {\n#endif\n\t\t\t\t\treturn SQLite3.ColumnInt (stmt, index);\n\t\t\t\t} else if (clrType == typeof(Int64)) {\n\t\t\t\t\treturn SQLite3.ColumnInt64 (stmt, index);\n\t\t\t\t} else if (clrType == typeof(UInt32)) {\n\t\t\t\t\treturn (uint)SQLite3.ColumnInt64 (stmt, index);\n\t\t\t\t} else if (clrType == typeof(decimal)) {\n\t\t\t\t\treturn (decimal)SQLite3.ColumnDouble (stmt, index);\n\t\t\t\t} else if (clrType == typeof(Byte)) {\n\t\t\t\t\treturn (byte)SQLite3.ColumnInt (stmt, index);\n\t\t\t\t} else if (clrType == typeof(UInt16)) {\n\t\t\t\t\treturn (ushort)SQLite3.ColumnInt (stmt, index);\n\t\t\t\t} else if (clrType == typeof(Int16)) {\n\t\t\t\t\treturn (short)SQLite3.ColumnInt (stmt, index);\n\t\t\t\t} else if (clrType == typeof(sbyte)) {\n\t\t\t\t\treturn (sbyte)SQLite3.ColumnInt (stmt, index);\n\t\t\t\t} else if (clrType == typeof(byte[])) {\n\t\t\t\t\treturn SQLite3.ColumnByteArray (stmt, index);\n\t\t\t\t} else if (clrType == typeof(Guid)) {\n                  var text = SQLite3.ColumnString(stmt, index);\n                  return new Guid(text);\n                } else{\n\t\t\t\t\tthrow new NotSupportedException (\"Don't know how to read \" + clrType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/// <summary>\n\t/// Since the insert never changed, we only need to prepare once.\n\t/// </summary>\n\tpublic class PreparedSqlLiteInsertCommand : IDisposable\n\t{\n\t\tpublic bool Initialized { get; set; }\n\n\t\tprotected SQLiteConnection Connection { get; set; }\n\n\t\tpublic string CommandText { get; set; }\n\n\t\tprotected Sqlite3Statement Statement { get; set; }\n\t\tinternal static readonly Sqlite3Statement NullStatement = default(Sqlite3Statement);\n\n\t\tinternal PreparedSqlLiteInsertCommand (SQLiteConnection conn)\n\t\t{\n\t\t\tConnection = conn;\n\t\t}\n\n\t\tpublic int ExecuteNonQuery (object[] source)\n\t\t{\n\t\t\tif (Connection.Trace) {\n\t\t\t\tDebug.WriteLine (\"Executing: \" + CommandText);\n\t\t\t}\n\n\t\t\tvar r = SQLite3.Result.OK;\n\n\t\t\tif (!Initialized) {\n\t\t\t\tStatement = Prepare ();\n\t\t\t\tInitialized = true;\n\t\t\t}\n\n\t\t\t//bind the values.\n\t\t\tif (source != null) {\n\t\t\t\tfor (int i = 0; i < source.Length; i++) {\n\t\t\t\t\tSQLiteCommand.BindParameter (Statement, i + 1, source [i], Connection.StoreDateTimeAsTicks);\n\t\t\t\t}\n\t\t\t}\n\t\t\tr = SQLite3.Step (Statement);\n\n\t\t\tif (r == SQLite3.Result.Done) {\n\t\t\t\tint rowsAffected = SQLite3.Changes (Connection.Handle);\n\t\t\t\tSQLite3.Reset (Statement);\n\t\t\t\treturn rowsAffected;\n\t\t\t} else if (r == SQLite3.Result.Error) {\n\t\t\t\tstring msg = SQLite3.GetErrmsg (Connection.Handle);\n\t\t\t\tSQLite3.Reset (Statement);\n\t\t\t\tthrow SQLiteException.New (r, msg);\n\t\t\t} else if (r == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode (Connection.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) {\n\t\t\t\tSQLite3.Reset (Statement);\n\t\t\t\tthrow NotNullConstraintViolationException.New (r, SQLite3.GetErrmsg (Connection.Handle));\n\t\t\t} else {\n\t\t\t\tSQLite3.Reset (Statement);\n\t\t\t\tthrow SQLiteException.New (r, r.ToString ());\n\t\t\t}\n\t\t}\n\n\t\tprotected virtual Sqlite3Statement Prepare ()\n\t\t{\n\t\t\tvar stmt = SQLite3.Prepare2 (Connection.Handle, CommandText);\n\t\t\treturn stmt;\n\t\t}\n\n\t\tpublic void Dispose ()\n\t\t{\n\t\t\tDispose (true);\n\t\t\tGC.SuppressFinalize (this);\n\t\t}\n\n\t\tprivate void Dispose (bool disposing)\n\t\t{\n\t\t\tif (Statement != NullStatement) {\n\t\t\t\ttry {\n\t\t\t\t\tSQLite3.Finalize (Statement);\n\t\t\t\t} finally {\n\t\t\t\t\tStatement = NullStatement;\n\t\t\t\t\tConnection = null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t~PreparedSqlLiteInsertCommand ()\n\t\t{\n\t\t\tDispose (false);\n\t\t}\n\t}\n\n\tpublic abstract class BaseTableQuery\n\t{\n\t\tprotected class Ordering\n\t\t{\n\t\t\tpublic string ColumnName { get; set; }\n\t\t\tpublic bool Ascending { get; set; }\n\t\t}\n\t}\n\n\tpublic class TableQuery<T> : BaseTableQuery, IEnumerable<T>\n\t{\n\t\tpublic SQLiteConnection Connection { get; private set; }\n\n\t\tpublic TableMapping Table { get; private set; }\n\n\t\tExpression _where;\n\t\tList<Ordering> _orderBys;\n\t\tint? _limit;\n\t\tint? _offset;\n\n\t\tBaseTableQuery _joinInner;\n\t\tExpression _joinInnerKeySelector;\n\t\tBaseTableQuery _joinOuter;\n\t\tExpression _joinOuterKeySelector;\n\t\tExpression _joinSelector;\n\t\t\t\t\n\t\tExpression _selector;\n\n\t\tTableQuery (SQLiteConnection conn, TableMapping table)\n\t\t{\n\t\t\tConnection = conn;\n\t\t\tTable = table;\n\t\t}\n\n\t\tpublic TableQuery (SQLiteConnection conn)\n\t\t{\n\t\t\tConnection = conn;\n\t\t\tTable = Connection.GetMapping (typeof(T));\n\t\t}\n\n\t\tpublic TableQuery<U> Clone<U> ()\n\t\t{\n\t\t\tvar q = new TableQuery<U> (Connection, Table);\n\t\t\tq._where = _where;\n\t\t\tq._deferred = _deferred;\n\t\t\tif (_orderBys != null) {\n\t\t\t\tq._orderBys = new List<Ordering> (_orderBys);\n\t\t\t}\n\t\t\tq._limit = _limit;\n\t\t\tq._offset = _offset;\n\t\t\tq._joinInner = _joinInner;\n\t\t\tq._joinInnerKeySelector = _joinInnerKeySelector;\n\t\t\tq._joinOuter = _joinOuter;\n\t\t\tq._joinOuterKeySelector = _joinOuterKeySelector;\n\t\t\tq._joinSelector = _joinSelector;\n\t\t\tq._selector = _selector;\n\t\t\treturn q;\n\t\t}\n\n\t\tpublic TableQuery<T> Where (Expression<Func<T, bool>> predExpr)\n\t\t{\n\t\t\tif (predExpr.NodeType == ExpressionType.Lambda) {\n\t\t\t\tvar lambda = (LambdaExpression)predExpr;\n\t\t\t\tvar pred = lambda.Body;\n\t\t\t\tvar q = Clone<T> ();\n\t\t\t\tq.AddWhere (pred);\n\t\t\t\treturn q;\n\t\t\t} else {\n\t\t\t\tthrow new NotSupportedException (\"Must be a predicate\");\n\t\t\t}\n\t\t}\n\n\t\tpublic TableQuery<T> Take (int n)\n\t\t{\n\t\t\tvar q = Clone<T> ();\n\t\t\tq._limit = n;\n\t\t\treturn q;\n\t\t}\n\n\t\tpublic TableQuery<T> Skip (int n)\n\t\t{\n\t\t\tvar q = Clone<T> ();\n\t\t\tq._offset = n;\n\t\t\treturn q;\n\t\t}\n\n\t\tpublic T ElementAt (int index)\n\t\t{\n\t\t\treturn Skip (index).Take (1).First ();\n\t\t}\n\n\t\tbool _deferred;\n\t\tpublic TableQuery<T> Deferred ()\n\t\t{\n\t\t\tvar q = Clone<T> ();\n\t\t\tq._deferred = true;\n\t\t\treturn q;\n\t\t}\n\n\t\tpublic TableQuery<T> OrderBy<U> (Expression<Func<T, U>> orderExpr)\n\t\t{\n\t\t\treturn AddOrderBy<U> (orderExpr, true);\n\t\t}\n\n\t\tpublic TableQuery<T> OrderByDescending<U> (Expression<Func<T, U>> orderExpr)\n\t\t{\n\t\t\treturn AddOrderBy<U> (orderExpr, false);\n\t\t}\n\n\t\tpublic TableQuery<T> ThenBy<U>(Expression<Func<T, U>> orderExpr)\n\t\t{\n\t\t\treturn AddOrderBy<U>(orderExpr, true);\n\t\t}\n\n\t\tpublic TableQuery<T> ThenByDescending<U>(Expression<Func<T, U>> orderExpr)\n\t\t{\n\t\t\treturn AddOrderBy<U>(orderExpr, false);\n\t\t}\n\n\t\tprivate TableQuery<T> AddOrderBy<U> (Expression<Func<T, U>> orderExpr, bool asc)\n\t\t{\n\t\t\tif (orderExpr.NodeType == ExpressionType.Lambda) {\n\t\t\t\tvar lambda = (LambdaExpression)orderExpr;\n\t\t\t\t\n\t\t\t\tMemberExpression mem = null;\n\t\t\t\t\n\t\t\t\tvar unary = lambda.Body as UnaryExpression;\n\t\t\t\tif (unary != null && unary.NodeType == ExpressionType.Convert) {\n\t\t\t\t\tmem = unary.Operand as MemberExpression;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tmem = lambda.Body as MemberExpression;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (mem != null && (mem.Expression.NodeType == ExpressionType.Parameter)) {\n\t\t\t\t\tvar q = Clone<T> ();\n\t\t\t\t\tif (q._orderBys == null) {\n\t\t\t\t\t\tq._orderBys = new List<Ordering> ();\n\t\t\t\t\t}\n\t\t\t\t\tq._orderBys.Add (new Ordering {\n\t\t\t\t\t\tColumnName = Table.FindColumnWithPropertyName(mem.Member.Name).Name,\n\t\t\t\t\t\tAscending = asc\n\t\t\t\t\t});\n\t\t\t\t\treturn q;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new NotSupportedException (\"Order By does not support: \" + orderExpr);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new NotSupportedException (\"Must be a predicate\");\n\t\t\t}\n\t\t}\n\n\t\tprivate void AddWhere (Expression pred)\n\t\t{\n\t\t\tif (_where == null) {\n\t\t\t\t_where = pred;\n\t\t\t} else {\n\t\t\t\t_where = Expression.AndAlso (_where, pred);\n\t\t\t}\n\t\t}\n\t\t\t\t\n\t\tpublic TableQuery<TResult> Join<TInner, TKey, TResult> (\n\t\t\tTableQuery<TInner> inner,\n\t\t\tExpression<Func<T, TKey>> outerKeySelector,\n\t\t\tExpression<Func<TInner, TKey>> innerKeySelector,\n\t\t\tExpression<Func<T, TInner, TResult>> resultSelector)\n\t\t{\n\t\t\tvar q = new TableQuery<TResult> (Connection, Connection.GetMapping (typeof (TResult))) {\n\t\t\t\t_joinOuter = this,\n\t\t\t\t_joinOuterKeySelector = outerKeySelector,\n\t\t\t\t_joinInner = inner,\n\t\t\t\t_joinInnerKeySelector = innerKeySelector,\n\t\t\t\t_joinSelector = resultSelector,\n\t\t\t};\n\t\t\treturn q;\n\t\t}\n\t\t\t\t\n\t\tpublic TableQuery<TResult> Select<TResult> (Expression<Func<T, TResult>> selector)\n\t\t{\n\t\t\tvar q = Clone<TResult> ();\n\t\t\tq._selector = selector;\n\t\t\treturn q;\n\t\t}\n\n\t\tprivate SQLiteCommand GenerateCommand (string selectionList)\n\t\t{\n\t\t\tif (_joinInner != null && _joinOuter != null) {\n\t\t\t\tthrow new NotSupportedException (\"Joins are not supported.\");\n\t\t\t}\n\t\t\telse {\n\t\t\t\tvar cmdText = \"select \" + selectionList + \" from \\\"\" + Table.TableName + \"\\\"\";\n\t\t\t\tvar args = new List<object> ();\n\t\t\t\tif (_where != null) {\n\t\t\t\t\tvar w = CompileExpr (_where, args);\n\t\t\t\t\tcmdText += \" where \" + w.CommandText + \" collate nocase \";\n\t\t\t\t}\n\t\t\t\tif ((_orderBys != null) && (_orderBys.Count > 0)) {\n\t\t\t\t\tvar t = string.Join (\", \", _orderBys.Select (o => \"\\\"\" + o.ColumnName + \"\\\"\" + (o.Ascending ? \"\" : \" desc\")).ToArray ());\n\t\t\t\t\tcmdText += \" order by \" + t;\n\t\t\t\t}\n\t\t\t\tif (_limit.HasValue) {\n\t\t\t\t\tcmdText += \" limit \" + _limit.Value;\n\t\t\t\t}\n\t\t\t\tif (_offset.HasValue) {\n\t\t\t\t\tif (!_limit.HasValue) {\n\t\t\t\t\t\tcmdText += \" limit -1 \";\n\t\t\t\t\t}\n\t\t\t\t\tcmdText += \" offset \" + _offset.Value;\n\t\t\t\t}\n\t\t\t\treturn Connection.CreateCommand (cmdText, args.ToArray ());\n\t\t\t}\n\t\t}\n\n\t\tclass CompileResult\n\t\t{\n\t\t\tpublic string CommandText { get; set; }\n\n\t\t\tpublic object Value { get; set; }\n\t\t}\n\n\t\tprivate CompileResult CompileExpr (Expression expr, List<object> queryArgs)\n\t\t{\n\t\t\tif (expr == null) {\n\t\t\t\tthrow new NotSupportedException (\"Expression is NULL\");\n\t\t\t} else if (expr is BinaryExpression) {\n\t\t\t\tvar bin = (BinaryExpression)expr;\n\t\t\t\t\n\t\t\t\tvar leftr = CompileExpr (bin.Left, queryArgs);\n\t\t\t\tvar rightr = CompileExpr (bin.Right, queryArgs);\n\n\t\t\t\t//If either side is a parameter and is null, then handle the other side specially (for \"is null\"/\"is not null\")\n\t\t\t\tstring text;\n\t\t\t\tif (leftr.CommandText == \"?\" && leftr.Value == null)\n\t\t\t\t\ttext = CompileNullBinaryExpression(bin, rightr);\n\t\t\t\telse if (rightr.CommandText == \"?\" && rightr.Value == null)\n\t\t\t\t\ttext = CompileNullBinaryExpression(bin, leftr);\n\t\t\t\telse\n\t\t\t\t\ttext = \"(\" + leftr.CommandText + \" \" + GetSqlName(bin) + \" \" + rightr.CommandText + \")\";\n\t\t\t\treturn new CompileResult { CommandText = text };\n\t\t\t} else if (expr.NodeType == ExpressionType.Call) {\n\t\t\t\t\n\t\t\t\tvar call = (MethodCallExpression)expr;\n\t\t\t\tvar args = new CompileResult[call.Arguments.Count];\n\t\t\t\tvar obj = call.Object != null ? CompileExpr (call.Object, queryArgs) : null;\n\t\t\t\t\n\t\t\t\tfor (var i = 0; i < args.Length; i++) {\n\t\t\t\t\targs [i] = CompileExpr (call.Arguments [i], queryArgs);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar sqlCall = \"\";\n\t\t\t\t\n\t\t\t\tif (call.Method.Name == \"Like\" && args.Length == 2) {\n\t\t\t\t\tsqlCall = \"(\" + args [0].CommandText + \" like \" + args [1].CommandText + \")\";\n\t\t\t\t}\n\t\t\t\telse if (call.Method.Name == \"Contains\" && args.Length == 2) {\n\t\t\t\t\tsqlCall = \"(\" + args [1].CommandText + \" in \" + args [0].CommandText + \")\";\n\t\t\t\t}\n\t\t\t\telse if (call.Method.Name == \"Contains\" && args.Length == 1) {\n\t\t\t\t\tif (call.Object != null && call.Object.Type == typeof(string)) {\n\t\t\t\t\t\tsqlCall = \"(\" + obj.CommandText + \" like ('%' || \" + args [0].CommandText + \" || '%'))\";\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tsqlCall = \"(\" + args [0].CommandText + \" in \" + obj.CommandText + \")\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (call.Method.Name == \"StartsWith\" && args.Length == 1) {\n\t\t\t\t\tsqlCall = \"(\" + obj.CommandText + \" like (\" + args [0].CommandText + \" || '%'))\";\n\t\t\t\t}\n\t\t\t\telse if (call.Method.Name == \"EndsWith\" && args.Length == 1) {\n\t\t\t\t\tsqlCall = \"(\" + obj.CommandText + \" like ('%' || \" + args [0].CommandText + \"))\";\n\t\t\t\t}\n\t\t\t\telse if (call.Method.Name == \"Equals\" && args.Length == 1) {\n\t\t\t\t\tsqlCall = \"(\" + obj.CommandText + \" = (\" + args[0].CommandText + \"))\";\n\t\t\t\t} else if (call.Method.Name == \"ToLower\") {\n\t\t\t\t\tsqlCall = \"(lower(\" + obj.CommandText + \"))\"; \n\t\t\t\t} else if (call.Method.Name == \"ToUpper\") {\n\t\t\t\t\tsqlCall = \"(upper(\" + obj.CommandText + \"))\"; \n\t\t\t\t} else {\n\t\t\t\t\tsqlCall = call.Method.Name.ToLower () + \"(\" + string.Join (\",\", args.Select (a => a.CommandText).ToArray ()) + \")\";\n\t\t\t\t}\n\t\t\t\treturn new CompileResult { CommandText = sqlCall };\n\t\t\t\t\n\t\t\t} else if (expr.NodeType == ExpressionType.Constant) {\n\t\t\t\tvar c = (ConstantExpression)expr;\n\t\t\t\tqueryArgs.Add (c.Value);\n\t\t\t\treturn new CompileResult {\n\t\t\t\t\tCommandText = \"?\",\n\t\t\t\t\tValue = c.Value\n\t\t\t\t};\n\t\t\t} else if (expr.NodeType == ExpressionType.Convert) {\n\t\t\t\tvar u = (UnaryExpression)expr;\n\t\t\t\tvar ty = u.Type;\n\t\t\t\tvar valr = CompileExpr (u.Operand, queryArgs);\n\t\t\t\treturn new CompileResult {\n\t\t\t\t\tCommandText = valr.CommandText,\n\t\t\t\t\tValue = valr.Value != null ? ConvertTo (valr.Value, ty) : null\n\t\t\t\t};\n\t\t\t} else if (expr.NodeType == ExpressionType.MemberAccess) {\n\t\t\t\tvar mem = (MemberExpression)expr;\n\t\t\t\t\n\t\t\t\tif (mem.Expression!=null && mem.Expression.NodeType == ExpressionType.Parameter) {\n\t\t\t\t\t//\n\t\t\t\t\t// This is a column of our table, output just the column name\n\t\t\t\t\t// Need to translate it if that column name is mapped\n\t\t\t\t\t//\n\t\t\t\t\tvar columnName = Table.FindColumnWithPropertyName (mem.Member.Name).Name;\n\t\t\t\t\treturn new CompileResult { CommandText = \"\\\"\" + columnName + \"\\\"\" };\n\t\t\t\t} else {\n\t\t\t\t\tobject obj = null;\n\t\t\t\t\tif (mem.Expression != null) {\n\t\t\t\t\t\tvar r = CompileExpr (mem.Expression, queryArgs);\n\t\t\t\t\t\tif (r.Value == null) {\n\t\t\t\t\t\t\tthrow new NotSupportedException (\"Member access failed to compile expression\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (r.CommandText == \"?\") {\n\t\t\t\t\t\t\tqueryArgs.RemoveAt (queryArgs.Count - 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tobj = r.Value;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t//\n\t\t\t\t\t// Get the member value\n\t\t\t\t\t//\n\t\t\t\t\tobject val = null;\n\t\t\t\t\t\n#if !NETFX_CORE\n\t\t\t\t\tif (mem.Member.MemberType == MemberTypes.Property) {\n#else\n\t\t\t\t\tif (mem.Member is PropertyInfo) {\n#endif\n\t\t\t\t\t\tvar m = (PropertyInfo)mem.Member;\n\t\t\t\t\t\tval = m.GetValue (obj, null);\n#if !NETFX_CORE\n\t\t\t\t\t} else if (mem.Member.MemberType == MemberTypes.Field) {\n#else\n\t\t\t\t\t} else if (mem.Member is FieldInfo) {\n#endif\n#if SILVERLIGHT\n\t\t\t\t\t\tval = Expression.Lambda (expr).Compile ().DynamicInvoke ();\n#else\n\t\t\t\t\t\tvar m = (FieldInfo)mem.Member;\n\t\t\t\t\t\tval = m.GetValue (obj);\n#endif\n\t\t\t\t\t} else {\n#if !NETFX_CORE\n\t\t\t\t\t\tthrow new NotSupportedException (\"MemberExpr: \" + mem.Member.MemberType);\n#else\n\t\t\t\t\t\tthrow new NotSupportedException (\"MemberExpr: \" + mem.Member.DeclaringType);\n#endif\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t//\n\t\t\t\t\t// Work special magic for enumerables\n\t\t\t\t\t//\n\t\t\t\t\tif (val != null && val is System.Collections.IEnumerable && !(val is string) && !(val is System.Collections.Generic.IEnumerable<byte>)) {\n\t\t\t\t\t\tvar sb = new System.Text.StringBuilder();\n\t\t\t\t\t\tsb.Append(\"(\");\n\t\t\t\t\t\tvar head = \"\";\n\t\t\t\t\t\tforeach (var a in (System.Collections.IEnumerable)val) {\n\t\t\t\t\t\t\tqueryArgs.Add(a);\n\t\t\t\t\t\t\tsb.Append(head);\n\t\t\t\t\t\t\tsb.Append(\"?\");\n\t\t\t\t\t\t\thead = \",\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsb.Append(\")\");\n\t\t\t\t\t\treturn new CompileResult {\n\t\t\t\t\t\t\tCommandText = sb.ToString(),\n\t\t\t\t\t\t\tValue = val\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tqueryArgs.Add (val);\n\t\t\t\t\t\treturn new CompileResult {\n\t\t\t\t\t\t\tCommandText = \"?\",\n\t\t\t\t\t\t\tValue = val\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new NotSupportedException (\"Cannot compile: \" + expr.NodeType.ToString ());\n\t\t}\n\n\t\tstatic object ConvertTo (object obj, Type t)\n\t\t{\n\t\t\tType nut = Nullable.GetUnderlyingType(t);\n\t\t\t\n\t\t\tif (nut != null) {\n\t\t\t\tif (obj == null) return null;\t\t\t\t\n\t\t\t\treturn Convert.ChangeType (obj, nut);\n\t\t\t} else {\n\t\t\t\treturn Convert.ChangeType (obj, t);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Compiles a BinaryExpression where one of the parameters is null.\n\t\t/// </summary>\n\t\t/// <param name=\"parameter\">The non-null parameter</param>\n\t\tprivate string CompileNullBinaryExpression(BinaryExpression expression, CompileResult parameter)\n\t\t{\n\t\t\tif (expression.NodeType == ExpressionType.Equal)\n\t\t\t\treturn \"(\" + parameter.CommandText + \" is ?)\";\n\t\t\telse if (expression.NodeType == ExpressionType.NotEqual)\n\t\t\t\treturn \"(\" + parameter.CommandText + \" is not ?)\";\n\t\t\telse\n\t\t\t\tthrow new NotSupportedException(\"Cannot compile Null-BinaryExpression with type \" + expression.NodeType.ToString());\n\t\t}\n\n\t\tstring GetSqlName (Expression expr)\n\t\t{\n\t\t\tvar n = expr.NodeType;\n\t\t\tif (n == ExpressionType.GreaterThan)\n\t\t\t\treturn \">\"; else if (n == ExpressionType.GreaterThanOrEqual) {\n\t\t\t\treturn \">=\";\n\t\t\t} else if (n == ExpressionType.LessThan) {\n\t\t\t\treturn \"<\";\n\t\t\t} else if (n == ExpressionType.LessThanOrEqual) {\n\t\t\t\treturn \"<=\";\n\t\t\t} else if (n == ExpressionType.And) {\n\t\t\t\treturn \"&\";\n\t\t\t} else if (n == ExpressionType.AndAlso) {\n\t\t\t\treturn \"and\";\n\t\t\t} else if (n == ExpressionType.Or) {\n\t\t\t\treturn \"|\";\n\t\t\t} else if (n == ExpressionType.OrElse) {\n\t\t\t\treturn \"or\";\n\t\t\t} else if (n == ExpressionType.Equal) {\n\t\t\t\treturn \"=\";\n\t\t\t} else if (n == ExpressionType.NotEqual) {\n\t\t\t\treturn \"!=\";\n\t\t\t} else {\n\t\t\t\tthrow new NotSupportedException (\"Cannot get SQL for: \" + n);\n\t\t\t}\n\t\t}\n\t\t\n\t\tpublic int Count ()\n\t\t{\n\t\t\treturn GenerateCommand(\"count(*)\").ExecuteScalar<int> ();\t\t\t\n\t\t}\n\n\t\tpublic int Count (Expression<Func<T, bool>> predExpr)\n\t\t{\n\t\t\treturn Where (predExpr).Count ();\n\t\t}\n\n\t\tpublic IEnumerator<T> GetEnumerator ()\n\t\t{\n\t\t\tif (!_deferred)\n\t\t\t\treturn GenerateCommand(\"*\").ExecuteQuery<T>().GetEnumerator();\n\n\t\t\treturn GenerateCommand(\"*\").ExecuteDeferredQuery<T>().GetEnumerator();\n\t\t}\n\n\t\tSystem.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()\n\t\t{\n\t\t\treturn GetEnumerator ();\n\t\t}\n\n\t\tpublic T First ()\n\t\t{\n\t\t\tvar query = Take (1);\n\t\t\treturn query.ToList<T>().First ();\n\t\t}\n\n\t\tpublic T FirstOrDefault ()\n\t\t{\n\t\t\tvar query = Take (1);\n\t\t\treturn query.ToList<T>().FirstOrDefault ();\n\t\t}\n    }\n\n\tpublic static class SQLite3\n\t{\n\t\tpublic enum Result : int\n\t\t{\n\t\t\tOK = 0,\n\t\t\tError = 1,\n\t\t\tInternal = 2,\n\t\t\tPerm = 3,\n\t\t\tAbort = 4,\n\t\t\tBusy = 5,\n\t\t\tLocked = 6,\n\t\t\tNoMem = 7,\n\t\t\tReadOnly = 8,\n\t\t\tInterrupt = 9,\n\t\t\tIOError = 10,\n\t\t\tCorrupt = 11,\n\t\t\tNotFound = 12,\n\t\t\tFull = 13,\n\t\t\tCannotOpen = 14,\n\t\t\tLockErr = 15,\n\t\t\tEmpty = 16,\n\t\t\tSchemaChngd = 17,\n\t\t\tTooBig = 18,\n\t\t\tConstraint = 19,\n\t\t\tMismatch = 20,\n\t\t\tMisuse = 21,\n\t\t\tNotImplementedLFS = 22,\n\t\t\tAccessDenied = 23,\n\t\t\tFormat = 24,\n\t\t\tRange = 25,\n\t\t\tNonDBFile = 26,\n\t\t\tNotice = 27,\n\t\t\tWarning = 28,\n\t\t\tRow = 100,\n\t\t\tDone = 101\n\t\t}\n\n\t\tpublic enum ExtendedResult : int\n\t\t{\n\t\t\tIOErrorRead = (Result.IOError | (1 << 8)),\n\t\t\tIOErrorShortRead = (Result.IOError | (2 << 8)),\n\t\t\tIOErrorWrite = (Result.IOError | (3 << 8)),\n\t\t\tIOErrorFsync = (Result.IOError | (4 << 8)),\n\t\t\tIOErrorDirFSync = (Result.IOError | (5 << 8)),\n\t\t\tIOErrorTruncate = (Result.IOError | (6 << 8)),\n\t\t\tIOErrorFStat = (Result.IOError | (7 << 8)),\n\t\t\tIOErrorUnlock = (Result.IOError | (8 << 8)),\n\t\t\tIOErrorRdlock = (Result.IOError | (9 << 8)),\n\t\t\tIOErrorDelete = (Result.IOError | (10 << 8)),\n\t\t\tIOErrorBlocked = (Result.IOError | (11 << 8)),\n\t\t\tIOErrorNoMem = (Result.IOError | (12 << 8)),\n\t\t\tIOErrorAccess = (Result.IOError | (13 << 8)),\n\t\t\tIOErrorCheckReservedLock = (Result.IOError | (14 << 8)),\n\t\t\tIOErrorLock = (Result.IOError | (15 << 8)),\n\t\t\tIOErrorClose = (Result.IOError | (16 << 8)),\n\t\t\tIOErrorDirClose = (Result.IOError | (17 << 8)),\n\t\t\tIOErrorSHMOpen = (Result.IOError | (18 << 8)),\n\t\t\tIOErrorSHMSize = (Result.IOError | (19 << 8)),\n\t\t\tIOErrorSHMLock = (Result.IOError | (20 << 8)),\n\t\t\tIOErrorSHMMap = (Result.IOError | (21 << 8)),\n\t\t\tIOErrorSeek = (Result.IOError | (22 << 8)),\n\t\t\tIOErrorDeleteNoEnt = (Result.IOError | (23 << 8)),\n\t\t\tIOErrorMMap = (Result.IOError | (24 << 8)),\n\t\t\tLockedSharedcache = (Result.Locked | (1 << 8)),\n\t\t\tBusyRecovery = (Result.Busy | (1 << 8)),\n\t\t\tCannottOpenNoTempDir = (Result.CannotOpen | (1 << 8)),\n\t\t\tCannotOpenIsDir = (Result.CannotOpen | (2 << 8)),\n\t\t\tCannotOpenFullPath = (Result.CannotOpen | (3 << 8)),\n\t\t\tCorruptVTab = (Result.Corrupt | (1 << 8)),\n\t\t\tReadonlyRecovery = (Result.ReadOnly | (1 << 8)),\n\t\t\tReadonlyCannotLock = (Result.ReadOnly | (2 << 8)),\n\t\t\tReadonlyRollback = (Result.ReadOnly | (3 << 8)),\n\t\t\tAbortRollback = (Result.Abort | (2 << 8)),\n\t\t\tConstraintCheck = (Result.Constraint | (1 << 8)),\n\t\t\tConstraintCommitHook = (Result.Constraint | (2 << 8)),\n\t\t\tConstraintForeignKey = (Result.Constraint | (3 << 8)),\n\t\t\tConstraintFunction = (Result.Constraint | (4 << 8)),\n\t\t\tConstraintNotNull = (Result.Constraint | (5 << 8)),\n\t\t\tConstraintPrimaryKey = (Result.Constraint | (6 << 8)),\n\t\t\tConstraintTrigger = (Result.Constraint | (7 << 8)),\n\t\t\tConstraintUnique = (Result.Constraint | (8 << 8)),\n\t\t\tConstraintVTab = (Result.Constraint | (9 << 8)),\n\t\t\tNoticeRecoverWAL = (Result.Notice | (1 << 8)),\n\t\t\tNoticeRecoverRollback = (Result.Notice | (2 << 8))\n\t\t}\n        \n\n\t\tpublic enum ConfigOption : int\n\t\t{\n\t\t\tSingleThread = 1,\n\t\t\tMultiThread = 2,\n\t\t\tSerialized = 3\n\t\t}\n\n#if !USE_CSHARP_SQLITE && !USE_WP8_NATIVE_SQLITE\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_open\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Open ([MarshalAs(UnmanagedType.LPStr)] string filename, out IntPtr db);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_open_v2\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Open ([MarshalAs(UnmanagedType.LPStr)] string filename, out IntPtr db, int flags, IntPtr zvfs);\n\t\t\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_open_v2\", CallingConvention = CallingConvention.Cdecl)]\n\t\tpublic static extern Result Open(byte[] filename, out IntPtr db, int flags, IntPtr zvfs);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_open16\", CallingConvention = CallingConvention.Cdecl)]\n\t\tpublic static extern Result Open16([MarshalAs(UnmanagedType.LPWStr)] string filename, out IntPtr db);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_enable_load_extension\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result EnableLoadExtension (IntPtr db, int onoff);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_close\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Close (IntPtr db);\n\t\t\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_initialize\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Initialize();\n\t\t\t\t\t\t\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_shutdown\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Shutdown();\n\t\t\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_config\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Config (ConfigOption option);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_win32_set_directory\", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Unicode)]\n\t\tpublic static extern int SetDirectory (uint directoryType, string directoryPath);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_busy_timeout\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result BusyTimeout (IntPtr db, int milliseconds);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_changes\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int Changes (IntPtr db);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_prepare_v2\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Prepare2 (IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string sql, int numBytes, out IntPtr stmt, IntPtr pzTail);\n\n#if NETFX_CORE\n\t\t[DllImport (\"sqlite3\", EntryPoint = \"sqlite3_prepare_v2\", CallingConvention = CallingConvention.Cdecl)]\n\t\tpublic static extern Result Prepare2 (IntPtr db, byte[] queryBytes, int numBytes, out IntPtr stmt, IntPtr pzTail);\n#endif\n\n\t\tpublic static IntPtr Prepare2 (IntPtr db, string query)\n\t\t{\n\t\t\tIntPtr stmt;\n#if NETFX_CORE\n            byte[] queryBytes = System.Text.UTF8Encoding.UTF8.GetBytes (query);\n            var r = Prepare2 (db, queryBytes, queryBytes.Length, out stmt, IntPtr.Zero);\n#else\n            var r = Prepare2 (db, query, System.Text.UTF8Encoding.UTF8.GetByteCount (query), out stmt, IntPtr.Zero);\n#endif\n\t\t\tif (r != Result.OK) {\n\t\t\t\tthrow SQLiteException.New (r, GetErrmsg (db));\n\t\t\t}\n\t\t\treturn stmt;\n\t\t}\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_step\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Step (IntPtr stmt);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_reset\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Reset (IntPtr stmt);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_finalize\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern Result Finalize (IntPtr stmt);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_last_insert_rowid\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern long LastInsertRowid (IntPtr db);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_errmsg16\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern IntPtr Errmsg (IntPtr db);\n\n\t\tpublic static string GetErrmsg (IntPtr db)\n\t\t{\n\t\t\treturn Marshal.PtrToStringUni (Errmsg (db));\n\t\t}\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_bind_parameter_index\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int BindParameterIndex (IntPtr stmt, [MarshalAs(UnmanagedType.LPStr)] string name);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_bind_null\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int BindNull (IntPtr stmt, int index);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_bind_int\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int BindInt (IntPtr stmt, int index, int val);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_bind_int64\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int BindInt64 (IntPtr stmt, int index, long val);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_bind_double\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int BindDouble (IntPtr stmt, int index, double val);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_bind_text16\", CallingConvention=CallingConvention.Cdecl, CharSet = CharSet.Unicode)]\n\t\tpublic static extern int BindText (IntPtr stmt, int index, [MarshalAs(UnmanagedType.LPWStr)] string val, int n, IntPtr free);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_bind_blob\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int BindBlob (IntPtr stmt, int index, byte[] val, int n, IntPtr free);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_count\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int ColumnCount (IntPtr stmt);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_name\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern IntPtr ColumnName (IntPtr stmt, int index);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_name16\", CallingConvention=CallingConvention.Cdecl)]\n\t\tstatic extern IntPtr ColumnName16Internal (IntPtr stmt, int index);\n\t\tpublic static string ColumnName16(IntPtr stmt, int index)\n\t\t{\n\t\t\treturn Marshal.PtrToStringUni(ColumnName16Internal(stmt, index));\n\t\t}\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_type\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern ColType ColumnType (IntPtr stmt, int index);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_int\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int ColumnInt (IntPtr stmt, int index);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_int64\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern long ColumnInt64 (IntPtr stmt, int index);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_double\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern double ColumnDouble (IntPtr stmt, int index);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_text\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern IntPtr ColumnText (IntPtr stmt, int index);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_text16\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern IntPtr ColumnText16 (IntPtr stmt, int index);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_blob\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern IntPtr ColumnBlob (IntPtr stmt, int index);\n\n\t\t[DllImport(\"sqlite3\", EntryPoint = \"sqlite3_column_bytes\", CallingConvention=CallingConvention.Cdecl)]\n\t\tpublic static extern int ColumnBytes (IntPtr stmt, int index);\n\n\t\tpublic static string ColumnString (IntPtr stmt, int index)\n\t\t{\n\t\t\treturn Marshal.PtrToStringUni (SQLite3.ColumnText16 (stmt, index));\n\t\t}\n\n\t\tpublic static byte[] ColumnByteArray (IntPtr stmt, int index)\n\t\t{\n\t\t\tint length = ColumnBytes (stmt, index);\n\t\t\tvar result = new byte[length];\n\t\t\tif (length > 0)\n\t\t\t\tMarshal.Copy (ColumnBlob (stmt, index), result, 0, length);\n\t\t\treturn result;\n\t\t}\n\n\t\t[DllImport (\"sqlite3\", EntryPoint = \"sqlite3_extended_errcode\", CallingConvention = CallingConvention.Cdecl)]\n\t\tpublic static extern ExtendedResult ExtendedErrCode (IntPtr db);\n\n\t\t[DllImport (\"sqlite3\", EntryPoint = \"sqlite3_libversion_number\", CallingConvention = CallingConvention.Cdecl)]\n\t\tpublic static extern int LibVersionNumber ();\n#else\n\t\tpublic static Result Open(string filename, out Sqlite3DatabaseHandle db)\n\t\t{\n\t\t\treturn (Result) Sqlite3.sqlite3_open(filename, out db);\n\t\t}\n\n\t\tpublic static Result Open(string filename, out Sqlite3DatabaseHandle db, int flags, IntPtr zVfs)\n\t\t{\n#if USE_WP8_NATIVE_SQLITE\n\t\t\treturn (Result)Sqlite3.sqlite3_open_v2(filename, out db, flags, \"\");\n#else\n\t\t\treturn (Result)Sqlite3.sqlite3_open_v2(filename, out db, flags, null);\n#endif\n\t\t}\n\n\t\tpublic static Result Close(Sqlite3DatabaseHandle db)\n\t\t{\n\t\t\treturn (Result)Sqlite3.sqlite3_close(db);\n\t\t}\n\n\t\tpublic static Result BusyTimeout(Sqlite3DatabaseHandle db, int milliseconds)\n\t\t{\n\t\t\treturn (Result)Sqlite3.sqlite3_busy_timeout(db, milliseconds);\n\t\t}\n\n\t\tpublic static int Changes(Sqlite3DatabaseHandle db)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_changes(db);\n\t\t}\n\n\t\tpublic static Sqlite3Statement Prepare2(Sqlite3DatabaseHandle db, string query)\n\t\t{\n\t\t\tSqlite3Statement stmt = default(Sqlite3Statement);\n#if USE_WP8_NATIVE_SQLITE\n\t\t\tvar r = Sqlite3.sqlite3_prepare_v2(db, query, out stmt);\n#else\n\t\t\tstmt = new Sqlite3Statement();\n\t\t\tvar r = Sqlite3.sqlite3_prepare_v2(db, query, -1, ref stmt, 0);\n#endif\n\t\t\tif (r != 0)\n\t\t\t{\n\t\t\t\tthrow SQLiteException.New((Result)r, GetErrmsg(db));\n\t\t\t}\n\t\t\treturn stmt;\n\t\t}\n\n\t\tpublic static Result Step(Sqlite3Statement stmt)\n\t\t{\n\t\t\treturn (Result)Sqlite3.sqlite3_step(stmt);\n\t\t}\n\n\t\tpublic static Result Reset(Sqlite3Statement stmt)\n\t\t{\n\t\t\treturn (Result)Sqlite3.sqlite3_reset(stmt);\n\t\t}\n\n\t\tpublic static Result Finalize(Sqlite3Statement stmt)\n\t\t{\n\t\t\treturn (Result)Sqlite3.sqlite3_finalize(stmt);\n\t\t}\n\n\t\tpublic static long LastInsertRowid(Sqlite3DatabaseHandle db)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_last_insert_rowid(db);\n\t\t}\n\n\t\tpublic static string GetErrmsg(Sqlite3DatabaseHandle db)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_errmsg(db);\n\t\t}\n\n\t\tpublic static int BindParameterIndex(Sqlite3Statement stmt, string name)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_bind_parameter_index(stmt, name);\n\t\t}\n\n\t\tpublic static int BindNull(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_bind_null(stmt, index);\n\t\t}\n\n\t\tpublic static int BindInt(Sqlite3Statement stmt, int index, int val)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_bind_int(stmt, index, val);\n\t\t}\n\n\t\tpublic static int BindInt64(Sqlite3Statement stmt, int index, long val)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_bind_int64(stmt, index, val);\n\t\t}\n\n\t\tpublic static int BindDouble(Sqlite3Statement stmt, int index, double val)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_bind_double(stmt, index, val);\n\t\t}\n\n\t\tpublic static int BindText(Sqlite3Statement stmt, int index, string val, int n, IntPtr free)\n\t\t{\n#if USE_WP8_NATIVE_SQLITE\n\t\t\treturn Sqlite3.sqlite3_bind_text(stmt, index, val, n);\n#else\n\t\t\treturn Sqlite3.sqlite3_bind_text(stmt, index, val, n, null);\n#endif\n\t\t}\n\n\t\tpublic static int BindBlob(Sqlite3Statement stmt, int index, byte[] val, int n, IntPtr free)\n\t\t{\n#if USE_WP8_NATIVE_SQLITE\n\t\t\treturn Sqlite3.sqlite3_bind_blob(stmt, index, val, n);\n#else\n\t\t\treturn Sqlite3.sqlite3_bind_blob(stmt, index, val, n, null);\n#endif\n\t\t}\n\n\t\tpublic static int ColumnCount(Sqlite3Statement stmt)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_count(stmt);\n\t\t}\n\n\t\tpublic static string ColumnName(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_name(stmt, index);\n\t\t}\n\n\t\tpublic static string ColumnName16(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_name(stmt, index);\n\t\t}\n\n\t\tpublic static ColType ColumnType(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn (ColType)Sqlite3.sqlite3_column_type(stmt, index);\n\t\t}\n\n\t\tpublic static int ColumnInt(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_int(stmt, index);\n\t\t}\n\n\t\tpublic static long ColumnInt64(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_int64(stmt, index);\n\t\t}\n\n\t\tpublic static double ColumnDouble(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_double(stmt, index);\n\t\t}\n\n\t\tpublic static string ColumnText(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_text(stmt, index);\n\t\t}\n\n\t\tpublic static string ColumnText16(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_text(stmt, index);\n\t\t}\n\n\t\tpublic static byte[] ColumnBlob(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_blob(stmt, index);\n\t\t}\n\n\t\tpublic static int ColumnBytes(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_bytes(stmt, index);\n\t\t}\n\n\t\tpublic static string ColumnString(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn Sqlite3.sqlite3_column_text(stmt, index);\n\t\t}\n\n\t\tpublic static byte[] ColumnByteArray(Sqlite3Statement stmt, int index)\n\t\t{\n\t\t\treturn ColumnBlob(stmt, index);\n\t\t}\n\n\t\tpublic static Result EnableLoadExtension(Sqlite3DatabaseHandle db, int onoff)\n\t\t{\n\t\t\treturn (Result)Sqlite3.sqlite3_enable_load_extension(db, onoff);\n\t\t}\n\n\t\tpublic static ExtendedResult ExtendedErrCode(Sqlite3DatabaseHandle db)\n\t\t{\n\t\t\treturn (ExtendedResult)Sqlite3.sqlite3_extended_errcode(db);\n\t\t}\n#endif\n\n\t\tpublic enum ColType : int\n\t\t{\n\t\t\tInteger = 1,\n\t\t\tFloat = 2,\n\t\t\tText = 3,\n\t\t\tBlob = 4,\n\t\t\tNull = 5\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Meridian/SQLiteAsync.cs",
    "content": "//\n// Copyright (c) 2012 Krueger Systems, Inc.\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n//\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Linq.Expressions;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace SQLite\n{\n\tpublic partial class SQLiteAsyncConnection\n\t{\n\t\tSQLiteConnectionString _connectionString;\n        SQLiteOpenFlags _openFlags;\n\n\t    private bool _caseSensitive;\n\n        public SQLiteAsyncConnection(string databasePath, bool storeDateTimeAsTicks = false, bool caseSensitive = true)\n            : this(databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, storeDateTimeAsTicks, caseSensitive)\n        {\n            _caseSensitive = caseSensitive;\n        }\n\n        public SQLiteAsyncConnection(string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = false, bool caseSensitive = true)\n        {\n            _openFlags = openFlags;\n            _connectionString = new SQLiteConnectionString(databasePath, storeDateTimeAsTicks, caseSensitive);\n            _caseSensitive = caseSensitive;\n        }\n\n\t\tSQLiteConnectionWithLock GetConnection ()\n\t\t{\n\t\t\treturn SQLiteConnectionPool.Shared.GetConnection (_connectionString, _openFlags);\n\t\t}\n\n\t\tpublic Task<CreateTablesResult> CreateTableAsync<T> ()\n\t\t\twhere T : new ()\n\t\t{\n\t\t\treturn CreateTablesAsync (typeof (T));\n\t\t}\n\n\t\tpublic Task<CreateTablesResult> CreateTablesAsync<T, T2> ()\n\t\t\twhere T : new ()\n\t\t\twhere T2 : new ()\n\t\t{\n\t\t\treturn CreateTablesAsync (typeof (T), typeof (T2));\n\t\t}\n\n\t\tpublic Task<CreateTablesResult> CreateTablesAsync<T, T2, T3> ()\n\t\t\twhere T : new ()\n\t\t\twhere T2 : new ()\n\t\t\twhere T3 : new ()\n\t\t{\n\t\t\treturn CreateTablesAsync (typeof (T), typeof (T2), typeof (T3));\n\t\t}\n\n\t\tpublic Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4> ()\n\t\t\twhere T : new ()\n\t\t\twhere T2 : new ()\n\t\t\twhere T3 : new ()\n\t\t\twhere T4 : new ()\n\t\t{\n\t\t\treturn CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4));\n\t\t}\n\n\t\tpublic Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4, T5> ()\n\t\t\twhere T : new ()\n\t\t\twhere T2 : new ()\n\t\t\twhere T3 : new ()\n\t\t\twhere T4 : new ()\n\t\t\twhere T5 : new ()\n\t\t{\n\t\t\treturn CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4), typeof (T5));\n\t\t}\n\n\t\tpublic Task<CreateTablesResult> CreateTablesAsync (params Type[] types)\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tCreateTablesResult result = new CreateTablesResult ();\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\tforeach (Type type in types) {\n\t\t\t\t\t\tint aResult = conn.CreateTable (type);\n\t\t\t\t\t\tresult.Results[type] = aResult;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<int> DropTableAsync<T> ()\n\t\t\twhere T : new ()\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.DropTable<T> ();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<int> InsertAsync (object item)\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.Insert (item);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<int> UpdateAsync (object item)\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.Update (item);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<int> DeleteAsync (object item)\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.Delete (item);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n        public Task<T> GetAsync<T>(object pk)\n            where T : new()\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                var conn = GetConnection();\n                using (conn.Lock())\n                {\n                    return conn.Get<T>(pk);\n                }\n            });\n        }\n\n\t\tpublic Task<T> FindAsync<T> (object pk)\n\t\t\twhere T : new ()\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.Find<T> (pk);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t\n\t\tpublic Task<T> GetAsync<T> (Expression<Func<T, bool>> predicate)\n            where T : new()\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                var conn = GetConnection();\n                using (conn.Lock())\n                {\n                    return conn.Get<T> (predicate);\n                }\n            });\n        }\n\n\t\tpublic Task<T> FindAsync<T> (Expression<Func<T, bool>> predicate)\n\t\t\twhere T : new ()\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.Find<T> (predicate);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<int> ExecuteAsync (string query, params object[] args)\n\t\t{\n\t\t\treturn Task<int>.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.Execute (query, args);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<int> InsertAllAsync (IEnumerable items)\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.InsertAll (items);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n        public Task<int> InsertOrReplaceAsync(object item)\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                SQLiteConnectionWithLock conn = GetConnection();\n                using (conn.Lock())\n                {\n                    return conn.InsertOrReplace(item);\n                }\n            });\n        }\n\n        public Task<int> InsertOrIgnoreAsync(object item)\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                SQLiteConnectionWithLock conn = GetConnection();\n                using (conn.Lock())\n                {\n                    return conn.InsertOrIgnore(item);\n                }\n            });\n        }\n\n        public Task<int> InsertOrReplaceAllAsync(IEnumerable items)\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                var conn = GetConnection();\n                using (conn.Lock())\n                {\n                    return conn.InsertOrReplaceAll(items);\n                }\n            });\n        }\n\n        public Task<int> InsertOrIgnoreAllAsync(IEnumerable items)\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                var conn = GetConnection();\n                using (conn.Lock())\n                {\n                    return conn.InsertOrIgnoreAll(items);\n                }\n            });\n        }\n\t\t\n\t\tpublic Task<int> UpdateAllAsync (IEnumerable items)\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.UpdateAll (items);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n        public Task<int> DeleteAllAsync<T>()\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                var conn = GetConnection();\n                using (conn.Lock())\n                {\n                    return conn.DeleteAll<T>();\n                }\n            });\n        }\n\n\n        [Obsolete(\"Will cause a deadlock if any call in action ends up in a different thread. Use RunInTransactionAsync(Action<SQLiteConnection>) instead.\")]\n\t\tpublic Task RunInTransactionAsync (Action<SQLiteAsyncConnection> action)\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tvar conn = this.GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\tconn.BeginTransaction ();\n\t\t\t\t\ttry {\n\t\t\t\t\t\taction (this);\n\t\t\t\t\t\tconn.Commit ();\n\t\t\t\t\t}\n\t\t\t\t\tcatch (Exception) {\n\t\t\t\t\t\tconn.Rollback ();\n\t\t\t\t\t\tthrow;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n        public Task RunInTransactionAsync(Action<SQLiteConnection> action)\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                var conn = this.GetConnection();\n                using (conn.Lock())\n                {\n                    conn.BeginTransaction();\n                    try\n                    {\n                        action(conn);\n                        conn.Commit();\n                    }\n                    catch (Exception)\n                    {\n                        conn.Rollback();\n                        throw;\n                    }\n                }\n            });\n        }\n\n\t\tpublic AsyncTableQuery<T> Table<T> ()\n\t\t\twhere T : new ()\n\t\t{\n\t\t\t//\n\t\t\t// This isn't async as the underlying connection doesn't go out to the database\n\t\t\t// until the query is performed. The Async methods are on the query iteself.\n\t\t\t//\n\t\t\tvar conn = GetConnection ();\n\t\t\treturn new AsyncTableQuery<T> (conn.Table<T> ());\n\t\t}\n\n\t\tpublic Task<T> ExecuteScalarAsync<T> (string sql, params object[] args)\n\t\t{\n\t\t\treturn Task<T>.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\tvar command = conn.CreateCommand (sql, args);\n\t\t\t\t\treturn command.ExecuteScalar<T> ();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<List<T>> QueryAsync<T> (string sql, params object[] args)\n\t\t\twhere T : new ()\n\t\t{\n\t\t\treturn Task<List<T>>.Factory.StartNew (() => {\n\t\t\t\tvar conn = GetConnection ();\n\t\t\t\tusing (conn.Lock ()) {\n\t\t\t\t\treturn conn.Query<T> (sql, args);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t//\n\t// TODO: Bind to AsyncConnection.GetConnection instead so that delayed\n\t// execution can still work after a Pool.Reset.\n\t//\n\tpublic class AsyncTableQuery<T>\n\t\twhere T : new ()\n\t{\n\t\tTableQuery<T> _innerQuery;\n\n\t\tpublic AsyncTableQuery (TableQuery<T> innerQuery)\n\t\t{\n\t\t\t_innerQuery = innerQuery;\n\t\t}\n\n\t\tpublic AsyncTableQuery<T> Where (Expression<Func<T, bool>> predExpr)\n\t\t{\n\t\t\treturn new AsyncTableQuery<T> (_innerQuery.Where (predExpr));\n\t\t}\n\n\t\tpublic AsyncTableQuery<T> Skip (int n)\n\t\t{\n\t\t\treturn new AsyncTableQuery<T> (_innerQuery.Skip (n));\n\t\t}\n\n\t\tpublic AsyncTableQuery<T> Take (int n)\n\t\t{\n\t\t\treturn new AsyncTableQuery<T> (_innerQuery.Take (n));\n\t\t}\n\n\t\tpublic AsyncTableQuery<T> OrderBy<U> (Expression<Func<T, U>> orderExpr)\n\t\t{\n\t\t\treturn new AsyncTableQuery<T> (_innerQuery.OrderBy<U> (orderExpr));\n\t\t}\n\n\t\tpublic AsyncTableQuery<T> OrderByDescending<U> (Expression<Func<T, U>> orderExpr)\n\t\t{\n\t\t\treturn new AsyncTableQuery<T> (_innerQuery.OrderByDescending<U> (orderExpr));\n\t\t}\n\n\t\tpublic Task<List<T>> ToListAsync ()\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tusing (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {\n\t\t\t\t\treturn _innerQuery.ToList ();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<int> CountAsync ()\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tusing (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {\n\t\t\t\t\treturn _innerQuery.Count ();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<T> ElementAtAsync (int index)\n\t\t{\n\t\t\treturn Task.Factory.StartNew (() => {\n\t\t\t\tusing (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {\n\t\t\t\t\treturn _innerQuery.ElementAt (index);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<T> FirstAsync ()\n\t\t{\n\t\t\treturn Task<T>.Factory.StartNew(() => {\n\t\t\t\tusing (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {\n\t\t\t\t\treturn _innerQuery.First ();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tpublic Task<T> FirstOrDefaultAsync ()\n\t\t{\n\t\t\treturn Task<T>.Factory.StartNew(() => {\n\t\t\t\tusing (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) {\n\t\t\t\t\treturn _innerQuery.FirstOrDefault ();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n    }\n\n\tpublic class CreateTablesResult\n\t{\n\t\tpublic Dictionary<Type, int> Results { get; private set; }\n\n\t\tinternal CreateTablesResult ()\n\t\t{\n\t\t\tthis.Results = new Dictionary<Type, int> ();\n\t\t}\n\t}\n\n\tclass SQLiteConnectionPool\n\t{\n\t\tclass Entry\n\t\t{\n\t\t\tpublic SQLiteConnectionString ConnectionString { get; private set; }\n\t\t\tpublic SQLiteConnectionWithLock Connection { get; private set; }\n\n            public Entry (SQLiteConnectionString connectionString, SQLiteOpenFlags openFlags)\n\t\t\t{\n\t\t\t\tConnectionString = connectionString;\n\t\t\t\tConnection = new SQLiteConnectionWithLock (connectionString, openFlags);\n\t\t\t}\n\n\t\t\tpublic void OnApplicationSuspended ()\n\t\t\t{\n\t\t\t\tConnection.Dispose ();\n\t\t\t\tConnection = null;\n\t\t\t}\n\t\t}\n\n\t\treadonly Dictionary<string, Entry> _entries = new Dictionary<string, Entry> ();\n\t\treadonly object _entriesLock = new object ();\n\n\t\tstatic readonly SQLiteConnectionPool _shared = new SQLiteConnectionPool ();\n\n\t\t/// <summary>\n\t\t/// Gets the singleton instance of the connection tool.\n\t\t/// </summary>\n\t\tpublic static SQLiteConnectionPool Shared\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\treturn _shared;\n\t\t\t}\n\t\t}\n\n\t\tpublic SQLiteConnectionWithLock GetConnection (SQLiteConnectionString connectionString, SQLiteOpenFlags openFlags)\n\t\t{\n\t\t\tlock (_entriesLock) {\n\t\t\t\tEntry entry;\n\t\t\t\tstring key = connectionString.ConnectionString;\n\n\t\t\t\tif (!_entries.TryGetValue (key, out entry)) {\n\t\t\t\t\tentry = new Entry (connectionString, openFlags);\n\t\t\t\t\t_entries[key] = entry;\n\t\t\t\t}\n\n\t\t\t\treturn entry.Connection;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Closes all connections managed by this pool.\n\t\t/// </summary>\n\t\tpublic void Reset ()\n\t\t{\n\t\t\tlock (_entriesLock) {\n\t\t\t\tforeach (var entry in _entries.Values) {\n\t\t\t\t\tentry.OnApplicationSuspended ();\n\t\t\t\t}\n\t\t\t\t_entries.Clear ();\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Call this method when the application is suspended.\n\t\t/// </summary>\n\t\t/// <remarks>Behaviour here is to close any open connections.</remarks>\n\t\tpublic void ApplicationSuspended ()\n\t\t{\n\t\t\tReset ();\n\t\t}\n\t}\n\n\tclass SQLiteConnectionWithLock : SQLiteConnection\n\t{\n\t\treadonly object _lockPoint = new object ();\n\n        public SQLiteConnectionWithLock (SQLiteConnectionString connectionString, SQLiteOpenFlags openFlags)\n\t\t\t: base (connectionString.DatabasePath, openFlags, connectionString.StoreDateTimeAsTicks, connectionString.CaseSensitive)\n\t\t{\n\t\t}\n\n\t\tpublic IDisposable Lock ()\n\t\t{\n\t\t\treturn new LockWrapper (_lockPoint);\n\t\t}\n\n\t\tprivate class LockWrapper : IDisposable\n\t\t{\n\t\t\tobject _lockPoint;\n\n\t\t\tpublic LockWrapper (object lockPoint)\n\t\t\t{\n\t\t\t\t_lockPoint = lockPoint;\n\t\t\t\tMonitor.Enter (_lockPoint);\n\t\t\t}\n\n\t\t\tpublic void Dispose ()\n\t\t\t{\n\t\t\t\tMonitor.Exit (_lockPoint);\n\t\t\t}\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "Meridian/Services/AccountManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Messaging;\nusing LastFmLib;\nusing Meridian.Domain;\nusing Meridian.Model;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Messages;\nusing Neptune.Messages;\nusing VkLib;\nusing VkLib.Auth;\nusing VkLib.Core.Auth;\n\nnamespace Meridian.Services\n{\n    public static class AccountManager\n    {\n        private static readonly Vk _vkontakte;\n        private static readonly LastFm _lastFm;\n        private const VkScopeSettings ScopeSettings = VkScopeSettings.CanAccessAudios | VkScopeSettings.CanAccessVideos | VkScopeSettings.CanAccessFriends |\n                      VkScopeSettings.CanAccessGroups | VkScopeSettings.CanAccessWall | VkScopeSettings.CanAccessStatus | VkScopeSettings.CanAccessPhotos;\n\n        public static List<Account> Accounts\n        {\n            get { return Settings.Instance.Accounts; }\n        }\n\n        static AccountManager()\n        {\n            _vkontakte = ViewModelLocator.Vkontakte;\n            _lastFm = ViewModelLocator.LastFm;\n\n            Initialize();\n        }\n\n        private static void Initialize()\n        {\n            if (!Accounts.Any(a => a is VkAccount))\n                Accounts.Add(new VkAccount());\n\n            if (!Accounts.Any(a => a is LastFmAccount))\n                Accounts.Add(new LastFmAccount());\n        }\n\n        public static async Task LoginVk(string login, string password, string captchaSid, string captchaKey)\n        {\n            var token = await _vkontakte.Auth.Login(login, password, ScopeSettings, captchaSid, captchaKey);\n            if (token == null || token.Token == null)\n            {\n                throw new ArgumentException(\"AccessToken is empty\");\n            }\n            else\n            {\n                Settings.Instance.AccessToken = token;\n                Settings.Instance.Save();\n\n                var p = _vkontakte.LoginParams ?? new Dictionary<string, string>()\n                {\n                    [\"version\"] = \"4.11.1\",\n                    [\"func_v\"] = \"5\"\n                };\n\n                p[\"userId\"] = token.UserId.ToString();\n\n                await _vkontakte.Execute.GetBaseData(p);\n\n                Messenger.Default.Send(new LoginMessage() { Type = LoginType.LogIn, Service = \"vk\" });\n            }\n        }\n\n        public static void SetLoginVk(VkAccessToken token)\n        {\n            if (token == null || token.Token == null)\n            {\n                throw new ArgumentException(\"AccessToken is empty\");\n            }\n            else\n            {\n                _vkontakte.AccessToken = token;\n                Settings.Instance.AccessToken = token;\n                Settings.Instance.Save();\n                Messenger.Default.Send(new LoginMessage() { Type = LoginType.LogIn, Service = \"vk\" });\n            }\n        }\n\n        public static async Task LoginLastFm(string login, string password)\n        {\n            var result = await _lastFm.Auth.GetMobileSession(login, password);\n            if (result == null || result.Key == null)\n            {\n                throw new ArgumentException(\"Session key is empty\");\n            }\n            else\n            {\n                _lastFm.SessionKey = result.Key;\n                Settings.Instance.LastFmUsername = result.Username;\n                Settings.Instance.LastFmSession = result.Key;\n                Settings.Instance.Save();\n\n                Messenger.Default.Send(new LoginMessage() { Type = LoginType.LogIn, Service = \"lastfm\" });\n            }\n        }\n\n        public static void LogoutLastFm()\n        {\n            Settings.Instance.LastFmUsername = null;\n            Settings.Instance.LastFmSession = null;\n            Settings.Instance.Save();\n\n            Messenger.Default.Send(new LoginMessage() { Type = LoginType.LogOut, Service = \"lastfm\" });\n        }\n\n        public static void LogOutVk()\n        {\n            AudioService.Stop();\n            AudioService.CurrentAudio = null;\n            AudioService.SetCurrentPlaylist(null);\n            AudioService.Clear();\n\n            _vkontakte.AccessToken.Token = null;\n            _vkontakte.AccessToken.UserId = 0;\n            _vkontakte.AccessToken.ExpiresIn = DateTime.MinValue;\n\n            Settings.Instance.AccessToken = null;\n            Settings.Instance.Save();\n\n            ViewModelLocator.Main.ShowSidebar = false;\n            ViewModelLocator.Main.User = null;\n            Messenger.Default.Send(new NavigateToPageMessage() { Page = \"/Main.LoginView\" });\n        }\n\n        public static bool IsLoggedInLastFm()\n        {\n            return !string.IsNullOrEmpty(Settings.Instance.LastFmSession);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/CacheService.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing Neptune.Desktop.Storage;\n\nnamespace Meridian.Services\n{\n    public static class CacheService\n    {\n        private const string CachePath = \"Cache\";\n\n        public static async Task<ImageSource> GetCachedImage(string path)\n        {\n            var filePath = Path.Combine(CachePath, path);\n\n            if (await FileStorage.FileExists(filePath))\n            {\n                using (var stream = await FileStorage.OpenFile(filePath))\n                {\n\n                    var ms = new MemoryStream();\n                    await stream.CopyToAsync(ms);\n                    ms.Seek(0, SeekOrigin.Begin);\n\n                    var bi = new BitmapImage();\n                    bi.BeginInit();\n                    bi.StreamSource = ms;\n                    bi.EndInit();\n                    return bi;\n                }\n            }\n\n            return null;\n        }\n\n        public static async Task<ImageSource> CacheImage(string url, string path)\n        {\n            if (string.IsNullOrEmpty(url))\n                return null;\n\n            var savePath = Path.Combine(CachePath, path);\n            var parentDir = Path.GetDirectoryName(savePath);\n\n            if (!await FileStorage.FolderExists(parentDir))\n                await FileStorage.CreateFolder(parentDir);\n\n            try\n            {\n                ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;\n                using (var stream = await new HttpClient().GetStreamAsync(url))\n                {\n                    using (var ms = new MemoryStream())\n                    {\n                        await stream.CopyToAsync(ms);\n                        ms.Seek(0, SeekOrigin.Begin);\n                        await SaveStream(ms, savePath);\n                    }\n                }\n\n                return await GetCachedImage(path);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n\n            return null;\n        }\n\n        public static string GetSafeFileName(string input)\n        {\n            var fileName = input;\n            foreach (var c in Path.GetInvalidFileNameChars())\n            {\n                fileName = fileName.Replace(c, '-');\n            }\n\n            return fileName;\n        }\n\n        private static async Task SaveStream(Stream stream, string fileName)\n        {\n            using (var fileStream = File.OpenWrite(fileName))\n            {\n                var buffer = new byte[1024];\n\n                while (stream.Read(buffer, 0, buffer.Length) > 0)\n                {\n                    fileStream.Write(buffer, 0, buffer.Length);\n                }\n\n                fileStream.Flush();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/DataBaseService.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq.Expressions;\nusing System.Threading.Tasks;\nusing Meridian.Model;\nusing SQLite;\n\nnamespace Meridian.Services\n{\n    public class DataBaseService\n    {\n        private const string DbName = \"music.library\";\n        private readonly string _dbPath;\n\n\n        public DataBaseService()\n        {\n            _dbPath = System.IO.Path.Combine(App.Root, DbName);\n        }\n\n        public async Task Initialize()\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n\n            await db.CreateTablesAsync(\n                typeof(Audio), \n                typeof(LocalAudio),\n                typeof(AudioAlbum), \n                typeof(AudioArtist)).ConfigureAwait(false);\n\n            Debug.WriteLine(\"Database initialized.\");\n        }\n\n        public async Task Clear<T>() where T : new()\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n\n            await db.DeleteAllAsync<T>();\n        }\n\n        public async Task SaveItems<T>(IEnumerable<T> items) where T : new()\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n\n            await db.InsertOrIgnoreAllAsync(items).ConfigureAwait(false);\n        }\n\n        public async Task SaveItem<T>(T item) where T : new()\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n\n            await db.InsertOrIgnoreAsync(item).ConfigureAwait(false);\n        }\n\n        public Task<List<T>> GetItems<T>() where T : new()\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n\n            return db.Table<T>().ToListAsync();\n        }\n\n        public async Task UpdateItems(IEnumerable items)\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n\n            await db.UpdateAllAsync(items);\n        }\n\n        public async Task DeleteItems(IEnumerable items)\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n\n            foreach (var item in items)\n            {\n                await db.DeleteAsync(item);\n            }\n        }\n\n        public async Task<List<T>> Search<T>(Expression<Func<T, bool>> predicate) where T : new()\n        {\n            var db = new SQLiteAsyncConnection(_dbPath, caseSensitive: false);\n\n            return await db.Table<T>().Where(predicate).ToListAsync();\n        }\n\n        //albums\n        public async Task<List<LocalAudio>> GetLocalAlbumTracks(string albumId)\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n\n            var tracks = await db.Table<LocalAudio>().Where(track => track.AlbumId == albumId).ToListAsync();\n\n            return tracks;\n        }\n\n        public async Task<List<AudioAlbum>> GetLocalArtistAlbums(string artistId)\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n            var a = await db.Table<AudioAlbum>().ToListAsync();\n\n            var albums = await db.Table<AudioAlbum>().Where(album => album.ArtistId == artistId).ToListAsync();\n\n            return albums;\n        }\n\n        public async Task<List<LocalAudio>> GetLocalArtistUnsortedTracks(string artistId)\n        {\n            var db = new SQLiteAsyncConnection(_dbPath);\n\n            var tracks = await db.Table<LocalAudio>().Where(track => track.ArtistId == artistId && (track.AlbumId == null || track.AlbumId == string.Empty)).ToListAsync();\n\n            return tracks;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/DataService.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing LastFmLib;\nusing LastFmLib.Core.Album;\nusing LastFmLib.Core.Artist;\nusing Meridian.Controls;\nusing Meridian.Domain;\nusing Meridian.Extensions;\nusing Meridian.Helpers;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.View.Flyouts;\nusing Meridian.ViewModel;\nusing VkLib;\nusing VkLib.Core.Attachments;\nusing VkLib.Core.Audio;\nusing VkLib.Core.Friends;\nusing VkLib.Core.Groups;\nusing VkLib.Core.Users;\nusing VkLib.Error;\nusing DateTimeConverter = Meridian.Helpers.DateTimeConverter;\nusing VkAudio = Meridian.Model.VkAudio;\n\nnamespace Meridian.Services\n{\n    public static class DataService\n    {\n        private static readonly Vk _vkontakte;\n        private static readonly LastFm _lastFm;\n\n        static DataService()\n        {\n            _vkontakte = ViewModelLocator.Vkontakte;\n            _lastFm = ViewModelLocator.LastFm;\n        }\n\n        public static async Task<VkProfile> GetUserInfo()\n        {\n            try\n            {\n                var info = await _vkontakte.Users.Get(_vkontakte.AccessToken.UserId, \"photo\");\n                return info;\n            }\n            catch (VkInvalidTokenException)\n            {\n                Settings.Instance.AccessToken = null;\n                Settings.Instance.Save();\n\n                AccountManager.LogOutVk();\n            }\n\n            return null;\n        }\n\n        public static async Task<ItemsResponse<VkPlaylist>> GetUserAlbums(long ownerId = 0, int count = 0, int offset = 0)\n        {\n            try\n            {\n                var response = await _vkontakte.Audio.GetPlaylists(ownerId == 0 ? _vkontakte.AccessToken.UserId : ownerId, count, offset);\n                if (response.Items != null)\n                {\n                    return new ItemsResponse<VkPlaylist>(response.Items, response.TotalCount);\n                }\n            }\n            catch (VkInvalidTokenException)\n            {\n                Settings.Instance.AccessToken = null;\n                Settings.Instance.Save();\n\n                AccountManager.LogOutVk();\n            }\n\n            return ItemsResponse<VkPlaylist>.Empty;\n        }\n\n        public static async Task<ItemsResponse<VkAudio>> GetUserTracks(int count = 0, int offset = 0, long albumId = 0, long ownerId = 0)\n        {\n            try\n            {\n                var response = await _vkontakte.Audio.Get(ownerId, albumId, count, offset);\n                if (response.Items != null)\n                {\n                    var validTracks = RemoveCorruptedTracks(response.Items.Select(i => i.ToAudio()));\n\n                    return new ItemsResponse<VkAudio>(validTracks.ToList(), response.TotalCount);\n                }\n            }\n            catch (VkInvalidTokenException)\n            {\n                Settings.Instance.AccessToken = null;\n                Settings.Instance.Save();\n\n                AccountManager.LogOutVk();\n            }\n            catch (VkFloodControlException)\n            {\n                Settings.Instance.AccessToken = null;\n                Settings.Instance.Save();\n\n                AccountManager.LogOutVk();\n            }\n\n            return ItemsResponse<VkAudio>.Empty;\n        }\n\n        public static async Task<ItemsResponse<VkAudio>> GetPopularTracks(int genreId = 0, bool foreignOnly = false, int count = 0, int offset = 0)\n        {\n            var response = await _vkontakte.Audio.GetPopular(count: count, offset: offset, genreId: genreId, onlyEng: foreignOnly);\n            if (response.Items != null)\n            {\n                return new ItemsResponse<VkAudio>(response.Items.Select(i => i.ToAudio()).ToList(), response.TotalCount);\n            }\n\n            return ItemsResponse<VkAudio>.Empty;\n        }\n\n        public static async Task<ItemsResponse<VkProfile>> GetFriends(int count = 0, int offset = 0, long userId = 0, string fields = null)\n        {\n            var response = await _vkontakte.Friends.Get(userId, fields, null, count, offset, FriendsOrder.ByRating);\n            if (response.Items != null)\n            {\n                return new ItemsResponse<VkProfile>(response.Items, response.TotalCount);\n            }\n\n            return ItemsResponse<VkProfile>.Empty;\n        }\n\n        public static async Task<ItemsResponse<VkProfile>> GetSubscriptions(int count = 0, int offset = 0, string fields = null)\n        {\n            var response = await _vkontakte.Subscriptions.Get();\n            if (response.Items != null && response.Items.Count > 0)\n            {\n                var users = await _vkontakte.Users.Get(response.Items.Select(s => s.Id.ToString()), fields);\n                if (users.Items != null)\n                {\n                    return new ItemsResponse<VkProfile>(users.Items, users.TotalCount);\n                }\n            }\n\n            return ItemsResponse<VkProfile>.Empty;\n        }\n\n        public static async Task<ItemsResponse<VkGroup>> GetSocieties(int count = 0, int offset = 0, long userId = 0, string fields = null)\n        {\n            var response = await _vkontakte.Groups.Get(userId, fields, null, count, offset);\n            if (response.Items != null)\n            {\n                return new ItemsResponse<VkGroup>(response.Items, response.TotalCount);\n            }\n\n            return ItemsResponse<VkGroup>.Empty;\n        }\n\n        public static async Task<List<VkAudio>> GetRecommendations(int count = 0, int offset = 0)\n        {\n            var vkAudios = await _vkontakte.Audio.GetRecommendations(count: count, offset: offset);\n            if (vkAudios.Items != null)\n            {\n                var result = (from a in vkAudios.Items\n                              select a.ToAudio()).ToList();\n\n                return result;\n            }\n\n            return null;\n        }\n\n        public static async Task<Uri> GetArtistImage(string artist, bool big)\n        {\n            if (string.IsNullOrEmpty(artist))\n                return null;\n\n            if (artist.Contains(\", \") || artist.Contains(\" feat \", StringComparison.OrdinalIgnoreCase) || artist.Contains(\" ft. \", StringComparison.OrdinalIgnoreCase))\n            {\n                //if there are more then 1 artist, get first\n                var artists = artist.Split(new[] { \", \", \" feat. \", \" feat \", \" ft. \" }, StringSplitOptions.RemoveEmptyEntries);\n                if (artists.Length > 0)\n                    artist = artists.First();\n            }\n\n            var info = await _lastFm.Artist.GetInfo(null, artist);\n            if (info == null || string.IsNullOrEmpty(big ? info.ImageMega : info.ImageExtraLarge))\n                return null;\n\n            return new Uri(big ? info.ImageMega : info.ImageExtraLarge);\n        }\n\n        public static async Task<Uri> GetTrackImage(string artist, string title)\n        {\n            if (string.IsNullOrEmpty(artist) || string.IsNullOrEmpty(title))\n                return null;\n\n            var info = await _lastFm.Track.GetInfo(title, artist);\n            if (info == null || info.ImageExtraLarge == null || string.IsNullOrEmpty(info.ImageExtraLarge))\n                return null;\n\n            return new Uri(info.ImageExtraLarge);\n        }\n\n        public static async Task<List<VkAudio>> GetTagTopTracks(string tag, int count = 50)\n        {\n            var tracks = await _lastFm.Tag.GetTopTracks(tag, count);\n            if (tracks != null)\n            {\n                return (from track in tracks\n                        select track.ToAudio()).ToList();\n            }\n\n            return null;\n        }\n\n        public static async Task<VkAudio> GetAudioByArtistAndTitle(string artist, string title)\n        {\n            var audios = await SearchAudio(artist + \" - \" + title, 10, 0);\n            if (audios != null && audios.Count > 0)\n            {\n                var audio = audios.FirstOrDefault(x => (String.Equals(x.Title, title, StringComparison.OrdinalIgnoreCase) && String.Equals(x.Artist, artist, StringComparison.OrdinalIgnoreCase)));\n                if (audio == null)\n                    audio = audios.FirstOrDefault(x => String.Equals(x.Title, title, StringComparison.OrdinalIgnoreCase));\n                if (audio == null)\n                {\n                    audio = audios.First();\n                }\n\n                return audio;\n            }\n            else\n            {\n                bool searchAgain = false;\n                if (artist.Contains(\"(\") && artist.Contains(\")\"))\n                {\n                    artist = artist.Substring(0, artist.IndexOf(\"(\")) + artist.Substring(artist.LastIndexOf(\")\") + 1);\n                    searchAgain = true;\n                }\n\n                if (title.Contains(\"(\") && title.Contains(\")\"))\n                {\n                    title = title.Substring(0, title.IndexOf(\"(\")) + title.Substring(title.LastIndexOf(\")\") + 1);\n                    searchAgain = true;\n                }\n\n                if (searchAgain)\n                    return await GetAudioByArtistAndTitle(artist, title);\n            }\n\n            return null;\n        }\n\n        public static async Task<List<VkAudio>> SearchAudio(string query, int count = 0, int offset = 0)\n        {\n            var vkAudios = await _vkontakte.Audio.Search(query, count, offset, VkAudioSortType.DateAdded, false, false);\n            if (vkAudios.Items != null)\n            {\n                var result = (from a in vkAudios.Items\n                              select a.ToAudio()).ToList();\n\n                return result;\n            }\n\n            return null;\n        }\n\n        public static async Task<List<LastFmAlbum>> SearchAlbums(string query)\n        {\n            var albums = await _lastFm.Album.Search(query);\n\n            return albums;\n        }\n\n        public static async Task<List<LastFmArtist>> SearchArtists(string query)\n        {\n            var artists = await _lastFm.Artist.Search(query);\n\n            return artists;\n        }\n\n        public static async Task<LastFmAlbum> GetAlbumInfo(string id, string name, string artist, bool loadTracks = true, bool autoCorrent = true)\n        {\n            var album = await _lastFm.Album.GetInfo(id, name, artist, autoCorrent);\n            return album;\n        }\n\n        public static async Task<LastFmArtist> GetArtistInfo(string id, string name)\n        {\n            var artist = await _lastFm.Artist.GetInfo(id, name);\n\n            return artist;\n        }\n\n        public static async Task<List<LastFmAlbum>> GetArtistAlbums(string id, string artist, int count = 0)\n        {\n            var albums = await _lastFm.Artist.GetTopAlbums(id, artist, count);\n\n            return albums.FindAll(album => album.Name != \"(null)\");\n        }\n\n        public static async Task<List<VkAudio>> GetArtistTopTracks(string id, string artist, int count = 0)\n        {\n            var tracks = await _lastFm.Artist.GetTopTracks(id, artist, count);\n            if (tracks != null)\n            {\n                return (from track in tracks\n                        select track.ToAudio()).ToList();\n            }\n\n            return null;\n        }\n\n        public static async Task<NewsItemsResponse<Audio>> GetNewsAudio(int count, string nextFrom, CancellationToken token, List<long> sourceIds = null)\n        {\n            try\n            {\n                var vkNews = await _vkontakte.News.Get(sourceIds != null ? string.Join(\",\", sourceIds) : null, \"post\", count, nextFrom);\n                if (vkNews.Items != null)\n                {\n                    var audioIds = new List<string>();\n\n                    foreach (var vkNewsEntry in vkNews.Items)\n                    {\n                        var attachments = vkNewsEntry.Attachments;\n                        if ((vkNewsEntry.Attachments == null || vkNewsEntry.Attachments.Count == 0) && (vkNewsEntry.CopyHistory != null && vkNewsEntry.CopyHistory.Count > 0))\n                        {\n                            attachments = vkNewsEntry.CopyHistory.Last().Attachments;\n                        }\n\n                        if (attachments != null)\n                        {\n                            var audioEntries = (from a in attachments\n                                                where a is VkAudioAttachment\n                                                select a.OwnerId + \"_\" + a.Id).ToList();\n                            if (audioEntries.Any())\n                                audioIds.AddRange(audioEntries);\n                        }\n                    }\n\n                    if (audioIds.Count == 0)\n                        return new NewsItemsResponse<Audio>(new List<Audio>());\n\n                    var vkAudios = new List<VkLib.Core.Audio.VkAudio>();\n                    if (audioIds.Count >= 100)\n                    {\n                        //если аудиозаписей больше 100, разбиваем на несколько запросов по 100 аудиозаписей\n                        int i = 0, j = 99;\n                        while (i + j < audioIds.Count)\n                        {\n                            if (token.IsCancellationRequested)\n                                return new NewsItemsResponse<Audio>(new List<Audio>());\n\n                            var x = await _vkontakte.Audio.GetById(audioIds.GetRange(i, j));\n                            if (x != null)\n                                vkAudios.AddRange(x);\n                            else\n                                break;\n\n                            i += 100;\n                            if (j >= audioIds.Count)\n                                j = audioIds.Count;\n                        }\n                    }\n                    else\n                    {\n                        if (token.IsCancellationRequested)\n                        {\n                            Debug.WriteLine(\"News audio cancelled\");\n                            return new NewsItemsResponse<Audio>(new List<Audio>());\n                        }\n\n                        var a = await _vkontakte.Audio.GetById(audioIds);\n                        if (a != null)\n                            vkAudios.AddRange(a);\n                    }\n\n                    var audios = from a in vkAudios select a.ToAudio();\n\n                    var result = new List<Audio>();\n\n                    foreach (var vkNewsEntry in vkNews.Items)\n                    {\n                        var attachments = vkNewsEntry.Attachments;\n                        if ((vkNewsEntry.Attachments == null || vkNewsEntry.Attachments.Count == 0) && (vkNewsEntry.CopyHistory != null && vkNewsEntry.CopyHistory.Count > 0))\n                        {\n                            attachments = vkNewsEntry.CopyHistory.Last().Attachments;\n                        }\n\n                        if (attachments == null)\n                            continue;\n\n                        var audioAttachments = attachments.Where(a => a is VkAudioAttachment).ToList();\n                        if (!audioAttachments.Any())\n                            continue;\n\n                        var tracks = audioAttachments.Select(a => audios.FirstOrDefault(audio => audio.Id == a.Id.ToString())).Where(a => a != null).ToList();\n                        result.AddRange(tracks);\n                        //var post = new AudioPost();\n                        //post.Id = vkNewsEntry.Id;\n                        //post.Text = vkNewsEntry.Text;\n                        //if (!string.IsNullOrEmpty(post.Text))\n                        //{\n                        //    var regex = new Regex(@\"\\[.*?\\]\", RegexOptions.Singleline);\n                        //    var matches = regex.Matches(post.Text);\n\n                        //    foreach (Match match in matches)\n                        //    {\n                        //        if (!match.Value.Contains(\"|\"))\n                        //            continue;\n\n                        //        var title = match.Value.Substring(match.Value.IndexOf(\"|\") + 1,\n                        //                                          match.Value.Length - match.Value.IndexOf(\"|\") - 2);\n                        //        post.Text = post.Text.Replace(match.Value, title);\n                        //    }\n                        //}\n\n                        //post.Audios = audioAttachments.Select(a => audios.FirstOrDefault(audio => audio.Id == a.Id)).ToList();\n                        //post.Author = new VkProfile()\n                        //{\n                        //    FirstName = vkNewsEntry.Author.Name,\n                        //};\n                        //post.Date = vkNewsEntry.Date;\n                        //result.Add(post);\n                    }\n\n                    return new NewsItemsResponse<Audio>(result) { NextFrom = vkNews.NextFrom };\n                }\n            }\n            catch (VkAccessDeniedException ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            return null;\n        }\n\n        public static async Task<List<Audio>> GetWallAudio(int count, int offset, long userId = 0, CancellationToken token = default(CancellationToken))\n        {\n            try\n            {\n                var vkWallResult = await _vkontakte.Wall.Get(userId, \"all\", count, offset);\n                if (token != CancellationToken.None && token.IsCancellationRequested)\n                    return null;\n\n                if (vkWallResult.TotalCount < offset)\n                    return null;\n\n                var vkWallPosts = vkWallResult.Items;\n\n                if (vkWallPosts != null)\n                {\n                    var audioIds = new List<string>();\n\n                    foreach (var vkwallPost in vkWallPosts)\n                    {\n                        var attachments = vkwallPost.Attachments;\n                        if ((vkwallPost.Attachments == null || vkwallPost.Attachments.Count == 0) && (vkwallPost.CopyHistory != null && vkwallPost.CopyHistory.Count > 0))\n                        {\n                            attachments = vkwallPost.CopyHistory.Last().Attachments;\n                        }\n\n                        if (attachments != null)\n                        {\n                            var audioEntries = (from a in attachments\n                                                where a is VkAudioAttachment\n                                                select a.OwnerId + \"_\" + a.Id).ToList();\n                            if (audioEntries.Any())\n                                audioIds.AddRange(audioEntries);\n                        }\n                    }\n\n                    var vkAudios = new List<VkLib.Core.Audio.VkAudio>();\n                    if (audioIds.Count >= 100)\n                    {\n                        //если аудиозаписей больше 100, разбиваем на несколько запросов по 100 аудиозаписей\n                        int i = 0, j = 99;\n                        while (i + j < audioIds.Count)\n                        {\n                            if (token != CancellationToken.None && token.IsCancellationRequested)\n                                return null;\n\n                            vkAudios.AddRange(await _vkontakte.Audio.GetById(audioIds.GetRange(i, j)));\n\n                            i += 100;\n                            if (j >= audioIds.Count)\n                                j = audioIds.Count;\n                        }\n                    }\n                    else if (audioIds.Count > 0)\n                    {\n                        if (token != CancellationToken.None && token.IsCancellationRequested)\n                        {\n                            Debug.WriteLine(\"News audio cancelled\");\n                            return null;\n                        }\n\n                        var a = await _vkontakte.Audio.GetById(audioIds);\n                        if (a != null)\n                            vkAudios.AddRange(a);\n                    }\n\n                    var audios = from a in vkAudios select a.ToAudio();\n\n                    var result = new List<Audio>();\n\n                    foreach (var vkWallPost in vkWallPosts)\n                    {\n                        var attachments = vkWallPost.Attachments;\n                        if ((vkWallPost.Attachments == null || vkWallPost.Attachments.Count == 0) && (vkWallPost.CopyHistory != null && vkWallPost.CopyHistory.Count > 0))\n                        {\n                            attachments = vkWallPost.CopyHistory.Last().Attachments;\n                        }\n\n                        if (attachments == null)\n                            continue;\n\n                        var audioAttachments = attachments.Where(a => a is VkAudioAttachment).ToList();\n                        if (!audioAttachments.Any())\n                            continue;\n\n                        var tracks = audioAttachments.Select(a => audios.FirstOrDefault(audio => audio.Id == a.Id.ToString())).Where(a => a != null).ToList();\n                        result.AddRange(tracks);\n                        //var post = new AudioPost();\n                        //post.Id = vkWallPost.Id.ToString();\n                        //post.Text = vkWallPost.Text;\n                        //if (!string.IsNullOrEmpty(post.Text))\n                        //{\n                        //    var regex = new Regex(@\"\\[.*?\\]\", RegexOptions.Singleline);\n                        //    var matches = regex.Matches(post.Text);\n\n                        //    foreach (Match match in matches)\n                        //    {\n                        //        if (!match.Value.Contains(\"|\"))\n                        //            continue;\n\n                        //        var title = match.Value.Substring(match.Value.IndexOf(\"|\") + 1,\n                        //                                          match.Value.Length - match.Value.IndexOf(\"|\") - 2);\n                        //        post.Text = post.Text.Replace(match.Value, title);\n                        //    }\n                        //}\n\n                        //post.Image = vkWallPost.Attachments.Select(a =>\n                        //{\n                        //    if (a is VkPhotoAttachment)\n                        //        return new Uri(((VkPhotoAttachment)a).SourceBig);\n                        //    return null;\n                        //}).FirstOrDefault();\n                        //post.Audios = audioAttachments.Select(a => audios.FirstOrDefault(audio => audio.Id == a.Id.ToString())).ToList();\n                        //post.Author = new UserProfile()\n                        //{\n                        //    FirstName = vkWallPost.Author.Name,\n                        //    PhotoUri = vkWallPost.Author.Photo.ToUri()\n                        //};\n                        //post.Date = vkWallPost.Date;\n                        //result.Add(post);\n                    }\n\n                    return result;\n                }\n            }\n            catch (VkAccessDeniedException ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            return null;\n        }\n\n        public static async Task<List<Audio>> GetFavoritesAudio(int count, int offset, long userId = 0, CancellationToken token = default(CancellationToken))\n        {\n            try\n            {\n                var vkWallResult = await _vkontakte.Favorites.GetPosts(count, offset);\n                if (token != CancellationToken.None && token.IsCancellationRequested)\n                    return null;\n\n                if (vkWallResult.TotalCount < offset)\n                    return null;\n\n                var vkWallPosts = vkWallResult.Items;\n\n                if (vkWallPosts != null)\n                {\n                    var audioIds = new List<string>();\n\n                    foreach (var vkwallPost in vkWallPosts)\n                    {\n                        if (vkwallPost.Attachments != null)\n                        {\n                            var audioEntries = (from a in vkwallPost.Attachments\n                                                where a is VkAudioAttachment\n                                                select a.OwnerId + \"_\" + a.Id).ToList();\n                            if (audioEntries.Any())\n                                audioIds.AddRange(audioEntries);\n                        }\n                    }\n\n                    var vkAudios = new List<VkLib.Core.Audio.VkAudio>();\n                    if (audioIds.Count >= 100)\n                    {\n                        //если аудиозаписей больше 100, разбиваем на несколько запросов по 100 аудиозаписей\n                        int i = 0, j = 99;\n                        while (i + j < audioIds.Count)\n                        {\n                            if (token != CancellationToken.None && token.IsCancellationRequested)\n                                return null;\n\n                            vkAudios.AddRange(await _vkontakte.Audio.GetById(audioIds.GetRange(i, j)));\n\n                            i += 100;\n                            if (j >= audioIds.Count)\n                                j = audioIds.Count;\n                        }\n                    }\n                    else if (audioIds.Count > 0)\n                    {\n                        if (token != CancellationToken.None && token.IsCancellationRequested)\n                        {\n                            Debug.WriteLine(\"Favorites audio cancelled\");\n                            return null;\n                        }\n\n                        var a = await _vkontakte.Audio.GetById(audioIds);\n                        if (a != null)\n                            vkAudios.AddRange(a);\n                    }\n\n                    var audios = from a in vkAudios select a.ToAudio();\n\n                    var result = new List<Audio>();\n\n                    foreach (var vkWallPost in vkWallPosts)\n                    {\n                        if (vkWallPost.Attachments == null)\n                            continue;\n\n                        var audioAttachments = vkWallPost.Attachments.Where(a => a is VkAudioAttachment).ToList();\n                        if (!audioAttachments.Any())\n                            continue;\n\n                        var tracks = audioAttachments.Select(a => audios.FirstOrDefault(audio => audio.Id == a.Id.ToString())).Where(a => a != null).ToList();\n                        result.AddRange(tracks);\n                        //var post = new AudioPost();\n                        //post.Id = vkWallPost.Id.ToString();\n                        //post.Text = vkWallPost.Text;\n                        //if (!string.IsNullOrEmpty(post.Text))\n                        //{\n                        //    var regex = new Regex(@\"\\[.*?\\]\", RegexOptions.Singleline);\n                        //    var matches = regex.Matches(post.Text);\n\n                        //    foreach (Match match in matches)\n                        //    {\n                        //        if (!match.Value.Contains(\"|\"))\n                        //            continue;\n\n                        //        var title = match.Value.Substring(match.Value.IndexOf(\"|\") + 1,\n                        //                                          match.Value.Length - match.Value.IndexOf(\"|\") - 2);\n                        //        post.Text = post.Text.Replace(match.Value, title);\n                        //    }\n                        //}\n\n                        //post.Image = vkWallPost.Attachments.Select(a =>\n                        //{\n                        //    if (a is VkPhotoAttachment)\n                        //        return new Uri(((VkPhotoAttachment)a).SourceBig);\n                        //    return null;\n                        //}).FirstOrDefault();\n                        //post.Audios = audioAttachments.Select(a => audios.FirstOrDefault(audio => audio.Id == a.Id.ToString())).ToList();\n                        //post.Author = new UserProfile()\n                        //{\n                        //    FirstName = vkWallPost.Author.Name,\n                        //    PhotoUri = vkWallPost.Author.Photo.ToUri()\n                        //};\n                        //post.Date = vkWallPost.Date;\n                        //result.Add(post);\n                    }\n\n                    return result;\n                }\n            }\n            catch (VkAccessDeniedException ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            return null;\n        }\n\n        public static async Task<bool> SetMusicStatus(VkAudio audio, List<long> targetIds = null)\n        {\n            if (audio == null)\n                return false;\n\n            var result = await _vkontakte.Audio.SetBroadcast(long.Parse(audio.Id), audio.OwnerId, targetIds);\n\n            return result != null;\n        }\n\n        public static async Task<bool> AddAudio(VkAudio audio, string captchaSid = null, string captchaKey = null)\n        {\n            if (string.IsNullOrEmpty(audio.Source))\n            {\n                var vkAudio = await GetAudioByArtistAndTitle(audio.Artist, audio.Title);\n                if (vkAudio != null)\n                {\n                    audio.Id = vkAudio.Id;\n                    audio.Artist = vkAudio.Artist;\n                    audio.Title = vkAudio.Title;\n                    audio.Source = vkAudio.Source;\n                    audio.OwnerId = vkAudio.OwnerId;\n                    audio.AlbumId = vkAudio.AlbumId;\n                    audio.LyricsId = vkAudio.LyricsId;\n                }\n            }\n\n            var newId = await _vkontakte.Audio.Add(long.Parse(audio.Id), audio.OwnerId, captchaSid: captchaSid, captchaKey: captchaKey);\n            if (newId > 0)\n            {\n                audio.Id = newId.ToString();\n                audio.OwnerId = _vkontakte.AccessToken.UserId;\n                audio.IsAddedByCurrentUser = true;\n                return true;\n            }\n            return false;\n        }\n\n        public static async Task<bool> RemoveAudio(VkAudio audio)\n        {\n            var result = await _vkontakte.Audio.Delete(long.Parse(audio.Id), audio.OwnerId);\n            if (result)\n            {\n                audio.IsAddedByCurrentUser = false;\n            }\n\n            return result;\n        }\n\n        public static async Task<string> GetLyrics(string lyricsId)\n        {\n            var result = await _vkontakte.Audio.GetLyrics(long.Parse(lyricsId));\n            return result;\n        }\n\n        public static async Task<string> EditAudio(string audioId, string ownerId, string title, string artist, string lyrics = null)\n        {\n            var lyricsId = await _vkontakte.Audio.Edit(long.Parse(ownerId), long.Parse(audioId), artist, title, lyrics);\n            return lyricsId.ToString();\n        }\n\n        public static async Task<bool> UpdateNowPlaying(Audio audio)\n        {\n            await _lastFm.Track.UpdateNowPlaying(audio.Artist, audio.Title, null, (int)audio.Duration.TotalSeconds);\n            return true;\n        }\n\n        public static async Task<bool> Scrobble(Audio audio)\n        {\n            var time = (int)DateTimeConverter.ToUnixTime(DateTime.Now);\n\n            await _lastFm.Track.Scrobble(audio.Artist, audio.Title, time.ToString(), null, (int)audio.Duration.TotalSeconds);\n            return true;\n        }\n\n        public static Task<List<AudioArtist>> GetArtistsFromTracks(IEnumerable<Audio> tracks, CancellationToken token)\n        {\n            return Task.Run(() =>\n            {\n                var artists = new Dictionary<string, AudioArtist>();\n\n                foreach (var track in tracks)\n                {\n                    if (token.IsCancellationRequested)\n                        break;\n\n                    //parse artist\n\n                    var artistName = track.Artist;\n                    var artistId = Md5Helper.Md5(artistName.ToLowerInvariant()); //artistid = md5(artistName)\n                    if (!artists.ContainsKey(artistId))\n                    {\n                        var artist = new AudioArtist();\n                        artist.Id = artistId;\n                        artist.Title = artistName;\n                        artists.Add(artistId, artist);\n                    }\n\n                    artists[artistId].Tracks.Add(track);\n                }\n\n                return artists.Values.OrderBy(a => a.Title).ToList();\n            });\n        }\n\n        public static async Task CopyAlbum(string title, long albumId, long ownerId)\n        {\n            var newAlbumId = await ViewModelLocator.Vkontakte.Audio.AddAlbum(title);\n\n            var audio = await GetUserTracks(albumId: albumId, ownerId: ownerId);\n            if (audio.Items != null && audio.Items.Count > 0)\n            {\n\n                NotificationService.NotifyProgressStarted(MainResources.NotificationSaving);\n                int progressStep = (int)(100.0f / audio.Items.Count);\n\n\n                bool captchaNeeded = false;\n                string captchaImg = string.Empty;\n                string captchaSid = string.Empty;\n                string captchaKey = string.Empty;\n\n                var audioIds = new List<long>();\n\n                int count = 0;\n                audio.Items.Reverse();\n                for (int i = 0; i < audio.Items.Count; i++)\n                {\n                    var track = audio.Items[i];\n\n                    if (count > 1)\n                    {\n                        count = 0;\n                        await Task.Delay(1000); //не больше 2-х запросов в секунду\n                    }\n\n                    try\n                    {\n                        var newAudioId = await ViewModelLocator.Vkontakte.Audio.Add(long.Parse(track.Id), track.OwnerId, captchaSid: captchaSid, captchaKey: captchaKey);\n                        audioIds.Add(newAudioId);\n\n                        captchaNeeded = false;\n                        captchaKey = null;\n                        captchaSid = null;\n                    }\n                    catch (VkCaptchaNeededException ex)\n                    {\n                        captchaNeeded = true;\n                        captchaImg = ex.CaptchaImg;\n                        captchaSid = ex.CaptchaSid;\n                    }\n\n                    if (captchaNeeded)\n                    {\n                        var flyout = new FlyoutControl();\n                        flyout.FlyoutContent = new CaptchaRequestView(captchaSid, captchaImg);\n                        var result = await flyout.ShowAsync();\n                        if (!string.IsNullOrEmpty((string)result))\n                        {\n                            captchaKey = (string)result;\n                            i = i - 1;\n                            continue;\n                        }\n                        else\n                        {\n                            NotificationService.NotifyProgressFinished();\n                            return;\n                        }\n                    }\n\n                    count++;\n\n                    NotificationService.NotifyProgressChanged(progressStep);\n                }\n\n                await ViewModelLocator.Vkontakte.Audio.MoveToAlbum(newAlbumId, audioIds);\n\n                NotificationService.NotifyProgressFinished(MainResources.NotificationSaved);\n            }\n        }\n\n        private static IEnumerable<VkAudio> RemoveCorruptedTracks(IEnumerable<VkAudio> source)\n        {\n            return source.Where(x => x.Source != string.Empty);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/HostService.cs",
    "content": "﻿using Meridian.ViewModel;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nnamespace Meridian.Services\n{\n    public class HostService\n    {\n        public static async Task Update()\n        {\n            try\n            {\n                LoggingService.Log(\"Getting host info from server.\");\n\n                var httpClient = new HttpClient();\n                var hostString = await httpClient.GetStringAsync(\"http://meridianvk.com/host.js\");\n\n                LoggingService.Log(\"Got host info: \" + hostString);\n\n                var host = JObject.Parse(hostString);\n                var clientId = host[\"clientId\"].Value<string>();\n                var clientSecret = host[\"clientSecret\"].Value<string>();\n                var userAgent = host[\"userAgent\"].Value<string>();\n\n                var p = host[\"params\"];\n\n                ViewModelLocator.Vkontakte.AppId = clientId;\n                ViewModelLocator.Vkontakte.ClientSecret = clientSecret;\n                ViewModelLocator.Vkontakte.UserAgent = userAgent;\n                ViewModelLocator.Vkontakte.LoginParams = JsonConvert.DeserializeObject<Dictionary<string,string>>(p.ToString());\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/LoggingService.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing Yandex.Metrica;\n\nnamespace Meridian.Services\n{\n    \n    public static class LoggingService\n    {\n        private static readonly NLog.Logger _logger = NLog.LogManager.GetLogger(\"logger\");\n\n        public static void Log(string message)\n        {\n            Debug.WriteLine(message);\n\n            _logger.Info(message);\n        }\n\n        public static void Log(Exception ex)\n        {\n            Debug.WriteLine(ex);\n\n            _logger.Error(ex);\n\n            YandexMetrica.ReportError(\"Exception\", ex);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/Media/AudioService.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Media;\nusing System.Windows.Threading;\nusing GalaSoft.MvvmLight.Messaging;\nusing Meridian.Controls;\nusing Meridian.Domain;\nusing Meridian.Extensions;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services.Media.Core;\nusing Meridian.View.Flyouts;\nusing Meridian.ViewModel.Messages;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\n\nnamespace Meridian.Services\n{\n    public static class AudioService\n    {\n        //private static MediaElement _mediaPlayerBase;\n        private static MediaPlayerBase _mediaPlayer;\n        private static IList<Audio> _originalPlaylist;\n        private static ObservableCollection<Audio> _playlist;\n        private static Audio _currentAudio;\n        private static readonly DispatcherTimer _positionTimer;\n        private static PlayerPlayState _state;\n        private static int _playFailsCount;\n        private static CancellationTokenSource _cancellationToken = new CancellationTokenSource();\n\n        private static MediaPlayerBase MediaPlayer\n        {\n            get\n            {\n                if (_mediaPlayer == null)\n                {\n\n                    switch (Settings.Instance.MediaEngine)\n                    {\n                        case MediaEngine.Wmp:\n                            _mediaPlayer = new WmpMediaPlayer();\n                            break;\n                        case MediaEngine.Uwp:\n                            _mediaPlayer = new UwpMediaPlayer();\n                            break;\n\n                        case MediaEngine.NAudio:\n                            _mediaPlayer = new NaudioMediaPlayer();\n                            break;\n                    }\n\n                    _mediaPlayer.Initialize();\n                    _mediaPlayer.MediaEnded += MediaPlayerOnMediaEnded;\n                    _mediaPlayer.MediaFailed += MediaPlayerOnMediaFailed;\n                    _mediaPlayer.MediaOpened += MediaPlayerOnMediaOpened;\n                    _mediaPlayer.Volume = Volume;\n                }\n\n                return _mediaPlayer;\n            }\n        }\n\n        private static PlayerPlayState State\n        {\n            get { return _state; }\n            set\n            {\n                if (_state == value)\n                    return;\n\n                _state = value;\n\n                if (_state == PlayerPlayState.Playing)\n                    _positionTimer.Start();\n                else\n                    _positionTimer.Stop();\n\n                _mediaPlayer.UpdateTransportControls(CurrentAudio);\n\n                Messenger.Default.Send(new PlayStateChangedMessage() { NewState = value });\n            }\n        }\n\n        public static Audio CurrentAudio\n        {\n            get\n            {\n                return _currentAudio;\n            }\n            set\n            {\n                var old = _currentAudio;\n                _currentAudio = value;\n\n                NotifyAudioChanged(old);\n                _mediaPlayer.UpdateTransportControls(value);\n            }\n        }\n\n        public static ObservableCollection<Audio> Playlist\n        {\n            get { return _playlist; }\n            set\n            {\n                if (Shuffle)\n                {\n                    _originalPlaylist = value.ToList(); //save original playlist\n                    _playlist = value;\n                    _playlist.Shuffle();\n                }\n                else\n                {\n                    _originalPlaylist = value;\n                    _playlist = value;\n                }\n            }\n        }\n\n        public static bool Shuffle\n        {\n            get { return Settings.Instance.Shuffle; }\n            set\n            {\n                Settings.Instance.Shuffle = value;\n\n                if (value)\n                {\n                    _playlist = new ObservableCollection<Audio>(_originalPlaylist.ToList()); //copy original playlist to current\n                    _playlist.Shuffle(); //shuffle\n                }\n                else\n                {\n                    _playlist = new ObservableCollection<Audio>(_originalPlaylist);\n                }\n            }\n        }\n\n        public static bool Repeat\n        {\n            get { return Settings.Instance.Repeat; }\n            set\n            {\n                Settings.Instance.Repeat = value;\n            }\n        }\n\n        public static bool IsPlaying\n        {\n            get\n            {\n                return State == PlayerPlayState.Playing;\n            }\n        }\n\n        public static TimeSpan CurrentAudioPosition\n        {\n            get\n            {\n                if (MediaPlayer == null)\n                    return TimeSpan.Zero;\n\n                return MediaPlayer.Position;\n            }\n            set\n            {\n                if (MediaPlayer == null)\n                    return;\n\n                if (MediaPlayer.Position.TotalSeconds == value.TotalSeconds)\n                    return;\n\n                MediaPlayer.Position = value;\n            }\n        }\n\n        public static TimeSpan CurrentAudioDuration\n        {\n            get\n            {\n                if (MediaPlayer != null)\n                    return MediaPlayer.Duration;\n\n                return TimeSpan.Zero;\n            }\n        }\n\n        public static float Volume\n        {\n            get { return Settings.Instance.Volume; }\n            set\n            {\n                if (Settings.Instance.Volume == value)\n                    return;\n\n                Settings.Instance.Volume = value.Clamp(0f, 1f);\n                MediaPlayer.Volume = Settings.Instance.Volume;\n            }\n        }\n\n        static AudioService()\n        {\n            _positionTimer = new DispatcherTimer();\n            _positionTimer.Interval = TimeSpan.FromMilliseconds(500);\n            _positionTimer.Tick += PositionTimerTick;\n            if (IsPlaying)\n                _positionTimer.Start();\n        }\n\n        public static void Play(Audio track)\n        {\n            CancelAsync();\n            PlayInternal(track, _cancellationToken.Token);\n        }\n\n        private async static void PlayInternal(Audio track, CancellationToken token)\n        {\n            if (CurrentAudio != null)\n            {\n                CurrentAudio.IsPlaying = false;\n\n                Stop();\n            }\n\n            track.IsPlaying = true;\n\n            CurrentAudio = track;\n\n            if (track.Source == null)\n            {\n                VkAudio vkAudio = null;\n                try\n                {\n                    vkAudio = await DataService.GetAudioByArtistAndTitle(track.Artist, track.Title);\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n\n                if (vkAudio != null)\n                {\n                    vkAudio.IsPlaying = true;\n                    if (_playlist != null)\n                    {\n                        var playlistTrackIndex = _playlist.IndexOf(track);\n                        if (playlistTrackIndex >= 0)\n                        {\n                            var playlistTrack = (VkAudio)_playlist[_playlist.IndexOf(track)];\n                            playlistTrack.Id = vkAudio.Id;\n                            playlistTrack.Source = vkAudio.Source;\n                            playlistTrack.OwnerId = vkAudio.OwnerId;\n                            playlistTrack.IsAddedByCurrentUser = vkAudio.IsAddedByCurrentUser;\n                            playlistTrack.AlbumId = vkAudio.AlbumId;\n                            playlistTrack.Title = vkAudio.Title;\n                            playlistTrack.Artist = vkAudio.Artist;\n                            playlistTrack.Duration = vkAudio.Duration;\n                            playlistTrack.GenreId = vkAudio.GenreId;\n                            playlistTrack.LyricsId = vkAudio.LyricsId;\n                            //_playlist[_playlist.IndexOf(track)] = vkAudio; //to fix radio vk scrobbling\n                        }\n                    }\n\n                    track = vkAudio;\n                    //_currentAudio = track;\n                    _playFailsCount = 0;\n                }\n                else\n                {\n                    LoggingService.Log(\"Failed to find audio \" + track.Artist + \" - \" + track.Title);\n\n                    _playFailsCount++;\n                    if (_playFailsCount > 5)\n                        return;\n                    \n                    Next();\n\n                    return;\n                }\n            }\n\n#if DEBUG\n            LoggingService.Log(string.Format(\"Playing: {0} {1} {2} {3}\", track.Id, track.Artist, track.Title, track.Source));\n#endif\n\n            if (token.IsCancellationRequested)\n                return;\n\n            track.IsPlaying = true;\n\n            //look like MediaElement doen't work with https, temporary hack\n            var url = track.Source;\n            if (!string.IsNullOrEmpty(url))\n            {\n                if (!Settings.Instance.UseHttps)\n                    url = url.Replace(\"https://\", \"http://\");\n\n                MediaPlayer.Source = new Uri(url);\n                MediaPlayer.Play();\n\n                State = PlayerPlayState.Playing;\n            }\n        }\n\n        public static void Play()\n        {\n            if (MediaPlayer.Source == null && CurrentAudio != null)\n            {\n                Play(CurrentAudio);\n                //MediaPlayer.Source = new Uri(CurrentAudio.Source);\n                //CurrentAudio.IsPlaying = true;\n            }\n\n            MediaPlayer.Play();\n\n            State = PlayerPlayState.Playing;\n\n            //MediaPlayerBase.Position = CurrentAudioPosition;\n        }\n\n        public static void PlayNext(Audio audio)\n        {\n            if (Playlist != null && CurrentAudio != null)\n            {\n                var currentAudio = Playlist.FirstOrDefault(a => a.Id == CurrentAudio.Id);\n                if (currentAudio == null)\n                    return;\n\n                var index = Playlist.IndexOf(currentAudio);\n                if (index >= 0)\n                {\n                    index++;\n                    var newAudio = audio.Clone();\n                    Playlist.Insert(index, newAudio);\n                }\n            }\n        }\n\n        public static void Pause()\n        {\n            MediaPlayer.Pause();\n\n            State = PlayerPlayState.Paused;\n        }\n\n        public static void Stop()\n        {\n            MediaPlayer.Stop();\n\n            State = PlayerPlayState.Stopped;\n        }\n\n        public static void FastForward(int step)\n        {\n            if (CurrentAudioPosition.TotalSeconds + step < CurrentAudio.Duration.TotalSeconds)\n                CurrentAudioPosition += TimeSpan.FromSeconds(step);\n            else\n                SwitchNext();\n        }\n\n        public static void Rewind(int step)\n        {\n            if (CurrentAudioPosition.TotalSeconds - step > 0)\n                CurrentAudioPosition -= TimeSpan.FromSeconds(step);\n            else\n                CurrentAudioPosition = TimeSpan.Zero;\n        }\n\n        /// <summary>\n        /// Перейти к следующему треку. Обычно вызывается при нажатии пользователем кнопки Next.\n        /// </summary>\n        public static void SkipNext()\n        {\n            //если прошло больше 1/3 трека, считаем, что трек послушали полностью\n            if (CurrentAudioPosition.TotalSeconds > CurrentAudioDuration.TotalSeconds / 3)\n                SwitchNext();\n            else\n                Next(true);\n        }\n\n        /// <summary>\n        /// Переключиться на следующий трек. Обычно вызывается автоматически при окончании текущего трека.\n        /// </summary>\n        public static void SwitchNext()\n        {\n            Next();\n        }\n\n        private static void Next(bool invokedByUser = false)\n        {\n            if (Repeat && !invokedByUser)\n            {\n                //\n                Play(CurrentAudio);\n                NotifyAudioChanged(CurrentAudio); //to scrobble repeating track\n                return;\n            }\n\n\n            if (_playlist != null && _playlist.Count > 0)\n            {\n                int currentIndex = -1;\n                if (_currentAudio != null)\n                {\n                    currentIndex = _playlist.IndexOf(_currentAudio);\n                    if (currentIndex == -1)\n                    {\n                        var current = _playlist.FirstOrDefault(a => a.Id == _currentAudio.Id);\n                        if (current != null)\n                            currentIndex = _playlist.IndexOf(current);\n                    }\n                }\n\n                currentIndex++;\n\n                if (currentIndex >= _playlist.Count)\n                {\n                    currentIndex = 0;\n                }\n\n                Play(_playlist[currentIndex]);\n            }\n        }\n\n        public static void Prev()\n        {\n            if (CurrentAudioPosition.TotalSeconds > 3)\n            {\n                CurrentAudioPosition = TimeSpan.Zero;\n                return;\n            }\n\n            if (_playlist != null)\n            {\n                int currentIndex = -1;\n                if (_currentAudio != null)\n                {\n                    var current = _playlist.FirstOrDefault(a => a.Id == _currentAudio.Id);\n                    if (current != null)\n                        currentIndex = _playlist.IndexOf(current);\n                }\n\n                currentIndex--;\n\n                if (currentIndex >= 0)\n                    Play(_playlist[currentIndex]);\n            }\n        }\n\n        public static void SetCurrentPlaylist(IEnumerable<Audio> playlist, bool radio = false)\n        {\n            if (playlist == null)\n            {\n                Playlist?.Clear();\n            }\n            else\n                Playlist = new ObservableCollection<Audio>(playlist);\n        }\n\n        public static Task Load()\n        {\n            return Task.Run(() =>\n            {\n                try\n                {\n                    if (!File.Exists(\"currentPlaylist.js\"))\n                        return;\n\n                    var json = File.ReadAllText(\"currentPlaylist.js\");\n                    if (string.IsNullOrEmpty(json))\n                        return;\n\n                    var o = JObject.Parse(json);\n                    if (o[\"currentAudio\"] != null)\n                    {\n                        var audio = JsonConvert.DeserializeObject<Audio>(o[\"currentAudio\"].ToString(), new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Objects });\n                        Application.Current.Dispatcher.Invoke(() => \n                        { \n                            CurrentAudio = audio;\n                            _mediaPlayer.UpdateTransportControls(CurrentAudio);\n                        });\n                    }\n\n                    if (o[\"currentPlaylist\"] != null)\n                    {\n                        var playlist = JsonConvert.DeserializeObject<List<object>>(o[\"currentPlaylist\"].ToString(), new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Objects });\n                        if (playlist != null)\n                            Application.Current.Dispatcher.Invoke(() => SetCurrentPlaylist(playlist.OfType<Audio>()));\n                    }\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n            });\n        }\n\n        public static void Save()\n        {\n            try\n            {\n                var o = new\n                {\n                    currentAudio = CurrentAudio,\n                    currentPlaylist = Playlist\n                };\n\n                var json = JsonConvert.SerializeObject(o, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Objects });\n                File.WriteAllText(\"currentPlaylist.js\", json);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        public static void Clear()\n        {\n            try\n            {\n                if (File.Exists(\"currentPlaylist.js\"))\n                    File.Delete(\"currentPlaylist.js\");\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        public static void Dispose()\n        {\n            _positionTimer.Stop();\n            _mediaPlayer.Dispose();\n        }\n\n        private static void NotifyAudioChanged(Audio oldAudio = null)\n        {\n            Messenger.Default.Send(new CurrentAudioChangedMessage\n            {\n                OldAudio = oldAudio,\n                NewAudio = CurrentAudio\n            });\n        }\n\n        private static void PositionTimerTick(object sender, object e)\n        {\n            try\n            {\n                Messenger.Default.Send(new PlayerPositionChangedMessage() { NewPosition = MediaPlayer.Position });\n\n                //possible fix for not switching tracks issue\n                if (MediaPlayer.Position > CurrentAudio.Duration)\n                    MediaPlayerOnMediaEnded(MediaPlayer, EventArgs.Empty);\n            }\n            catch (Exception ex)\n            {\n\n                LoggingService.Log(ex);\n            }\n        }\n\n        private static void CancelAsync()\n        {\n            _cancellationToken.Cancel();\n            _cancellationToken = new CancellationTokenSource();\n        }\n\n        private static void MediaPlayerOnMediaOpened(object sender, EventArgs e)\n        {\n            _playFailsCount = 0;\n            State = PlayerPlayState.Playing;\n        }\n\n        private static void MediaPlayerOnMediaFailed(object sender, Exception e)\n        {\n            if (CurrentAudio != null)\n                LoggingService.Log(\"Media failed \" + CurrentAudio.Id + \" \" + CurrentAudio.Artist + \" - \" + CurrentAudio.Title + \". \" + e);\n\n            if (e is InvalidWmpVersionException)\n            {\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new CommonMessageView() { Header = ErrorResources.AudioFailedErrorHeaderCommon, Message = ErrorResources.WmpMissingError };\n                flyout.Show();\n                return;\n            }\n\n            if (e is COMException)\n            {\n                var com = (COMException)e;\n                if ((uint)com.ErrorCode == 0xC00D0035) //not found or connection problem\n                {\n                    var flyout = new FlyoutControl();\n                    flyout.FlyoutContent = new CommonMessageView() { Header = ErrorResources.AudioFailedErrorHeaderCommon, Message = ErrorResources.WmpMissingError };\n                    flyout.Show();\n\n                    return;\n                }\n            }\n\n            _playFailsCount++;\n            if (_playFailsCount < 5)\n            {\n                if (e is FileNotFoundException && CurrentAudio is VkAudio)\n                {\n                    CurrentAudio.Source = null;\n                    PlayInternal(CurrentAudio, _cancellationToken.Token);\n                }\n                else\n                {\n                    Next();\n                }\n            }\n        }\n\n        private static void MediaPlayerOnMediaEnded(object sender, EventArgs e)\n        {\n            SwitchNext();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/Media/Core/MediaPlayerBase.cs",
    "content": "﻿using System;\nusing System.Windows;\nusing System.Windows.Media;\nusing Meridian.Model;\nusing Meridian.ViewModel.Messages;\n\nnamespace Meridian.Services.Media.Core\n{\n    public enum MediaEngine\n    {\n        /// <summary>\n        /// Windows Media Player engine\n        /// </summary>\n        Wmp,\n        /// <summary>\n        /// NAudio engine\n        /// </summary>\n        NAudio,\n        /// <summary>\n        /// UWP (Win 10) media engine\n        /// </summary>\n        Uwp\n    }\n\n    public abstract class MediaPlayerBase : IDisposable\n    {\n        //fields\n        public abstract TimeSpan Position { get; set; }\n        public abstract TimeSpan Duration { get; }\n        public abstract Uri Source { get; set; }\n        public abstract double Volume { get; set; }\n\n        //events\n        public EventHandler MediaOpened;\n        public EventHandler MediaEnded;\n        public EventHandler<Exception> MediaFailed; \n\n        //methods\n        public abstract void Initialize();\n        public abstract void Play();\n        public abstract void Pause();\n        public abstract void Stop();\n\n        public virtual void UpdateTransportControls(Audio currentTrack)\n        {\n\n        }\n\n        public abstract void Dispose();\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/Media/Core/NaudioMediaPlayer.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Drawing.Printing;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing NAudio.Wave;\n\nnamespace Meridian.Services.Media.Core\n{\n    /// <summary>\n    /// NAudio Media Player implementation\n    /// </summary>\n    public class NaudioMediaPlayer : MediaPlayerBase\n    {\n        private IWavePlayer _wavePlayer;\n        private WaveStream _outputStream;\n        private WaveChannel32 _volumeStream;\n        private bool _initialized;\n        private Uri _source;\n        private TimeSpan _duration;\n        private double _volume;\n        private AutoResetEvent _initSourceEvent = new AutoResetEvent(false);\n\n        public override TimeSpan Position\n        {\n            get\n            {\n                if (_outputStream == null)\n                    return TimeSpan.Zero;\n\n                var currentPos = _outputStream.CurrentTime;\n                //if (Math.Round(currentPos.TotalSeconds, 1) >= Math.Round(_duration.TotalSeconds, 1))\n                //    SwitchNext();\n\n                return TimeSpan.FromSeconds(Math.Min(Duration.TotalSeconds, currentPos.TotalSeconds));\n            }\n            set\n            {\n                if (_outputStream != null)\n                    _outputStream.CurrentTime = value;\n            }\n        }\n\n        public override TimeSpan Duration\n        {\n            get { return _duration; }\n        }\n\n        public override Uri Source\n        {\n            get { return _source; }\n            set\n            {\n                if (_source == value)\n                    Stop();\n\n                _source = value;\n\n                InitSource();\n            }\n        }\n\n        public override double Volume\n        {\n            get\n            {\n                return _volume;\n            }\n            set\n            {\n                if (_volume == value)\n                    return;\n\n                _volume = value;\n\n                if (_volumeStream != null)\n                    _volumeStream.Volume = (float)value;\n            }\n        }\n\n        public override void Initialize()\n        {\n            _wavePlayer = new WaveOutEvent();\n        }\n\n        public override void Dispose()\n        {\n            try\n            {\n                _wavePlayer.Dispose();\n            }\n            catch (Exception ex)\n            {\n                Debug.WriteLine(ex);\n            }\n\n            _initSourceEvent.Dispose();\n\n            if (_volumeStream != null)\n                _volumeStream.Dispose();\n\n            if (_outputStream != null)\n                _outputStream.Dispose();\n\n        }\n\n        private void SwitchNext()\n        {\n            if (MediaEnded != null)\n                MediaEnded(this, EventArgs.Empty);\n        }\n\n        public async override void Play()\n        {\n            if (!_initialized)\n            {\n                await Task.Run(() => _initSourceEvent.WaitOne());\n            }\n            if (!_initialized)\n                return;\n\n            _wavePlayer.Play();\n        }\n\n        public override void Pause()\n        {\n            _wavePlayer.Pause();\n        }\n\n        public override void Stop()\n        {\n            _wavePlayer.Stop();\n        }\n\n        private async Task InitSource()\n        {\n            if (_outputStream != null)\n            {\n                _outputStream.Dispose();\n                _outputStream = null;\n            }\n\n            if (_volumeStream != null)\n            {\n                _volumeStream.Dispose();\n                _volumeStream = null;\n            }\n\n            _initialized = false;\n\n            if (_source == null)\n                return;\n\n            await Task.Run(() =>\n            {\n                try\n                {\n                    _outputStream = new MediaFoundationReader(_source.OriginalString);\n                    _volumeStream = new WaveChannel32(_outputStream, (float)Volume, 0);\n                    _volumeStream.PadWithZeroes = false;\n                    _wavePlayer.Init(_volumeStream);\n                    _wavePlayer.PlaybackStopped += _wavePlayer_PlaybackStopped;\n                    _duration = _outputStream.TotalTime;\n                    _initialized = true;\n                    _initSourceEvent.Set();\n\n                    if (MediaOpened != null)\n                        MediaOpened(this, EventArgs.Empty);\n                }\n                catch (Exception ex)\n                {\n                    if (MediaFailed != null)\n                        MediaFailed(this, ex);\n                }\n            });\n        }\n\n        void _wavePlayer_PlaybackStopped(object sender, StoppedEventArgs e)\n        {\n            if (_outputStream != null && _outputStream.CurrentTime.TotalSeconds > Duration.TotalSeconds / 2)\n                SwitchNext();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/Media/Core/UwpMediaPlayer.cs",
    "content": "﻿using Meridian.Model;\nusing System;\nusing Windows.Media;\nusing Windows.Media.Core;\nusing Windows.Media.Playback;\n\nnamespace Meridian.Services.Media.Core\n{\n    /// <summary>\n    /// Wrapper on UWP MediaPlayer (Win10)\n    /// </summary>\n    public class UwpMediaPlayer : MediaPlayerBase\n    {\n        private MediaPlayer _mediaPlayer;\n\n        private bool IsPlaying => \n            _mediaPlayer.PlaybackSession.PlaybackState == MediaPlaybackState.Playing\n            || _mediaPlayer.PlaybackSession.PlaybackState == MediaPlaybackState.Opening\n            || _mediaPlayer.PlaybackSession.PlaybackState == MediaPlaybackState.Buffering;\n\n        public override TimeSpan Position\n        {\n            get { return _mediaPlayer.PlaybackSession.Position; }\n            set { _mediaPlayer.PlaybackSession.Position = value; }\n        }\n\n        public override TimeSpan Duration\n        {\n            get\n            {\n                if (_mediaPlayer.PlaybackSession.NaturalDuration != null)\n                    return _mediaPlayer.PlaybackSession.NaturalDuration;\n\n                return TimeSpan.Zero;\n            }\n        }\n\n        public override Uri Source\n        {\n            get\n            { \n                return _mediaPlayer.Source as Uri;\n            }\n            set { _mediaPlayer.Source = MediaSource.CreateFromUri(value); }\n        }\n\n        public override double Volume\n        {\n            get { return _mediaPlayer.Volume; }\n            set { _mediaPlayer.Volume = value; }\n        }\n\n        public override void Initialize()\n        {\n            _mediaPlayer = new MediaPlayer();\n            _mediaPlayer.MediaEnded += MediaPlayerOnMediaEnded;\n            _mediaPlayer.MediaFailed += MediaPlayerOnMediaFailed;\n            _mediaPlayer.MediaOpened += MediaPlayerOnMediaOpened;\n        }\n\n        public override void Play()\n        {\n            _mediaPlayer.Play();\n        }\n\n        public override void Pause()\n        {\n            _mediaPlayer.Pause();\n        }\n\n        public override void Stop()\n        {\n            _mediaPlayer.Source = null;\n        }\n\n        public override void Dispose()\n        {\n            _mediaPlayer.MediaEnded -= MediaPlayerOnMediaEnded;\n            _mediaPlayer.MediaFailed -= MediaPlayerOnMediaFailed;\n            _mediaPlayer.MediaOpened -= MediaPlayerOnMediaOpened;\n\n            _mediaPlayer = null;\n        }\n\n        private void MediaPlayerOnMediaOpened(MediaPlayer sender, object e)\n        {\n            if (MediaOpened != null)\n                MediaOpened(sender, EventArgs.Empty);\n        }\n\n        private void MediaPlayerOnMediaFailed(MediaPlayer sender, MediaPlayerFailedEventArgs e)\n        {\n            if (MediaFailed != null)\n                MediaFailed(sender, new Exception(e.ErrorMessage));\n        }\n\n        private void MediaPlayerOnMediaEnded(MediaPlayer sender, object e)\n        {\n            if (MediaEnded != null)\n                MediaEnded(sender, EventArgs.Empty);\n        }\n\n        public override void UpdateTransportControls(Audio currentTrack)\n        {\n            _mediaPlayer.SystemMediaTransportControls.PlaybackStatus = IsPlaying ? MediaPlaybackStatus.Playing : MediaPlaybackStatus.Stopped;\n\n            var updater = _mediaPlayer.SystemMediaTransportControls.DisplayUpdater;\n\n            if (currentTrack != null)\n            {\n                updater.Type = MediaPlaybackType.Music;\n                updater.MusicProperties.Title = currentTrack.Title;\n                updater.MusicProperties.Artist = currentTrack.Artist;\n                updater.Update();\n            }\n            else\n            {\n                updater.ClearAll();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/Media/Core/WmpMediaPlayer.cs",
    "content": "﻿using System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Media;\nusing Meridian.Model;\nusing Meridian.ViewModel.Messages;\n\nnamespace Meridian.Services.Media.Core\n{\n    /// <summary>\n    /// Wrapper on MediaElement which uses Windows Media Player engine\n    /// </summary>\n    public class WmpMediaPlayer : MediaPlayerBase\n    {\n        private MediaPlayer _mediaPlayer;\n\n        public override TimeSpan Position\n        {\n            get { return _mediaPlayer.Position; }\n            set { _mediaPlayer.Position = value; }\n        }\n\n        public override TimeSpan Duration\n        {\n            get\n            {\n                if (_mediaPlayer.NaturalDuration != null && _mediaPlayer.NaturalDuration.HasTimeSpan)\n                    return _mediaPlayer.NaturalDuration.TimeSpan;\n\n                return TimeSpan.Zero;\n            }\n        }\n\n        public override Uri Source\n        {\n            get { return _mediaPlayer.Source; }\n            set { _mediaPlayer.Open(value); }\n        }\n\n        public override double Volume\n        {\n            get { return _mediaPlayer.Volume; }\n            set { _mediaPlayer.Volume = value; }\n        }\n\n        public override void Initialize()\n        {\n            _mediaPlayer = new MediaPlayer();\n            _mediaPlayer.MediaEnded  += MediaPlayerOnMediaEnded;\n            _mediaPlayer.MediaFailed += MediaPlayerOnMediaFailed;\n            _mediaPlayer.MediaOpened += MediaPlayerOnMediaOpened;\n        }\n\n        public override void Play()\n        {\n            _mediaPlayer.Play();\n        }\n\n        public override void Pause()\n        {\n            _mediaPlayer.Pause();\n        }\n\n        public override void Stop()\n        {\n            _mediaPlayer.Stop();\n        }\n\n        public override void Dispose()\n        {\n            _mediaPlayer.MediaEnded -= MediaPlayerOnMediaEnded;\n            _mediaPlayer.MediaFailed -= MediaPlayerOnMediaFailed;\n            _mediaPlayer.MediaOpened -= MediaPlayerOnMediaOpened;\n\n            _mediaPlayer = null;\n        }\n\n        private void MediaPlayerOnMediaOpened(object sender, EventArgs e)\n        {\n            if (MediaOpened != null)\n                MediaOpened(sender, e);\n        }\n\n        private void MediaPlayerOnMediaFailed(object sender, ExceptionEventArgs e)\n        {\n            if (MediaFailed != null)\n                MediaFailed(sender, e.ErrorException);\n        }\n\n        private void MediaPlayerOnMediaEnded(object sender, EventArgs e)\n        {\n            if (MediaEnded != null)\n                MediaEnded(sender, e);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/Music/LocalMusicService.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Meridian.Helpers;\nusing Meridian.Model;\nusing Meridian.Services.Music.Repositories;\nusing Microsoft.WindowsAPICodePack.Shell;\n\nnamespace Meridian.Services.Music\n{\n    public class LocalMusicService\n    {\n        private CancellationTokenSource _scanCancellationToken = new CancellationTokenSource();\n        private readonly LocalTracksRepository _tracksRepository;\n        private readonly LocalArtistsRepository _artistsRepository;\n        private readonly LocalAlbumsRepository _albumsRepository;\n\n        public LocalMusicService()\n        {\n            _tracksRepository = new LocalTracksRepository();\n            _artistsRepository = new LocalArtistsRepository();\n            _albumsRepository = new LocalAlbumsRepository();\n        }\n\n        public async Task ScanMusic(IProgress<double> progress)\n        {\n            LoggingService.Log(\"Music scan started\");\n\n            try\n            {\n                int count = 0;\n\n                var tracks = new List<LocalAudio>();\n\n\n                await Task.Run(async () =>\n                {\n                    var musicFiles = FilesHelper.GetMusicFiles();\n\n                    double totalCount = musicFiles.Count;\n\n                    //not cool but ¯\\_(ツ)_/¯\n\n                    var albums = new Dictionary<string, AudioAlbum>();\n                    var artists = new Dictionary<string, AudioArtist>();\n\n                    foreach (var filePath in musicFiles)\n                    {\n                        TagLib.File audioFile = null;\n\n                        try\n                        {\n                            audioFile = TagLib.File.Create(filePath);\n                        }\n                        catch (Exception ex)\n                        {\n                            LoggingService.Log(ex);\n                            continue;\n                        }\n\n                        var track = new LocalAudio();\n                        track.Id = Md5Helper.Md5(filePath);\n                        if (!string.IsNullOrEmpty(audioFile.Tag.Title))\n                            track.Title = StringHelper.ToUtf8(audioFile.Tag.Title);\n                        else\n                            track.Title = Path.GetFileNameWithoutExtension(filePath);\n\n                        var artist = audioFile.Tag.FirstPerformer;\n                        if (string.IsNullOrEmpty(artist))\n                            artist = audioFile.Tag.FirstAlbumArtist;\n\n                        track.Artist = StringHelper.ToUtf8(artist);\n                        if (!string.IsNullOrEmpty(track.Artist))\n                            track.Artist = track.Artist.Trim();\n                        else\n                            track.Artist = string.Empty;\n\n                        track.Duration = audioFile.Properties.Duration;\n                        track.Source = filePath;\n\n                        if (!string.IsNullOrWhiteSpace(audioFile.Tag.Album))\n                        {\n                            track.AlbumId = Md5Helper.Md5(track.Artist.Trim().ToLower() + \"_\" + StringHelper.ToUtf8(audioFile.Tag.Album).Trim());\n                            track.Album = StringHelper.ToUtf8(audioFile.Tag.Album).Trim();\n                            if (!albums.ContainsKey(track.AlbumId))\n                                albums.Add(track.AlbumId, new AudioAlbum() { Id = track.AlbumId, Artist = track.Artist, ArtistId = !string.IsNullOrEmpty(track.Artist) ? Md5Helper.Md5(track.Artist.Trim().ToLower()) : null, Title = StringHelper.ToUtf8(audioFile.Tag.Album), Year = (int)audioFile.Tag.Year });\n                            else\n                            {\n                                if (string.IsNullOrEmpty(albums[track.AlbumId].CoverPath) && audioFile.Tag.Pictures != null && audioFile.Tag.Pictures.Length > 0)\n                                {\n                                    albums[track.AlbumId].CoverPath = filePath;\n                                }\n                            }\n                        }\n\n                        if (!string.IsNullOrWhiteSpace(track.Artist))\n                        {\n                            track.ArtistId = Md5Helper.Md5(track.Artist.Trim().ToLower());\n                            track.Artist = track.Artist.Trim();\n                            if (!artists.ContainsKey(track.ArtistId))\n                                artists.Add(track.ArtistId, new AudioArtist() { Id = track.ArtistId, Title = track.Artist });\n                        }\n\n                        tracks.Add(track);\n\n                        count++;\n\n                        progress.Report(count / totalCount * 100);\n                        audioFile.Dispose();\n                    }\n\n                    await ServiceLocator.DataBaseService.SaveItems(tracks);\n                    await ServiceLocator.DataBaseService.SaveItems(albums.Values);\n                    await ServiceLocator.DataBaseService.SaveItems(artists.Values);\n\n                    LoggingService.Log(\"Music scan finished. Found \" + count + \" tracks; \" + albums.Count + \" albums; \" + artists.Count + \" artists\");\n\n                    tracks.Clear();\n                    albums.Clear();\n                    artists.Clear();\n\n                }, _scanCancellationToken.Token);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(\"Music scan error. \" + ex);\n            }\n        }\n\n        public void ScanMusicCancel()\n        {\n            _scanCancellationToken.Cancel();\n\n            _scanCancellationToken = new CancellationTokenSource();\n        }\n\n        public async Task<List<LocalAudio>> GetTracks()\n        {\n            return await _tracksRepository.GetTracks();\n        }\n\n        public async Task<List<LocalAudio>> GetAlbumTracks(string albumId)\n        {\n            return await ServiceLocator.DataBaseService.GetLocalAlbumTracks(albumId);\n        }\n\n        public async Task<List<AudioAlbum>> GetAlbums()\n        {\n            return await _albumsRepository.Get();\n        }\n\n        public async Task<List<AudioArtist>> GetArtists()\n        {\n            return await _artistsRepository.Get();\n        }\n\n        public async Task<List<AudioAlbum>> GetArtistAlbums(string artistId)\n        {\n            return await ServiceLocator.DataBaseService.GetLocalArtistAlbums(artistId);\n        }\n\n        public async Task<List<LocalAudio>> GetArtistUnsortedTracks(string artistId)\n        {\n            return await ServiceLocator.DataBaseService.GetLocalArtistUnsortedTracks(artistId);\n        }\n\n        public async Task<List<LocalAudio>> SearchTracks(string query)\n        {\n            //not good, but sqlite doesn't support case insensitive queries for unicode\n            var tracks = await ServiceLocator.DataBaseService.GetItems<LocalAudio>();\n\n            return await Task.Run(() =>\n            {\n                var result = tracks.Where(a => a.Title != null && a.Title.StartsWith(query, StringComparison.OrdinalIgnoreCase)).ToList();\n                result.AddRange(tracks.Where(a => a.Artist != null && a.Artist.StartsWith(query, StringComparison.OrdinalIgnoreCase)).ToList());\n                result.AddRange(tracks.Where(a => a.Album != null && a.Album.StartsWith(query, StringComparison.OrdinalIgnoreCase)).ToList());\n\n                tracks.Clear();\n                return result;\n            });\n        }\n\n        public async Task<List<AudioAlbum>> SearchAlbums(string query)\n        {\n            //not good, but sqlite doesn't support case insensitive queries for unicode\n            var albums = await ServiceLocator.DataBaseService.GetItems<AudioAlbum>();\n\n            return await Task.Run(() =>\n            {\n                var result = albums.Where(a => a.Title != null && a.Title.StartsWith(query, StringComparison.OrdinalIgnoreCase)).ToList();\n                result.AddRange(albums.Where(a => a.Artist != null && a.Artist.StartsWith(query, StringComparison.OrdinalIgnoreCase)).ToList());\n                albums.Clear();\n                return result;\n            });\n        }\n\n        public async Task<List<AudioArtist>> SearchArtists(string query)\n        {\n            //not good, but sqlite doesn't support case insensitive queries for unicode\n            var artists = await ServiceLocator.DataBaseService.GetItems<AudioArtist>();\n\n            return await Task.Run(() =>\n            {\n                var result = artists.Where(a => a.Title != null && a.Title.StartsWith(query, StringComparison.OrdinalIgnoreCase)).ToList();\n                artists.Clear();\n                return result;\n            });\n        }\n\n        public async Task Clear()\n        {\n            await ServiceLocator.DataBaseService.Clear<Audio>();\n            await ServiceLocator.DataBaseService.Clear<AudioAlbum>();\n            await ServiceLocator.DataBaseService.Clear<AudioArtist>();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/Music/Repositories/LocalAlbumsRepository.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Messaging;\nusing Meridian.Helpers;\nusing Meridian.Model;\nusing Meridian.ViewModel.Messages;\n\nnamespace Meridian.Services.Music.Repositories\n{\n    public class LocalAlbumsRepository\n    {\n        private bool _refreshed;\n\n        public LocalAlbumsRepository()\n        {\n\n        }\n\n        public async Task<List<AudioAlbum>> Get()\n        {\n            if (!_refreshed)\n            {\n                //check for updates on first time\n                _refreshed = true;\n                Refresh().ContinueWith(t =>\n                {\n                    AlbumsRepositoryUpdated(t.Result);\n                });\n            }\n\n            return await ServiceLocator.DataBaseService.GetItems<AudioAlbum>();\n        }\n\n        public async Task<Tuple<List<AudioAlbum>, List<AudioAlbum>, List<AudioAlbum>>> Refresh()\n        {\n            var localAlbums = await GetFromLibrary(); //list of local albums from file system\n\n            var cachedData = await ServiceLocator.DataBaseService.GetItems<AudioAlbum>(); //list of cached albums from database\n\n            var deleted = new List<AudioAlbum>();\n            var changed = new List<AudioAlbum>();\n            var added = new List<AudioAlbum>();\n\n            //check albums changes\n            foreach (var cachedAlbum in cachedData)\n            {\n                var associatedAlbum = localAlbums.FirstOrDefault(t => t.Id == cachedAlbum.Id);\n                if (associatedAlbum == null) //if album is cached but doesn't exists in file system it supposed to be deleted\n                {\n                    //TODO remove album mappings\n\n                    deleted.Add(cachedAlbum);\n                    continue;\n                }\n\n                //check properties changes\n                if (UpdateAlbum(cachedAlbum, associatedAlbum))\n                {\n                    //properties was changed, add album to list of changed albums\n                    changed.Add(cachedAlbum);\n                }\n            }\n\n            //looking for new albums\n            foreach (var localAlbum in localAlbums)\n            {\n                if (cachedData.Any(t => t.Id == localAlbum.Id))\n                    continue;\n\n                added.Add(localAlbum);\n            }\n\n            return new Tuple<List<AudioAlbum>, List<AudioAlbum>, List<AudioAlbum>>(deleted, changed, added);\n        }\n\n        private Task<List<AudioAlbum>> GetFromLibrary()\n        {\n            return Task.Run(async () =>\n            {\n                var musicFiles = FilesHelper.GetMusicFiles();\n\n                double totalCount = musicFiles.Count;\n\n                var albums = new Dictionary<string, AudioAlbum>();\n\n                foreach (var filePath in musicFiles)\n                {\n                    TagLib.File audioFile = null;\n\n                    try\n                    {\n                        audioFile = TagLib.File.Create(filePath);\n                    }\n                    catch (Exception ex)\n                    {\n                        LoggingService.Log(ex);\n                        continue;\n                    }\n\n                    var track = new LocalAudio();\n\n                    if (!string.IsNullOrWhiteSpace(audioFile.Tag.Album))\n                    {\n                        string artist = string.Empty;\n                        if (!string.IsNullOrEmpty(audioFile.Tag.FirstPerformer))\n                            artist = StringHelper.ToUtf8(audioFile.Tag.FirstPerformer);\n                        else if (!string.IsNullOrEmpty(audioFile.Tag.FirstAlbumArtist))\n                            artist = StringHelper.ToUtf8(audioFile.Tag.FirstAlbumArtist);\n\n                        track.AlbumId = Md5Helper.Md5(artist.Trim().ToLower() + \"_\" + StringHelper.ToUtf8(audioFile.Tag.Album).Trim());\n                        track.Album = StringHelper.ToUtf8(audioFile.Tag.Album).Trim();\n                        if (!albums.ContainsKey(track.AlbumId))\n                            albums.Add(track.AlbumId, new AudioAlbum()\n                            {\n                                Id = track.AlbumId,\n                                Artist = artist.Trim(),\n                                Title = StringHelper.ToUtf8(audioFile.Tag.Album).Trim(),\n                                Year = (int)audioFile.Tag.Year,\n                                ArtistId = Md5Helper.Md5(artist.Trim().ToLower())\n                            });\n                        else\n                        {\n                            if (string.IsNullOrEmpty(albums[track.AlbumId].CoverPath) && audioFile.Tag.Pictures != null && audioFile.Tag.Pictures.Length > 0)\n                            {\n                                albums[track.AlbumId].CoverPath = filePath;\n                            }\n                        }\n                    }\n                    audioFile.Dispose();\n\n                    await Task.Delay(50);\n                }\n\n                LoggingService.Log(\"Music scan finished. Found \" + albums.Count + \" albums\");\n\n                return albums.Values.ToList();\n            });\n        }\n\n        private bool UpdateAlbum(AudioAlbum cachedAlbum, AudioAlbum updatedAlbum)\n        {\n            bool changed = false;\n\n            if (cachedAlbum.Title != updatedAlbum.Title)\n            {\n                cachedAlbum.Title = updatedAlbum.Title;\n                changed = true;\n            }\n\n            if (cachedAlbum.Artist != updatedAlbum.Artist)\n            {\n                cachedAlbum.Artist = updatedAlbum.Artist;\n                changed = true;\n            }\n\n            if (cachedAlbum.ArtistId != updatedAlbum.ArtistId)\n            {\n                cachedAlbum.ArtistId = updatedAlbum.ArtistId;\n                changed = true;\n            }\n\n            if (cachedAlbum.CoverPath != updatedAlbum.CoverPath)\n            {\n                cachedAlbum.CoverPath = updatedAlbum.CoverPath;\n                changed = true;\n            }\n\n            if (cachedAlbum.Year != updatedAlbum.Year)\n            {\n                cachedAlbum.Year = updatedAlbum.Year;\n                changed = true;\n            }\n\n            return changed;\n        }\n\n        private async void AlbumsRepositoryUpdated(Tuple<List<AudioAlbum>, List<AudioAlbum>, List<AudioAlbum>> result)\n        {\n            var deleted = result.Item1;\n            var changed = result.Item2;\n            var added = result.Item3;\n\n            await ServiceLocator.DataBaseService.DeleteItems(deleted);\n\n            await ServiceLocator.DataBaseService.UpdateItems(changed);\n\n            await ServiceLocator.DataBaseService.SaveItems(added);\n\n            if (deleted.Count > 0 || changed.Count > 0 || added.Count > 0)\n                Messenger.Default.Send(new LocalRepositoryUpdatedMessage() { RepositoryType = typeof(AudioAlbum) });\n\n            LoggingService.Log(string.Format(\"Local albums database updated. Deleted: {0}, Changed: {1}, Added: {2}\", deleted.Count, changed.Count, added.Count));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/Music/Repositories/LocalArtistsRepository.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Messaging;\nusing Meridian.Helpers;\nusing Meridian.Model;\nusing Meridian.ViewModel.Messages;\n\nnamespace Meridian.Services.Music.Repositories\n{\n    public class LocalArtistsRepository\n    {\n        private bool _refreshed;\n\n        public LocalArtistsRepository()\n        {\n\n        }\n\n        public async Task<List<AudioArtist>> Get()\n        {\n            if (!_refreshed)\n            {\n                //check for updates on first time\n                _refreshed = true;\n                Refresh().ContinueWith(t =>\n                {\n                    ArtistsRepositoryUpdated(t.Result);\n                });\n            }\n\n            return await ServiceLocator.DataBaseService.GetItems<AudioArtist>();\n        }\n\n        public async Task<Tuple<List<AudioArtist>, List<AudioArtist>, List<AudioArtist>>> Refresh()\n        {\n            var localArtists = await GetFromLibrary(); //list of local artists from file system\n\n            var cachedData = await ServiceLocator.DataBaseService.GetItems<AudioArtist>(); //list of cached artists from database\n\n            var deleted = new List<AudioArtist>();\n            var changed = new List<AudioArtist>();\n            var added = new List<AudioArtist>();\n\n            //check artists changes\n            foreach (var cachedArtist in cachedData)\n            {\n                var associatedArtist = localArtists.FirstOrDefault(t => t.Id == cachedArtist.Id);\n                if (associatedArtist == null) //if artist is cached but doesn't exists in file system it supposed to be deleted\n                {\n                    deleted.Add(cachedArtist);\n                    continue;\n                }\n\n                //check properties changes\n                if (UpdateArtist(cachedArtist, associatedArtist))\n                {\n                    //properties was changed, add artist to list of changed artists\n                    changed.Add(cachedArtist);\n                }\n            }\n\n            //looking for new artists\n            foreach (var localArtist in localArtists)\n            {\n                if (cachedData.Any(t => t.Id == localArtist.Id))\n                    continue;\n\n                added.Add(localArtist);\n            }\n\n            return new Tuple<List<AudioArtist>, List<AudioArtist>, List<AudioArtist>>(deleted, changed, added);\n        }\n\n        private Task<List<AudioArtist>> GetFromLibrary()\n        {\n            return Task.Run(async () =>\n            {\n                var musicFiles = FilesHelper.GetMusicFiles();\n\n                double totalCount = musicFiles.Count;\n\n                var artists = new Dictionary<string, AudioArtist>();\n\n                foreach (var filePath in musicFiles)\n                {\n                    TagLib.File audioFile = null;\n\n                    try\n                    {\n                        audioFile = TagLib.File.Create(filePath);\n                    }\n                    catch (Exception ex)\n                    {\n                        LoggingService.Log(ex);\n                        continue;\n                    }\n\n                    var track = new LocalAudio();\n                    string artist = string.Empty;\n                    if (!string.IsNullOrWhiteSpace(audioFile.Tag.FirstPerformer))\n                        artist = audioFile.Tag.FirstPerformer;\n                    else if (!string.IsNullOrWhiteSpace(audioFile.Tag.FirstAlbumArtist))\n                        artist = audioFile.Tag.FirstAlbumArtist;\n\n                    if (!string.IsNullOrWhiteSpace(artist))\n                    {\n                        track.ArtistId = Md5Helper.Md5(StringHelper.ToUtf8(artist).Trim().ToLower());\n                        track.Artist = StringHelper.ToUtf8(artist).Trim();\n                        if (!artists.ContainsKey(track.ArtistId))\n                            artists.Add(track.ArtistId, new AudioArtist() { Id = track.ArtistId, Title = track.Artist });\n                    }\n\n                    audioFile.Dispose();\n\n                    await Task.Delay(50);\n                }\n\n                LoggingService.Log(\"Music scan finished. Found \" + artists.Count + \" artists\");\n\n                return artists.Values.ToList();\n            });\n        }\n\n        private bool UpdateArtist(AudioArtist cachedArtist, AudioArtist updatedArtist)\n        {\n            bool changed = false;\n\n            if (!cachedArtist.Title.Equals(updatedArtist.Title, StringComparison.OrdinalIgnoreCase))\n            {\n                cachedArtist.Title = updatedArtist.Title;\n                changed = true;\n            }\n\n            return changed;\n        }\n\n        private async void ArtistsRepositoryUpdated(Tuple<List<AudioArtist>, List<AudioArtist>, List<AudioArtist>> result)\n        {\n            var deleted = result.Item1;\n            var changed = result.Item2;\n            var added = result.Item3;\n\n            await ServiceLocator.DataBaseService.DeleteItems(deleted);\n\n            await ServiceLocator.DataBaseService.UpdateItems(changed);\n\n            await ServiceLocator.DataBaseService.SaveItems(added);\n\n            if (deleted.Count > 0 || changed.Count > 0 || added.Count > 0)\n                Messenger.Default.Send(new LocalRepositoryUpdatedMessage() { RepositoryType = typeof(AudioArtist) });\n\n            LoggingService.Log(string.Format(\"Local artists database updated. Deleted: {0}, Changed: {1}, Added: {2}\", deleted.Count, changed.Count, added.Count));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/Music/Repositories/LocalTracksRepository.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Messaging;\nusing Meridian.Helpers;\nusing Meridian.Model;\nusing Meridian.ViewModel.Messages;\n\nnamespace Meridian.Services.Music.Repositories\n{\n    public class LocalTracksRepository\n    {\n        private bool _refreshed;\n\n        public async Task<List<LocalAudio>> GetTracks()\n        {\n            if (!_refreshed)\n            {\n                //check for updates on first time\n                _refreshed = true;\n                Refresh().ContinueWith(t =>\n                {\n                    TracksRepositoryUpdated(t.Result);\n                });\n            }\n\n            return await ServiceLocator.DataBaseService.GetItems<LocalAudio>();\n        }\n\n        public async Task<Tuple<List<LocalAudio>, List<LocalAudio>, List<LocalAudio>>> Refresh()\n        {\n            var localTracks = await GetFromLibrary(); //list of local tracks from file system\n\n            var cachedData = await ServiceLocator.DataBaseService.GetItems<LocalAudio>(); //list of cached tracks from database\n\n            var deleted = new List<LocalAudio>();\n            var changed = new List<LocalAudio>();\n            var added = new List<LocalAudio>();\n\n            //check tracks changes\n            foreach (var cachedTrack in cachedData)\n            {\n                var associatedTrack = localTracks.FirstOrDefault(t => t.Id == cachedTrack.Id);\n                if (associatedTrack == null) //if track is cached but doesn't exists in file system it supposed to be deleted\n                {\n                    //TODO remove track mappings\n\n                    deleted.Add(cachedTrack);\n                    continue;\n                }\n\n                //check properties changes\n                if (UpdateTrack(cachedTrack, associatedTrack))\n                {\n                    //properties was changed, add track to list of changed tracks\n                    changed.Add(cachedTrack);\n                }\n            }\n\n            //looking for new tracks\n            foreach (var localTrack in localTracks)\n            {\n                if (cachedData.Any(t => t.Id == localTrack.Id))\n                    continue;\n\n                added.Add(localTrack);\n            }\n\n            return new Tuple<List<LocalAudio>, List<LocalAudio>, List<LocalAudio>>(deleted, changed, added);\n        }\n\n        private Task<List<LocalAudio>> GetFromLibrary()\n        {\n            return Task.Run(async () =>\n            {\n                var musicFiles = FilesHelper.GetMusicFiles();\n\n                double totalCount = musicFiles.Count;\n\n                var tracks = new List<LocalAudio>();\n\n                foreach (var filePath in musicFiles)\n                {\n                    TagLib.File audioFile = null;\n\n                    try\n                    {\n                        audioFile = TagLib.File.Create(filePath);\n                    }\n                    catch (Exception ex)\n                    {\n                        LoggingService.Log(ex);\n                        continue;\n                    }\n\n                    var track = new LocalAudio();\n                    track.Id = Md5Helper.Md5(filePath);\n                    if (!string.IsNullOrEmpty(audioFile.Tag.Title))\n                        track.Title = StringHelper.ToUtf8(audioFile.Tag.Title);\n                    else\n                        track.Title = Path.GetFileNameWithoutExtension(filePath);\n\n                    var artist = audioFile.Tag.FirstPerformer;\n                    if (string.IsNullOrEmpty(artist))\n                        artist = audioFile.Tag.FirstAlbumArtist;\n\n                    track.Artist = StringHelper.ToUtf8(artist);\n\n                    if (!string.IsNullOrEmpty(track.Artist))\n                    {\n                        track.Artist = track.Artist.Trim();\n                        track.ArtistId = Md5Helper.Md5(track.Artist.Trim().ToLower());\n                    }\n                    else\n                        track.Artist = string.Empty;\n\n                    track.Duration = audioFile.Properties.Duration;\n                    track.Source = filePath;\n\n                    if (!string.IsNullOrWhiteSpace(audioFile.Tag.Album))\n                    {\n                        track.AlbumId = Md5Helper.Md5(track.Artist.Trim().ToLower() + \"_\" + StringHelper.ToUtf8(audioFile.Tag.Album).Trim());\n                        track.Album = StringHelper.ToUtf8(audioFile.Tag.Album).Trim();\n                    }\n\n                    tracks.Add(track);\n                    audioFile.Dispose();\n\n                    await Task.Delay(50);\n                }\n\n                LoggingService.Log(\"Music scan finished. Found \" + tracks.Count + \" tracks\");\n\n                return tracks;\n            });\n        }\n\n        private bool UpdateTrack(LocalAudio cachedTrack, LocalAudio updatedTrack)\n        {\n            bool changed = false;\n\n            if (cachedTrack.Title != updatedTrack.Title)\n            {\n                cachedTrack.Title = updatedTrack.Title;\n                changed = true;\n            }\n\n            if (cachedTrack.Artist != updatedTrack.Artist)\n            {\n                cachedTrack.Artist = updatedTrack.Artist;\n                changed = true;\n            }\n\n            if (cachedTrack.Album != updatedTrack.Album)\n            {\n                cachedTrack.Album = updatedTrack.Album;\n                changed = true;\n            }\n\n            if (cachedTrack.AlbumId != updatedTrack.AlbumId)\n            {\n                cachedTrack.AlbumId = updatedTrack.AlbumId;\n                changed = true;\n            }\n\n            if (cachedTrack.ArtistId != updatedTrack.ArtistId)\n            {\n                cachedTrack.ArtistId = updatedTrack.ArtistId;\n                changed = true;\n            }\n\n            if (cachedTrack.Duration != updatedTrack.Duration)\n            {\n                cachedTrack.Duration = updatedTrack.Duration;\n                changed = true;\n            }\n\n            return changed;\n        }\n\n        private async void TracksRepositoryUpdated(Tuple<List<LocalAudio>, List<LocalAudio>, List<LocalAudio>> result)\n        {\n            var deleted = result.Item1;\n            var changed = result.Item2;\n            var added = result.Item3;\n\n            await ServiceLocator.DataBaseService.DeleteItems(deleted);\n\n            await ServiceLocator.DataBaseService.UpdateItems(changed);\n\n            await ServiceLocator.DataBaseService.SaveItems(added);\n\n            if (deleted.Count > 0 || changed.Count > 0 || added.Count > 0)\n                Messenger.Default.Send(new LocalRepositoryUpdatedMessage() { RepositoryType = typeof(LocalAudio) });\n\n            LoggingService.Log(string.Format(\"Local tracks database updated. Deleted: {0}, Changed: {1}, Added: {2}\", deleted.Count, changed.Count, added.Count));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/NotificationService.cs",
    "content": "﻿using Meridian.Controls;\n\nnamespace Meridian.Services\n{\n    public static class NotificationService\n    {\n        private static NotificationControl _control;\n\n        public static void Initialize(NotificationControl control)\n        {\n            _control = control;\n        }\n\n        public static void Notify(string message)\n        {\n            _control.Status = message;\n        }\n\n        public static void NotifyProgressStarted(string message = null)\n        {\n            _control.Progress = 0;\n\n            if (!string.IsNullOrEmpty(message))\n                _control.Status = message;\n        }\n\n        public static void NotifyProgressChanged(int progress, string message = null)\n        {\n            _control.Progress += progress;\n\n            if (!string.IsNullOrEmpty(message))\n                _control.Status = message;\n        }\n\n        public static void NotifyProgressFinished(string message = null)\n        {\n            _control.Progress = 100;\n\n            if (!string.IsNullOrEmpty(message))\n                _control.Status = message;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/ServiceLocator.cs",
    "content": "﻿using Meridian.Services.Music;\n\nnamespace Meridian.Services\n{\n    /// <summary>\n    /// Contains instances of frequnetly used services\n    /// </summary>\n    public static class ServiceLocator\n    {\n        private static readonly LocalMusicService _localMusicService = new LocalMusicService();\n        private static readonly DataBaseService _dataBaseService = new DataBaseService();\n\n        public static LocalMusicService LocalMusicService\n        {\n            get { return _localMusicService; }\n        }\n\n        public static DataBaseService DataBaseService\n        {\n            get { return _dataBaseService; }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/Services/UpdateService.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.IO;\nusing System.Net;\nusing System.Net.Http;\nusing System.Reflection;\nusing System.Threading.Tasks;\nusing ICSharpCode.SharpZipLib.Zip;\nusing Meridian.Domain;\nusing Newtonsoft.Json.Linq;\n\nnamespace Meridian.Services\n{\n    public class UpdateService : INotifyPropertyChanged\n    {\n        private const string BASE_URL = \"http://store.meridianvk.com/update/\";\n        private const string MANIFEST_PATH = \"update-v5.js\";\n        private const string MANIFEST_PATH_DEV = \"update-v5-dev.js\";\n\n        private bool _isCheckingUpdates;\n        private bool _isUpdating;\n        private int _updateProgress;\n        private bool _isUpdateInstalled;\n        private string _updateDescription;\n\n        public bool IsCheckingUpdates\n        {\n            get { return _isCheckingUpdates; }\n            private set\n            {\n                if (_isCheckingUpdates == value)\n                    return;\n\n                _isCheckingUpdates = value;\n                OnPropertyChanged(\"IsCheckingUpdates\");\n            }\n        }\n\n        public bool IsUpdating\n        {\n            get { return _isUpdating; }\n            private set\n            {\n                if (_isUpdating == value)\n                    return;\n\n                _isUpdating = value;\n                OnPropertyChanged(\"IsUpdating\");\n            }\n        }\n\n        public int UpdateProgress\n        {\n            get { return _updateProgress; }\n            private set\n            {\n                if (_updateProgress == value)\n                    return;\n\n                _updateProgress = value;\n                OnPropertyChanged(\"UpdateProgress\");\n            }\n        }\n\n        public bool IsUpdateInstalled\n        {\n            get { return _isUpdateInstalled; }\n            private set\n            {\n                if (_isUpdateInstalled == value)\n                    return;\n\n                _isUpdateInstalled = value;\n                OnPropertyChanged(\"IsUpdateInstalled\");\n            }\n        }\n\n        public string UpdateDescription\n        {\n            get { return _updateDescription; }\n            private set\n            {\n                if (_updateDescription == value)\n                    return;\n\n                _updateDescription = value;\n                OnPropertyChanged(\"UpdateDescription\");\n            }\n        }\n\n        public async void CheckUpdates()\n        {\n            IsCheckingUpdates = true;\n\n            await Task.Delay(2000);\n\n            var httpClient = new HttpClient();\n            JObject json = null;\n            try\n            {\n                var manifestResponse = await httpClient.GetAsync(BASE_URL + (Settings.Instance.InstallDevUpdates ? MANIFEST_PATH_DEV : MANIFEST_PATH));\n                var manifestContent = await manifestResponse.Content.ReadAsStringAsync();\n\n                json = JObject.Parse(manifestContent);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsCheckingUpdates = false;\n\n            if (json == null || json[\"build\"] == null)\n            {\n                return;\n            }\n\n            var lastestBuild = json[\"build\"].Value<int>();\n            if (lastestBuild > Assembly.GetExecutingAssembly().GetName().Version.Build)\n            {\n                var path = json[\"path\"].Value<string>();\n                var details = json[\"details\"];\n                if (details != null)\n                {\n                    var lang = Domain.Settings.Instance.Language == \"ru\" ? \"ru\" : \"en\";\n                    if (details[lang] != null)\n                        UpdateDescription = details[lang].Value<string>();\n                }\n                UpdateInternal(path);\n            }\n        }\n\n        //delete .old files\n        public void Clean()\n        {\n            foreach (var file in Directory.GetFiles(App.Root, \"*.old\", SearchOption.AllDirectories))\n            {\n                try\n                {\n                    var info = new FileInfo(file);\n                    if (info.IsReadOnly)\n                        info.IsReadOnly = false;\n\n                    File.Delete(file);\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n            }\n        }\n\n        private void UpdateInternal(string path)\n        {\n            if (string.IsNullOrEmpty(path))\n                return;\n\n            IsUpdating = true;\n\n            var webClient = new WebClient();\n            webClient.DownloadProgressChanged += webClient_DownloadProgressChanged;\n            webClient.DownloadFileCompleted += webClient_DownloadFileCompleted;\n\n            var file = Path.GetTempFileName();\n            webClient.DownloadFileAsync(new Uri(BASE_URL + path), file, file);\n        }\n\n        private void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)\n        {\n            var webClient = sender as WebClient;\n            if (webClient == null)\n                return;\n\n            webClient.DownloadProgressChanged -= webClient_DownloadProgressChanged;\n\n            var file = e.UserState as string;\n            if (file == null)\n                return;\n\n            try\n            {\n                Unpack(App.Root, file);\n                Settings.Instance.NeedClean = true;\n\n                IsUpdateInstalled = true;\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsUpdating = false;\n        }\n\n        private void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)\n        {\n            UpdateProgress = e.ProgressPercentage;\n        }\n\n        private void Unpack(string path, string file)\n        {\n            using (var fileStreamIn = new FileStream(file, FileMode.Open, FileAccess.Read))\n            {\n                using (var zipInStream = new ZipInputStream(fileStreamIn))\n                {\n                    while (true)\n                    {\n                        ZipEntry entry = zipInStream.GetNextEntry();\n                        if (entry == null)\n                            break;\n                        if (!entry.IsDirectory)\n                        {\n                            if (File.Exists(path + \"\\\\\" + entry.Name))\n                            {\n                                string name = path + \"\\\\\" + entry.Name;\n                                while (File.Exists(name))\n                                {\n                                    name += \".old\";\n                                }\n\n                                File.Move(path + \"\\\\\" + entry.Name, name);\n\n                                var info = new FileInfo(name);\n                                if (info.IsReadOnly)\n                                    info.IsReadOnly = false;\n                            }\n\n                            using (var fileStreamOut = new FileStream(string.Format(@\"{0}\\{1}\", path, entry.Name), FileMode.Create, FileAccess.Write))\n                            {\n                                int size;\n                                var buffer = new byte[1024];\n                                do\n                                {\n                                    size = zipInStream.Read(buffer, 0, buffer.Length);\n                                    fileStreamOut.Write(buffer, 0, size);\n                                } while (size > 0);\n                                fileStreamOut.Close();\n                            }\n                        }\n                        else\n                            if (!Directory.Exists(string.Format(@\"{0}\\{1}\", path, entry.Name)))\n                                Directory.CreateDirectory(string.Format(@\"{0}\\{1}\", path, entry.Name));\n                    }\n\n                    zipInStream.Close();\n                }\n                fileStreamIn.Close();\n            }\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged(string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Compact/CompactLandscapeView.xaml",
    "content": "﻿<Window x:Class=\"Meridian.View.Compact.CompactLandscapeView\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n        xmlns:converters=\"clr-namespace:Meridian.Converters\"\n        xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n        xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n        xmlns:controls=\"clr-namespace:Meridian.Controls\"\n        x:Name=\"pageRoot\"\n        Title=\"{Binding Main.WindowTitle, Source={StaticResource Locator}}\" Height=\"140\" Width=\"355\"\n        Background=\"{DynamicResource MainBackgroundBrush}\" ShowInTaskbar=\"{Binding Main.ShowTrayIcon, Source={StaticResource Locator}, Converter={StaticResource InvertBoolConverter}}\"\n        DataContext=\"{Binding Main, Source={StaticResource Locator}}\" Topmost=\"{Binding IsChecked, ElementName=pinButton}\"\n        ResizeMode=\"NoResize\"\n        MouseMove=\"CompactView_OnMouseMove\" Loaded=\"CompactView_OnLoaded\"\n        StateChanged=\"CompactLandscapeView_OnStateChanged\">\n    <Window.Style>\n        <Style TargetType=\"Window\">\n            <Setter Property=\"WindowChrome.WindowChrome\">\n                <Setter.Value>\n                    <WindowChrome NonClientFrameEdges=\"None\" GlassFrameThickness=\"0,0,0,1\" ResizeBorderThickness=\"7\" CaptionHeight=\"0\" CornerRadius=\"0\"/>\n                </Setter.Value>\n            </Setter>\n        </Style>\n    </Window.Style>\n    <Window.TaskbarItemInfo>\n        <TaskbarItemInfo x:Name=\"Taskbar\">\n            <TaskbarItemInfo.ThumbButtonInfos>\n                <ThumbButtonInfo ImageSource=\"/Meridian;component/Resources/Images/prev_thumb.png\" \n                                 Command=\"{Binding Main.PrevAudioCommand, Source={StaticResource Locator}}\"/>\n                <ThumbButtonInfo ImageSource=\"{Binding Main.IsPlaying, Source={StaticResource Locator}, Converter={StaticResource PlayIconConverter}}\"\n                                 Command=\"{Binding Main.PlayPauseCommand, Source={StaticResource Locator}}\"/>\n                <ThumbButtonInfo ImageSource=\"/Meridian;component/Resources/Images/next_thumb.png\"\n                                 Command=\"{Binding Main.NextAudioCommand, Source={StaticResource Locator}}\"/>\n            </TaskbarItemInfo.ThumbButtonInfos>\n        </TaskbarItemInfo>\n    </Window.TaskbarItemInfo>\n    <Window.Resources>\n        <converters:BooleanToValueConverter x:Key=\"LikeDislikeTooltipConverter\" FalseValue=\"{x:Static localization:MainResources.ContextMenuAdd}\" TrueValue=\"{x:Static localization:MainResources.ContextMenuRemove}\"/>\n\n        <Storyboard x:Key=\"TracklistTransitionIn\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(RenderTransform).X\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"30\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard x:Key=\"TracklistTransitionOut\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(RenderTransform).X\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"30\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n\n        <Storyboard x:Key=\"PlayerTransitionIn\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(RenderTransform).X\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"-30\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard x:Key=\"PlayerTransitionOut\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(RenderTransform).X\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"-30\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n    </Window.Resources>\n\n    <Grid Background=\"{DynamicResource BackgroundBrush}\">\n        <Grid.RowDefinitions>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n\n        <controls:ImageTransitionControl x:Name=\"BackgroundArtControl\" Source=\"{Binding Main.ArtistImage, Source={StaticResource Locator}}\" Grid.RowSpan=\"2\" ImageOpacity=\"0.2\" \n                                         Visibility=\"{Binding Main.ShowBackgroundArtCompactMode, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n\n        <!-- Player view -->\n        <Grid Margin=\"0,0,0,0\">\n            <Grid.RenderTransform>\n                <TranslateTransform />\n            </Grid.RenderTransform>\n            <i:Interaction.Behaviors>\n                <behaviours:VisibilityTransitionBehaviour Value=\"{Binding ShowTracklist, ElementName=pageRoot, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\" \n                                                          AnimationIn=\"{StaticResource PlayerTransitionIn}\" AnimationOut=\"{StaticResource PlayerTransitionOut}\"/>\n            </i:Interaction.Behaviors>\n\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"Auto\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n\n            <ToggleButton x:Name=\"pinButton\" Style=\"{StaticResource PinButtonStyle}\" ToolTip=\"{x:Static localization:MainResources.CompactModePin}\"\n                          VerticalAlignment=\"Top\" HorizontalAlignment=\"Left\" Width=\"24\" Height=\"24\" Margin=\"11,3,0,0\"/>\n\n            <Grid Grid.Row=\"2\" Margin=\"15,30,0,0\" HorizontalAlignment=\"Left\" Height=\"100\" VerticalAlignment=\"Top\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition />\n                    <ColumnDefinition Width=\"Auto\"/>\n                </Grid.ColumnDefinitions>\n                <Border Margin=\"0,0,0,0\" Width=\"100\">\n                    <Grid>\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition />\n                            <ColumnDefinition Width=\"Auto\"/>\n                        </Grid.ColumnDefinitions>\n                        <Rectangle Fill=\"{DynamicResource BackgroundBrush}\"/>\n                        <Rectangle Fill=\"{DynamicResource AccentBrush}\" Opacity=\"0.6\"/>\n                        <Image Source=\"/Resources/Images/cover_default.png\" Margin=\"35\" RenderOptions.BitmapScalingMode=\"HighQuality\" />\n                        <controls:ImageTransitionControl Source=\"{Binding Main.TrackImage, Source={StaticResource Locator}}\" RenderOptions.BitmapScalingMode=\"HighQuality\"\n                                                         HorizontalContentAlignment=\"Center\"/>\n                    </Grid>\n                </Border>\n\n                <Grid Grid.Column=\"1\" Margin=\"-2,0,-3,0\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition />\n                        <RowDefinition />\n                        <RowDefinition />\n                    </Grid.RowDefinitions>\n                    <ToggleButton VerticalAlignment=\"Top\" Width=\"32\" Height=\"32\" Padding=\"10\" Margin=\"1,-10,0,0\" IsChecked=\"{Binding Main.CurrentAudio.IsAddedByCurrentUser, Mode=OneWay, Source={StaticResource Locator}}\" Style=\"{StaticResource LikeDislikeButtonStyle}\"\n                          ToolTip=\"{Binding Main.CurrentAudio.IsAddedByCurrentUser, Source={StaticResource Locator}, Converter={StaticResource LikeDislikeTooltipConverter}}\"\n                          Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Main.CurrentAudio, Source={StaticResource Locator}}\"\n                          IsEnabled=\"{Binding Main.CanBroadcast, Source={StaticResource Locator}}\">\n                        <ToggleButton.RenderTransform>\n                            <TranslateTransform />\n                        </ToggleButton.RenderTransform>\n                    </ToggleButton>\n                    <ToggleButton Grid.Row=\"1\" VerticalAlignment=\"Center\" Width=\"32\" Height=\"32\" Margin=\"0,0,0,0\" IsChecked=\"{Binding Main.Shuffle, Mode=TwoWay, Source={StaticResource Locator}}\" Style=\"{StaticResource ShuffleButtonStyle}\"\n                          ToolTip=\"{x:Static localization:MainResources.Shuffle}\" Foreground=\"{StaticResource ForegroundBrush}\">\n                        <ToggleButton.RenderTransform>\n                            <TranslateTransform />\n                        </ToggleButton.RenderTransform>\n                    </ToggleButton>\n                    <ToggleButton VerticalAlignment=\"Bottom\" Grid.Row=\"2\" Width=\"32\" Height=\"32\" Margin=\"0,0,0,-10\" IsChecked=\"{Binding Main.Repeat, Mode=TwoWay, Source={StaticResource Locator}}\" Style=\"{StaticResource RepeatButtonStyle}\"\n                          ToolTip=\"{x:Static localization:MainResources.Repeat}\" Foreground=\"{StaticResource ForegroundBrush}\">\n                        <ToggleButton.RenderTransform>\n                            <TranslateTransform />\n                        </ToggleButton.RenderTransform>\n                    </ToggleButton>\n                </Grid>\n            </Grid>\n\n            <StackPanel Margin=\"15,30,15,0\" VerticalAlignment=\"Top\" Grid.Column=\"1\">\n                <controls:ContentTransitionControl Margin=\"0,-5,0,0\" VerticalAlignment=\"Center\"\n                                               Visibility=\"{Binding Main.CurrentAudio, Source={StaticResource Locator}, Converter={StaticResource NullToVisibilityConverter}}\"\n                                               Source=\"{Binding Main.CurrentAudio, Source={StaticResource Locator}}\">\n                    <controls:ContentTransitionControl.ContentTemplate>\n                        <DataTemplate>\n                            <StackPanel>\n                                <TextBlock Text=\"{Binding Title, Converter={StaticResource StringToUpperConverter}}\" FontWeight=\"SemiBold\" FontSize=\"16\" TextTrimming=\"CharacterEllipsis\" MaxHeight=\"36\"\n                                   Foreground=\"{DynamicResource ForegroundBrush}\" ToolTip=\"{Binding Title}\">\n                                </TextBlock>\n                                <TextBlock Text=\"{Binding Artist}\" FontWeight=\"Normal\" FontSize=\"13\" Opacity=\"0.7\" Margin=\"0,0,0,0\" TextTrimming=\"CharacterEllipsis\"\n                                   Foreground=\"{DynamicResource ForegroundBrush}\" ToolTip=\"{Binding Artist}\">\n                                </TextBlock>\n                            </StackPanel>\n                        </DataTemplate>\n                    </controls:ContentTransitionControl.ContentTemplate>\n                </controls:ContentTransitionControl>\n\n                <Grid VerticalAlignment=\"Center\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition />\n                        <RowDefinition />\n                    </Grid.RowDefinitions>\n                    <Slider IsMoveToPointEnabled=\"True\"\n                        Value=\"{Binding Main.CurrentAudioPositionSeconds, Source={StaticResource Locator}, Mode=TwoWay}\" Maximum=\"{Binding Main.CurrentAudioDuration.TotalSeconds, Source={StaticResource Locator}, Mode=OneWay}\"\n                        Style=\"{StaticResource CommonSliderStyle}\" />\n                    <TextBlock Text=\"{Binding Main.CurrentAudioPosition, Source={StaticResource Locator}, Converter={StaticResource AudioTimeSpanConverter}}\" FontSize=\"12\" Opacity=\"0.5\" Margin=\"0,15,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <TextBlock Text=\"{Binding Main.CurrentAudioDuration, Source={StaticResource Locator}, Converter={StaticResource AudioTimeSpanConverter}}\" FontSize=\"12\" Opacity=\"0.5\" Margin=\"0,15,0,0\" HorizontalAlignment=\"Right\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                </Grid>\n\n                <Border Background=\"Transparent\" MouseWheel=\"UIElement_OnMouseWheel\" ToolTip=\"{Binding Main.Volume, Source={StaticResource Locator}}\">\n                    <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Center\" Margin=\"0,-10,0,5\" DataContext=\"{Binding Main, Source={StaticResource Locator}}\">\n                        <Button Margin=\"0,0,7,0\" Command=\"{Binding Main.PrevAudioCommand, Source={StaticResource Locator}}\" Width=\"26\" Height=\"26\" Style=\"{StaticResource PrevButtonStyle}\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                                ToolTip=\"{x:Static localization:MainResources.PrevTrack}\">\n                            <Button.RenderTransform>\n                                <TranslateTransform />\n                            </Button.RenderTransform>\n                        </Button>\n                        <ToggleButton Width=\"36\" Height=\"36\" IsChecked=\"{Binding IsPlaying, Mode=TwoWay}\" Command=\"{Binding Main.PlayPauseCommand, Source={StaticResource Locator}}\" Style=\"{StaticResource PlayPauseButtonStyle}\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                          ToolTip=\"{x:Static localization:MainResources.PlayPause}\">\n                            <ToggleButton.RenderTransform>\n                                <TranslateTransform />\n                            </ToggleButton.RenderTransform>\n                        </ToggleButton>\n                        <Button Margin=\"7,0,0,0\" Command=\"{Binding Main.NextAudioCommand, Source={StaticResource Locator}}\" Width=\"26\" Height=\"26\" Style=\"{StaticResource NextButtonStyle}\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                                ToolTip=\"{x:Static localization:MainResources.NextTrack}\">\n                            <Button.RenderTransform>\n                                <TranslateTransform />\n                            </Button.RenderTransform>\n                        </Button>\n                    </StackPanel>\n                </Border>\n\n                <ToggleButton Name=\"TracklistButton\" HorizontalAlignment=\"Center\" Cursor=\"Hand\" Margin=\"0,-8,0,0\" IsChecked=\"{Binding ShowTracklist, ElementName=pageRoot, Mode=TwoWay}\" Content=\"{x:Static localization:MainResources.CompactModeTracklist}\">\n                    <ToggleButton.Template>\n                        <ControlTemplate TargetType=\"ToggleButton\">\n                            <TextBlock Name=\"Title\" Text=\"{TemplateBinding Content}\" Foreground=\"{DynamicResource ForegroundBrush}\" Opacity=\"0.7\"/>\n                            <ControlTemplate.Triggers>\n                                <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                                    <Setter TargetName=\"Title\" Property=\"Opacity\" Value=\"1\"/>\n                                </Trigger>\n                            </ControlTemplate.Triggers>\n                        </ControlTemplate>\n                    </ToggleButton.Template>\n                </ToggleButton>\n            </StackPanel>\n        </Grid>\n\n        <!-- Tracklist view -->\n        <Grid Margin=\"0,0,0,0\">\n            <Grid.RenderTransform>\n                <TranslateTransform />\n            </Grid.RenderTransform>\n            <i:Interaction.Behaviors>\n                <behaviours:VisibilityTransitionBehaviour Value=\"{Binding ShowTracklist, ElementName=pageRoot, Converter={StaticResource BoolToVisibilityConverter}}\" \n                                                          AnimationIn=\"{StaticResource TracklistTransitionIn}\" AnimationOut=\"{StaticResource TracklistTransitionOut}\"/>\n            </i:Interaction.Behaviors>\n\n            <ToggleButton IsChecked=\"{Binding ShowTracklist, ElementName=pageRoot, Mode=TwoWay}\" Style=\"{StaticResource CompactBackButtonStyle}\"\n                          VerticalAlignment=\"Top\" HorizontalAlignment=\"Left\" Width=\"24\" Height=\"24\" Margin=\"11,3,0,0\"/>\n\n            <ListBox x:Name=\"AudioList\" Margin=\"0,30,0,0\" Padding=\"0,0,0,0\" ItemsSource=\"{Binding Main.CurrentPlaylist, Source={StaticResource Locator}}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                     VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                     ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                     ItemTemplate=\"{StaticResource CompactAudioItemTemplate}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:AutoScrollToCurrentItemBehaviour />\n                </i:Interaction.Behaviors>\n            </ListBox>\n        </Grid>\n\n        <StackPanel Orientation=\"Horizontal\" VerticalAlignment=\"Top\" HorizontalAlignment=\"Right\" Margin=\"0,5,5,5\" DataContext=\"{Binding Main, Source={StaticResource Locator}}\">\n            <Button Style=\"{StaticResource PortraitModeButtonStyle}\" Margin=\"0,0,15,0\" SnapsToDevicePixels=\"True\" Command=\"{Binding SwitchToUIModeCommand}\" CommandParameter=\"Compact\"\n                    ToolTip=\"{x:Static localization:MainResources.PortraitMode}\"/>\n            <Button Style=\"{StaticResource MiniModeButtonStyle}\" Margin=\"0,0,15,0\" SnapsToDevicePixels=\"True\" Command=\"{Binding SwitchUIModeCommand}\"\n                    ToolTip=\"{x:Static localization:MainResources.FullMode}\"/>\n            <Button Style=\"{StaticResource MinimizeButtonStyle}\" VerticalAlignment=\"Bottom\" Margin=\"0,0,15,0\" SnapsToDevicePixels=\"True\" ToolTip=\"{x:Static localization:MainResources.Minimize}\"\n                    Click=\"ButtonBase_OnClick\"/>\n            <Button Style=\"{StaticResource CloseButtonStyle}\" SnapsToDevicePixels=\"True\" Command=\"{Binding CloseWindowCommand}\" ToolTip=\"{x:Static localization:MainResources.Close}\" Margin=\"0,0,5,0\"/>\n        </StackPanel>\n    </Grid>\n</Window>\n"
  },
  {
    "path": "Meridian/View/Compact/CompactLandscapeView.xaml.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Windows;\nusing System.Windows.Input;\nusing System.Windows.Media.Effects;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Main;\n\nnamespace Meridian.View.Compact\n{\n    /// <summary>\n    /// Interaction logic for CompactLandscapeView.xaml\n    /// </summary>\n    public partial class CompactLandscapeView : Window, INotifyPropertyChanged\n    {\n        private NowPlayingViewModel _viewModel;\n        private bool _showTracklist;\n\n        public bool ShowTracklist\n        {\n            get { return _showTracklist; }\n            set\n            {\n                if (_showTracklist == value)\n                    return;\n\n                _showTracklist = value;\n                OnPropertyChanged(\"ShowTracklist\");\n            }\n        }\n\n        public CompactLandscapeView()\n        {\n            InitializeComponent();\n\n            _viewModel = new NowPlayingViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void CompactView_OnMouseMove(object sender, MouseEventArgs e)\n        {\n            if (e.LeftButton == MouseButtonState.Pressed && e.GetPosition(this).Y < 30)\n            {\n                DragMove();\n                Domain.Settings.Instance.CompactTop = Top;\n                Domain.Settings.Instance.CompactLeft = Left;\n            }\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged(string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n\n        private void CompactView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            Top = Domain.Settings.Instance.CompactTop;\n            Left = Domain.Settings.Instance.CompactLeft;\n\n            BackgroundArtControl.Effect = Domain.Settings.Instance.BlurBackground ? new BlurEffect() { RenderingBias = RenderingBias.Quality, Radius = 35 } : null;\n        }\n\n        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)\n        {\n            WindowState = WindowState.Minimized;\n        }\n\n        private void UIElement_OnMouseWheel(object sender, MouseWheelEventArgs e)\n        {\n            if (e.Delta < 0)\n            {\n                ViewModelLocator.Main.Volume -= 5;\n                if (ViewModelLocator.Main.Volume < 0)\n                    ViewModelLocator.Main.Volume = 0;\n            }\n            else\n            {\n                ViewModelLocator.Main.Volume += 5;\n                if (ViewModelLocator.Main.Volume > 100)\n                    ViewModelLocator.Main.Volume = 100;\n            }\n        }\n\n        private void CompactLandscapeView_OnStateChanged(object sender, EventArgs e)\n        {\n            if (WindowState == WindowState.Minimized && Domain.Settings.Instance.EnableTrayIcon)\n            {\n                Hide();\n                Visibility = Visibility.Collapsed;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Compact/CompactView.xaml",
    "content": "﻿<Window x:Class=\"Meridian.View.Compact.CompactView\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n        xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n        xmlns:controls=\"clr-namespace:Meridian.Controls\"\n        xmlns:converters=\"clr-namespace:Meridian.Converters\"\n        xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n        x:Name=\"pageRoot\"\n        Title=\"{Binding Main.WindowTitle, Source={StaticResource Locator}}\" Height=\"268\" Width=\"160\"\n        Background=\"{DynamicResource MainBackgroundBrush}\" ShowInTaskbar=\"{Binding Main.ShowTrayIcon, Source={StaticResource Locator}, Converter={StaticResource InvertBoolConverter}}\"\n        DataContext=\"{Binding Main, Source={StaticResource Locator}}\" Topmost=\"{Binding IsChecked, ElementName=pinButton}\" ResizeMode=\"NoResize\"\n        MouseMove=\"CompactView_OnMouseMove\" Loaded=\"CompactView_OnLoaded\"\n        StateChanged=\"CompactView_OnStateChanged\">\n    <Window.Style>\n        <Style TargetType=\"Window\">\n            <Setter Property=\"WindowChrome.WindowChrome\">\n                <Setter.Value>\n                    <WindowChrome NonClientFrameEdges=\"None\" GlassFrameThickness=\"0,0,0,1\" ResizeBorderThickness=\"7\" CaptionHeight=\"0\" CornerRadius=\"0\"/>\n                </Setter.Value>\n            </Setter>\n        </Style>\n    </Window.Style>\n    <Window.TaskbarItemInfo>\n        <TaskbarItemInfo x:Name=\"Taskbar\">\n            <TaskbarItemInfo.ThumbButtonInfos>\n                <ThumbButtonInfo ImageSource=\"/Meridian;component/Resources/Images/prev_thumb.png\" \n                                 Command=\"{Binding Main.PrevAudioCommand, Source={StaticResource Locator}}\"/>\n                <ThumbButtonInfo ImageSource=\"{Binding Main.IsPlaying, Source={StaticResource Locator}, Converter={StaticResource PlayIconConverter}}\"\n                                 Command=\"{Binding Main.PlayPauseCommand, Source={StaticResource Locator}}\"/>\n                <ThumbButtonInfo ImageSource=\"/Meridian;component/Resources/Images/next_thumb.png\"\n                                 Command=\"{Binding Main.NextAudioCommand, Source={StaticResource Locator}}\"/>\n            </TaskbarItemInfo.ThumbButtonInfos>\n        </TaskbarItemInfo>\n    </Window.TaskbarItemInfo>\n    <Window.Resources>\n        <converters:BooleanToValueConverter x:Key=\"LikeDislikeTooltipConverter\" FalseValue=\"{x:Static localization:MainResources.ContextMenuAdd}\" TrueValue=\"{x:Static localization:MainResources.ContextMenuRemove}\"/>\n\n        <Storyboard x:Key=\"TracklistTransitionIn\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(RenderTransform).X\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"30\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard x:Key=\"TracklistTransitionOut\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(RenderTransform).X\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"30\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n\n        <Storyboard x:Key=\"PlayerTransitionIn\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(RenderTransform).X\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"-30\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard x:Key=\"PlayerTransitionOut\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(RenderTransform).X\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"-30\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n    </Window.Resources>\n    <Grid Background=\"{DynamicResource BackgroundBrush}\">\n        <Grid.RowDefinitions>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <!-- Player view -->\n        <Grid Margin=\"0,0,0,0\">\n            <Grid.RenderTransform>\n                <TranslateTransform />\n            </Grid.RenderTransform>\n            <i:Interaction.Behaviors>\n                <behaviours:VisibilityTransitionBehaviour Value=\"{Binding ShowTracklist, ElementName=pageRoot, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\" \n                                                          AnimationIn=\"{StaticResource PlayerTransitionIn}\" AnimationOut=\"{StaticResource PlayerTransitionOut}\"/>\n            </i:Interaction.Behaviors>\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\"/>\n                <RowDefinition Height=\"Auto\"/>\n                <RowDefinition />\n                <RowDefinition Height=\"Auto\"/>\n            </Grid.RowDefinitions>\n\n            <ToggleButton x:Name=\"pinButton\" Style=\"{StaticResource PinButtonStyle}\" ToolTip=\"{x:Static localization:MainResources.CompactModePin}\"\n                          VerticalAlignment=\"Top\" HorizontalAlignment=\"Left\" Width=\"24\" Height=\"24\" Margin=\"11,3,0,0\"/>\n\n            <controls:ContentTransitionControl Grid.Row=\"1\" Margin=\"15,0,0,-10\" VerticalAlignment=\"Center\"\n                                               Visibility=\"{Binding Main.CurrentAudio, Source={StaticResource Locator}, Converter={StaticResource NullToVisibilityConverter}}\"\n                                               Source=\"{Binding Main.CurrentAudio, Source={StaticResource Locator}}\">\n                <controls:ContentTransitionControl.ContentTemplate>\n                    <DataTemplate>\n                        <StackPanel>\n                            <TextBlock Text=\"{Binding Title}\" FontWeight=\"Normal\" FontSize=\"16\" TextTrimming=\"CharacterEllipsis\" MaxHeight=\"36\"\n                                   Foreground=\"{DynamicResource ForegroundBrush}\" ToolTip=\"{Binding Title}\">\n                            </TextBlock>\n                            <TextBlock Text=\"{Binding Artist}\" FontWeight=\"Normal\" FontSize=\"12\" Opacity=\"0.7\" Margin=\"0,0,0,0\" TextTrimming=\"CharacterEllipsis\"\n                                   Foreground=\"{DynamicResource ForegroundBrush}\" ToolTip=\"{Binding Artist}\">\n                            </TextBlock>\n                        </StackPanel>\n                    </DataTemplate>\n                </controls:ContentTransitionControl.ContentTemplate>\n            </controls:ContentTransitionControl>\n\n            <Grid Grid.Row=\"2\" Margin=\"15,15,0,0\" HorizontalAlignment=\"Left\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition />\n                    <ColumnDefinition Width=\"Auto\"/>\n                </Grid.ColumnDefinitions>\n                <Border Margin=\"0,0,0,0\" Width=\"110\" Height=\"110\">\n                    <Grid>\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition />\n                            <ColumnDefinition Width=\"Auto\"/>\n                        </Grid.ColumnDefinitions>\n                        <Rectangle Fill=\"{DynamicResource AccentBrush}\" Opacity=\"0.6\"/>\n                        <Image Source=\"/Resources/Images/cover_default.png\" Margin=\"35\" RenderOptions.BitmapScalingMode=\"HighQuality\" />\n                        <controls:ImageTransitionControl Source=\"{Binding Main.TrackImage, Source={StaticResource Locator}}\" RenderOptions.BitmapScalingMode=\"HighQuality\" HorizontalContentAlignment=\"Center\"/>\n                    </Grid>\n                </Border>\n\n                <Grid Grid.Column=\"1\" Margin=\"-2,0,-3,0\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition />\n                        <RowDefinition />\n                        <RowDefinition />\n                    </Grid.RowDefinitions>\n                    <ToggleButton VerticalAlignment=\"Top\" Width=\"32\" Height=\"32\" Padding=\"10\" Margin=\"1,-10,0,0\" IsChecked=\"{Binding Main.CurrentAudio.IsAddedByCurrentUser, Mode=OneWay, Source={StaticResource Locator}}\" Style=\"{StaticResource LikeDislikeButtonStyle}\"\n                          ToolTip=\"{Binding Main.CurrentAudio.IsAddedByCurrentUser, Source={StaticResource Locator}, Converter={StaticResource LikeDislikeTooltipConverter}}\"\n                          Command=\"{Binding Main.AddRemoveAudioCommand, Source={StaticResource Locator}}\" CommandParameter=\"{Binding Main.CurrentAudio, Source={StaticResource Locator}}\"\n                          IsEnabled=\"{Binding Main.CanBroadcast, Source={StaticResource Locator}}\">\n                        <ToggleButton.RenderTransform>\n                            <TranslateTransform />\n                        </ToggleButton.RenderTransform>\n                    </ToggleButton>\n                    <ToggleButton Grid.Row=\"1\" VerticalAlignment=\"Center\" Width=\"32\" Height=\"32\" Margin=\"0,0,0,0\" IsChecked=\"{Binding Main.Shuffle, Mode=TwoWay, Source={StaticResource Locator}}\" Style=\"{StaticResource ShuffleButtonStyle}\"\n                          ToolTip=\"{x:Static localization:MainResources.Shuffle}\" Foreground=\"{StaticResource ForegroundBrush}\">\n                        <ToggleButton.RenderTransform>\n                            <TranslateTransform />\n                        </ToggleButton.RenderTransform>\n                    </ToggleButton>\n                    <ToggleButton VerticalAlignment=\"Bottom\" Grid.Row=\"2\" Width=\"32\" Height=\"32\" Margin=\"0,0,0,-10\" IsChecked=\"{Binding Main.Repeat, Mode=TwoWay, Source={StaticResource Locator}}\" Style=\"{StaticResource RepeatButtonStyle}\"\n                          ToolTip=\"{x:Static localization:MainResources.Repeat}\" Foreground=\"{StaticResource ForegroundBrush}\">\n                        <ToggleButton.RenderTransform>\n                            <TranslateTransform />\n                        </ToggleButton.RenderTransform>\n                    </ToggleButton>\n                </Grid>\n            </Grid>\n\n            <StackPanel Margin=\"15,3,0,0\" Grid.Row=\"3\" Width=\"110\" HorizontalAlignment=\"Left\">\n                <Grid VerticalAlignment=\"Center\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition />\n                        <RowDefinition />\n                    </Grid.RowDefinitions>\n                    <Slider IsMoveToPointEnabled=\"True\"\n                        Value=\"{Binding Main.CurrentAudioPositionSeconds, Source={StaticResource Locator}, Mode=TwoWay}\" Maximum=\"{Binding Main.CurrentAudioDuration.TotalSeconds, Source={StaticResource Locator}, Mode=OneWay}\"\n                        Style=\"{StaticResource CommonSliderStyle}\" />\n                    <TextBlock Text=\"{Binding Main.CurrentAudioPosition, Source={StaticResource Locator}, Converter={StaticResource AudioTimeSpanConverter}}\" FontSize=\"11\" Opacity=\"0.5\" Margin=\"0,15,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <TextBlock Text=\"{Binding Main.CurrentAudioDuration, Source={StaticResource Locator}, Converter={StaticResource AudioTimeSpanConverter}}\" FontSize=\"11\" Opacity=\"0.5\" Margin=\"0,15,0,0\" HorizontalAlignment=\"Right\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                </Grid>\n\n                <ToggleButton Name=\"TracklistButton\" Cursor=\"Hand\" IsChecked=\"{Binding ShowTracklist, ElementName=pageRoot, Mode=TwoWay}\" Content=\"{x:Static localization:MainResources.CompactModeTracklist}\">\n                    <ToggleButton.Template>\n                        <ControlTemplate TargetType=\"ToggleButton\">\n                            <TextBlock Name=\"Title\" Text=\"{TemplateBinding Content}\" Foreground=\"{DynamicResource ForegroundBrush}\" Opacity=\"0.7\"/>\n                            <ControlTemplate.Triggers>\n                                <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                                    <Setter TargetName=\"Title\" Property=\"Opacity\" Value=\"1\"/>\n                                </Trigger>\n                            </ControlTemplate.Triggers>\n                        </ControlTemplate>\n                    </ToggleButton.Template>\n                </ToggleButton>\n            </StackPanel>\n        </Grid>\n\n        <!-- Tracklist view -->\n        <Grid Margin=\"0,0,0,0\">\n            <Grid.RenderTransform>\n                <TranslateTransform />\n            </Grid.RenderTransform>\n            <i:Interaction.Behaviors>\n                <behaviours:VisibilityTransitionBehaviour Value=\"{Binding ShowTracklist, ElementName=pageRoot, Converter={StaticResource BoolToVisibilityConverter}}\" \n                                                          AnimationIn=\"{StaticResource TracklistTransitionIn}\" AnimationOut=\"{StaticResource TracklistTransitionOut}\"/>\n            </i:Interaction.Behaviors>\n\n            <ToggleButton IsChecked=\"{Binding ShowTracklist, ElementName=pageRoot, Mode=TwoWay}\" Style=\"{StaticResource CompactBackButtonStyle}\"\n                          VerticalAlignment=\"Top\" HorizontalAlignment=\"Left\" Width=\"24\" Height=\"24\" Margin=\"8,3,0,0\"/>\n\n            <ListBox x:Name=\"AudioList\" Margin=\"0,30,0,0\" Padding=\"0,0,0,0\" ItemsSource=\"{Binding Main.CurrentPlaylist, Source={StaticResource Locator}}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                     VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                     ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                     ItemTemplate=\"{StaticResource CompactAudioItemTemplate}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:AutoScrollToCurrentItemBehaviour />\n                </i:Interaction.Behaviors>\n            </ListBox>\n        </Grid>\n\n        <Border Grid.Row=\"1\" Background=\"Transparent\" MouseWheel=\"UIElement_OnMouseWheel\" ToolTip=\"{Binding Main.Volume, Source={StaticResource Locator}}\">\n            <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Center\"  Margin=\"0,3,0,2\" DataContext=\"{Binding Main, Source={StaticResource Locator}}\">\n                <Button Margin=\"0,0,7,0\" Command=\"{Binding Main.PrevAudioCommand, Source={StaticResource Locator}}\" Width=\"26\" Height=\"26\" Style=\"{StaticResource PrevButtonStyle}\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                    ToolTip=\"{x:Static localization:MainResources.PrevTrack}\">\n                    <Button.RenderTransform>\n                        <TranslateTransform />\n                    </Button.RenderTransform>\n                </Button>\n                <ToggleButton Width=\"36\" Height=\"36\" IsChecked=\"{Binding IsPlaying, Mode=TwoWay}\" Command=\"{Binding Main.PlayPauseCommand, Source={StaticResource Locator}}\" Style=\"{StaticResource PlayPauseButtonStyle}\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                          ToolTip=\"{x:Static localization:MainResources.PlayPause}\">\n                    <ToggleButton.RenderTransform>\n                        <TranslateTransform />\n                    </ToggleButton.RenderTransform>\n                </ToggleButton>\n                <Button Margin=\"7,0,0,0\" Command=\"{Binding Main.NextAudioCommand, Source={StaticResource Locator}}\" Width=\"26\" Height=\"26\" Style=\"{StaticResource NextButtonStyle}\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                    ToolTip=\"{x:Static localization:MainResources.NextTrack}\">\n                    <Button.RenderTransform>\n                        <TranslateTransform />\n                    </Button.RenderTransform>\n                </Button>\n            </StackPanel>\n        </Border>\n        <StackPanel Orientation=\"Horizontal\" VerticalAlignment=\"Top\" HorizontalAlignment=\"Right\" Margin=\"0,5,5,5\" DataContext=\"{Binding Main, Source={StaticResource Locator}}\">\n            <Button Style=\"{StaticResource LandscapeModeButtonStyle}\" Margin=\"0,0,10,0\" SnapsToDevicePixels=\"True\" Command=\"{Binding SwitchToUIModeCommand}\" CommandParameter=\"CompactLandscape\"\n                    ToolTip=\"{x:Static localization:MainResources.LandscapeMode}\"/>\n            <Button Style=\"{StaticResource MiniModeButtonStyle}\" Margin=\"0,0,10,0\" SnapsToDevicePixels=\"True\" Command=\"{Binding SwitchUIModeCommand}\"\n                    ToolTip=\"{x:Static localization:MainResources.FullMode}\" Width=\"20\" Height=\"20\"/>\n            <Button Style=\"{StaticResource MinimizeButtonStyle}\" VerticalAlignment=\"Bottom\" Margin=\"0,0,10,0\" SnapsToDevicePixels=\"True\" ToolTip=\"{x:Static localization:MainResources.Minimize}\"\n                    Click=\"ButtonBase_OnClick\" Width=\"21\" Height=\"21\"/>\n            <Button Style=\"{StaticResource CloseButtonStyle}\" SnapsToDevicePixels=\"True\" Command=\"{Binding CloseWindowCommand}\" ToolTip=\"{x:Static localization:MainResources.Close}\" Margin=\"0,0,5,0\"\n                    Width=\"20\" Height=\"20\"/>\n        </StackPanel>\n    </Grid>\n</Window>\n"
  },
  {
    "path": "Meridian/View/Compact/CompactView.xaml.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Windows;\nusing System.Windows.Input;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Main;\n\nnamespace Meridian.View.Compact\n{\n    /// <summary>\n    /// Interaction logic for CompactView.xaml\n    /// </summary>\n    public partial class CompactView : Window, INotifyPropertyChanged\n    {\n        private NowPlayingViewModel _viewModel;\n        private bool _showTracklist;\n\n        public bool ShowTracklist\n        {\n            get { return _showTracklist; }\n            set\n            {\n                if (_showTracklist == value)\n                    return;\n\n                _showTracklist = value;\n                OnPropertyChanged(\"ShowTracklist\");\n            }\n        }\n\n        public CompactView()\n        {\n            InitializeComponent();\n\n            _viewModel = new NowPlayingViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void CompactView_OnMouseMove(object sender, MouseEventArgs e)\n        {\n            if (e.LeftButton == MouseButtonState.Pressed && e.GetPosition(this).Y < 30)\n            {\n                DragMove();\n                Domain.Settings.Instance.CompactTop = Top;\n                Domain.Settings.Instance.CompactLeft = Left;\n            }\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged(string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n\n        private void CompactView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            Top = Domain.Settings.Instance.CompactTop;\n            Left = Domain.Settings.Instance.CompactLeft;\n        }\n\n        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)\n        {\n            WindowState = WindowState.Minimized;\n        }\n\n        private void UIElement_OnMouseWheel(object sender, MouseWheelEventArgs e)\n        {\n            if (e.Delta < 0)\n            {\n                ViewModelLocator.Main.Volume -= 5;\n                if (ViewModelLocator.Main.Volume < 0)\n                    ViewModelLocator.Main.Volume = 0;\n            }\n            else\n            {\n                ViewModelLocator.Main.Volume += 5;\n                if (ViewModelLocator.Main.Volume > 100)\n                    ViewModelLocator.Main.Volume = 100;\n            }\n        }\n\n        private void CompactView_OnStateChanged(object sender, EventArgs e)\n        {\n            if (WindowState == WindowState.Minimized && Domain.Settings.Instance.EnableTrayIcon)\n            {\n                Hide();\n                Visibility = Visibility.Collapsed;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/AddSocietyFlyout.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.Flyouts.AddSocietyFlyout\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:helpers=\"clr-namespace:Meridian.Helpers\"\n             xmlns:Properties=\"clr-namespace:Meridian.Resources.Localization\"\n             xmlns:controls=\"clr-namespace:Meridian.Controls\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"600\" Margin=\"0,50,0,50\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Center\"\n             x:Name=\"rootElement\">\n    <Grid Margin=\"0,20,0,20\" HorizontalAlignment=\"Center\" Width=\"400\">\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition MinHeight=\"150\"/>\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <StackPanel>\n            <TextBlock x:Name=\"Title\" Text=\"{x:Static Properties:MainResources.FeedAddSocietyTitle}\" FontSize=\"24\" FontWeight=\"Light\" Foreground=\"{DynamicResource AccentBrush}\"/>\n        </StackPanel>\n\n\n        <controls:BusyIndicator Grid.Row=\"1\" IsBusy=\"{Binding Tasks[societies].IsWorking, ElementName=rootElement}\" Error=\"{Binding Tasks[societies].Error, ElementName=rootElement}\">\n            <controls:BusyIndicator.BusyContentStyle>\n                <Style TargetType=\"ContentPresenter\">\n                    <Setter Property=\"Margin\" Value=\"0,5,0,0\"/>\n                </Style>\n            </controls:BusyIndicator.BusyContentStyle>\n            <ListBox Style=\"{StaticResource CommonListBoxStyle}\"  ItemsSource=\"{Binding ElementName=rootElement, Path=Societies}\"\n                 Padding=\"0\" Margin=\"0,10,0,10\"\n                 VirtualizingStackPanel.ScrollUnit=\"Pixel\"\n                 ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\">\n                <ListBox.ItemContainerStyle>\n                    <Style TargetType=\"ListBoxItem\" BasedOn=\"{StaticResource AlbumListBoxItemStyle}\">\n                        <Setter Property=\"Padding\" Value=\"0\" />\n                        <Setter Property=\"Margin\" Value=\"0,5,0,5\"></Setter>\n                    </Style>\n                </ListBox.ItemContainerStyle>\n                <ListBox.ItemTemplate>\n                    <DataTemplate>\n                        <Button Style=\"{StaticResource SimpleButtonStyle}\" ToolTip=\"{Binding Name}\" Height=\"50\" Command=\"{Binding ElementName=rootElement, Path=SelectSocietyCommand}\" CommandParameter=\"{Binding}\">\n                            <Grid x:Name=\"RootGrid\">\n                                <Grid.ColumnDefinitions>\n                                    <ColumnDefinition Width=\"Auto\"/>\n                                    <ColumnDefinition />\n                                </Grid.ColumnDefinitions>\n                                <Grid Width=\"50\">\n                                    <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding PhotoMedium}\" Stretch=\"UniformToFill\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                                </Grid>\n                                <TextBlock Grid.Column=\"1\" Text=\"{Binding Name}\" FontWeight=\"Normal\" FontSize=\"16\" Margin=\"10,0,0,0\" TextTrimming=\"CharacterEllipsis\" Opacity=\"0.8\"\n                                       Foreground=\"{DynamicResource ForegroundBrush}\" VerticalAlignment=\"Center\"/>\n                            </Grid>\n                        </Button>\n                    </DataTemplate>\n                </ListBox.ItemTemplate>\n            </ListBox>\n        </controls:BusyIndicator>\n        <StackPanel Grid.Row=\"2\" Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,20,0,0\">\n            <Button Content=\"{x:Static Properties:MainResources.CancelButton}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\" Click=\"CloseButtonClick\"/>\n        </StackPanel>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/AddSocietyFlyout.xaml.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Controls;\nusing Meridian.Domain;\nusing Meridian.Helpers;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.ViewModel;\nusing Neptune.UI.Extensions;\nusing VkLib.Core.Groups;\n\nnamespace Meridian.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for AddSocietyCommand.xaml\n    /// </summary>\n    public partial class AddSocietyFlyout : UserControl, INotifyPropertyChanged\n    {\n        private List<VkGroup> _societies;\n        private readonly Dictionary<string, LongRunningOperation> _tasks = new Dictionary<string, LongRunningOperation>();\n\n        #region Commands\n\n        public RelayCommand<VkGroup> SelectSocietyCommand { get; set; }\n\n        #endregion\n\n\n        public Dictionary<string, LongRunningOperation> Tasks\n        {\n            get { return _tasks; }\n        }\n\n        public List<VkGroup> Societies\n        {\n            get { return _societies; }\n            set\n            {\n                if (_societies == value)\n                    return;\n\n                _societies = value;\n                OnPropertyChanged(\"Societies\");\n            }\n        }\n\n        public AddSocietyFlyout()\n        {\n            _tasks.Add(\"societies\", new LongRunningOperation());\n\n            InitializeComponent();\n\n            InitializeCommands();\n            LoadSocieties();\n        }\n\n        private void InitializeCommands()\n        {\n            SelectSocietyCommand = new RelayCommand<VkGroup>(society =>\n            {\n                Close(society);\n            });\n        }\n\n        private async void LoadSocieties()\n        {\n            OnTaskStarted(\"societies\");\n\n            try\n            {\n                var response = await DataService.GetSocieties();\n                if (response != null && response.TotalCount > 0)\n                    Societies = response.Items.Where(s => Settings.Instance.FeedSocieties.All(x => x.Id != s.Id)).ToList();\n                else\n                {\n                    OnTaskError(\"societies\", ErrorResources.LoadSocietiesErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"societies\", ErrorResources.LoadSocietiesErrorCommon);\n            }\n\n            OnTaskFinished(\"societies\");\n        }\n\n        private void CloseButtonClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private void Close(object result = null)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n                flyout.Close(result);\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n\n        private void OnTaskStarted(string id)\n        {\n            _tasks[id].Error = null;\n            _tasks[id].IsWorking = true;\n        }\n\n        private void OnTaskFinished(string id)\n        {\n            _tasks[id].IsWorking = false;\n        }\n\n        private void OnTaskError(string id, string error)\n        {\n            _tasks[id].Error = error;\n            _tasks[id].IsWorking = false;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/AddToAlbumView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.AddToAlbumView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"600\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Center\"\n             x:Name=\"rootElement\"\n             Loaded=\"AddToAlbumView_OnLoaded\">\n    <Grid Margin=\"0,20,0,20\" HorizontalAlignment=\"Center\" Width=\"400\">\n        <Grid.RowDefinitions>\n            <RowDefinition/>\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <StackPanel>\n            <TextBlock x:Name=\"Title\" Text=\"Add to album\" FontSize=\"24\" FontWeight=\"Light\" Foreground=\"{DynamicResource AccentBrush}\"/>\n            <TextBlock Text=\"Album\" Opacity=\"0.6\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <ComboBox x:Name=\"AlbumsComboBox\" IsEditable=\"True\" Margin=\"0,5,0,0\" ItemsSource=\"{Binding Albums, ElementName=rootElement}\" DisplayMemberPath=\"Title\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                      Style=\"{StaticResource CommonComboBoxStyle}\"/>\n        </StackPanel>\n\n        <StackPanel Grid.Row=\"1\" Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,20,0,0\">\n            <Button Content=\"Add\" Padding=\"23,3\" Margin=\"0,0,10,0\" Style=\"{StaticResource HighlightedButtonStyle}\" Click=\"AddButtonClick\"/>\n            <Button Content=\"Cancel\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\" Click=\"CloseButtonClick\"/>\n        </StackPanel>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/AddToAlbumView.xaml.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Meridian.Controls;\nusing Meridian.Services;\nusing Meridian.ViewModel;\nusing Neptune.UI.Extensions;\nusing VkLib.Core.Audio;\nusing VkAudio = Meridian.Model.VkAudio;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for AddToAlbumView.xaml\n    /// </summary>\n    public partial class AddToAlbumView : UserControl, INotifyPropertyChanged\n    {\n        private List<VkPlaylist> _albums;\n        private VkAudio _track;\n\n        public List<VkPlaylist> Albums\n        {\n            get { return _albums; }\n            set\n            {\n                if (_albums == value)\n                    return;\n\n                _albums = value;\n                OnPropertyChanged(\"Albums\");\n            }\n        }\n\n        public AddToAlbumView(VkAudio track)\n        {\n            _track = track;\n\n            InitializeComponent();\n        }\n\n\n        private void Close(bool result = false)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n                flyout.Close(result);\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged(string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null)\n                handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n\n        private async void AddToAlbumView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            try\n            {\n                var albums = await DataService.GetUserAlbums();\n                if (albums != null && albums.Items != null)\n                {\n                    Albums = albums.Items;\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private void CloseButtonClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private async void AddButtonClick(object sender, RoutedEventArgs e)\n        {\n            var album = AlbumsComboBox.SelectedValue as VkAudioAlbum;\n            if (album == null && !string.IsNullOrEmpty(AlbumsComboBox.Text))\n            {\n                album = await AddNewAlbum(AlbumsComboBox.Text);\n            }\n\n            if (album == null)\n                return;\n\n            if (!_track.IsAddedByCurrentUser)\n            {\n                var result = await DataService.AddAudio(_track);\n                if (!result)\n                {\n                    LoggingService.Log(\"Unable to add audio \" + _track.Id + \" to current user.\");\n                    return;\n                }\n            }\n\n            try\n            {\n                var result = await ViewModelLocator.Vkontakte.Audio.MoveToAlbum(album.Id,\n                    new List<long>() { long.Parse(_track.Id) });\n                if (!result)\n                {\n                    LoggingService.Log(\"Unable to move audio \" + _track.Id + \" to album \" + album.Id + \".\");\n                    return;\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            Close();\n        }\n\n        private async Task<VkAudioAlbum> AddNewAlbum(string title)\n        {\n            try\n            {\n                var newAlbumId = await ViewModelLocator.Vkontakte.Audio.AddAlbum(title);\n                if (newAlbumId != 0)\n                {\n                    var album = new VkAudioAlbum();\n                    album.Id = newAlbumId;\n                    album.OwnerId = ViewModelLocator.Vkontakte.AccessToken.UserId;\n                    album.Title = title;\n                    return album;\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/CaptchaRequestView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.CaptchaRequestView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"400\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Center\"\n             Loaded=\"CaptchaRequestView_OnLoaded\">\n    <Grid Margin=\"0,20,0,20\" HorizontalAlignment=\"Center\" Width=\"300\">\n        <Grid.RowDefinitions>\n            <RowDefinition/>\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <StackPanel>\n            <TextBlock Text=\"{x:Static localization:MainResources.CaptchaTitle}\" FontSize=\"24\" FontWeight=\"Light\" Foreground=\"{DynamicResource AccentBrush}\"/>\n            <Image x:Name=\"Image\" Margin=\"0,10,0,0\" Stretch=\"Uniform\" Height=\"70\" HorizontalAlignment=\"Left\"/>\n            <TextBlock Text=\"{x:Static localization:MainResources.CaptchaEnterSymbols}\" Opacity=\"0.6\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <TextBox x:Name=\"CaptchaTextBox\" Style=\"{StaticResource CommonTextBoxStyle}\" Margin=\"0,5,0,0\" KeyUp=\"CaptchaTextBox_OnKeyUp\"/>\n        </StackPanel>\n\n        <StackPanel Grid.Row=\"1\" Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,20,0,0\">\n            <Button Content=\"{x:Static localization:MainResources.OkButton}\" Padding=\"36,3\" Margin=\"0,0,10,0\" Style=\"{StaticResource HighlightedButtonStyle}\" Click=\"SaveButtonClick\"/>\n            <Button Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\" Click=\"CloseButtonClick\"/>\n        </StackPanel>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/CaptchaRequestView.xaml.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing System.Windows.Media.Imaging;\nusing Meridian.Controls;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for CaptchaRequestView.xaml\n    /// </summary>\n    public partial class CaptchaRequestView : UserControl\n    {\n        private string _captchaSid;\n        private string _captchaImg;\n        private string _captchaKey;\n\n        public CaptchaRequestView(string captchaSid, string captchaImg)\n        {\n            _captchaImg = captchaImg;\n            _captchaSid = captchaSid;\n\n            InitializeComponent();\n\n\n            Image.Source = new BitmapImage(new Uri(_captchaImg));\n\n        }\n\n        private void CloseButtonClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private void SaveButtonClick(object sender, RoutedEventArgs e)\n        {\n            if (!string.IsNullOrEmpty(CaptchaTextBox.Text))\n                Close(CaptchaTextBox.Text);\n        }\n\n        private void Close(string result = null)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n                flyout.Close(result);\n        }\n\n        private void CaptchaTextBox_OnKeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.Key == Key.Enter && !string.IsNullOrEmpty(CaptchaTextBox.Text))\n            {\n                Close(CaptchaTextBox.Text);\n            }\n        }\n\n        private void CaptchaRequestView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            CaptchaTextBox.Focus();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/CommonErrorView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.CommonErrorView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" \n             VerticalAlignment=\"Center\">\n    <Grid>\n        <Grid HorizontalAlignment=\"Center\" Width=\"350\">\n            <StackPanel Margin=\"0,20,0,20\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\">\n                <TextBlock x:Name=\"TitleTextBlock\"  Text=\"{x:Static localization:MainResources.CommonErrorViewTitle}\" Foreground=\"{StaticResource AccentBrush}\" FontSize=\"24\" FontWeight=\"Light\"/>\n                <TextBlock x:Name=\"DescriptionTextBlock\"  Text=\"{x:Static localization:MainResources.CommonErrorViewContent}\" FontSize=\"12\" Margin=\"0,20,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\" TextWrapping=\"Wrap\"/>\n\n                <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,30,0,0\">\n                    <Button x:Name=\"RestartButton\" Content=\"{x:Static localization:MainResources.CommonErrorViewRestart}\" Padding=\"23,3\" Margin=\"0,0,10,0\" Style=\"{StaticResource HighlightedButtonStyle}\"\n                            Click=\"RestartButton_OnClick\"/>\n                    <Button x:Name=\"CloseButton\" Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\"\n                            Click=\"CloseButton_OnClick\"/>\n                </StackPanel>\n            </StackPanel>\n        </Grid>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/CommonErrorView.xaml.cs",
    "content": "﻿using System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Meridian.Controls;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for CommonErrorView.xaml\n    /// </summary>\n    public partial class CommonErrorView : UserControl\n    {\n        public CommonErrorView()\n        {\n            InitializeComponent();\n        }\n\n        public CommonErrorView(string title, string description) : this()\n        {\n            TitleTextBlock.Text = title;\n            DescriptionTextBlock.Text = description;\n        }\n\n        private void RestartButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            Close(true, true);\n        }\n\n        private void CloseButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private void Close(bool now = false, bool restart = false)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n            {\n                if (now)\n                    flyout.CloseNow(restart);\n                else\n                    flyout.Close(restart);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/CommonMessageView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.CommonMessageView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" \n             VerticalAlignment=\"Center\"\n             x:Name=\"rootElement\">\n    \n    <Grid HorizontalAlignment=\"Center\" Width=\"350\">\n        <StackPanel Margin=\"0,20,0,20\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\">\n            <TextBlock Text=\"{Binding Header, ElementName=rootElement}\" Foreground=\"{StaticResource AccentBrush}\" FontSize=\"24\" FontWeight=\"Light\"/>\n            <TextBlock Text=\"{Binding Message, ElementName=rootElement}\" FontSize=\"12\" Margin=\"0,20,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\" TextWrapping=\"Wrap\"/>\n\n            <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,30,0,0\">\n                <Button x:Name=\"OkButton\" Content=\"{x:Static localization:MainResources.OkButton}\" Padding=\"32,3\" Margin=\"0,0,10,0\" Style=\"{StaticResource HighlightedButtonStyle}\"\n                        Click=\"OkButton_OnClick\"/>\n            </StackPanel>\n        </StackPanel>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/CommonMessageView.xaml.cs",
    "content": "﻿using System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Meridian.Controls;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for CommonMessageView.xaml\n    /// </summary>\n    public partial class CommonMessageView : UserControl\n    {\n        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(\n            \"Header\", typeof (string), typeof (CommonMessageView), new PropertyMetadata(default(string)));\n\n        public string Header\n        {\n            get { return (string) GetValue(HeaderProperty); }\n            set { SetValue(HeaderProperty, value); }\n        }\n\n        public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(\n            \"Message\", typeof (string), typeof (CommonMessageView), new PropertyMetadata(default(string)));\n\n        public string Message\n        {\n            get { return (string) GetValue(MessageProperty); }\n            set { SetValue(MessageProperty, value); }\n        }\n\n        public CommonMessageView()\n        {\n            InitializeComponent();\n        }\n\n        private void OkButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private void Close(bool now = false)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n            {\n                if (now)\n                    flyout.CloseNow();\n                else\n                    flyout.Close();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/EditAlbumView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.EditAlbumView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"300\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Center\">\n\n    <Grid Margin=\"0,20,0,20\" HorizontalAlignment=\"Center\" Width=\"400\">\n        <Grid.RowDefinitions>\n            <RowDefinition/>\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <StackPanel>\n            <TextBlock x:Name=\"Title\" Text=\"{x:Static localization:MainResources.EditAlbumNewTitle}\" FontSize=\"24\" FontWeight=\"Light\" Foreground=\"{DynamicResource AccentBrush}\"/>\n            <TextBlock Text=\"{x:Static localization:MainResources.EditAlbumName}\" Opacity=\"0.6\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <TextBox x:Name=\"TitleTextBox\" Style=\"{StaticResource CommonTextBoxStyle}\" Margin=\"0,5,0,0\" />\n        </StackPanel>\n\n        <StackPanel Grid.Row=\"1\" Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,20,0,0\">\n            <Button Content=\"{x:Static localization:MainResources.EditAlbumSave}\" Padding=\"23,3\" Margin=\"0,0,10,0\" Style=\"{StaticResource HighlightedButtonStyle}\" Click=\"SaveButtonClick\"/>\n            <Button Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\" Click=\"CloseButtonClick\"/>\n        </StackPanel>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/EditAlbumView.xaml.cs",
    "content": "﻿using System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Meridian.Controls;\nusing Meridian.Resources.Localization;\nusing Neptune.UI.Extensions;\nusing VkLib.Core.Audio;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for EditAlbumView.xaml\n    /// </summary>\n    public partial class EditAlbumView : UserControl\n    {\n        private VkPlaylist _album;\n\n        public EditAlbumView(VkPlaylist album)\n        {\n            InitializeComponent();\n\n            _album = album;\n\n            TitleTextBox.Text = _album.Title;\n\n            if (album.Id != 0)\n                Title.Text = MainResources.EditAlbumTitle;\n        }\n\n        private void CloseButtonClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private void Close(bool result = false)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n                flyout.Close(result);\n        }\n\n        private void SaveButtonClick(object sender, RoutedEventArgs e)\n        {\n            if (string.IsNullOrWhiteSpace(TitleTextBox.Text))\n                return;\n\n            _album.Title = TitleTextBox.Text;\n\n            Close(true);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/EditAudioView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.EditAudioView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"400\" d:DesignWidth=\"400\"\n             Focusable=\"True\" FocusManager.IsFocusScope=\"True\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Center\">\n    <Grid HorizontalAlignment=\"Center\" Width=\"320\" Height=\"380\">\n        <StackPanel Margin=\"0,20,0,20\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\">\n            <TextBlock Text=\"{x:Static localization:MainResources.EditAudioTitle}\" Foreground=\"{DynamicResource AccentBrush}\" FontSize=\"24\" FontWeight=\"Light\"/>\n            <TextBlock Text=\"{x:Static localization:MainResources.EditAudioName}\" FontSize=\"12\" Margin=\"0,20,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <TextBox x:Name=\"TitleTextBox\" Margin=\"0,3,0,0\" Text=\"{Binding Title, Mode=TwoWay}\" Style=\"{StaticResource CommonTextBoxStyle}\" Foreground=\"{DynamicResource ForegroundBrush}\" />\n            <TextBlock Text=\"{x:Static localization:MainResources.EditAudioArtist}\" FontSize=\"12\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <TextBox Margin=\"0,3,0,0\" Text=\"{Binding Artist, Mode=TwoWay}\" Style=\"{StaticResource CommonTextBoxStyle}\" Foreground=\"{DynamicResource ForegroundBrush}\" />\n            <TextBlock Text=\"{x:Static localization:MainResources.EditAudioLyrics}\" FontSize=\"12\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <ScrollViewer Margin=\"0,3,0,0\">\n                <TextBox AcceptsReturn=\"True\" Text=\"{Binding Lyrics, Mode=TwoWay}\" TextWrapping=\"Wrap\" Style=\"{StaticResource CommonTextBoxStyle}\" Height=\"100\"\n                         Foreground=\"{DynamicResource ForegroundBrush}\" MaxLength=\"999999\"/>\n            </ScrollViewer>\n            <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,20,0,0\">\n                <Button Content=\"{x:Static localization:MainResources.EditAudioSave}\" Padding=\"23,3\" Margin=\"0,0,10,0\" Style=\"{StaticResource HighlightedButtonStyle}\" Command=\"{Binding SaveCommand}\"/>\n                <Button Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\" Command=\"{Binding CloseCommand}\"/>\n            </StackPanel>\n        </StackPanel>\n        <ProgressBar Style=\"{StaticResource CommonProgressBarStyle}\" IsIndeterminate=\"{Binding IsWorking}\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}}\" VerticalAlignment=\"Center\"/>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/EditAudioView.xaml.cs",
    "content": "﻿using System.Windows.Controls;\nusing Meridian.Model;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Flyouts;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for EditAudioView.xaml\n    /// </summary>\n    public partial class EditAudioView : UserControl\n    {\n        private EditAudioViewModel _viewModel;\n\n        public EditAudioView(VkAudio audio)\n        {\n            InitializeComponent();\n\n            _viewModel = new EditAudioViewModel();\n            this.DataContext = _viewModel;\n            _viewModel.Track = audio;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/Local/MusicScanView.xaml",
    "content": "﻿<controls:FlyoutContent x:Class=\"Meridian.View.Flyouts.Local.MusicScanView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             xmlns:controls=\"clr-namespace:Meridian.Controls\"\n             mc:Ignorable=\"d\" \n             d:DesignWidth=\"600\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Center\"\n             x:Name=\"rootElement\">\n    <Grid HorizontalAlignment=\"Center\" Width=\"320\">\n        <StackPanel Margin=\"0,20,0,20\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\">\n            <StackPanel>\n                <TextBlock Text=\"{x:Static localization:MainResources.MusicScanTitle}\" Foreground=\"{StaticResource AccentBrush}\" FontSize=\"24\" FontWeight=\"Light\"/>\n                <TextBlock Text=\"{x:Static localization:MainResources.MusicScanDescription}\" FontSize=\"12\" Margin=\"0,20,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                <ProgressBar Style=\"{StaticResource CommonProgressBarStyle}\" Value=\"{Binding ElementName=rootElement, Path=Progress}\" VerticalAlignment=\"Center\" Margin=\"-12,0,-12,0\"/>\n            </StackPanel>\n\n            <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,20,0,0\">\n                <Button Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\" Command=\"{Binding CancelCommand, ElementName=rootElement}\"\n                         Visibility=\"{Binding IsFinished, ElementName=rootElement, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\"/>\n            </StackPanel>\n        </StackPanel>\n    </Grid>\n</controls:FlyoutContent>\n"
  },
  {
    "path": "Meridian/View/Flyouts/Local/MusicScanView.xaml.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Runtime.CompilerServices;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Controls;\nusing Meridian.Services;\nusing Microsoft;\n\nnamespace Meridian.View.Flyouts.Local\n{\n    /// <summary>\n    /// Interaction logic for MusicScanView.xaml\n    /// </summary>\n    public partial class MusicScanView : FlyoutContent, INotifyPropertyChanged\n    {\n        private double _progress;\n\n        #region Commands\n\n        /// <summary>\n        /// Cancel scanning command\n        /// </summary>\n        public RelayCommand CancelCommand { get; private set; }\n\n        #endregion\n\n        /// <summary>\n        /// Scan progress\n        /// </summary>\n        public double Progress\n        {\n            get { return _progress; }\n            set\n            {\n                if (_progress == value)\n                    return;\n\n                _progress = value;\n                OnPropertyChanged();\n            }\n        }\n\n        public MusicScanView()\n        {\n            InitializeComponent();\n            InitializeCommands();\n\n            Load();\n        }\n\n        private void InitializeCommands()\n        {\n            CancelCommand = new RelayCommand(() =>\n            {\n                ServiceLocator.LocalMusicService.ScanMusicCancel();\n                Close();\n            });\n        }\n\n        private async void Load()\n        {\n            await ServiceLocator.LocalMusicService.ScanMusic(new Progress<double>(UpdateProgress));\n            Close();\n        }\n\n        private void UpdateProgress(double progress)\n        {\n            Progress = progress;\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/LoginLastFmMessageView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.LoginLastFmMessageView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"180\" d:DesignWidth=\"600\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Center\">\n    <Grid Margin=\"0,20,0,20\" HorizontalAlignment=\"Center\" Width=\"400\">\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <TextBlock Text=\"{x:Static localization:MainResources.LastFmScrobblingTitle}\" FontSize=\"24\" FontWeight=\"Light\" Foreground=\"#e51400\"/>\n        <TextBlock Text=\"{x:Static localization:MainResources.LastFmScrobblingMessage}\" Grid.Row=\"1\" TextWrapping=\"Wrap\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n        <StackPanel Grid.Row=\"2\" Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,20,0,0\">\n            <Button Content=\"{x:Static localization:MainResources.LastFmScrobblingGoSettings}\" Padding=\"23,3\" Margin=\"0,0,10,0\" Style=\"{StaticResource LastFmHighlightedButtonStyle}\" Click=\"SettingsButtonClick\"/>\n            <Button Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\" Click=\"CancelButtonClick\"/>\n        </StackPanel>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/LoginLastFmMessageView.xaml.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing GalaSoft.MvvmLight.Messaging;\nusing Meridian.Controls;\nusing Meridian.ViewModel;\nusing Neptune.Messages;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for LoginLastFmMessageView.xaml\n    /// </summary>\n    public partial class LoginLastFmMessageView : UserControl\n    {\n        public LoginLastFmMessageView()\n        {\n            InitializeComponent();\n        }\n\n        private void CancelButtonClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private void SettingsButtonClick(object sender, RoutedEventArgs e)\n        {\n            Close(true);\n\n            Messenger.Default.Send(new NavigateToPageMessage()\n            {\n                Page = \"/Settings.SettingsView\",\n                Parameters = new Dictionary<string, object>()\n                {\n                    {\"section\", \"accounts\"}\n                }\n            });\n\n            ViewModelLocator.Main.ShowSidebar = false;\n        }\n\n        private void Close(bool now = false)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n            {\n                if (now)\n                    flyout.CloseNow();\n                else\n                    flyout.Close();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/LoginLastFmView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.LoginLastFmView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:controls=\"clr-namespace:Meridian.Controls\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" \n             VerticalAlignment=\"Center\">\n    <Grid HorizontalAlignment=\"Center\" Width=\"285\">\n        <StackPanel Margin=\"0,20,0,20\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\">\n            <TextBlock Text=\"Last.FM\" Foreground=\"#e51400\" FontSize=\"24\" FontWeight=\"Light\"/>\n            <TextBlock Text=\"{x:Static localization:MainResources.LastFmLoginTitle}\" FontSize=\"12\" Margin=\"0,20,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <TextBox x:Name=\"LoginTextBox\" Margin=\"0,3,0,0\" Text=\"{Binding Login, Mode=TwoWay}\" Style=\"{StaticResource CommonTextBoxStyle}\" KeyUp=\"LoginTextBox_OnKeyUp\"/>\n            <TextBlock Text=\"{x:Static localization:MainResources.LoginPasswordTitle}\" FontSize=\"12\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <controls:BindablePasswordBox x:Name=\"PasswordBox\" Password=\"{Binding Password, Mode=TwoWay}\" Width=\"285\" Margin=\"0,3,0,0\" KeyUp=\"PasswordBox_OnKeyUp\"/>\n            <TextBlock Foreground=\"Red\" Text=\"{Binding LoginError}\" Margin=\"0,3,0,0\" Visibility=\"{Binding LoginError, Converter={StaticResource NullToVisibilityConverter}}\"\n                       TextWrapping=\"Wrap\"/>\n            <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,10,0,0\">\n                <Button Content=\"{x:Static localization:MainResources.LoginLoginButton}\" Padding=\"23,3\" Margin=\"0,0,10,0\" Command=\"{Binding LoginCommand}\" Style=\"{StaticResource LastFmHighlightedButtonStyle}\"/>\n                <Button Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Command=\"{Binding CancelCommand}\" Style=\"{StaticResource CommonButtonStyle}\"/>\n            </StackPanel>\n        </StackPanel>\n        <StackPanel Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}}\" HorizontalAlignment=\"Stretch\" VerticalAlignment=\"Center\" Margin=\"0,50,0,50\">\n            <TextBlock Text=\"Last.FM\" Foreground=\"#e51400\" FontSize=\"24\" FontWeight=\"Light\" HorizontalAlignment=\"Left\"/>\n            <TextBlock Text=\"{x:Static localization:MainResources.Loading}\" FontSize=\"14\" HorizontalAlignment=\"Left\" Opacity=\"0.4\" FontWeight=\"Light\" Foreground=\"{DynamicResource ForegroundBrush}\" Margin=\"0,10,0,10\"/>\n            <ProgressBar Style=\"{StaticResource CommonProgressBarStyle}\" IsIndeterminate=\"{Binding IsWorking}\" Foreground=\"#e51400\" Margin=\"-12,0,-12,0\"/>\n        </StackPanel>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/LoginLastFmView.xaml.cs",
    "content": "﻿using System.Windows.Controls;\nusing System.Windows.Input;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Flyouts;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for LoginLastFmView.xaml\n    /// </summary>\n    public partial class LoginLastFmView : UserControl\n    {\n        private LoginLastFmViewModel _viewModel;\n\n        public LoginLastFmView()\n        {\n            InitializeComponent();\n\n            _viewModel = new LoginLastFmViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void LoginTextBox_OnKeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.Key != Key.Enter)\n                return;\n\n            if (!string.IsNullOrEmpty(LoginTextBox.Text))\n            {\n                if (!string.IsNullOrEmpty(PasswordBox.Password))\n                {\n                    _viewModel.LoginCommand.Execute(null);\n                }\n                else\n                {\n                    PasswordBox.Child.Focus();\n                }\n            }\n        }\n\n        private void PasswordBox_OnKeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.Key != Key.Enter)\n                return;\n\n            if (!string.IsNullOrEmpty(PasswordBox.Password))\n            {\n                if (!string.IsNullOrEmpty(LoginTextBox.Text))\n                {\n                    _viewModel.LoginCommand.Execute(null);\n                }\n                else\n                {\n                    LoginTextBox.Focus();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/LyricsView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.LyricsView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"600\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Center\">\n    <Grid Margin=\"0,5,0,5\" HorizontalAlignment=\"Center\" Width=\"400\" MaxHeight=\"500\">\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <StackPanel>\n            <TextBlock Text=\"{Binding Track.Title}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"24\" Margin=\"0,10,0,0\" FontFamily=\"Segoe UI SemiLight\"/>\n            <TextBlock Text=\"{Binding Track.Artist}\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"14\" Margin=\"0,-2,0,0\" Opacity=\"0.6\"/>\n        </StackPanel>\n        <ScrollViewer Grid.Row=\"1\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\" Margin=\"0,10,0,10\">\n            <TextBox AcceptsReturn=\"True\" Text=\"{Binding Lyrics}\" TextWrapping=\"Wrap\" BorderThickness=\"0\" Padding=\"0,0,5,0\" Margin=\"-4,0,0,0\" IsReadOnly=\"True\" IsReadOnlyCaretVisible=\"False\"\n                     IsInactiveSelectionHighlightEnabled=\"True\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                     Style=\"{StaticResource CommonTextBoxStyle}\"/>\n        </ScrollViewer>\n\n        <ProgressBar Style=\"{StaticResource CommonProgressBarStyle}\" IsIndeterminate=\"{Binding IsWorking}\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}}\" Grid.Row=\"1\"/>\n\n        <Button Grid.Row=\"2\" Style=\"{StaticResource HighlightedButtonStyle}\" Content=\"{x:Static localization:MainResources.Close}\" HorizontalAlignment=\"Right\" Margin=\"0,0,0,10\" Click=\"ButtonBase_OnClick\"/>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/LyricsView.xaml.cs",
    "content": "﻿using System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Meridian.Controls;\nusing Meridian.Model;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Flyouts;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for LyricsView.xaml\n    /// </summary>\n    public partial class LyricsView : UserControl\n    {\n        private LyricsViewModel _viewModel;\n\n        public LyricsView(VkAudio audio)\n        {\n            InitializeComponent();\n\n            _viewModel = new LyricsViewModel();\n            this.DataContext = _viewModel;\n            _viewModel.Track = audio;\n        }\n\n        private void Close(bool now = false)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n            {\n                if (now)\n                    flyout.CloseNow();\n                else\n                    flyout.Close();\n            }\n        }\n\n        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/ShareView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.ShareView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"450\" d:DesignWidth=\"722\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" VerticalAlignment=\"Center\"\n             x:Name=\"rootElement\">\n    <Grid HorizontalAlignment=\"Center\" MinWidth=\"300\" Height=\"410\" Margin=\"0,20,0,20\">\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"Auto\"/>\n            <ColumnDefinition />\n        </Grid.ColumnDefinitions>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition/>\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <TextBlock Text=\"{x:Static localization:MainResources.ShareTitle}\" FontSize=\"24\" FontWeight=\"Light\" Margin=\"0,0,0,10\" Foreground=\"{DynamicResource AccentBrush}\"/>\n\n        <!-- Art -->\n        <Grid Grid.RowSpan=\"2\" Grid.Row=\"1\" Width=\"250\" Height=\"250\" VerticalAlignment=\"Top\" >\n            <Rectangle Fill=\"Black\" Opacity=\"0.05\" StrokeThickness=\"10\"/>\n            <Rectangle Stroke=\"#22000000\" StrokeThickness=\"1\"/>\n            <Button Style=\"{StaticResource AddButtonStyle}\" VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\" Width=\"50\" Height=\"50\" Command=\"{Binding AddImageCommand}\"/>\n            <Image Source=\"{Binding Image}\" Stretch=\"UniformToFill\"/>\n            <Rectangle Fill=\"Black\" Opacity=\"0.1\" Visibility=\"{Binding Image, Converter={StaticResource NullToVisibilityConverter}}\"/>\n            <Button Style=\"{StaticResource CloseButtonStyle}\" Visibility=\"{Binding Image, Converter={StaticResource NullToVisibilityConverter}}\" VerticalAlignment=\"Top\" HorizontalAlignment=\"Right\" Margin=\"10\" Foreground=\"White\" Command=\"{Binding ClearImageCommand}\"/>\n        </Grid>\n\n        <ScrollViewer Grid.Column=\"1\" Margin=\"20,0,0,0\" Padding=\"0,0,20,0\" Grid.Row=\"1\" VerticalScrollBarVisibility=\"Auto\" HorizontalScrollBarVisibility=\"Disabled\">\n            <Grid>\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\"/>\n                    <RowDefinition Height=\"Auto\"/>\n                    <RowDefinition />\n                </Grid.RowDefinitions>\n                <StackPanel >\n                    <RadioButton Content=\"{x:Static localization:MainResources.ShareToMyWall}\" FontSize=\"18\" FontWeight=\"Light\" VerticalContentAlignment=\"Center\" IsChecked=\"True\" Padding=\"5,0,0,3\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <TextBlock Text=\"{x:Static localization:MainResources.ShareToMyWallHint}\" Margin=\"19,-3,0,0\" FontSize=\"14\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <RadioButton x:Name=\"ShareToUserCheckbox\" Content=\"{x:Static localization:MainResources.ShareToUserWall}\" Margin=\"0,10,0,0\" Padding=\"5,0,0,3\" FontSize=\"18\" FontWeight=\"Light\" VerticalContentAlignment=\"Center\" IsChecked=\"{Binding ShareToUser, Mode=TwoWay}\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <ComboBox IsEditable=\"True\" Margin=\"0,5,0,0\" IsEnabled=\"{Binding IsChecked, ElementName=ShareToUserCheckbox}\" ItemsSource=\"{Binding Friends}\" DisplayMemberPath=\"Name\" SelectedItem=\"{Binding SelectedFriend, Mode=TwoWay}\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                              Style=\"{StaticResource CommonComboBoxStyle}\"/>\n                    <RadioButton x:Name=\"ShareToSocietyCheckbox\" Content=\"{x:Static localization:MainResources.ShareToSociety}\" Margin=\"0,10,0,0\" Padding=\"5,0,0,3\" FontSize=\"18\" FontWeight=\"Light\" VerticalContentAlignment=\"Center\" IsChecked=\"{Binding ShareToSociety, Mode=TwoWay}\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <ComboBox IsEditable=\"True\" Margin=\"0,5,0,0\" IsEnabled=\"{Binding IsChecked, ElementName=ShareToSocietyCheckbox}\" ItemsSource=\"{Binding Societies}\" DisplayMemberPath=\"Name\" SelectedItem=\"{Binding SelectedSociety, Mode=TwoWay}\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                              Style=\"{StaticResource CommonComboBoxStyle}\"/>\n                    <CheckBox x:Name=\"ShareAsSocietyCheckBox\" Content=\"{x:Static localization:MainResources.ShareAsSociety}\" Margin=\"0,5,0,0\" IsEnabled=\"{Binding SelectedSociety.IsAdmin, FallbackValue=False}\" IsChecked=\"{Binding ShareAsSociety, Mode=TwoWay}\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <CheckBox Content=\"{x:Static localization:MainResources.ShareSigned}\" Margin=\"0,5,0,0\" IsEnabled=\"{Binding IsChecked, ElementName=ShareAsSocietyCheckBox}\" IsChecked=\"{Binding ShareSigned, Mode=TwoWay}\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                </StackPanel>\n\n                <Rectangle Grid.Row=\"1\" Height=\"1\" Stroke=\"{DynamicResource ForegroundBrush}\" StrokeThickness=\"1\" Opacity=\"0.2\" StrokeDashArray=\"4 4\" Margin=\"0,10,0,10\" SnapsToDevicePixels=\"True\" VerticalAlignment=\"Top\"/>\n\n                <ItemsControl Grid.Row=\"2\" Margin=\"0,5,0,10\" ItemsSource=\"{Binding Tracks}\">\n                    <ItemsControl.ItemTemplate>\n                        <DataTemplate>\n                            <Grid Margin=\"0,0,0,5\">\n                                <Grid.ColumnDefinitions>\n                                    <ColumnDefinition />\n                                    <ColumnDefinition Width=\"Auto\"/>\n                                </Grid.ColumnDefinitions>\n                                <TextBlock Text=\"{Binding Title}\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                <Button Grid.Column=\"1\" Style=\"{StaticResource CloseButtonStyle}\" Width=\"12\" Height=\"12\" Foreground=\"{DynamicResource ForegroundBrush}\" VerticalAlignment=\"Center\" Margin=\"10,0,0,0\"\n                                    Command=\"{Binding DataContext.RemoveTrackCommand, ElementName=rootElement}\" CommandParameter=\"{Binding}\"/>\n                            </Grid>\n                        </DataTemplate>\n                    </ItemsControl.ItemTemplate>\n                </ItemsControl>\n            </Grid>\n        </ScrollViewer>\n\n        <StackPanel Grid.Column=\"1\" Grid.Row=\"2\" Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,20,0,0\">\n            <Button Content=\"{x:Static localization:MainResources.SharePublishButton}\" Padding=\"23,3\" Margin=\"0,0,10,0\" IsEnabled=\"{Binding CanGoNext}\" Style=\"{StaticResource HighlightedButtonStyle}\" Command=\"{Binding PublishCommand}\"/>\n            <Button Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\" Command=\"{Binding CloseCommand}\"/>\n        </StackPanel>\n\n        <Border Background=\"{DynamicResource MainBackgroundBrush}\" Grid.ColumnSpan=\"2\" Grid.RowSpan=\"2\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, FallbackValue=Collapsed}\">\n            <Grid VerticalAlignment=\"Center\">\n                <Grid.RowDefinitions>\n                    <RowDefinition />\n                    <RowDefinition />\n                </Grid.RowDefinitions>\n                <Rectangle Grid.RowSpan=\"2\" Fill=\"{DynamicResource MainBackgroundBrush}\" Opacity=\"0.6\" />\n                <TextBlock Text=\"{x:Static localization:MainResources.SharePublishing}\" FontSize=\"18\" FontWeight=\"Light\"/>\n                <ProgressBar Grid.Row=\"1\" Value=\"{Binding Progress}\" Margin=\"0,5,0,0\" Padding=\"0\" Height=\"5\" Style=\"{StaticResource CommonProgressBarStyle}\" Maximum=\"{Binding ProgressMaximum}\"/>\n            </Grid>\n        </Border>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/ShareView.xaml.cs",
    "content": "﻿using System.Windows.Controls;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for ShareView.xaml\n    /// </summary>\n    public partial class ShareView : UserControl\n    {\n        public ShareView()\n        {\n            InitializeComponent();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/TellFriendsRequestView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.TellFriendsRequestView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             Background=\"{DynamicResource MainBackgroundBrush}\" \n             VerticalAlignment=\"Center\">\n    <Grid>\n        <Grid HorizontalAlignment=\"Center\" Width=\"350\">\n            <StackPanel Margin=\"0,20,0,20\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\">\n                <TextBlock Text=\"{x:Static localization:MainResources.TellFriendsRequestTitle}\" Foreground=\"{StaticResource AccentBrush}\" FontSize=\"24\" FontWeight=\"Light\"/>\n                <TextBlock Text=\"{x:Static localization:MainResources.TellFriendsRequestContent}\" FontSize=\"12\" Margin=\"0,20,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\" TextWrapping=\"Wrap\"/>\n\n                <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,30,0,0\">\n                    <Button x:Name=\"TellButton\" Content=\"{x:Static localization:MainResources.TellFriendsRequestTellButton}\" Padding=\"23,3\" Margin=\"0,0,10,0\" Style=\"{StaticResource HighlightedButtonStyle}\"\n                            Click=\"TellButton_OnClick\"/>\n                    <Button x:Name=\"CancelButton\" Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\"\n                            Click=\"CancelButton_OnClick\"/>\n                </StackPanel>\n            </StackPanel>\n        </Grid>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/TellFriendsRequestView.xaml.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Meridian.Controls;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.ViewModel;\nusing Neptune.UI.Extensions;\nusing VkLib.Core.Attachments;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for TellFriendsRequestView.xaml\n    /// </summary>\n    public partial class TellFriendsRequestView : UserControl\n    {\n        public TellFriendsRequestView()\n        {\n            InitializeComponent();\n        }\n\n        private void Close(bool now = false)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n            {\n                if (now)\n                    flyout.CloseNow();\n                else\n                    flyout.Close();\n            }\n        }\n\n        private void TellButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n            Tell();\n        }\n\n        private void CancelButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private async void Tell()\n        {\n            try\n            {\n                var posId = await ViewModelLocator.Vkontakte.Wall.Post(message: MainResources.AboutTellMessage, attachments:\n                    new[] { new VkLinkAttachment() { Url = \"http://meridianvk.com\" } });\n\n                if (posId != 0)\n                {\n                    var flyout = new FlyoutControl();\n                    flyout.FlyoutContent = new TellResultView(posId);\n                    flyout.Show();\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/TellResultView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.TellResultView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n             Background=\"{DynamicResource MainBackgroundBrush}\" \n             VerticalAlignment=\"Center\">\n    <Grid HorizontalAlignment=\"Center\" Width=\"285\">\n        <StackPanel Margin=\"0,20,0,20\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\">\n            <TextBlock Text=\"{x:Static localization:MainResources.TellViewTitle}\" Foreground=\"{DynamicResource AccentBrush}\" FontSize=\"24\" FontWeight=\"Light\"/>\n            <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,30,0,0\">\n                <Button x:Name=\"GoToPostButton\" Content=\"{x:Static localization:MainResources.TellViewGoToPost}\" Padding=\"23,3\" Margin=\"0,0,10,0\" Style=\"{StaticResource HighlightedButtonStyle}\"\n                        Click=\"GoToPostButton_OnClick\"/>\n                <Button x:Name=\"CancelButton\" Content=\"{x:Static localization:MainResources.Close}\" Padding=\"23,3\" Style=\"{StaticResource CommonButtonStyle}\"\n                        Click=\"CancelButton_OnClick\"/>\n            </StackPanel>\n        </StackPanel>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/TellResultView.xaml.cs",
    "content": "﻿using System.Diagnostics;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Meridian.Controls;\nusing Meridian.ViewModel;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for TellResultView.xaml\n    /// </summary>\n    public partial class TellResultView : UserControl\n    {\n        private readonly long _postId;\n\n        public TellResultView(long postId)\n        {\n            _postId = postId;\n\n            InitializeComponent();\n        }\n\n        private void CancelButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private void GoToPostButton_OnClick(object sender, RoutedEventArgs e)\n        {\n            var url = \"http://vk.com/wall\" + ViewModelLocator.Vkontakte.AccessToken.UserId + \"_\" + _postId;\n            Process.Start(url);\n\n            Close();\n        }\n\n        private void Close()\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n            {\n                flyout.Close();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Flyouts/WebValidationView.xaml",
    "content": "﻿<UserControl x:Class=\"Meridian.View.Flyouts.WebValidationView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n             xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"300\" d:DesignWidth=\"600\"\n             Background=\"{DynamicResource MainBackgroundBrush}\"\n             Loaded=\"WebValidationView_OnLoaded\" Margin=\"0,100,0,100\">\n    <Grid Margin=\"0,5,0,5\" HorizontalAlignment=\"Center\" Width=\"400\" MaxHeight=\"500\">\n        <Grid.RowDefinitions>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <WebBrowser x:Name=\"Browser\" Navigating=\"Browser_OnNavigating\" Navigated=\"Browser_OnNavigated\" Visibility=\"Collapsed\" Margin=\"0,0,0,0\"/>\n        \n        <ProgressBar x:Name=\"ProgressBar\" Style=\"{StaticResource CommonProgressBarStyle}\" IsIndeterminate=\"True\" VerticalAlignment=\"Center\"/>\n\n        <Button Grid.Row=\"1\" Style=\"{StaticResource HighlightedButtonStyle}\" Content=\"{x:Static localization:MainResources.Close}\" HorizontalAlignment=\"Right\" Margin=\"0,10,0,10\" Click=\"ButtonBase_OnClick\"/>\n\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "Meridian/View/Flyouts/WebValidationView.xaml.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Navigation;\nusing Meridian.Controls;\nusing Meridian.ViewModel;\nusing Neptune.UI.Extensions;\nusing Microsoft.Win32;\nusing System.IO;\nusing System.Reflection;\n\nnamespace Meridian.View.Flyouts\n{\n    /// <summary>\n    /// Interaction logic for WebValidationView.xaml\n    /// </summary>\n    public partial class WebValidationView : UserControl\n    {\n        private Uri _redirectUri;\n\n        public WebValidationView(Uri redirectUri)\n        {\n            EnableIE11Mode();\n\n            InitializeComponent();\n\n            _redirectUri = redirectUri;\n        }\n\n        private void EnableIE11Mode()\n        {\n            //force webbrowser to use IE9 engine instead of default IE7\n            var browserEmulationKey = Registry.CurrentUser.OpenSubKey(\"Software\\\\Microsoft\\\\Internet Explorer\\\\Main\\\\FeatureControl\\\\FEATURE_BROWSER_EMULATION\", true);\n            if (browserEmulationKey == null)\n            {\n                //if there is no such key in registry create it\n                browserEmulationKey = Registry.CurrentUser.CreateSubKey(\"Software\\\\Microsoft\\\\Internet Explorer\\\\Main\\\\FeatureControl\\\\FEATURE_BROWSER_EMULATION\");\n            }\n\n            var appName = Path.GetFileName(Assembly.GetExecutingAssembly().Location);\n            var v = browserEmulationKey.GetValue(appName);\n            if (v == null || (int)v != 0x270f)\n            {\n                browserEmulationKey.SetValue(appName, 0x270f);\n            }\n        }\n\n        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private void WebValidationView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            Browser.Navigate(_redirectUri);\n        }\n\n\n        private void Close(object result = null, bool now = false)\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n            {\n                if (now)\n                    flyout.CloseNow(result);\n                else\n                    flyout.Close(result);\n            }\n        }\n\n        private void Browser_OnNavigated(object sender, NavigationEventArgs e)\n        {\n            Debug.WriteLine(\"Navigated \" + e.Uri);\n\n            ProgressBar.Visibility = Visibility.Collapsed;\n            Browser.Visibility = Visibility.Visible;\n        }\n\n        private void Browser_OnNavigating(object sender, NavigatingCancelEventArgs e)\n        {\n            Debug.WriteLine(\"Navigating \" + e.Uri);\n\n            ProgressBar.Visibility = Visibility.Visible;\n            Browser.Visibility = Visibility.Collapsed;\n\n            var token = ViewModelLocator.Vkontakte.OAuth.ProcessAuth(e.Uri);\n            if (token != null && token.AccessToken != null && !string.IsNullOrEmpty(token.AccessToken.Token))\n            {\n                token.AccessToken.ExpiresIn = DateTime.MaxValue;\n                Close(token.AccessToken);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Local/LocalAlbumView.xaml",
    "content": "﻿<controls:PageBase x:Class=\"Meridian.View.Local.LocalAlbumView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"800\"\n      Background=\"{DynamicResource MainBackgroundBrush}\"\n      Loaded=\"LocalAlbumView_OnLoaded\"\n      x:Name=\"pageRoot\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\"/>\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n\n        <!-- Background art -->\n        <Grid x:Name=\"BackgroundArtGrid\" Grid.RowSpan=\"2\" MaxWidth=\"800\" MaxHeight=\"800\" Margin=\"0,85,0,0\" HorizontalAlignment=\"Right\" VerticalAlignment=\"Top\" ClipToBounds=\"True\" Opacity=\"0.4\">\n            <Grid.OpacityMask>\n                <LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\">\n                    <GradientStop Offset=\"0.5\" Color=\"White\"/>\n                    <GradientStop Offset=\"1\" Color=\"Transparent\"/>\n                </LinearGradientBrush>\n            </Grid.OpacityMask>\n\n            <controls:ImageTransitionControl x:Name=\"BackgroundArtControl\" Source=\"{Binding Album.Cover}\" Margin=\"0,0,0,0\" HorizontalContentAlignment=\"Right\">\n                <controls:ImageTransitionControl.OpacityMask>\n                    <LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"1,0\">\n                        <GradientStop Offset=\"0\" Color=\"Transparent\"/>\n                        <GradientStop Offset=\"1\" Color=\"White\"/>\n                    </LinearGradientBrush>\n                </controls:ImageTransitionControl.OpacityMask>\n            </controls:ImageTransitionControl>\n        </Grid>\n\n        <Grid>\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"20\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n            <!--<Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"160\" StaysOpen=\"False\" VerticalOffset=\"10\"\n                   PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n                <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"Black\">\n                    <ItemsControl>\n                        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuSave}\" Command=\"{Binding SaveCommand}\" Click=\"MenuItem_OnClick\"/>\n                        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuShare}\" Command=\"{Binding ShareCommand}\" Click=\"MenuItem_OnClick\"/>\n                    </ItemsControl>\n                </Border>\n            </Popup>-->\n            <Button Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                    HorizontalAlignment=\"Left\"\n                    Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n            <Grid Grid.Column=\"1\" Margin=\"5,20,0,15\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\"/>\n                    <ColumnDefinition />\n                </Grid.ColumnDefinitions>\n                <Rectangle Fill=\"{StaticResource ForegroundBrush}\" Opacity=\"0.1\" Width=\"45\" Height=\"45\"/>\n                <Image Source=\"{Binding Album.Cover}\" Width=\"45\" Height=\"45\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                <StackPanel Grid.Column=\"1\" Margin=\"10,-7,0,0\">\n                    <ToggleButton x:Name=\"HeaderButton\" Content=\"{Binding Album.Title}\" Style=\"{StaticResource HeaderButtonStyle}\" Margin=\"-2,0,0,0\"/>\n                    <TextBlock Text=\"{Binding Album.Artist}\" FontSize=\"14\" Margin=\"0,0,0,0\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                </StackPanel>\n            </Grid>\n        </Grid>\n\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <ListBox Grid.Row=\"1\" x:Name=\"AudioList\" Margin=\"0,0,0,0\" Padding=\"0,5,0,0\" ItemsSource=\"{Binding Tracks}\" Style=\"{StaticResource CommonListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                 ItemTemplate=\"{StaticResource LocalAudioItemTemplate}\">\n            <i:Interaction.Behaviors>\n                <behaviours:AutoScrollToCurrentItemBehaviour />\n            </i:Interaction.Behaviors>\n        </ListBox>\n    </Grid>\n</controls:PageBase>\n"
  },
  {
    "path": "Meridian/View/Local/LocalAlbumView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Media.Effects;\nusing Meridian.Controls;\nusing Meridian.Model;\nusing Meridian.ViewModel.Local;\n\nnamespace Meridian.View.Local\n{\n    /// <summary>\n    /// Interaction logic for LocalAlbumView.xaml\n    /// </summary>\n    public partial class LocalAlbumView : PageBase\n    {\n        private LocalAlbumViewModel _viewModel;\n\n        public LocalAlbumView()\n        {\n            InitializeComponent();\n\n\n            _viewModel = new LocalAlbumViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        public override void OnNavigatedTo()\n        {\n            var album = (AudioAlbum)NavigationContext.Parameters[\"album\"];\n            _viewModel.Album = album;\n\n            _viewModel.Activate();\n        }\n\n        private void LocalAlbumView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            BackgroundArtControl.Effect = Domain.Settings.Instance.BlurBackground ? new BlurEffect() { RenderingBias = RenderingBias.Quality, Radius = 80 } : null;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Local/LocalCollectionView.xaml",
    "content": "﻿<Page x:Class=\"Meridian.View.Local.LocalCollectionView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:Properties=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:behaviours1=\"clr-namespace:Neptune.UI.Desktop.Behaviours;assembly=Neptune.Desktop\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"800\"\n      x:Name=\"pageRoot\" Loaded=\"LocalCollectionView_OnLoaded\">\n\n    <Page.Resources>\n        <CollectionViewSource x:Key=\"TracksCollection\" Source=\"{Binding Tracks}\" />\n        <CollectionViewSource x:Key=\"SelectedArtistTracksCollection\" Source=\"{Binding SelectedArtistTracks}\">\n            <CollectionViewSource.GroupDescriptions>\n                <PropertyGroupDescription PropertyName=\"Album\"/>\n            </CollectionViewSource.GroupDescriptions>\n        </CollectionViewSource>\n    </Page.Resources>\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition/>\n        </Grid.RowDefinitions>\n\n        <Grid Margin=\"0,5,0,0\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"20\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n            <Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"140\" StaysOpen=\"False\" VerticalOffset=\"10\"\n                   PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n                <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"Black\">\n                    <ItemsControl>\n                        <MenuItem Header=\"{x:Static Properties:MainResources.HeaderMenuRefresh}\" Command=\"{Binding RefreshCommand}\" CommandParameter=\"{Binding}\" Click=\"MenuItem_OnClick\"/>\n                        <MenuItem x:Name=\"LocalSearchItem\" Header=\"{x:Static Properties:MainResources.HeaderMenuLocalSearch}\" Click=\"LocalSearchItem_OnClick\"/>\n                    </ItemsControl>\n                </Border>\n            </Popup>\n            <Button Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                    HorizontalAlignment=\"Left\"\n                    Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n            <ToggleButton Grid.Column=\"1\" x:Name=\"HeaderButton\" Content=\"{x:Static Properties:MainResources.MainMenuCollection}\" Style=\"{StaticResource HeaderButtonStyle}\"/>\n        </Grid>\n\n        <TabControl Grid.Row=\"2\" Style=\"{StaticResource CommonTabControlStyle}\" Margin=\"0,4.5,0,0\" SelectedIndex=\"{Binding SelectedTabIndex, Mode=TwoWay}\">\n            <TabItem Header=\"{x:Static Properties:MainResources.TracksTab}\" Style=\"{StaticResource CommonTabItemStyle}\">\n                <Grid>\n                    <controls:BusyIndicator IsBusy=\"{Binding Tasks[tracks].IsWorking}\" Error=\"{Binding Tasks[tracks].Error}\">\n                        <ListBox x:Name=\"AudioList\" Margin=\"0\" ItemsSource=\"{Binding Source={StaticResource TracksCollection}}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                                 ItemTemplate=\"{StaticResource LocalAudioItemTemplate}\">\n                            <i:Interaction.Behaviors>\n                                <behaviours:AutoScrollToCurrentItemBehaviour />\n                            </i:Interaction.Behaviors>\n                        </ListBox>\n                    </controls:BusyIndicator>\n\n                    <controls:LocalSearchControl x:Name=\"LocalSearchBox\" Grid.ColumnSpan=\"2\" Source=\"{StaticResource TracksCollection}\" FontSize=\"12\" VerticalAlignment=\"Top\"/>\n                </Grid>\n            </TabItem>\n            <TabItem Header=\"{x:Static Properties:MainResources.AlbumsTab}\" Style=\"{StaticResource CommonTabItemStyle}\">\n                <Grid>\n                    <controls:BusyIndicator IsBusy=\"{Binding Tasks[albums].IsWorking}\" Error=\"{Binding Tasks[albums].Error}\">\n                        <ListBox Margin=\"0,0,0,0\" Padding=\"24,5,0,0\" ItemsSource=\"{Binding AlbumGroups}\" ItemContainerStyle=\"{StaticResource GroupListBoxItemStyle}\"\n                             VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                             Style=\"{StaticResource CommonListBoxStyle}\">\n                            <ListBox.ItemTemplate>\n                                <DataTemplate>\n                                    <Grid x:Name=\"RootGrid\">\n                                        <Grid.RowDefinitions>\n                                            <RowDefinition Height=\"Auto\"/>\n                                            <RowDefinition/>\n                                        </Grid.RowDefinitions>\n                                        <TextBlock Text=\"{Binding Title}\" FontSize=\"14\" FontFamily=\"Segoe UI\" Opacity=\"0.85\" Margin=\"0,0,0,5\" \n                                                   Visibility=\"{Binding Title, Converter={StaticResource NullToVisibilityConverter}}\"\n                                                   Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                        <ItemsControl Grid.Row=\"1\" ItemsSource=\"{Binding Albums}\" Margin=\"0,0,0,0\"\n                                           ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\" ScrollViewer.VerticalScrollBarVisibility=\"Disabled\">\n                                            <ItemsControl.ItemsPanel>\n                                                <ItemsPanelTemplate>\n                                                    <WrapPanel Orientation=\"Horizontal\" ItemHeight=\"170\" ItemWidth=\"130\">\n                                                        <i:Interaction.Behaviors>\n                                                            <behaviours:TransitionBehaviour Transition=\"{StaticResource LocalAlbumLoadAnim}\" TransitionDelay=\"20\"/>\n                                                        </i:Interaction.Behaviors>\n                                                    </WrapPanel>\n                                                </ItemsPanelTemplate>\n                                            </ItemsControl.ItemsPanel>\n                                            <ItemsControl.ItemContainerStyle>\n                                                <Style TargetType=\"ContentPresenter\">\n                                                    <Setter Property=\"RenderTransform\">\n                                                        <Setter.Value>\n                                                            <TranslateTransform />\n                                                        </Setter.Value>\n                                                    </Setter>\n                                                </Style>\n                                            </ItemsControl.ItemContainerStyle>\n                                            <ItemsControl.ItemTemplate>\n                                                <DataTemplate>\n                                                    <Button Style=\"{StaticResource SimpleButtonStyle}\" ToolTip=\"{Binding Title}\" Command=\"{Binding ElementName=pageRoot, Path=DataContext.GoToAlbumCommand}\"\n                                                        CommandParameter=\"{Binding}\" Margin=\"0,0,10,10\" VerticalAlignment=\"Top\">\n                                                        <Grid>\n                                                            <Grid.RowDefinitions>\n                                                                <RowDefinition />\n                                                                <RowDefinition Height=\"Auto\"/>\n                                                            </Grid.RowDefinitions>\n                                                            <Grid Height=\"120\">\n                                                                <Rectangle Fill=\"{DynamicResource ForegroundBrush}\" Opacity=\"0.3\"/>\n                                                                <Image Source=\"/Resources/Images/cover_default.png\" Margin=\"25,25,25,40\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                                                                <Image Source=\"{Binding Cover}\" Stretch=\"UniformToFill\" RenderOptions.BitmapScalingMode=\"HighQuality\" />\n                                                                <Border x:Name=\"Border\" Opacity=\"0.8\"/>\n                                                            </Grid>\n                                                            <StackPanel Grid.Row=\"1\">\n                                                                <TextBlock Text=\"{Binding Title}\" FontSize=\"12\" Margin=\"0,0,0,0\" TextTrimming=\"CharacterEllipsis\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                                                <TextBlock Text=\"{Binding Year}\" FontSize=\"12\" Margin=\"0,-2,0,0\" TextTrimming=\"CharacterEllipsis\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                                                                       Visibility=\"{Binding Year, Converter={StaticResource NullToVisibilityConverter}}\" Opacity=\"0.7\"/>\n                                                            </StackPanel>\n                                                        </Grid>\n                                                    </Button>\n                                                    <DataTemplate.Triggers>\n                                                        <DataTrigger Binding=\"{Binding RelativeSource={RelativeSource Mode=Self},Path=IsMouseOver}\" Value=\"True\">\n                                                            <Setter TargetName=\"Border\" Property=\"BorderThickness\" Value=\"4\" />\n                                                            <Setter TargetName=\"Border\" Property=\"BorderBrush\" Value=\"{DynamicResource AccentBrush}\" />\n                                                        </DataTrigger>\n                                                    </DataTemplate.Triggers>\n                                                </DataTemplate>\n                                            </ItemsControl.ItemTemplate>\n                                        </ItemsControl>\n                                    </Grid>\n                                </DataTemplate>\n                            </ListBox.ItemTemplate>\n                        </ListBox>\n                    </controls:BusyIndicator>\n                </Grid>\n            </TabItem>\n            <TabItem Header=\"{x:Static Properties:MainResources.ArtistsTab}\" Style=\"{StaticResource CommonTabItemStyle}\">\n                <Grid>\n                    <Grid.ColumnDefinitions>\n                        <ColumnDefinition />\n                        <ColumnDefinition Width=\"180\"/>\n                    </Grid.ColumnDefinitions>\n                    <controls:BusyIndicator IsBusy=\"{Binding Tasks[artists].IsWorking}\" Error=\"{Binding Tasks[artists].Error}\">\n                        <ListBox Margin=\"0,0,0,0\" Padding=\"0,5,0,0\" ItemsSource=\"{Binding Source={StaticResource SelectedArtistTracksCollection}}\"\n                             VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                             HorizontalContentAlignment=\"Stretch\" ItemTemplate=\"{StaticResource LocalAudioItemTemplate}\"\n                             Style=\"{StaticResource CommonListBoxStyle}\" ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                             VirtualizingPanel.IsVirtualizing=\"True\"\n                             VirtualizingPanel.IsVirtualizingWhenGrouping=\"True\">\n                            <ListBox.GroupStyle>\n                                <GroupStyle>\n                                    <GroupStyle.HeaderTemplate>\n                                        <DataTemplate>\n                                            <TextBlock Text=\"{Binding Name}\" Margin=\"10,10,10,10\"\n                                                       FontSize=\"14\" FontFamily=\"Segoe UI\" Opacity=\"0.85\"\n                                                       Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                        </DataTemplate>\n                                    </GroupStyle.HeaderTemplate>\n                                    <GroupStyle.ContainerStyle>\n                                        <Style TargetType=\"{x:Type GroupItem}\">\n                                            <Setter Property=\"Margin\" Value=\"10,0,15,0\"></Setter>\n                                        </Style>\n                                    </GroupStyle.ContainerStyle>\n                                </GroupStyle>\n                            </ListBox.GroupStyle>\n                        </ListBox>\n                    </controls:BusyIndicator>\n\n                    <Rectangle Grid.Column=\"1\" Fill=\"{DynamicResource MainBackgroundBrush}\" Margin=\"0,0,0,-25\" Opacity=\"0.4\"/>\n\n                    <ListBox Grid.Column=\"1\" ItemsSource=\"{Binding Artists}\" Style=\"{StaticResource CommonListBoxStyle}\" Margin=\"0,10,0,0\"\n                             VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                             SelectedItem=\"{Binding SelectedArtist, Mode=TwoWay}\" ItemContainerStyle=\"{StaticResource AlbumListBoxItemStyle}\"\n                             Padding=\"0\">\n                        <i:Interaction.Behaviors>\n                            <behaviours:TransitionBehaviour Transition=\"{StaticResource AlbumLoadAnim}\" TransitionDelay=\"25\"/>\n                        </i:Interaction.Behaviors>\n                        <ListBox.ItemTemplate>\n                            <DataTemplate>\n                                <TextBlock Tag=\"{Binding DataContext, ElementName=pageRoot}\" Text=\"{Binding Title}\" ToolTip=\"{Binding Title}\" VerticalAlignment=\"Center\" TextTrimming=\"CharacterEllipsis\">\n                                    <!--<TextBlock.ContextMenu>\n                                        <ContextMenu Visibility=\"{Binding Converter={StaticResource AlbumContextMenuVisibilityConverter}}\" Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                                            <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuPlay}\" Command=\"{Binding PlacementTarget.Tag.PlayAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                            <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding PlacementTarget.Tag.AddAlbumToNowPlayingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                            <Separator />\n                                            <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuEdit}\" Command=\"{Binding PlacementTarget.Tag.EditAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                            <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuRemoveRadio}\" Command=\"{Binding PlacementTarget.Tag.RemoveAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                        </ContextMenu>\n                                    </TextBlock.ContextMenu>-->\n                                </TextBlock>\n                            </DataTemplate>\n                        </ListBox.ItemTemplate>\n                    </ListBox>\n\n                    <!--<Rectangle Grid.ColumnSpan=\"2\" Height=\"1\" VerticalAlignment=\"Top\" Fill=\"{DynamicResource MainBackgroundSplitterBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\"/>-->\n                    <Rectangle Width=\"1\" Grid.Row=\"1\" Grid.Column=\"0\" HorizontalAlignment=\"Right\" Fill=\"{DynamicResource MainBackgroundSplitterBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\"/>\n                </Grid>\n            </TabItem>\n        </TabControl>\n    </Grid>\n</Page>\n"
  },
  {
    "path": "Meridian/View/Local/LocalCollectionView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing Meridian.Model;\nusing Meridian.ViewModel.Local;\n\nnamespace Meridian.View.Local\n{\n    /// <summary>\n    /// Interaction logic for LocalCollectionView.xaml\n    /// </summary>\n    public partial class LocalCollectionView : Page\n    {\n        private LocalMusicViewModel _viewModel;\n\n        public LocalCollectionView()\n        {\n            InitializeComponent();\n\n            _viewModel = new LocalMusicViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void MenuItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n        }\n\n        private void LocalSearchItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n            LocalSearchBox.IsActive = true;\n        }\n\n        private bool Filter(object o)\n        {\n            var track = (Audio)o;\n            var query = LocalSearchBox.Query.ToLower();\n            return track.Title.ToLower().Contains(query) || (track.Artist != null && track.Artist.ToLower().Contains(query));\n        }\n\n        private void LocalCollectionView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            LocalSearchBox.Filter = Filter;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Main/FeedView.xaml",
    "content": "﻿<layout:PageBase x:Class=\"Meridian.View.Main.FeedView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:layout=\"clr-namespace:Meridian.Layout\"\n      xmlns:Properties=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"1024\" d:DesignWidth=\"1024\"\n\t  Header=\"{x:Static Properties:MainResources.MainMenuFeed}\"\n      SubHeader=\"{x:Static Properties:MainResources.FeedSubHeader}\"\n      x:Name=\"pageRoot\">\n    <layout:PageBase.Resources>\n        <CollectionViewSource x:Key=\"TracksCollection\" Source=\"{Binding Tracks}\" />\n    </layout:PageBase.Resources>\n\n    <layout:TwoColumnPageLayout>\n        <layout:TwoColumnPageLayout.MainContent>\n            <controls:BusyIndicator IsBusy=\"{Binding Tasks[feed].IsWorking}\" Error=\"{Binding Tasks[feed].Error}\">\n                <ListBox x:Name=\"AudioList\" Margin=\"0,0,0,0\" ItemsSource=\"{Binding Source={StaticResource TracksCollection}}\" \n                     Style=\"{StaticResource CommonListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                     ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                     ItemTemplate=\"{StaticResource AudioItemTemplate}\">\n                    <i:Interaction.Behaviors>\n                        <behaviours:AutoScrollToCurrentItemBehaviour />\n                    </i:Interaction.Behaviors>\n                </ListBox>\n            </controls:BusyIndicator>\n        </layout:TwoColumnPageLayout.MainContent>\n        <layout:TwoColumnPageLayout.RightContent>\n            <Grid>\n                <StackPanel Orientation=\"Horizontal\" Margin=\"12,10,0,0\">\n                    <TextBlock Text=\"{x:Static Properties:MainResources.FeedSocieties}\" FontSize=\"11\" Opacity=\"0.7\" Foreground=\"{StaticResource ForegroundBrush}\" FontWeight=\"SemiBold\"/>\n                    <Button Style=\"{StaticResource AddButtonStyle}\" VerticalAlignment=\"Top\" Margin=\"3,0,0,0\" Command=\"{Binding AddSocietyCommand}\"\n                        ToolTip=\"{x:Static Properties:MainResources.FeedAdd}\"/>\n                </StackPanel>\n\n                <ListBox ItemsSource=\"{Binding Societies}\" Style=\"{StaticResource CommonListBoxStyle}\" Margin=\"0,35,0,0\"\n                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 HorizontalContentAlignment=\"Stretch\"\n                 ItemContainerStyle=\"{StaticResource AlbumListBoxItemStyle}\" SelectedItem=\"{Binding SelectedSociety, Mode=TwoWay}\"\n                 Padding=\"0\">\n                    <i:Interaction.Behaviors>\n                        <behaviours:TransitionBehaviour Transition=\"{StaticResource AlbumLoadAnim}\" TransitionDelay=\"25\"/>\n                    </i:Interaction.Behaviors>\n                    <ListBox.ItemTemplate>\n                        <DataTemplate>\n                            <Grid>\n                                <Grid.ColumnDefinitions>\n                                    <ColumnDefinition />\n                                    <ColumnDefinition Width=\"Auto\"/>\n                                </Grid.ColumnDefinitions>\n                                <TextBlock Text=\"{Binding Name}\" ToolTip=\"{Binding Name}\" VerticalAlignment=\"Center\" TextTrimming=\"CharacterEllipsis\"/>\n                                <Button x:Name=\"DeleteButton\" Grid.Column=\"1\" Style=\"{StaticResource CloseButtonStyle}\" Command=\"{Binding ElementName=pageRoot, Path=DataContext.RemoveSocietyCommand}\" CommandParameter=\"{Binding}\" \n                                    Opacity=\"0\" ToolTip=\"{x:Static Properties:MainResources.Delete}\" Margin=\"5,0,0,0\" Visibility=\"{Binding Id, Converter={StaticResource NullToVisibilityConverter}}\"/>\n                            </Grid>\n                            <DataTemplate.Triggers>\n                                <DataTrigger Binding=\"{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},Path=IsMouseOver}\" Value=\"True\">\n                                    <Setter TargetName=\"DeleteButton\" Property=\"Opacity\" Value=\"1\" />\n                                </DataTrigger>\n                            </DataTemplate.Triggers>\n                        </DataTemplate>\n                    </ListBox.ItemTemplate>\n                </ListBox>\n            </Grid>\n        </layout:TwoColumnPageLayout.RightContent>\n    </layout:TwoColumnPageLayout>\n</layout:PageBase>\n"
  },
  {
    "path": "Meridian/View/Main/FeedView.xaml.cs",
    "content": "﻿using Meridian.Layout;\nusing Meridian.ViewModel.Main;\n\nnamespace Meridian.View.Main\n{\n    /// <summary>\n    /// Interaction logic for FeedView.xaml\n    /// </summary>\n    public partial class FeedView : PageBase\n    {\n        private FeedViewModel _viewModel;\n\n        public FeedView()\n        {\n            InitializeComponent();\n\n            _viewModel = new FeedViewModel();\n            this.DataContext = _viewModel;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Main/LoginView.xaml",
    "content": "﻿<controls:PageBase x:Class=\"Meridian.View.Main.LoginView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Neptune.UI.Behaviours;assembly=Neptune.Desktop\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\"\n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      KeepAlive=\"False\" \n      Background=\"{DynamicResource MainBackgroundBrush}\">\n\n    <Page.Resources>\n        <Style x:Key=\"LoginButtonStyle\" TargetType=\"Button\">\n            <Setter Property=\"Background\" Value=\"{DynamicResource AccentBrush}\"/>\n            <Setter Property=\"Foreground\" Value=\"White\"/>\n            <Setter Property=\"FontSize\" Value=\"14\"/>\n            <Setter Property=\"FontWeight\" Value=\"SemiBold\"/>\n            <Setter Property=\"Padding\" Value=\"40,9,40,9\"/>\n            <Setter Property=\"BorderThickness\" Value=\"0\"/>\n            <Setter Property=\"Template\">\n                <Setter.Value>\n                    <ControlTemplate TargetType=\"{x:Type Button}\">\n                        <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                            <Grid Margin=\"{TemplateBinding Padding}\">\n                                <Grid.ColumnDefinitions>\n                                    <ColumnDefinition Width=\"Auto\"/>\n                                    <ColumnDefinition />\n                                </Grid.ColumnDefinitions>\n                                <ContentControl x:Name=\"VkIcon\" Foreground=\"{TemplateBinding Foreground}\" Margin=\"0,2,15,0\" Width=\"18\" Height=\"18\">\n                                    <ContentControl.Template>\n                                        <ControlTemplate>\n                                            <Path Data=\"{StaticResource VkIcon}\" Fill=\"White\" Stretch=\"Uniform\"/>\n                                        </ControlTemplate>\n                                    </ContentControl.Template>\n                                </ContentControl>\n                                <ContentPresenter x:Name=\"contentPresenter\" Grid.Column=\"1\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                            </Grid>\n                        </Border>\n                        <ControlTemplate.Triggers>\n                            <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                                <Setter Property=\"Opacity\" TargetName=\"border\" Value=\"0.8\"/>\n                            </Trigger>\n                            <Trigger Property=\"IsPressed\" Value=\"True\">\n                                <Setter Property=\"Opacity\" TargetName=\"border\" Value=\"0.9\"/>\n                            </Trigger>\n                        </ControlTemplate.Triggers>\n                    </ControlTemplate>\n                </Setter.Value>\n            </Setter>\n        </Style>\n        <Style x:Key=\"RegisterButtonStyle\" TargetType=\"{x:Type Button}\">\n            <Setter Property=\"Background\" Value=\"Transparent\"/>\n            <Setter Property=\"Foreground\" Value=\"{DynamicResource ForegroundBrush}\"/>\n            <Setter Property=\"FontSize\" Value=\"11\"/>\n            <Setter Property=\"FontWeight\" Value=\"SemiBold\"/>\n            <Setter Property=\"BorderThickness\" Value=\"0\"/>\n            <Setter Property=\"Opacity\" Value=\"0.5\" />\n            <Setter Property=\"Cursor\" Value=\"Hand\" />\n            <Setter Property=\"Template\">\n                <Setter.Value>\n                    <ControlTemplate TargetType=\"{x:Type Button}\">\n                        <Border x:Name=\"border\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" SnapsToDevicePixels=\"true\">\n                            <ContentPresenter x:Name=\"contentPresenter\" Focusable=\"False\" HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" RecognizesAccessKey=\"True\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                        </Border>\n                        <ControlTemplate.Triggers>\n                            <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                                <Setter Property=\"Opacity\" Value=\"1\"/>\n                            </Trigger>\n                            <Trigger Property=\"IsPressed\" Value=\"True\">\n                                <Setter Property=\"Opacity\" Value=\"0.9\"/>\n                            </Trigger>\n                        </ControlTemplate.Triggers>\n                    </ControlTemplate>\n                </Setter.Value>\n            </Setter>\n        </Style>\n\n        <Storyboard x:Key=\"LoginFormTransitionIn\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"1\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(RenderTransform).X\">\n                <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"30\"/>\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"6\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n        <Storyboard x:Key=\"LoginFormTransitionOut\">\n            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                <EasingDoubleKeyFrame KeyTime=\"0:0:0.2\" Value=\"0\">\n                    <EasingDoubleKeyFrame.EasingFunction>\n                        <ExponentialEase Exponent=\"8\"/>\n                    </EasingDoubleKeyFrame.EasingFunction>\n                </EasingDoubleKeyFrame>\n            </DoubleAnimationUsingKeyFrames>\n        </Storyboard>\n\n        <ControlTemplate x:Key=\"MeridianLogo\">\n            <Viewbox Margin=\"-5\">\n                <Canvas Width=\"428.799\" Height=\"469.596\" Clip=\"F1 M 0,0L 428.799,0L 428.799,469.596L 0,469.596L 0,0\" UseLayoutRounding=\"False\">\n                    <Path x:Name=\"Path\" Width=\"428.799\" Height=\"469.596\" Canvas.Left=\"-2.98023e-008\" Canvas.Top=\"-3.5733e-005\" Stretch=\"Fill\" StrokeThickness=\"5\" StrokeLineJoin=\"Round\" Stroke=\"{DynamicResource BackgroundBrush}\" Fill=\"{DynamicResource AccentBrush}\" Data=\"F1 M 306.7,254.793L 428.465,0.333298L 268.125,104.479M 90.7547,63.112L 0.333333,55.512L 107.937,130.405M 158.985,326.891L 220.3,202.433L 91.28,63.0626M 361.739,469.263L 158.984,326.891L 268.125,104.477L 361.739,469.263 Z\"/>\n                </Canvas>\n            </Viewbox>\n        </ControlTemplate>\n    </Page.Resources>\n\n    <Grid>\n        <Grid VerticalAlignment=\"Center\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"120\"/>\n                <RowDefinition />\n            </Grid.RowDefinitions>\n            <StackPanel>\n                <ContentControl Template=\"{StaticResource MeridianLogo}\" Width=\"50\" VerticalAlignment=\"Center\" Margin=\"0,20,10,0\" Foreground=\"{DynamicResource AccentBrush}\"/>\n                <StackPanel HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Orientation=\"Horizontal\" Margin=\"0,0,0,0\">\n                    <!--<ContentControl Template=\"{StaticResource MeridianLogo}\" Width=\"40\" VerticalAlignment=\"Center\" Margin=\"0,5,10,0\" Foreground=\"{StaticResource AccentBrush}\"/>-->\n                    <TextBlock Text=\"Meridian\" Foreground=\"{DynamicResource ForegroundBrush}\" FontFamily=\"Segoe UI SemiLight\" FontSize=\"32\" Margin=\"0,0,0,0\" Opacity=\"0.7\"/>\n                </StackPanel>\n            </StackPanel>\n            <Grid Grid.Row=\"1\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\">\n                <StackPanel HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Margin=\"0,20,0,0\">\n                    <StackPanel.RenderTransform>\n                        <TranslateTransform />\n                    </StackPanel.RenderTransform>\n                    <i:Interaction.Behaviors>\n                        <behaviours:VisibilityTransitionBehaviour Value=\"{Binding IsLoginFormVisible, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\" AnimationIn=\"{StaticResource LoginFormTransitionIn}\" AnimationOut=\"{StaticResource LoginFormTransitionOut}\"/>\n                    </i:Interaction.Behaviors>\n                    <TextBlock Text=\"{x:Static localization:MainResources.LoginWelcome}\" Margin=\"0,0,0,0\" FontSize=\"22\" HorizontalAlignment=\"Center\" Opacity=\"0.4\" FontFamily=\"Segoe UI SemiLight\" Foreground=\"{StaticResource ForegroundBrush}\"/>\n                    <Button Content=\"{x:Static localization:MainResources.LoginStartLoginButton}\" HorizontalAlignment=\"Center\" Margin=\"0,30,0,0\" Command=\"{Binding LoginVkCommand}\" Style=\"{StaticResource LoginButtonStyle}\"/>\n                    <Button Content=\"{x:Static localization:MainResources.LoginRegisterButton}\" Style=\"{StaticResource RegisterButtonStyle}\" HorizontalAlignment=\"Center\" Margin=\"0,30,0,0\" Command=\"{Binding SignUpVkCommand}\"/>\n                </StackPanel>\n                <Grid HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Visibility=\"{Binding IsLoginFormVisible, Converter={StaticResource BoolToVisibilityConverter}}\" Margin=\"0,0,0,0\">\n                    <Grid.RenderTransform>\n                        <TranslateTransform />\n                    </Grid.RenderTransform>\n                    <i:Interaction.Behaviors>\n                        <behaviours:VisibilityTransitionBehaviour Value=\"{Binding IsLoginFormVisible, Converter={StaticResource BoolToVisibilityConverter}}\" AnimationIn=\"{StaticResource LoginFormTransitionIn}\" AnimationOut=\"{StaticResource LoginFormTransitionOut}\"/>\n                    </i:Interaction.Behaviors>\n                    <StackPanel Margin=\"50,15,50,0\" Width=\"285\">\n                        <TextBlock Text=\"{x:Static localization:MainResources.LoginLoginTitle}\" FontSize=\"12\" Margin=\"0,20,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                        <TextBox x:Name=\"LoginTextBox\" Width=\"285\" Margin=\"0,3,0,0\" Text=\"{Binding Login, Mode=TwoWay}\" Style=\"{StaticResource CommonTextBoxStyle}\" KeyUp=\"LoginTextBox_OnKeyUp\"/>\n                        <TextBlock Text=\"{x:Static localization:MainResources.LoginPasswordTitle}\" FontSize=\"12\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                        <controls:BindablePasswordBox x:Name=\"PasswordBox\" Password=\"{Binding Password, Mode=TwoWay}\" Width=\"285\" Margin=\"0,3,0,0\" KeyUp=\"PasswordBox_OnKeyUp\"/>\n                        <StackPanel Visibility=\"{Binding ShowCaptcha, Converter={StaticResource BoolToVisibilityConverter}}\">\n                            <Image Source=\"{Binding CaptchaImg}\" Margin=\"0,10,0,0\" Height=\"70\" HorizontalAlignment=\"Left\"/>\n                            <TextBlock Text=\"{x:Static localization:MainResources.CaptchaEnterSymbols}\" FontSize=\"12\" Margin=\"0,5,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                            <TextBox Text=\"{Binding CaptchaKey, Mode=TwoWay}\" Margin=\"0,3,0,12\" Style=\"{StaticResource CommonTextBoxStyle}\"/>\n                        </StackPanel>\n                        <TextBlock Foreground=\"Red\" Text=\"{Binding LoginError}\" Margin=\"0,3,0,0\" Visibility=\"{Binding LoginError, Converter={StaticResource NullToVisibilityConverter}}\"\n                                    TextWrapping=\"Wrap\"/>\n                        <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Margin=\"0,10,0,0\">\n                            <Button Content=\"{x:Static localization:MainResources.LoginLoginButton}\" Padding=\"23,3\" Margin=\"0,0,10,0\" Command=\"{Binding LoginCommand}\" Style=\"{StaticResource HighlightedButtonStyle}\"/>\n                            <Button Content=\"{x:Static localization:MainResources.CancelButton}\" Padding=\"23,3\" Command=\"{Binding CancelLoginVkCommand}\" Style=\"{StaticResource CommonButtonStyle}\"/>\n                        </StackPanel>\n                    </StackPanel>\n                </Grid>\n            </Grid>\n\n            <StackPanel Grid.Row=\"1\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}}\" HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Margin=\"0,50,0,0\" >\n                <TextBlock Text=\"{x:Static localization:MainResources.LoginLoading}\" FontSize=\"22\" HorizontalAlignment=\"Center\" Opacity=\"0.4\" FontWeight=\"Light\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                <ProgressBar Style=\"{StaticResource CommonProgressBarStyle}\" IsIndeterminate=\"{Binding IsWorking}\"/>\n            </StackPanel>\n        </Grid>\n        <StackPanel Orientation=\"Horizontal\" VerticalAlignment=\"Bottom\" HorizontalAlignment=\"Center\" Margin=\"0,0,0,7\">\n            <TextBlock FontWeight=\"Normal\" Text=\"Copyright © Artem Shuba 2020.\" Foreground=\"{DynamicResource ForegroundBrush}\" FontSize=\"10\" Opacity=\"0.5\"/>\n            <TextBlock FontSize=\"10\" Opacity=\"0.5\" Margin=\"5,0,0,0\">\n                <Hyperlink Foreground=\"{DynamicResource ForegroundBrush}\" Command=\"{Binding Main.GoToSettingsCommand, Source={StaticResource Locator}}\">\n                    <Run Text=\"{x:Static localization:MainResources.LoginGoToSettings}\"/>\n                </Hyperlink>\n            </TextBlock>\n        </StackPanel>\n    </Grid>\n</controls:PageBase>\n"
  },
  {
    "path": "Meridian/View/Main/LoginView.xaml.cs",
    "content": "﻿using System.Windows.Input;\nusing Meridian.Controls;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Main;\n\nnamespace Meridian.View.Main\n{\n    /// <summary>\n    /// Interaction logic for LoginView.xaml\n    /// </summary>\n    public partial class LoginView : PageBase\n    {\n        private readonly LoginViewModel _viewModel;\n\n        public LoginView()\n        {\n            InitializeComponent();\n\n            _viewModel = new LoginViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void LoginTextBox_OnKeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.Key != Key.Enter)\n                return;\n\n            if (!string.IsNullOrEmpty(LoginTextBox.Text))\n            {\n                if (!string.IsNullOrEmpty(PasswordBox.Password))\n                {\n                    _viewModel.LoginCommand.Execute(null);\n                }\n                else\n                {\n                    PasswordBox.Child.Focus();\n                }\n            }\n        }\n\n        private void PasswordBox_OnKeyUp(object sender, KeyEventArgs e)\n        {\n            if (e.Key != Key.Enter)\n                return;\n\n            if (!string.IsNullOrEmpty(PasswordBox.Password))\n            {\n                if (!string.IsNullOrEmpty(LoginTextBox.Text))\n                {\n                    _viewModel.LoginCommand.Execute(null);\n                }\n                else\n                {\n                    LoginTextBox.Focus();\n                }\n            }\n        }\n\n        public override void OnNavigatedTo()\n        {\n            ViewModelLocator.Main.ShowSidebar = false;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Main/MusicView.xaml",
    "content": "﻿<layout:PageBase x:Class=\"Meridian.View.Main.MusicView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:layout=\"clr-namespace:Meridian.Layout\"\n      xmlns:Properties=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:dragDrop=\"clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:converters=\"clr-namespace:Meridian.Converters\"\n      mc:Ignorable=\"d\"\n      x:Name=\"pageRoot\"\n      KeepAlive=\"False\"\n      Header=\"{x:Static Properties:MainResources.MainMenuMyMusic}\"\n      SelectedTabIndex=\"{Binding SelectedTabIndex, Mode=TwoWay}\">\n\n    <layout:PageBase.Resources>\n        <converters:AudioTemplateSelector x:Key=\"AudioTemplateSelector\" AudioTemplate=\"{StaticResource AudioItemTemplate}\" PostTemplate=\"{StaticResource PostItemDataTemplate}\"/>\n\n        <CollectionViewSource x:Key=\"TracksCollection\" Source=\"{Binding Tracks}\" />\n    </layout:PageBase.Resources>\n\n    <layout:PageBase.HeaderMenuItems>\n        <MenuItem Header=\"{x:Static Properties:MainResources.HeaderMenuRefresh}\" Command=\"{Binding RefreshCommand}\"/>\n        <MenuItem x:Name=\"LocalSearchItem\" Header=\"{x:Static Properties:MainResources.HeaderMenuLocalSearch}\"\n                  Click=\"LocalSearchItem_OnClick\"/>\n    </layout:PageBase.HeaderMenuItems>\n\n    <TabItem Header=\"{x:Static Properties:MainResources.TracksTab}\">\n        <layout:TwoColumnPageLayout>\n            <layout:TwoColumnPageLayout.MainContent>\n                <Grid>\n                    <controls:BusyIndicator IsBusy=\"{Binding Tasks[audio].IsWorking}\" Error=\"{Binding Tasks[audio].Error}\">\n                        <ListBox x:Name=\"AudioList\" Margin=\"0,0,0,0\" ItemsSource=\"{Binding Source={StaticResource TracksCollection}}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                                 ItemTemplateSelector=\"{StaticResource AudioTemplateSelector}\"\n                                 dragDrop:DragDrop.IsDragSource=\"True\" dragDrop:DragDrop.IsDropTarget=\"True\" dragDrop:DragDrop.DragHandler=\"{Binding}\" dragDrop:DragDrop.DropHandler=\"{Binding}\">\n                            <i:Interaction.Behaviors>\n                                <behaviours:AutoScrollToCurrentItemBehaviour />\n                            </i:Interaction.Behaviors>\n                        </ListBox>\n                    </controls:BusyIndicator>\n\n                    <controls:LocalSearchControl x:Name=\"LocalSearchBox\" Grid.ColumnSpan=\"2\" Source=\"{StaticResource TracksCollection}\" FontSize=\"12\" VerticalAlignment=\"Top\"/>\n                </Grid>\n            </layout:TwoColumnPageLayout.MainContent>\n            <layout:TwoColumnPageLayout.RightContent>\n                <Grid>\n                    <StackPanel Orientation=\"Horizontal\" Margin=\"12,10,0,0\">\n                        <TextBlock Text=\"{x:Static Properties:MainResources.MyMusicAlbums}\" FontSize=\"11\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\" FontWeight=\"SemiBold\"/>\n                        <Button Style=\"{StaticResource AddButtonStyle}\" VerticalAlignment=\"Top\" Margin=\"3,0,0,0\" Command=\"{Binding AddAlbumCommand}\"\n                                ToolTip=\"{x:Static Properties:MainResources.MyMusicAlbumsAdd}\"/>\n                    </StackPanel>\n\n                    <controls:BusyIndicator Margin=\"0,35,0,0\" IsBusy=\"{Binding Tasks[albums].IsWorking}\" Error=\"{Binding Tasks[albums].Error}\">\n                        <controls:BusyIndicator.BusyContentStyle>\n                            <Style TargetType=\"ContentPresenter\">\n                                <Setter Property=\"Margin\" Value=\"12,5,5,0\"/>\n                            </Style>\n                        </controls:BusyIndicator.BusyContentStyle>\n                        <controls:ExtendedListBox ItemsSource=\"{Binding Albums}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                             VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                             SelectedItem=\"{Binding SelectedAlbum, Mode=TwoWay}\" ItemContainerStyleSelector=\"{StaticResource AlbumItemStyleSelector}\"\n                             LoadMoreCommand=\"{Binding LoadMoreAlbumsCommand}\" Padding=\"0\"\n                             dragDrop:DragDrop.IsDropTarget=\"True\" dragDrop:DragDrop.DropHandler=\"{Binding}\">\n                            <i:Interaction.Behaviors>\n                                <behaviours:TransitionBehaviour Transition=\"{StaticResource AlbumLoadAnim}\" TransitionDelay=\"25\"/>\n                            </i:Interaction.Behaviors>\n                            <ListBox.ItemTemplate>\n                                <DataTemplate>\n                                    <TextBlock Tag=\"{Binding DataContext, ElementName=pageRoot}\" Text=\"{Binding Title}\" ToolTip=\"{Binding Title}\" VerticalAlignment=\"Center\" TextTrimming=\"CharacterEllipsis\">\n                                        <TextBlock.ContextMenu>\n                                            <ContextMenu Visibility=\"{Binding Converter={StaticResource AlbumContextMenuVisibilityConverter}}\" Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                                                <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuPlay}\" Command=\"{Binding PlacementTarget.Tag.PlayAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                                <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding PlacementTarget.Tag.AddAlbumToNowPlayingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                                <Separator />\n                                                <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuEdit}\" Command=\"{Binding PlacementTarget.Tag.EditAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                                <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuRemoveRadio}\" Command=\"{Binding PlacementTarget.Tag.RemoveAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                            </ContextMenu>\n                                        </TextBlock.ContextMenu>\n                                    </TextBlock>\n                                </DataTemplate>\n                            </ListBox.ItemTemplate>\n                        </controls:ExtendedListBox>\n                    </controls:BusyIndicator>\n                </Grid>\n            </layout:TwoColumnPageLayout.RightContent>\n        </layout:TwoColumnPageLayout>\n    </TabItem>\n    <TabItem Header=\"{x:Static Properties:MainResources.ArtistsTab}\">\n        <layout:TwoColumnPageLayout>\n            <layout:TwoColumnPageLayout.MainContent>\n                <controls:BusyIndicator IsBusy=\"{Binding Tasks[audio].IsWorking}\" Error=\"{Binding Tasks[audio].Error}\">\n                    <ListBox Margin=\"0,0,0,0\" ItemsSource=\"{Binding SelectedArtist.Tracks}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                                 ItemTemplateSelector=\"{StaticResource AudioTemplateSelector}\">\n                        <i:Interaction.Behaviors>\n                            <behaviours:AutoScrollToCurrentItemBehaviour />\n                        </i:Interaction.Behaviors>\n                    </ListBox>\n                </controls:BusyIndicator>\n            </layout:TwoColumnPageLayout.MainContent>\n            <layout:TwoColumnPageLayout.RightContent>\n                <ListBox x:Name=\"ArtistList\" Grid.Column=\"1\" ItemsSource=\"{Binding Artists}\" Style=\"{StaticResource CommonListBoxStyle}\"\n                             VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                             Padding=\"0\"\n                             ItemContainerStyle=\"{StaticResource AlbumListBoxItemStyle}\" SelectedItem=\"{Binding SelectedArtist, Mode=TwoWay}\">\n                    <i:Interaction.Behaviors>\n                        <behaviours:TransitionBehaviour Transition=\"{StaticResource AlbumLoadAnim}\" TransitionDelay=\"25\"/>\n                    </i:Interaction.Behaviors>\n                    <ListBox.ItemTemplate>\n                        <DataTemplate>\n                            <TextBlock Tag=\"{Binding DataContext, ElementName=pageRoot}\" Text=\"{Binding Title}\" ToolTip=\"{Binding Title}\" TextTrimming=\"CharacterEllipsis\">\n                                <TextBlock.ContextMenu>\n                                    <ContextMenu Visibility=\"{Binding Converter={StaticResource AlbumContextMenuVisibilityConverter}}\" Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                                        <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuPlay}\" Command=\"{Binding PlacementTarget.Tag.PlayArtistCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                        <MenuItem Header=\"{x:Static Properties:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding PlacementTarget.Tag.AddArtistToNowPlayingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                    </ContextMenu>\n                                </TextBlock.ContextMenu>\n                            </TextBlock>\n                        </DataTemplate>\n                    </ListBox.ItemTemplate>\n                </ListBox>\n            </layout:TwoColumnPageLayout.RightContent>\n        </layout:TwoColumnPageLayout>\n    </TabItem>\n    <TabItem Header=\"{x:Static Properties:MainResources.NewsTab}\">\n        <controls:BusyIndicator IsBusy=\"{Binding Tasks[news].IsWorking}\" Error=\"{Binding Tasks[news].Error}\">\n            <ListBox Margin=\"0,0,0,0\" ItemsSource=\"{Binding NewsTracks}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                                 ItemTemplateSelector=\"{StaticResource AudioTemplateSelector}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:AutoScrollToCurrentItemBehaviour />\n                </i:Interaction.Behaviors>\n            </ListBox>\n        </controls:BusyIndicator>\n    </TabItem>\n    <TabItem Header=\"{x:Static Properties:MainResources.WallTab}\">\n        <controls:BusyIndicator IsBusy=\"{Binding Tasks[wall].IsWorking}\" Error=\"{Binding Tasks[wall].Error}\">\n            <ListBox Margin=\"0,0,0,0\" ItemsSource=\"{Binding WallTracks}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                                 ItemTemplateSelector=\"{StaticResource AudioTemplateSelector}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:AutoScrollToCurrentItemBehaviour />\n                </i:Interaction.Behaviors>\n            </ListBox>\n        </controls:BusyIndicator>\n    </TabItem>\n    <TabItem Header=\"{x:Static Properties:MainResources.FavoritesTab}\">\n        <controls:BusyIndicator IsBusy=\"{Binding Tasks[favorites].IsWorking}\" Error=\"{Binding Tasks[favorites].Error}\">\n            <ListBox Margin=\"0,0,0,0\" ItemsSource=\"{Binding FavoritesTracks}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                                 ItemTemplateSelector=\"{StaticResource AudioTemplateSelector}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:AutoScrollToCurrentItemBehaviour />\n                </i:Interaction.Behaviors>\n            </ListBox>\n        </controls:BusyIndicator>\n    </TabItem>\n</layout:PageBase>\n"
  },
  {
    "path": "Meridian/View/Main/MusicView.xaml.cs",
    "content": "﻿using System.Windows;\nusing Meridian.Layout;\nusing Meridian.Model;\nusing Meridian.ViewModel.Main;\n\nnamespace Meridian.View.Main\n{\n    /// <summary>\n    /// Interaction logic for MusicView.xaml\n    /// </summary>\n    public partial class MusicView : PageBase\n    {\n        private MusicViewModel _viewModel;\n\n        public MusicView()\n        {\n            InitializeComponent();\n\n            _viewModel = new MusicViewModel();\n            this.DataContext = _viewModel;\n\n            LocalSearchBox.Filter = Filter;\n        }\n\n        private void LocalSearchItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            LocalSearchBox.IsActive = true;\n        }\n\n        private bool Filter(object o)\n        {\n            var track = (Audio)o;\n            var query = LocalSearchBox.Query.ToLower();\n            return track.Title.ToLower().Contains(query) || track.Artist.ToLower().Contains(query);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Main/NowPlayingView.xaml",
    "content": "﻿<Page x:Class=\"Meridian.View.Main.NowPlayingView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:dragDrop=\"clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop\"\n      xmlns:converters=\"clr-namespace:Meridian.Converters\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      x:Name=\"pageRoot\" KeepAlive=\"False\"\n      Background=\"{DynamicResource MainBackgroundBrush}\"\n      Loaded=\"NowPlayingView_OnLoaded\" Unloaded=\"NowPlayingView_OnUnloaded\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Page.Resources>\n        <CollectionViewSource x:Key=\"TracksCollection\" Source=\"{Binding Main.CurrentPlaylist, Source={StaticResource Locator}}\" />\n        \n        <converters:AudioTemplateSelector x:Key=\"NowPlayingAudioTemplateSelector\" \n                                          AudioTemplate=\"{StaticResource NowPlayingAudioItemTemplate}\"\n                                          LocalAudioTemplate=\"{StaticResource NowPlayingLocalAudioItemTemplate}\"/>\n    </Page.Resources>\n    \n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <Grid Height=\"220\" Background=\"#202124\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"0.3*\"/>\n                <ColumnDefinition Width=\"0.7*\"/>\n            </Grid.ColumnDefinitions>\n            <Grid Grid.Column=\"1\">\n                <Grid.OpacityMask>\n                    <LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"1,0\">\n                        <GradientStop Offset=\"0\" Color=\"Transparent\"/>\n                        <GradientStop Offset=\"1\" Color=\"White\"/>\n                    </LinearGradientBrush>\n                </Grid.OpacityMask>\n                <controls:ImageTransitionControl x:Name=\"ArtistArt\" HorizontalAlignment=\"Right\" Opacity=\"1\" Source=\"{Binding ArtistImage}\" Margin=\"0,0,0,0\"\n                   RenderOptions.BitmapScalingMode=\"HighQuality\">\n\n                </controls:ImageTransitionControl>\n            </Grid>\n            <Grid Grid.ColumnSpan=\"2\" VerticalAlignment=\"Top\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"20\"/>\n                    <ColumnDefinition />\n                </Grid.ColumnDefinitions>\n                <Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"140\" StaysOpen=\"False\" VerticalOffset=\"10\"\n                   PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n                    <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"Black\">\n                        <ItemsControl>\n                            <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuClear}\" Command=\"{Binding ClearCommand}\" Click=\"MenuItem_OnClick\"/>\n                            <MenuItem x:Name=\"LocalSearchItem\" Header=\"{x:Static localization:MainResources.HeaderMenuLocalSearch}\" Click=\"LocalSearchItem_OnClick\"/>\n                        </ItemsControl>\n                    </Border>\n                </Popup>\n                <Button Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                    HorizontalAlignment=\"Left\" Foreground=\"White\"\n                    Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n                <ToggleButton Grid.Column=\"1\" x:Name=\"HeaderButton\" Style=\"{StaticResource HeaderButtonStyle}\" Foreground=\"White\" FontSize=\"18\">\n                    <TextBlock Text=\"{x:Static localization:MainResources.MainMenuNowPlaying}\" Margin=\"0,0,0,-3\"/>\n                </ToggleButton>\n                <!--<StackPanel Margin=\"0,24,24,-30\">\n                    <ToggleButton x:Name=\"HeaderButton\" Style=\"{StaticResource HeaderButtonStyle}\" Foreground=\"White\" FontSize=\"16\">\n                        <TextBlock Margin=\"0,0,7,0\" Text=\"{Binding Main.CurrentAudio.Artist, Source={StaticResource Locator}}\" Foreground=\"White\" FontSize=\"54\" FontWeight=\"Regular\" TextTrimming=\"CharacterEllipsis\"/>\n                    </ToggleButton>\n                    <TextBlock Text=\"{Binding Main.CurrentAudio.Title, Source={StaticResource Locator}}\" Foreground=\"White\" FontSize=\"18\" TextTrimming=\"CharacterEllipsis\" Margin=\"26,-20,0,0\"/>\n                </StackPanel>-->\n            </Grid>\n\n            <StackPanel Margin=\"24,0,24,20\" Grid.ColumnSpan=\"2\" HorizontalAlignment=\"Left\" VerticalAlignment=\"Bottom\">\n                <TextBlock Text=\"{Binding Main.CurrentAudio.Artist, Source={StaticResource Locator}}\" Foreground=\"White\" FontSize=\"36\" FontWeight=\"SemiBold\" TextTrimming=\"CharacterEllipsis\"/>\n                <TextBlock Text=\"{Binding Main.CurrentAudio.Title, Source={StaticResource Locator}}\" Foreground=\"White\" FontSize=\"20\" TextTrimming=\"CharacterEllipsis\"  Margin=\"0,-7,0,0\"/>\n            </StackPanel>\n\n        </Grid>\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n\n        <ListBox Grid.Row=\"2\" x:Name=\"AudioList\" Margin=\"0,0,0,0\"\n                 ItemsSource=\"{Binding Source={StaticResource TracksCollection}}\" \n                 Style=\"{StaticResource CommonListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                 ItemTemplateSelector=\"{StaticResource NowPlayingAudioTemplateSelector}\"\n                 dragDrop:DragDrop.IsDragSource=\"True\" dragDrop:DragDrop.IsDropTarget=\"True\" dragDrop:DragDrop.DragHandler=\"{Binding}\">\n            <i:Interaction.Behaviors>\n                <behaviours:AutoScrollToCurrentItemBehaviour />\n            </i:Interaction.Behaviors>\n        </ListBox>\n\n        <StackPanel Orientation=\"Horizontal\" VerticalAlignment=\"Top\" HorizontalAlignment=\"Right\" Margin=\"10\" DataContext=\"{Binding Main, Source={StaticResource Locator}}\">\n            <Button Style=\"{StaticResource MiniModeButtonStyle}\" Margin=\"0,0,20,0\" SnapsToDevicePixels=\"True\" Command=\"{Binding SwitchUIModeCommand}\"\n                    ToolTip=\"{x:Static localization:MainResources.CompactMode}\" Foreground=\"White\"/>\n            <Button Style=\"{StaticResource MinimizeButtonStyle}\" VerticalAlignment=\"Bottom\" Margin=\"0,0,20,0\" SnapsToDevicePixels=\"True\" Command=\"{Binding MinimizeWindowCommand}\" ToolTip=\"{x:Static localization:MainResources.Minimize}\" Foreground=\"White\"/>\n            <ToggleButton x:Name=\"MaximizeButton\" Style=\"{StaticResource MaximizeButtonStyle}\" VerticalAlignment=\"Bottom\" Margin=\"0,0,20,0\" SnapsToDevicePixels=\"True\" IsChecked=\"{Binding IsWindowMaximized, Mode=OneWay}\" Command=\"{Binding MaximizeWindowCommand}\"\n                          ToolTip=\"{x:Static localization:MainResources.Maximize}\" Foreground=\"White\"/>\n            <Button Style=\"{StaticResource CloseButtonStyle}\" SnapsToDevicePixels=\"True\" Command=\"{Binding CloseWindowCommand}\" ToolTip=\"{x:Static localization:MainResources.Close}\" Foreground=\"White\"/>\n        </StackPanel>\n\n        <controls:LocalSearchControl x:Name=\"LocalSearchBox\" Grid.ColumnSpan=\"2\" Grid.Row=\"1\" Grid.RowSpan=\"2\" Source=\"{StaticResource TracksCollection}\" Margin=\"0,1,0,0\"/>\n    </Grid>\n</Page>\n"
  },
  {
    "path": "Meridian/View/Main/NowPlayingView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing Meridian.Model;\nusing Meridian.ViewModel;\n\nnamespace Meridian.View.Main\n{\n    /// <summary>\n    /// Interaction logic for NowPlayingView.xaml\n    /// </summary>\n    public partial class NowPlayingView : Page\n    {\n        public NowPlayingView()\n        {\n            InitializeComponent();\n\n            this.DataContext = ViewModelLocator.NowPlaying;\n        }\n\n        private void MenuItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n        }\n\n        private void NowPlayingView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            ViewModelLocator.NowPlaying.Activate();\n\n            LocalSearchBox.Filter = Filter;\n        }\n\n        private void NowPlayingView_OnUnloaded(object sender, RoutedEventArgs e)\n        {\n            ViewModelLocator.NowPlaying.Deactivate();\n        }\n\n        private void LocalSearchItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n            LocalSearchBox.IsActive = true;\n        }\n\n        private bool Filter(object o)\n        {\n            var track = (Audio)o;\n            var query = LocalSearchBox.Query.ToLower();\n            return track.Title.ToLower().StartsWith(query) || track.Artist.ToLower().StartsWith(query);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Main/PopularAudioView.xaml",
    "content": "﻿<layout:PageBase x:Class=\"Meridian.View.Main.PopularAudioView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:layout=\"clr-namespace:Meridian.Layout\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"768\" d:DesignWidth=\"1024\"\n      KeepAlive=\"False\"\n      Header=\"{x:Static localization:MainResources.MainMenuPopular}\"\n      SubHeader=\"{x:Static localization:MainResources.PopularSubHeader}\"\n      x:Name=\"pageRoot\">\n\n    <layout:PageBase.HeaderMenuItems>\n        <MenuItem x:Name=\"LocalSearchItem\" Header=\"{x:Static localization:MainResources.HeaderMenuLocalSearch}\" Click=\"LocalSearchItem_OnClick\"/>\n    </layout:PageBase.HeaderMenuItems>\n\n    <layout:PageBase.Resources>\n        <CollectionViewSource x:Key=\"TracksCollection\" Source=\"{Binding Tracks}\" />\n    </layout:PageBase.Resources>\n\n    <TabItem>\n        <layout:TwoColumnPageLayout>\n            <layout:TwoColumnPageLayout.MainContent>\n                <Grid>\n                    <controls:BusyIndicator IsBusy=\"{Binding Tasks[audio].IsWorking}\" Error=\"{Binding Tasks[audio].Error}\">\n                        <ListBox Grid.Row=\"1\" x:Name=\"AudioList\" Margin=\"0,0,0,0\" ItemsSource=\"{Binding Source={StaticResource TracksCollection}}\" \n                     Style=\"{StaticResource CommonListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                     ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                     ItemTemplate=\"{StaticResource AudioItemTemplate}\">\n                            <i:Interaction.Behaviors>\n                                <behaviours:AutoScrollToCurrentItemBehaviour />\n                            </i:Interaction.Behaviors>\n                        </ListBox>\n                    </controls:BusyIndicator>\n\n                    <controls:LocalSearchControl x:Name=\"LocalSearchBox\" Source=\"{StaticResource TracksCollection}\"/>\n                </Grid>\n            </layout:TwoColumnPageLayout.MainContent>\n            <layout:TwoColumnPageLayout.RightContent>\n                <Grid>\n                    <Grid.RowDefinitions>\n                        <RowDefinition />\n                        <RowDefinition Height=\"Auto\"/>\n                    </Grid.RowDefinitions>\n                    <StackPanel Orientation=\"Horizontal\" Margin=\"12,10,0,0\">\n                        <TextBlock Text=\"{x:Static localization:MainResources.PopularGenresTitle}\" FontSize=\"11\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\" FontWeight=\"SemiBold\"/>\n                    </StackPanel>\n                    \n                    <ListBox Margin=\"0,35,0,0\" ItemsSource=\"{Binding Genres}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                             VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                             SelectedItem=\"{Binding SelectedGenre, Mode=TwoWay}\" ItemContainerStyle=\"{StaticResource AlbumListBoxItemStyle}\"\n                             Padding=\"0\">\n                        <i:Interaction.Behaviors>\n                            <behaviours:TransitionBehaviour Transition=\"{StaticResource AlbumLoadAnim}\" TransitionDelay=\"25\"/>\n                        </i:Interaction.Behaviors>\n                        <ListBox.ItemTemplate>\n                            <DataTemplate>\n                                <TextBlock Tag=\"{Binding DataContext, ElementName=pageRoot}\" Text=\"{Binding Title}\" ToolTip=\"{Binding Title}\" VerticalAlignment=\"Center\" TextTrimming=\"CharacterEllipsis\">\n                                </TextBlock>\n                            </DataTemplate>\n                        </ListBox.ItemTemplate>\n                    </ListBox>\n\n                    <CheckBox Grid.Row=\"1\" Style=\"{StaticResource CommonCheckBoxStyle}\" Content=\"{x:Static localization:MainResources.PopularForeignOnly}\" Margin=\"12,10,12,10\"\n                              IsChecked=\"{Binding ForeignOnly, Mode=TwoWay}\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                </Grid>\n            </layout:TwoColumnPageLayout.RightContent>\n        </layout:TwoColumnPageLayout>\n    </TabItem>\n</layout:PageBase>\n"
  },
  {
    "path": "Meridian/View/Main/PopularAudioView.xaml.cs",
    "content": "﻿using System.Windows;\nusing Meridian.Layout;\nusing Meridian.Model;\nusing Meridian.ViewModel.Main;\n\nnamespace Meridian.View.Main\n{\n    /// <summary>\n    /// Interaction logic for PopularAudioView.xaml\n    /// </summary>\n    public partial class PopularAudioView : PageBase\n    {\n        private PopularAudioViewModel _viewModel;\n\n        public PopularAudioView()\n        {\n            InitializeComponent();\n\n            _viewModel = new PopularAudioViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        public override void OnNavigatedTo()\n        {\n            base.OnNavigatedTo();\n\n            LocalSearchBox.Filter = Filter;\n        }\n\n        private bool Filter(object o)\n        {\n            var track = (Audio)o;\n            var query = LocalSearchBox.Query.ToLower();\n            return track.Title.ToLower().StartsWith(query) || track.Artist.ToLower().StartsWith(query);\n        }\n\n        private void LocalSearchItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            LocalSearchBox.IsActive = true;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Main/RecommendationsView.xaml",
    "content": "﻿<layout:PageBase x:Class=\"Meridian.View.Main.RecommendationsView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:componentModel=\"clr-namespace:System.ComponentModel;assembly=WindowsBase\"\n      xmlns:layout=\"clr-namespace:Meridian.Layout\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      mc:Ignorable=\"d\"\n      d:DesignHeight=\"768\" d:DesignWidth=\"1024\"\n      x:Name=\"pageRoot\"\n      Header=\"{x:Static localization:MainResources.MainMenuRecommendations}\"\n      SubHeader=\"{x:Static localization:MainResources.RecommendationsSubHeader}\"\n      Loaded=\"RecommendationsView_OnLoaded\">\n\n    <layout:PageBase.Resources>\n        <CollectionViewSource x:Key=\"RecommendationsCollection\" Source=\"{Binding RecommendationsCollection}\">\n            <CollectionViewSource.GroupDescriptions>\n                <PropertyGroupDescription PropertyName=\"Group\"/>\n            </CollectionViewSource.GroupDescriptions>\n            <CollectionViewSource.SortDescriptions>\n                <componentModel:SortDescription PropertyName=\"GroupOrder\" Direction=\"Ascending\"/>\n                <componentModel:SortDescription PropertyName=\"Title\"/>\n            </CollectionViewSource.SortDescriptions>\n        </CollectionViewSource>\n\n        <CollectionViewSource x:Key=\"TracksCollection\" Source=\"{Binding Tracks}\" />\n    </layout:PageBase.Resources>\n\n    <layout:PageBase.HeaderMenuItems>\n        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuRefresh}\" Command=\"{Binding RefreshCommand}\"/>\n        <MenuItem x:Name=\"LocalSearchItem\" Header=\"{x:Static localization:MainResources.HeaderMenuLocalSearch}\"\n                  Click=\"LocalSearchItem_OnClick\"/>\n    </layout:PageBase.HeaderMenuItems>\n\n    <layout:TwoColumnPageLayout>\n        <layout:TwoColumnPageLayout.RightContent>\n            <ListBox Grid.Column=\"1\" Grid.Row=\"1\" Padding=\"0\" Margin=\"0,10,0,0\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\" ItemsSource=\"{Binding Source={StaticResource RecommendationsCollection}}\"\n                 Foreground=\"Black\" Style=\"{StaticResource CommonListBoxStyle}\" ItemContainerStyle=\"{StaticResource AlbumListBoxItemStyle}\"\n                 SelectedItem=\"{Binding SelectedRecommendation}\" SelectedIndex=\"{Binding SelectedRecommendationIndex, Mode=TwoWay}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:TransitionBehaviour Transition=\"{StaticResource AlbumLoadAnim}\" TransitionDelay=\"40\"/>\n                </i:Interaction.Behaviors>\n                <ListBox.GroupStyle>\n                    <GroupStyle>\n                        <GroupStyle.ContainerStyle>\n                            <Style TargetType=\"{x:Type GroupItem}\">\n                                <Setter Property=\"Margin\" Value=\"0,0,0,5\"/>\n                                <Setter Property=\"Template\">\n                                    <Setter.Value>\n                                        <ControlTemplate TargetType=\"{x:Type GroupItem}\">\n                                            <Expander IsExpanded=\"True\" BorderThickness=\"0\" Style=\"{StaticResource MainMenuGroupExpanderStyle}\">\n                                                <Expander.Header>\n                                                    <TextBlock Text=\"{Binding Path=Name}\" Margin=\"11,0,0,0\" FontSize=\"12\" Foreground=\"{DynamicResource ForegroundBrush}\" Opacity=\"0.3\"/>\n                                                </Expander.Header>\n                                                <Expander.Content>\n                                                    <ItemsPresenter />\n                                                </Expander.Content>\n                                            </Expander>\n                                        </ControlTemplate>\n                                    </Setter.Value>\n                                </Setter>\n                            </Style>\n                        </GroupStyle.ContainerStyle>\n                    </GroupStyle>\n                </ListBox.GroupStyle>\n                <ListBox.ItemTemplate>\n                    <DataTemplate>\n                        <TextBlock Text=\"{Binding Title}\"/>\n                    </DataTemplate>\n                </ListBox.ItemTemplate>\n            </ListBox>\n        </layout:TwoColumnPageLayout.RightContent>\n        <layout:TwoColumnPageLayout.MainContent>\n            <Grid>\n                <controls:BusyIndicator IsBusy=\"{Binding Tasks[audio].IsWorking}\" Error=\"{Binding Tasks[audio].Error}\">\n                    <ListBox x:Name=\"AudioList\" Margin=\"0,0,0,0.2\" ItemsSource=\"{Binding Source={StaticResource TracksCollection}}\" Style=\"{StaticResource CommonListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                 ItemTemplate=\"{StaticResource AudioItemTemplate}\">\n                        <i:Interaction.Behaviors>\n                            <behaviours:AutoScrollToCurrentItemBehaviour />\n                        </i:Interaction.Behaviors>\n                    </ListBox>\n                </controls:BusyIndicator>\n                <controls:LocalSearchControl x:Name=\"LocalSearchBox\" Grid.ColumnSpan=\"2\" Source=\"{StaticResource TracksCollection}\"/>\n            </Grid>\n        </layout:TwoColumnPageLayout.MainContent>\n    </layout:TwoColumnPageLayout>\n\n</layout:PageBase>\n"
  },
  {
    "path": "Meridian/View/Main/RecommendationsView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing Meridian.Layout;\nusing Meridian.Model;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Main;\n\nnamespace Meridian.View.Main\n{\n    /// <summary>\n    /// Interaction logic for RecommendationsView.xaml\n    /// </summary>\n    public partial class RecommendationsView : PageBase\n    {\n        private RecommendationsViewModel _viewModel;\n\n        public RecommendationsView()\n        {\n            InitializeComponent();\n\n            _viewModel = new RecommendationsViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void RecommendationsView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            LocalSearchBox.Filter = Filter;\n        }\n\n        private void LocalSearchItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            LocalSearchBox.IsActive = true;\n        }\n\n        private bool Filter(object o)\n        {\n            var track = (Audio)o;\n            var query = LocalSearchBox.Query.ToLower();\n            return track.Title.ToLower().StartsWith(query) || track.Artist.ToLower().StartsWith(query);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/People/FriendsAudioView.xaml",
    "content": "﻿<controls:PageBase x:Class=\"Meridian.View.People.FriendAudioView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      x:Name=\"pageRoot\"\n      Unloaded=\"FriendAudioView_OnUnloaded\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n    \n    <Page.Resources>\n        <CollectionViewSource x:Key=\"TracksCollection\" Source=\"{Binding Tracks}\" />\n    </Page.Resources>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"71\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition />\n            <ColumnDefinition Width=\"180\"/>\n        </Grid.ColumnDefinitions>\n        <!--<Image Grid.ColumnSpan=\"2\" MaxHeight=\"85\" MaxWidth=\"155\" Source=\"{Binding SelectedFriend.PhotoLarge}\" HorizontalAlignment=\"Right\" Opacity=\"0.4\" VerticalAlignment=\"Top\" Stretch=\"UniformToFill\"\n               Margin=\"0,0,0,0\">\n            <Image.OpacityMask>\n                <LinearGradientBrush StartPoint=\"1,0\" EndPoint=\"0,0\">\n                    <GradientStop Color=\"White\" Offset=\"0\"/>\n                    <GradientStop Color=\"White\" Offset=\"0.5\"/>\n                    <GradientStop Color=\"Transparent\" Offset=\"1\"/>\n                </LinearGradientBrush>\n            </Image.OpacityMask>\n        </Image>-->\n        <Grid Grid.ColumnSpan=\"2\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"20\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n            <Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"140\" StaysOpen=\"False\" VerticalOffset=\"10\"\n                   PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n                <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"Black\">\n                    <ItemsControl>\n                        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuRefresh}\" Command=\"{Binding RefreshCommand}\" CommandParameter=\"{Binding}\" Click=\"MenuItem_OnClick\"/>\n                        <MenuItem x:Name=\"LocalSearchItem\" Header=\"{x:Static localization:MainResources.HeaderMenuLocalSearch}\" Click=\"LocalSearchItem_OnClick\"/>\n                    </ItemsControl>\n                </Border>\n            </Popup>\n\n            <Button Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                    HorizontalAlignment=\"Left\"\n                    Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n\n            <ToggleButton Grid.Column=\"1\" x:Name=\"HeaderButton\" Content=\"{Binding SelectedFriend.Name}\" Style=\"{StaticResource HeaderButtonStyle}\"/>\n        </Grid>\n\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <Rectangle Width=\"1\" Grid.Row=\"1\" Grid.Column=\"0\" HorizontalAlignment=\"Right\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n\n        <controls:BusyIndicator Grid.Row=\"1\" IsBusy=\"{Binding Tasks[audio].IsWorking}\" Error=\"{Binding Tasks[audio].Error}\">\n            <ListBox x:Name=\"AudioList\" Margin=\"0,0,0,0\" ItemsSource=\"{Binding Source={StaticResource TracksCollection}}\" Style=\"{StaticResource CommonListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                 ItemTemplate=\"{StaticResource AudioItemTemplate}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:AutoScrollToCurrentItemBehaviour />\n                </i:Interaction.Behaviors>\n            </ListBox>\n        </controls:BusyIndicator>\n\n        <Rectangle Grid.Row=\"1\" Grid.Column=\"1\" Fill=\"{DynamicResource MainBackgroundBrush}\" Margin=\"0,0,0,-25\" Opacity=\"0.4\"/>\n\n        <TextBlock Grid.Row=\"1\" Grid.Column=\"1\" Text=\"{x:Static localization:MainResources.MyMusicAlbums}\" FontSize=\"11\" Opacity=\"0.7\" FontWeight=\"SemiBold\" Margin=\"12,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n        <controls:ExtendedListBox Grid.Row=\"1\" Grid.Column=\"1\" Padding=\"0\" Margin=\"0,30,0,0\" ItemsSource=\"{Binding Albums}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 ItemContainerStyleSelector=\"{StaticResource AlbumItemStyleSelector}\" SelectedItem=\"{Binding SelectedAlbum, Mode=TwoWay}\"\n                 LoadMoreCommand=\"{Binding LoadMoreAlbumsCommand}\">\n            <i:Interaction.Behaviors>\n                <behaviours:TransitionBehaviour Transition=\"{StaticResource AlbumLoadAnim}\" TransitionDelay=\"65\"/>\n            </i:Interaction.Behaviors>\n            <ListBox.ItemTemplate>\n                <DataTemplate>\n                    <TextBlock Tag=\"{Binding DataContext, ElementName=pageRoot}\" Text=\"{Binding Title}\" ToolTip=\"{Binding Title}\" TextTrimming=\"CharacterEllipsis\">\n                        <TextBlock.ContextMenu>\n                            <ContextMenu Visibility=\"{Binding Converter={StaticResource AlbumContextMenuVisibilityConverter}}\" Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                                <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuPlay}\" Command=\"{Binding PlacementTarget.Tag.PlayAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding PlacementTarget.Tag.AddAlbumToNowPlayingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                <Separator />\n                                <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuCopyToMyAlbums}\" Command=\"{Binding PlacementTarget.Tag.CopyAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                            </ContextMenu>\n                        </TextBlock.ContextMenu>\n                    </TextBlock>\n                </DataTemplate>\n            </ListBox.ItemTemplate>\n        </controls:ExtendedListBox>\n\n        <controls:LocalSearchControl x:Name=\"LocalSearchBox\" Grid.ColumnSpan=\"2\" Grid.Row=\"1\" Source=\"{StaticResource TracksCollection}\"/>\n    </Grid>\n</controls:PageBase>\n"
  },
  {
    "path": "Meridian/View/People/FriendsAudioView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls.Primitives;\nusing Meridian.Controls;\nusing Meridian.Model;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.People;\nusing VkLib.Core.Users;\n\nnamespace Meridian.View.People\n{\n    /// <summary>\n    /// Interaction logic for FriendsAudio.xaml\n    /// </summary>\n    public partial class FriendAudioView : PageBase\n    {\n        private FriendAudioViewModel _viewModel;\n\n        public FriendAudioView()\n        {\n            InitializeComponent();\n\n            _viewModel = new FriendAudioViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        public override void OnNavigatedTo()\n        {\n            var friend = (VkProfile)NavigationContext.Parameters[\"friend\"];\n            _viewModel.SelectedFriend = friend;\n\n            _viewModel.Activate();\n\n            LocalSearchBox.Filter = Filter;\n        }\n\n        private void FriendAudioView_OnUnloaded(object sender, RoutedEventArgs e)\n        {\n            _viewModel.Deactivate();\n        }\n\n        private void MenuItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n        }\n\n        private void LocalSearchItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n            LocalSearchBox.IsActive = true;\n        }\n\n        private bool Filter(object o)\n        {\n            var track = (Audio)o;\n            var query = LocalSearchBox.Query.ToLower();\n            return track.Title.ToLower().StartsWith(query) || track.Artist.ToLower().StartsWith(query);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/People/FriendsView.xaml",
    "content": "﻿<layout:PageBase x:Class=\"Meridian.View.People.FriendsView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:helpers=\"clr-namespace:Meridian.Helpers\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:layout=\"clr-namespace:Meridian.Layout\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      x:Name=\"pageRoot\"\n      KeepAlive=\"False\" Background=\"{DynamicResource MainBackgroundBrush}\"\n      Header=\"{x:Static localization:MainResources.MainMenuFriends}\"\n      Loaded=\"FriendsView_OnLoaded\">\n\n    <Page.Resources>\n        <CollectionViewSource x:Key=\"FriendsCollection\" Source=\"{Binding Friends}\" />\n    </Page.Resources>\n\n    <layout:PageBase.HeaderMenuItems>\n        <MenuItem x:Name=\"LocalSearchItem\" Header=\"{x:Static localization:MainResources.HeaderMenuLocalSearch}\"\n                  Click=\"LocalSearchItem_OnClick\"/>\n    </layout:PageBase.HeaderMenuItems>\n\n    <Grid>\n        <controls:BusyIndicator IsBusy=\"{Binding Tasks[friends].IsWorking}\" Error=\"{Binding Tasks[friends].Error}\">\n            <ListBox Margin=\"24,0,0,0\" Padding=\"0,5,0,0\" ItemsSource=\"{Binding Source={StaticResource FriendsCollection}}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                         VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                         ItemContainerStyle=\"{StaticResource FriendListBoxItemStyle}\">\n                <ListBox.ItemsPanel>\n                    <ItemsPanelTemplate>\n                        <WrapPanel Orientation=\"Horizontal\"/>\n                    </ItemsPanelTemplate>\n                </ListBox.ItemsPanel>\n                <ListBox.ItemTemplate>\n                    <DataTemplate>\n                        <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.GoToFriendCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\"\n                                 Width=\"120\" Height=\"120\" ToolTip=\"{Binding Name}\">\n                            <Button.RenderTransform>\n                                <TranslateTransform />\n                            </Button.RenderTransform>\n                            <Button.Triggers>\n                                <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                                    <BeginStoryboard Storyboard=\"{StaticResource FriendLoadAnim}\" />\n                                </EventTrigger>\n                            </Button.Triggers>\n                            <Grid x:Name=\"RootGrid\">\n                                <Grid.RowDefinitions>\n                                    <RowDefinition />\n                                    <RowDefinition Height=\"Auto\"/>\n                                </Grid.RowDefinitions>\n                                <Grid Grid.RowSpan=\"2\">\n                                    <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding PhotoMedium}\" Stretch=\"UniformToFill\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                                </Grid>\n                                <Rectangle Grid.Row=\"1\" Fill=\"Black\" Opacity=\"0.8\" />\n                                <StackPanel Grid.Row=\"1\">\n                                    <TextBlock Text=\"{Binding FirstName}\" FontWeight=\"Normal\" FontSize=\"11\" Margin=\"5,3,5,0\" TextTrimming=\"CharacterEllipsis\" Opacity=\"0.8\" Foreground=\"White\"/>\n                                    <TextBlock Text=\"{Binding LastName}\" FontFamily=\"Segoe UI SemiLight\" FontSize=\"12\" Margin=\"5,-2,5,7\" TextTrimming=\"CharacterEllipsis\" Foreground=\"White\"/>\n                                </StackPanel>\n                            </Grid>\n                        </Button>\n                    </DataTemplate>\n                </ListBox.ItemTemplate>\n            </ListBox>\n        </controls:BusyIndicator>\n\n        <controls:LocalSearchControl x:Name=\"LocalSearchBox\" Grid.ColumnSpan=\"2\" Grid.Row=\"1\" Source=\"{StaticResource FriendsCollection}\"/>\n    </Grid>\n</layout:PageBase>\n"
  },
  {
    "path": "Meridian/View/People/FriendsView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls.Primitives;\nusing Meridian.Layout;\nusing Meridian.ViewModel.People;\nusing VkLib.Core.Users;\n\nnamespace Meridian.View.People\n{\n    /// <summary>\n    /// Interaction logic for FriendsView.xaml\n    /// </summary>\n    public partial class FriendsView : PageBase\n    {\n        private FriendsViewModel _viewModel;\n\n        public FriendsView()\n        {\n            InitializeComponent();\n\n            _viewModel = new FriendsViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void FriendsView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            _viewModel.Activate();\n\n            LocalSearchBox.Filter = Filter;\n        }\n\n        private void LocalSearchItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            LocalSearchBox.IsActive = true;\n        }\n\n        private bool Filter(object o)\n        {\n            var profile = (VkProfileBase)o;\n            var query = LocalSearchBox.Query.ToLower();\n            return profile.Name.ToLower().StartsWith(query);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/People/SocietiesView.xaml",
    "content": "﻿<layout:PageBase x:Class=\"Meridian.View.People.SocietiesView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:helpers=\"clr-namespace:Meridian.Helpers\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:layout=\"clr-namespace:Meridian.Layout\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      x:Name=\"pageRoot\"\n      KeepAlive=\"False\"\n      Background=\"{DynamicResource MainBackgroundBrush}\"\n      Header=\"{x:Static localization:MainResources.MainMenuSocieties}\"\n      Loaded=\"SocietiesView_OnLoaded\">\n\n    <Page.Resources>\n        <CollectionViewSource x:Key=\"SocietiesCollection\" Source=\"{Binding Societies}\" />\n    </Page.Resources>\n\n    <layout:PageBase.HeaderMenuItems>\n        <MenuItem x:Name=\"LocalSearchItem\" Header=\"{x:Static localization:MainResources.HeaderMenuLocalSearch}\"\n                  Click=\"LocalSearchItem_OnClick\"/>\n    </layout:PageBase.HeaderMenuItems>\n\n    <Grid>\n        <controls:BusyIndicator IsBusy=\"{Binding Tasks[groups].IsWorking}\" Error=\"{Binding Tasks[groups].Error}\">\n            <ListBox Margin=\"24,0,0,0\" Padding=\"0,5,0,0\" ItemsSource=\"{Binding Source={StaticResource SocietiesCollection}}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                     VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                     ItemContainerStyle=\"{StaticResource FriendListBoxItemStyle}\">\n                <ListBox.ItemsPanel>\n                    <ItemsPanelTemplate>\n                        <WrapPanel Orientation=\"Horizontal\"/>\n                    </ItemsPanelTemplate>\n                </ListBox.ItemsPanel>\n                <ListBox.ItemTemplate>\n                    <DataTemplate>\n                        <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.GoToSocietyCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\"\n                                 Width=\"120\" Height=\"120\" ToolTip=\"{Binding Name}\">\n                            <Button.RenderTransform>\n                                <TranslateTransform />\n                            </Button.RenderTransform>\n                            <Button.Triggers>\n                                <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                                    <BeginStoryboard Storyboard=\"{StaticResource FriendLoadAnim}\" />\n                                </EventTrigger>\n                            </Button.Triggers>\n                            <Grid x:Name=\"RootGrid\">\n                                <Grid.RowDefinitions>\n                                    <RowDefinition />\n                                    <RowDefinition Height=\"40\"/>\n                                </Grid.RowDefinitions>\n                                <Grid Grid.RowSpan=\"2\">\n                                    <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding PhotoMedium}\" Stretch=\"UniformToFill\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                                </Grid>\n                                <Rectangle Grid.Row=\"1\" Fill=\"Black\" Opacity=\"0.8\" />\n                                <TextBlock Grid.Row=\"1\" VerticalAlignment=\"Center\" Text=\"{Binding Name}\" FontWeight=\"Normal\" FontSize=\"11\" Foreground=\"White\" TextWrapping=\"Wrap\"\n                                                   TextTrimming=\"CharacterEllipsis\" Margin=\"5\"/>\n                            </Grid>\n                        </Button>\n                    </DataTemplate>\n                </ListBox.ItemTemplate>\n            </ListBox>\n        </controls:BusyIndicator>\n\n        <controls:LocalSearchControl x:Name=\"LocalSearchBox\" Grid.ColumnSpan=\"2\" Grid.Row=\"1\" Source=\"{StaticResource SocietiesCollection}\"/>\n\n    </Grid>\n</layout:PageBase>\n"
  },
  {
    "path": "Meridian/View/People/SocietiesView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls.Primitives;\nusing Meridian.Layout;\nusing Meridian.ViewModel.People;\nusing VkLib.Core.Users;\n\nnamespace Meridian.View.People\n{\n    /// <summary>\n    /// Interaction logic for SocietiesView.xaml\n    /// </summary>\n    public partial class SocietiesView : PageBase\n    {\n        private SocietiesViewModel _viewModel;\n\n        public SocietiesView()\n        {\n            InitializeComponent();\n\n            _viewModel = new SocietiesViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void SocietiesView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            _viewModel.Activate();\n\n            LocalSearchBox.Filter = Filter;\n        }\n\n        private void LocalSearchItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            LocalSearchBox.IsActive = true;\n        }\n\n        private bool Filter(object o)\n        {\n            var profile = (VkProfileBase)o;\n            var query = LocalSearchBox.Query.ToLower();\n            return profile.Name.ToLower().Contains(query);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/People/SocietyAudioView.xaml",
    "content": "﻿<controls:PageBase x:Class=\"Meridian.View.People.SocietyAudioView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      x:Name=\"pageRoot\"\n      Unloaded=\"SocietyAudioView_OnUnloaded\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Page.Resources>\n        <CollectionViewSource x:Key=\"TracksCollection\" Source=\"{Binding Tracks}\" />\n    </Page.Resources>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"71\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition />\n            <ColumnDefinition Width=\"180\"/>\n        </Grid.ColumnDefinitions>\n        <Grid Grid.ColumnSpan=\"2\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"20\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n            <Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"140\" StaysOpen=\"False\" VerticalOffset=\"10\"\n                   PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n                <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"Black\">\n                    <ItemsControl>\n                        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuRefresh}\" Command=\"{Binding RefreshCommand}\" CommandParameter=\"{Binding}\" Click=\"MenuItem_OnClick\"/>\n                        <MenuItem x:Name=\"LocalSearchItem\" Header=\"{x:Static localization:MainResources.HeaderMenuLocalSearch}\" Click=\"LocalSearchItem_OnClick\"/>\n                    </ItemsControl>\n                </Border>\n            </Popup>\n\n            <Button Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                    HorizontalAlignment=\"Left\"\n                    Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n\n            <ToggleButton Grid.Column=\"1\" x:Name=\"HeaderButton\" Content=\"{Binding SelectedSociety.Name}\" Style=\"{StaticResource HeaderButtonStyle}\"/>\n        </Grid>\n\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <Rectangle Width=\"1\" Grid.Row=\"1\" Grid.Column=\"0\" HorizontalAlignment=\"Right\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n\n        <controls:BusyIndicator Grid.Row=\"1\" IsBusy=\"{Binding Tasks[audio].IsWorking}\" Error=\"{Binding Tasks[audio].Error}\">\n            <ListBox x:Name=\"AudioList\" Margin=\"0,0,0,0\" ItemsSource=\"{Binding Source={StaticResource TracksCollection}}\" Style=\"{StaticResource CommonListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                 ItemTemplate=\"{StaticResource AudioItemTemplate}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:AutoScrollToCurrentItemBehaviour />\n                </i:Interaction.Behaviors>\n            </ListBox>\n        </controls:BusyIndicator>\n\n        <Rectangle Grid.Row=\"1\" Grid.Column=\"1\" Fill=\"{DynamicResource MainBackgroundBrush}\" Margin=\"0,0,0,-25\" Opacity=\"0.4\"/>\n        <TextBlock Grid.Row=\"1\" Grid.Column=\"1\" Text=\"{x:Static localization:MainResources.MyMusicAlbums}\" FontSize=\"11\" Opacity=\"0.7\" FontWeight=\"SemiBold\" Margin=\"12,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n        <controls:ExtendedListBox Grid.Row=\"1\" Grid.Column=\"1\" Padding=\"0\" Margin=\"0,30,0,0\" ItemsSource=\"{Binding Albums}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 ItemContainerStyleSelector=\"{StaticResource AlbumItemStyleSelector}\"\n                 SelectedItem=\"{Binding SelectedAlbum, Mode=TwoWay}\"\n                 LoadMoreCommand=\"{Binding LoadMoreAlbumsCommand}\">\n            <i:Interaction.Behaviors>\n                <behaviours:TransitionBehaviour Transition=\"{StaticResource AlbumLoadAnim}\" TransitionDelay=\"65\"/>\n            </i:Interaction.Behaviors>\n            <ListBox.ItemTemplate>\n                <DataTemplate>\n                    <TextBlock Tag=\"{Binding DataContext, ElementName=pageRoot}\" Text=\"{Binding Title}\" ToolTip=\"{Binding Title}\" TextTrimming=\"CharacterEllipsis\">\n                        <TextBlock.ContextMenu>\n                            <ContextMenu Visibility=\"{Binding Converter={StaticResource AlbumContextMenuVisibilityConverter}}\" Style=\"{StaticResource CommonContextMenuStyle}\" Focusable=\"False\">\n                                <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuPlay}\" Command=\"{Binding PlacementTarget.Tag.PlayAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuAddToNowPlaying}\" Command=\"{Binding PlacementTarget.Tag.AddAlbumToNowPlayingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                                <Separator />\n                                <MenuItem Header=\"{x:Static localization:MainResources.ContextMenuCopyToMyAlbums}\" Command=\"{Binding PlacementTarget.Tag.CopyAlbumCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}\" CommandParameter=\"{Binding}\"/>\n                            </ContextMenu>\n                        </TextBlock.ContextMenu>\n                    </TextBlock>\n                </DataTemplate>\n            </ListBox.ItemTemplate>\n        </controls:ExtendedListBox>\n\n        <controls:LocalSearchControl x:Name=\"LocalSearchBox\" Grid.ColumnSpan=\"2\" Grid.Row=\"1\" Source=\"{StaticResource TracksCollection}\"/>\n\n    </Grid>\n</controls:PageBase>\n"
  },
  {
    "path": "Meridian/View/People/SocietyAudioView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls.Primitives;\nusing Meridian.Controls;\nusing Meridian.Model;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.People;\nusing VkLib.Core.Groups;\n\nnamespace Meridian.View.People\n{\n    /// <summary>\n    /// Interaction logic for SocietyAudioView.xaml\n    /// </summary>\n    public partial class SocietyAudioView : PageBase\n    {\n        private SocietyAudioViewModel _viewModel;\n\n        public SocietyAudioView()\n        {\n            InitializeComponent();\n\n            _viewModel = new SocietyAudioViewModel();\n            this.DataContext = _viewModel;\n        }\n\n\n        public override void OnNavigatedTo()\n        {\n            var society = (VkGroup)NavigationContext.Parameters[\"society\"];\n            _viewModel.SelectedSociety = society;\n\n            _viewModel.Activate();\n\n            LocalSearchBox.Filter = Filter;\n        }\n\n        private void SocietyAudioView_OnUnloaded(object sender, RoutedEventArgs e)\n        {\n            _viewModel.Deactivate();\n        }\n\n        private void MenuItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n        }\n\n        private void LocalSearchItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n            LocalSearchBox.IsActive = true;\n        }\n\n        private bool Filter(object o)\n        {\n            var track = (Audio)o;\n            var query = LocalSearchBox.Query.ToLower();\n            return track.Title.ToLower().StartsWith(query) || track.Artist.ToLower().StartsWith(query);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/People/SubscriptionsView.xaml",
    "content": "﻿<layout:PageBase x:Class=\"Meridian.View.People.SubscriptionsView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:helpers=\"clr-namespace:Meridian.Helpers\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:layout=\"clr-namespace:Meridian.Layout\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      x:Name=\"pageRoot\" Background=\"{DynamicResource MainBackgroundBrush}\"\n      Header=\"{x:Static localization:MainResources.MainMenuSubscriptions}\"\n      Loaded=\"SubscriptionsView_OnLoaded\">\n\n    <Grid>\n        <controls:BusyIndicator IsBusy=\"{Binding Tasks[subscriptions].IsWorking}\" Error=\"{Binding Tasks[subscriptions].Error}\">\n            <ListBox Margin=\"24,0,0,0\" Padding=\"0,5,0,0\" ItemsSource=\"{Binding Subscriptions}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                         VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                         ItemContainerStyle=\"{StaticResource FriendListBoxItemStyle}\">\n                <i:Interaction.Behaviors>\n                    <behaviours:TransitionBehaviour Transition=\"{StaticResource FriendLoadAnim}\" TransitionDelay=\"25\"/>\n                </i:Interaction.Behaviors>\n                <ListBox.ItemsPanel>\n                    <ItemsPanelTemplate>\n                        <WrapPanel Orientation=\"Horizontal\"/>\n                    </ItemsPanelTemplate>\n                </ListBox.ItemsPanel>\n                <ListBox.ItemTemplate>\n                    <DataTemplate>\n                        <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.GoToSubscriptionCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\"\n                                 Width=\"120\" Height=\"120\" ToolTip=\"{Binding Name}\">\n                            <Button.RenderTransform>\n                                <TranslateTransform />\n                            </Button.RenderTransform>\n                            <Button.Triggers>\n                                <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                                    <BeginStoryboard Storyboard=\"{StaticResource FriendLoadAnim}\" />\n                                </EventTrigger>\n                            </Button.Triggers>\n                            <Grid x:Name=\"RootGrid\">\n                                <Grid.RowDefinitions>\n                                    <RowDefinition />\n                                    <RowDefinition Height=\"Auto\"/>\n                                </Grid.RowDefinitions>\n                                <Grid Grid.RowSpan=\"2\">\n                                    <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding PhotoMedium}\" Stretch=\"UniformToFill\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                                </Grid>\n                                <Rectangle Grid.Row=\"1\" Fill=\"Black\" Opacity=\"0.8\" />\n                                <StackPanel Grid.Row=\"1\">\n                                    <TextBlock Text=\"{Binding FirstName}\" FontWeight=\"Normal\" FontSize=\"11\" Margin=\"5,3,5,0\" TextTrimming=\"CharacterEllipsis\" Opacity=\"0.8\" Foreground=\"White\"/>\n                                    <TextBlock Text=\"{Binding LastName}\" FontFamily=\"Segoe UI SemiLight\" FontSize=\"12\" Margin=\"5,-2,5,7\" TextTrimming=\"CharacterEllipsis\" Foreground=\"White\"/>\n                                </StackPanel>\n                            </Grid>\n                        </Button>\n                    </DataTemplate>\n                </ListBox.ItemTemplate>\n            </ListBox>\n        </controls:BusyIndicator>\n    </Grid>\n</layout:PageBase>\n"
  },
  {
    "path": "Meridian/View/People/SubscriptionsView.xaml.cs",
    "content": "﻿using System.Windows;\nusing Meridian.Layout;\nusing Meridian.ViewModel.People;\n\nnamespace Meridian.View.People\n{\n    /// <summary>\n    /// Interaction logic for SubscriptionsView.xaml\n    /// </summary>\n    public partial class SubscriptionsView : PageBase\n    {\n        private SubscriptionsViewModel _viewModel;\n\n        public SubscriptionsView()\n        {\n            InitializeComponent();\n\n            _viewModel = new SubscriptionsViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void SubscriptionsView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            _viewModel.Activate();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Search/AlbumView.xaml",
    "content": "﻿<controls:PageBase x:Class=\"Meridian.View.Search.AlbumView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:helpers=\"clr-namespace:Meridian.Helpers\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\"\n      x:Name=\"pageRoot\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n    \n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"71\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition />\n            <ColumnDefinition Width=\"180\"/>\n        </Grid.ColumnDefinitions>\n        <Grid Grid.ColumnSpan=\"2\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"20\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n            <Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"160\" StaysOpen=\"False\" VerticalOffset=\"10\"\n                   PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n                <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"Black\">\n                    <ItemsControl>\n                        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuSave}\" Command=\"{Binding SaveCommand}\" Click=\"MenuItem_OnClick\"/>\n                        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuShare}\" Command=\"{Binding ShareCommand}\" Click=\"MenuItem_OnClick\"/>\n                    </ItemsControl>\n                </Border>\n            </Popup>\n            <Button Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                    HorizontalAlignment=\"Left\"\n                    Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n            <Grid Margin=\"5,15,0,15\" Grid.Column=\"1\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\"/>\n                    <ColumnDefinition />\n                </Grid.ColumnDefinitions>\n                <Image Source=\"{Binding Album.ImageLarge}\" Width=\"45\" Height=\"45\" Stretch=\"UniformToFill\" HorizontalAlignment=\"Center\"/>\n                <StackPanel Grid.Column=\"1\" Margin=\"10,-7,0,0\">\n                    <ToggleButton x:Name=\"HeaderButton\" Content=\"{Binding Album.Name}\" Style=\"{StaticResource HeaderButtonStyle}\" Margin=\"-2,0,0,0\" FontSize=\"24\"/>\n                    <TextBlock Text=\"{Binding Album.Artist}\" FontSize=\"13\" Margin=\"0,-2,0,0\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                </StackPanel>\n            </Grid>\n        </Grid>\n        <ProgressBar IsIndeterminate=\"{Binding IsWorking}\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}}\" Style=\"{StaticResource HeaderProgressBarStyle}\"/>\n\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <Rectangle Width=\"1\" Grid.Row=\"1\" Grid.Column=\"0\" HorizontalAlignment=\"Right\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n\n        <ListBox Grid.Row=\"1\" x:Name=\"AudioList\" Margin=\"0,0,0,0\" ItemsSource=\"{Binding Tracks}\" Style=\"{StaticResource CommonListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                 ItemTemplate=\"{StaticResource OrderedAudioItemTemplate}\">\n            <i:Interaction.Behaviors>\n                <behaviours:AutoScrollToCurrentItemBehaviour />\n            </i:Interaction.Behaviors>\n        </ListBox>\n\n        <TextBlock Grid.Row=\"1\" Grid.Column=\"1\" Text=\"{x:Static localization:MainResources.MyMusicAlbums}\" FontSize=\"11\" Opacity=\"0.7\" Margin=\"12,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                   FontWeight=\"SemiBold\"/>\n        <ListBox Grid.Row=\"1\" Grid.Column=\"1\" Padding=\"0\" Margin=\"0,35,0,0\" ItemsSource=\"{Binding ArtistAlbums}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 SelectedIndex=\"{Binding SelectedAlbumIndex, Mode=TwoWay}\" ItemContainerStyle=\"{StaticResource AlbumListBoxItemStyle}\">\n            <i:Interaction.Behaviors>\n                <behaviours:TransitionBehaviour Transition=\"{StaticResource AlbumLoadAnim}\" TransitionDelay=\"65\"/>\n            </i:Interaction.Behaviors>\n            <ListBox.ItemTemplate>\n                <DataTemplate>\n                    <Grid>\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"Auto\"/>\n                            <ColumnDefinition />\n                        </Grid.ColumnDefinitions>\n                        <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding ImageMedium}\" Width=\"30\" Height=\"30\"/>\n                        <TextBlock Text=\"{Binding Name}\" Grid.Column=\"1\" Margin=\"10,0,0,0\" TextTrimming=\"CharacterEllipsis\" VerticalAlignment=\"Center\"\n                                   ToolTip=\"{Binding Name}\"/>\n                    </Grid>\n                </DataTemplate>\n            </ListBox.ItemTemplate>\n        </ListBox>\n    </Grid>\n</controls:PageBase>\n"
  },
  {
    "path": "Meridian/View/Search/AlbumView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls.Primitives;\nusing LastFmLib.Core.Album;\nusing Meridian.Controls;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Search;\n\nnamespace Meridian.View.Search\n{\n    /// <summary>\n    /// Interaction logic for AlbumView.xaml\n    /// </summary>\n    public partial class AlbumView : PageBase\n    {\n        private AlbumViewModel _viewModel;\n\n        public AlbumView()\n        {\n            InitializeComponent();\n\n            _viewModel = new AlbumViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        public override void OnNavigatedTo()\n        {\n            var album = (LastFmAlbum)NavigationContext.Parameters[\"album\"];\n            _viewModel.Album = album;\n\n            _viewModel.Activate();\n        }\n\n        private void MenuItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Search/ArtistAlbumsView.xaml",
    "content": "﻿<controls:PageBase x:Class=\"Meridian.View.Search.ArtistAlbumsView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:helpers=\"clr-namespace:Meridian.Helpers\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\"\n      x:Name=\"pageRoot\" KeepAlive=\"False\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"71\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <Grid>\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"20\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n            <Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"120\" StaysOpen=\"False\" VerticalOffset=\"10\"\n                   PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n                <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"Black\">\n                    <ItemsControl>\n                        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuShare}\" Command=\"{Binding ShareCommand}\" Click=\"MenuItem_OnClick\"/>\n                    </ItemsControl>\n                </Border>\n            </Popup>\n            <Button Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                    HorizontalAlignment=\"Left\"\n                    Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n            <Grid Grid.Column=\"1\" Margin=\"5,15,0,15\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\"/>\n                    <ColumnDefinition />\n                </Grid.ColumnDefinitions>\n                <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding Artist.ImageLarge}\" Width=\"45\" Height=\"45\" Stretch=\"UniformToFill\" HorizontalAlignment=\"Center\"\n                       Visibility=\"{Binding Artist.ImageLarge, Converter={StaticResource NullToVisibilityConverter}}\"/>\n                <ToggleButton x:Name=\"HeaderButton\" Style=\"{StaticResource HeaderButtonStyle}\"\n                              Grid.Column=\"1\" Content=\"{Binding Artist.Name}\" Margin=\"10,0,0,0\" VerticalAlignment=\"Center\"/>\n            </Grid>\n        </Grid>\n\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n\n        <ListBox Grid.Row=\"1\" Margin=\"20,0,0,0\" Padding=\"0,5,0,0\" ItemsSource=\"{Binding AllAlbums}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                         VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                         ItemContainerStyle=\"{StaticResource LastFmAlbumListBoxItemStyle}\">\n            <ListBox.ItemsPanel>\n                <ItemsPanelTemplate>\n                    <WrapPanel Orientation=\"Horizontal\"/>\n                </ItemsPanelTemplate>\n            </ListBox.ItemsPanel>\n            <ListBox.ItemTemplate>\n                <DataTemplate>\n                    <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.GoToAlbumCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\">\n                        <Button.RenderTransform>\n                            <TranslateTransform />\n                        </Button.RenderTransform>\n                        <Button.Triggers>\n                            <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                                <BeginStoryboard Storyboard=\"{StaticResource FriendLoadAnim}\" />\n                            </EventTrigger>\n                        </Button.Triggers>\n                        <Grid Width=\"80\">\n                            <Grid.RowDefinitions>\n                                <RowDefinition />\n                                <RowDefinition Height=\"Auto\"/>\n                            </Grid.RowDefinitions>\n                            <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding ImageMedium}\" Width=\"80\" Height=\"80\"/>\n                            <TextBlock Grid.Row=\"1\" Text=\"{Binding Name}\" Margin=\"0,0,0,0\" TextWrapping=\"Wrap\" TextTrimming=\"CharacterEllipsis\"\n                                           FontSize=\"11\" Height=\"30\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                        </Grid>\n                    </Button>\n                </DataTemplate>\n            </ListBox.ItemTemplate>\n        </ListBox>\n    </Grid>\n</controls:PageBase>\n"
  },
  {
    "path": "Meridian/View/Search/ArtistAlbumsView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls.Primitives;\nusing Meridian.Controls;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Search;\n\nnamespace Meridian.View.Search\n{\n    /// <summary>\n    /// Interaction logic for ArtistAudioView.xaml\n    /// </summary>\n    public partial class ArtistAlbumsView : PageBase\n    {\n        public ArtistAlbumsView()\n        {\n            InitializeComponent();\n        }\n\n        public override void OnNavigatedTo()\n        {\n            var viewModel = (ArtistViewModel)NavigationContext.Parameters[\"viewModel\"];\n            this.DataContext = viewModel;\n        }\n\n        private void MenuItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Search/ArtistAudioView.xaml",
    "content": "﻿<controls:PageBase x:Class=\"Meridian.View.Search.ArtistAudioView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:helpers=\"clr-namespace:Meridian.Helpers\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\"\n      x:Name=\"pageRoot\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"71\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <Grid>\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"20\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n            <Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"120\" StaysOpen=\"False\" VerticalOffset=\"10\"\n                   PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n                <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"Black\">\n                    <ItemsControl>\n                        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuShare}\" Command=\"{Binding ShareCommand}\" Click=\"MenuItem_OnClick\"/>\n                    </ItemsControl>\n                </Border>\n            </Popup>\n            <Button Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                    HorizontalAlignment=\"Left\"\n                    Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n            <Grid Grid.Column=\"1\" Margin=\"5,15,0,15\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\"/>\n                    <ColumnDefinition />\n                </Grid.ColumnDefinitions>\n                <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding Artist.ImageLarge}\" Width=\"45\" Height=\"45\"\n                       Stretch=\"UniformToFill\" HorizontalAlignment=\"Center\"\n                       Visibility=\"{Binding Artist.ImageLarge, Converter={StaticResource NullToVisibilityConverter}}\"/>\n                <ToggleButton x:Name=\"HeaderButton\" Style=\"{StaticResource HeaderButtonStyle}\"\n                              Grid.Column=\"1\" Content=\"{Binding Artist.Name}\" Margin=\"10,0,0,0\" VerticalAlignment=\"Center\"/>\n            </Grid>\n        </Grid>\n\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <Rectangle Width=\"1\" Grid.Row=\"1\" Grid.Column=\"0\" HorizontalAlignment=\"Right\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n\n        <ListBox Grid.Row=\"1\" x:Name=\"AudioList\" Margin=\"0,0,0,0\" ItemsSource=\"{Binding AllTracks}\" \n                         Style=\"{StaticResource CommonListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\"\n                         ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                         ItemTemplate=\"{StaticResource AudioItemTemplate}\">\n            <i:Interaction.Behaviors>\n                <behaviours:AutoScrollToCurrentItemBehaviour />\n            </i:Interaction.Behaviors>\n        </ListBox>\n    </Grid>\n</controls:PageBase>\n"
  },
  {
    "path": "Meridian/View/Search/ArtistAudioView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls.Primitives;\nusing Meridian.Controls;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Search;\n\nnamespace Meridian.View.Search\n{\n    /// <summary>\n    /// Interaction logic for ArtistAudioView.xaml\n    /// </summary>\n    public partial class ArtistAudioView : PageBase\n    {\n        public ArtistAudioView()\n        {\n            InitializeComponent();\n        }\n\n        public override void OnNavigatedTo()\n        {\n            var viewModel = (ArtistViewModel)NavigationContext.Parameters[\"viewModel\"];\n            this.DataContext = viewModel;\n        }\n\n        private void MenuItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Search/ArtistView.xaml",
    "content": "﻿<controls:PageBase x:Class=\"Meridian.View.Search.ArtistView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:helpers=\"clr-namespace:Meridian.Helpers\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\"\n      x:Name=\"pageRoot\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"71\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n\n        <Grid Grid.Row=\"1\" MaxWidth=\"800\" MaxHeight=\"800\" Margin=\"0,0,0,0\" HorizontalAlignment=\"Right\" VerticalAlignment=\"Top\" ClipToBounds=\"True\" Opacity=\"0.4\">\n            <Grid.OpacityMask>\n                <LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"0,1\">\n                    <GradientStop Offset=\"0.5\" Color=\"White\"/>\n                    <GradientStop Offset=\"1\" Color=\"Transparent\"/>\n                </LinearGradientBrush>\n            </Grid.OpacityMask>\n            <controls:ImageTransitionControl Source=\"{Binding ArtistImage}\" Margin=\"0,0,0,0\">\n                <controls:ImageTransitionControl.OpacityMask>\n                    <LinearGradientBrush StartPoint=\"0,0\" EndPoint=\"1,0\">\n                        <GradientStop Offset=\"0\" Color=\"Transparent\"/>\n                        <GradientStop Offset=\"1\" Color=\"White\"/>\n                    </LinearGradientBrush>\n                </controls:ImageTransitionControl.OpacityMask>\n            </controls:ImageTransitionControl>\n        </Grid>\n\n        <Grid>\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"20\"/>\n                <ColumnDefinition />\n            </Grid.ColumnDefinitions>\n            <Popup x:Name=\"HeaderMenuPopup\" PlacementTarget=\"{Binding ElementName=HeaderButton}\" Width=\"120\" StaysOpen=\"False\" VerticalOffset=\"10\"\n                   PopupAnimation=\"Fade\" AllowsTransparency=\"True\" IsOpen=\"{Binding ElementName=HeaderButton, Path=IsChecked, Mode=TwoWay}\">\n                <Border Background=\"White\" BorderThickness=\"1\" BorderBrush=\"Black\">\n                    <ItemsControl>\n                        <MenuItem Header=\"{x:Static localization:MainResources.HeaderMenuShare}\" Command=\"{Binding ShareCommand}\" Click=\"MenuItem_OnClick\"/>\n                    </ItemsControl>\n                </Border>\n            </Popup>\n            <Button Style=\"{StaticResource MainBackButtonStyle}\" Command=\"{Binding Main.GoBackCommand, Source={StaticResource Locator}}\"\n                    HorizontalAlignment=\"Left\"\n                    Visibility=\"{Binding Main.CanGoBack, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n            <Grid Grid.Column=\"1\" Margin=\"5,15,0,15\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\"/>\n                    <ColumnDefinition />\n                </Grid.ColumnDefinitions>\n                <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding Artist.ImageLarge}\" Width=\"45\" Height=\"45\" Stretch=\"UniformToFill\" HorizontalAlignment=\"Center\"\n                       Visibility=\"{Binding Artist.ImageLarge, Converter={StaticResource NullToVisibilityConverter}}\"/>\n                <StackPanel Grid.Column=\"1\" Margin=\"10,0,0,0\" VerticalAlignment=\"Center\">\n                    <ToggleButton x:Name=\"HeaderButton\" Style=\"{StaticResource HeaderButtonStyle}\"\n                              Content=\"{Binding Artist.Name}\" Margin=\"0,-3,0,0\" FontSize=\"24\"/>\n                    <TextBlock Text=\"{Binding TagsString}\" Foreground=\"{DynamicResource ForegroundBrush}\" Margin=\"2,-4,10,0\" TextTrimming=\"CharacterEllipsis\" Opacity=\"0.7\"/>\n                </StackPanel>\n            </Grid>\n        </Grid>\n        <ProgressBar IsIndeterminate=\"{Binding IsWorking}\" Visibility=\"{Binding IsWorking, Converter={StaticResource BoolToVisibilityConverter}}\" Style=\"{StaticResource HeaderProgressBarStyle}\"/>\n\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n\n        <ScrollViewer Grid.Row=\"1\" Margin=\"0,0,0,0\" Padding=\"0,15,0,0\">\n            <StackPanel>\n                <Grid Margin=\"26,0,0,0\" Visibility=\"{Binding Albums, Converter={StaticResource NullToVisibilityConverter}}\">\n                    <TextBlock Text=\"{x:Static localization:MainResources.ArtistAlbums}\" FontSize=\"12\" Opacity=\"0.3\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <Button Style=\"{StaticResource ShowAllButton}\" Content=\"{x:Static localization:MainResources.ArtistShowAll}\" Foreground=\"{DynamicResource AccentBrush}\" Margin=\"15,0,24,0\" FontWeight=\"SemiBold\"\n                            FontSize=\"11\" Command=\"{Binding ShowAllAlbumsCommand}\" HorizontalAlignment=\"Right\"/>\n                </Grid>\n\n                <ListBox Margin=\"20,5,0,30\" ItemsSource=\"{Binding Albums}\" Style=\"{StaticResource AlbumsListBoxStyle}\" \n                         VirtualizingStackPanel.ScrollUnit=\"Pixel\"\n                         ItemContainerStyle=\"{StaticResource LastFmAlbumListBoxItemStyle}\" Visibility=\"{Binding Albums, Converter={StaticResource NullToVisibilityConverter}}\">\n                    <ListBox.ItemsPanel>\n                        <ItemsPanelTemplate>\n                            <WrapPanel Orientation=\"Horizontal\"/>\n                        </ItemsPanelTemplate>\n                    </ListBox.ItemsPanel>\n                    <ListBox.ItemTemplate>\n                        <DataTemplate>\n                            <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.GoToAlbumCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\">\n                                <Button.RenderTransform>\n                                    <TranslateTransform />\n                                </Button.RenderTransform>\n                                <Button.Triggers>\n                                    <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                                        <BeginStoryboard Storyboard=\"{StaticResource FriendLoadAnim}\" />\n                                    </EventTrigger>\n                                </Button.Triggers>\n                                <Grid Width=\"80\">\n                                    <Grid.RowDefinitions>\n                                        <RowDefinition />\n                                        <RowDefinition Height=\"Auto\"/>\n                                    </Grid.RowDefinitions>\n                                    <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding ImageMedium}\" Width=\"80\" Height=\"80\"/>\n                                    <TextBlock Grid.Row=\"1\" Text=\"{Binding Name}\" Margin=\"0,0,0,0\" TextWrapping=\"Wrap\" TextTrimming=\"CharacterEllipsis\"\n                                           FontSize=\"11\" Height=\"30\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                </Grid>\n                            </Button>\n                        </DataTemplate>\n                    </ListBox.ItemTemplate>\n                </ListBox>\n\n                <Grid Margin=\"26,0,0,0\" Visibility=\"{Binding Tracks, Converter={StaticResource NullToVisibilityConverter}}\">\n                    <TextBlock Text=\"{x:Static localization:MainResources.ArtistTopTracks}\" FontSize=\"12\" Opacity=\"0.3\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <Button Style=\"{StaticResource ShowAllButton}\" Content=\"{x:Static localization:MainResources.ArtistShowAll}\" Foreground=\"{DynamicResource AccentBrush}\" Margin=\"15,0,24,0\" FontWeight=\"SemiBold\"\n                            FontSize=\"11\" Command=\"{Binding ShowAllTracksCommand}\" HorizontalAlignment=\"Right\"/>\n                </Grid>\n\n                <ListBox x:Name=\"AudioList\" Margin=\"12,5,12,30\" ItemsSource=\"{Binding Tracks}\" Visibility=\"{Binding Tracks, Converter={StaticResource NullToVisibilityConverter}}\"\n                         Style=\"{StaticResource AlbumsListBoxStyle}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                         ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\" AlternationCount=\"2\"\n                         ItemTemplate=\"{StaticResource OrderedAudioItemTemplate}\" ScrollViewer.VerticalScrollBarVisibility=\"Disabled\">\n                    <i:Interaction.Behaviors>\n                        <behaviours:TransitionBehaviour Transition=\"{StaticResource AudioLoadAnim}\" TransitionDelay=\"25\"/>\n                    </i:Interaction.Behaviors>\n                </ListBox>\n\n                <TextBlock Text=\"{x:Static localization:MainResources.ArtistRelatedArtists}\" FontSize=\"12\" Opacity=\"0.3\" Margin=\"26,0,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                           Visibility=\"{Binding SimilarArtists, Converter={StaticResource NullToVisibilityConverter}}\"/>\n                <ListBox Margin=\"20,5,0,0\" ItemsSource=\"{Binding SimilarArtists}\" Style=\"{StaticResource AlbumsListBoxStyle}\" \n                         VirtualizingStackPanel.ScrollUnit=\"Pixel\"\n                         ItemContainerStyle=\"{StaticResource LastFmAlbumListBoxItemStyle}\">\n\n                    <ListBox.ItemsPanel>\n                        <ItemsPanelTemplate>\n                            <WrapPanel Orientation=\"Horizontal\"/>\n                        </ItemsPanelTemplate>\n                    </ListBox.ItemsPanel>\n                    <ListBox.ItemTemplate>\n                        <DataTemplate>\n                            <Button Style=\"{StaticResource SimpleButtonStyle}\" Command=\"{Binding DataContext.GoToArtistCommand, ElementName=pageRoot}\" CommandParameter=\"{Binding}\">\n                                <Button.RenderTransform>\n                                    <TranslateTransform />\n                                </Button.RenderTransform>\n                                <Button.Triggers>\n                                    <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                                        <BeginStoryboard Storyboard=\"{StaticResource FriendLoadAnim}\" />\n                                    </EventTrigger>\n                                </Button.Triggers>\n                                <Grid Width=\"200\">\n                                    <Grid.ColumnDefinitions>\n                                        <ColumnDefinition Width=\"Auto\"/>\n                                        <ColumnDefinition />\n                                    </Grid.ColumnDefinitions>\n                                    <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding ImageMedium}\" Width=\"50\" Height=\"50\" Stretch=\"UniformToFill\"/>\n                                    <TextBlock Grid.Column=\"1\" Text=\"{Binding Name}\" Margin=\"10,0,0,0\" TextWrapping=\"Wrap\" TextTrimming=\"CharacterEllipsis\"\n                                           FontSize=\"12\" MaxHeight=\"40\" VerticalAlignment=\"Center\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                </Grid>\n                            </Button>\n                        </DataTemplate>\n                    </ListBox.ItemTemplate>\n                </ListBox>\n            </StackPanel>\n        </ScrollViewer>\n    </Grid>\n</controls:PageBase>\n"
  },
  {
    "path": "Meridian/View/Search/ArtistView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls.Primitives;\nusing LastFmLib.Core.Artist;\nusing Meridian.Controls;\nusing Meridian.ViewModel;\nusing Meridian.ViewModel.Search;\n\nnamespace Meridian.View.Search\n{\n    /// <summary>\n    /// Interaction logic for ArtistView.xaml\n    /// </summary>\n    public partial class ArtistView : PageBase\n    {\n        private ArtistViewModel _viewModel;\n\n        public ArtistView()\n        {\n            InitializeComponent();\n\n            _viewModel = new ArtistViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        public override void OnNavigatedTo()\n        {\n            var artist = (LastFmArtist)NavigationContext.Parameters[\"artist\"];\n            _viewModel.Artist = artist;\n\n            _viewModel.Activate();\n        }\n\n        private void MenuItem_OnClick(object sender, RoutedEventArgs e)\n        {\n            HeaderMenuPopup.SetCurrentValue(Popup.IsOpenProperty, false);\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Search/SearchResultsView.xaml",
    "content": "﻿<layout:PageBase x:Class=\"Meridian.View.Search.SearchResultsView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:converters=\"clr-namespace:Meridian.Converters\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:helpers=\"clr-namespace:Meridian.Helpers\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      xmlns:layout=\"clr-namespace:Meridian.Layout\"\n      xmlns:behaviours1=\"clr-namespace:Neptune.UI.Desktop.Behaviours;assembly=Neptune.Desktop\"\n      mc:Ignorable=\"d\" \n      Header=\"{Binding Header}\"\n      x:Name=\"pageRoot\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Page.Resources>\n\n        <Style x:Key=\"TracksListBoxStyle\" TargetType=\"ListBox\" BasedOn=\"{StaticResource CommonListBoxStyle}\">\n            <Setter Property=\"Margin\" Value=\"0,0,0,0\" />\n        </Style>\n\n        <Style x:Key=\"AlbumsListBoxStyle\" TargetType=\"ListBox\" BasedOn=\"{StaticResource CommonListBoxStyle}\">\n            <Setter Property=\"Margin\" Value=\"10,0,0,0\" />\n            <Setter Property=\"ItemsPanel\">\n                <Setter.Value>\n                    <ItemsPanelTemplate>\n                        <WrapPanel Orientation=\"Horizontal\"/>\n                    </ItemsPanelTemplate>\n                </Setter.Value>\n            </Setter>\n        </Style>\n\n        <Style x:Key=\"ArtistsListBoxStyle\" TargetType=\"ListBox\" BasedOn=\"{StaticResource CommonListBoxStyle}\">\n            <Setter Property=\"Margin\" Value=\"0,0,0,0\" />\n            <Setter Property=\"Padding\" Value=\"5,0,0,0\" />\n            <Setter Property=\"HorizontalContentAlignment\" Value=\"Stretch\" />\n        </Style>\n\n        <DataTemplate x:Key=\"AlbumTemplate\">\n            <Button Style=\"{StaticResource SimpleButtonStyle}\" Width=\"120\" Height=\"120\" ToolTip=\"{Binding Name}\" Command=\"{Binding DataContext.GoToAlbumCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}\" CommandParameter=\"{Binding}\">\n                <Button.RenderTransform>\n                    <TranslateTransform />\n                </Button.RenderTransform>\n                <Button.Triggers>\n                    <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                        <BeginStoryboard Storyboard=\"{StaticResource FriendLoadAnim}\" />\n                    </EventTrigger>\n                </Button.Triggers>\n                <Grid x:Name=\"RootGrid\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition />\n                        <RowDefinition Height=\"Auto\"/>\n                    </Grid.RowDefinitions>\n                    <Grid Grid.RowSpan=\"2\">\n                        <Rectangle Fill=\"{DynamicResource AccentBrush}\"/>\n                        <Image Source=\"/Resources/Images/cover_default.png\" Margin=\"25,25,25,40\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                        <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding ImageLarge}\" Stretch=\"UniformToFill\" RenderOptions.BitmapScalingMode=\"HighQuality\" />\n                    </Grid>\n                    <Rectangle Grid.Row=\"1\" Fill=\"Black\" Opacity=\"0.8\" />\n                    <StackPanel Grid.Row=\"1\">\n                        <TextBlock Text=\"{Binding Artist}\" FontWeight=\"Normal\" FontSize=\"11\" Margin=\"5,3,5,0\" TextTrimming=\"CharacterEllipsis\" Opacity=\"0.8\" Foreground=\"White\"/>\n                        <TextBlock Text=\"{Binding Name}\" FontFamily=\"Segoe UI SemiLight\"  FontSize=\"12\" Margin=\"5,-2,5,7\" TextTrimming=\"CharacterEllipsis\" Foreground=\"White\"/>\n                    </StackPanel>\n                </Grid>\n            </Button>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"LocalAlbumTemplate\">\n            <Button Style=\"{StaticResource SimpleButtonStyle}\" Width=\"120\" Height=\"120\" ToolTip=\"{Binding Title}\" Command=\"{Binding DataContext.GoToLocalAlbumCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}\" CommandParameter=\"{Binding}\">\n                <Button.RenderTransform>\n                    <TranslateTransform />\n                </Button.RenderTransform>\n                <Button.Triggers>\n                    <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                        <BeginStoryboard Storyboard=\"{StaticResource FriendLoadAnim}\" />\n                    </EventTrigger>\n                </Button.Triggers>\n                <Grid x:Name=\"RootGrid\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition />\n                        <RowDefinition Height=\"Auto\"/>\n                    </Grid.RowDefinitions>\n                    <Grid Grid.RowSpan=\"2\">\n                        <Rectangle Fill=\"{DynamicResource AccentBrush}\"/>\n                        <Image Source=\"/Resources/Images/cover_default.png\" Margin=\"25,25,25,40\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                        <Image Source=\"{Binding Cover}\" Stretch=\"UniformToFill\" RenderOptions.BitmapScalingMode=\"HighQuality\" />\n                    </Grid>\n                    <Rectangle Grid.Row=\"1\" Fill=\"Black\" Opacity=\"0.8\" />\n                    <StackPanel Grid.Row=\"1\">\n                        <TextBlock Text=\"{Binding Artist}\" FontWeight=\"Normal\" FontSize=\"11\" Margin=\"5,3,5,0\" TextTrimming=\"CharacterEllipsis\" Opacity=\"0.8\" Foreground=\"White\"/>\n                        <TextBlock Text=\"{Binding Title}\" FontFamily=\"Segoe UI SemiLight\"  FontSize=\"12\" Margin=\"5,-2,5,7\" TextTrimming=\"CharacterEllipsis\" Foreground=\"White\"/>\n                    </StackPanel>\n                </Grid>\n            </Button>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"LocalArtistTemplate\">\n            <ListBox ItemsSource=\"{Binding Albums}\" Style=\"{StaticResource CommonListBoxStyle}\" ItemContainerStyle=\"{StaticResource GroupListBoxItemStyle}\"\n                     HorizontalAlignment=\"Stretch\" HorizontalContentAlignment=\"Stretch\" Padding=\"15,10,0,0\"\n                     ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\" ScrollViewer.VerticalScrollBarVisibility=\"Disabled\">\n                <i:Interaction.Behaviors>\n                    <behaviours1:IgnoreMouseWheelBehavior/>\n                </i:Interaction.Behaviors>\n                <ListBox.ItemTemplate>\n                    <DataTemplate>\n                        <Grid x:Name=\"RootGrid\">\n                            <Grid.RowDefinitions>\n                                <RowDefinition Height=\"Auto\"/>\n                                <RowDefinition/>\n                            </Grid.RowDefinitions>\n                            <TextBlock Text=\"{Binding Title}\" FontSize=\"14\" FontFamily=\"Segoe UI\" Opacity=\"0.85\" Margin=\"0,0,0,5\" \n                                                   Visibility=\"{Binding Title, Converter={StaticResource NullToVisibilityConverter}}\"\n                                                   Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                            <ListBox Grid.Row=\"1\" ItemsSource=\"{Binding Tracks}\" Margin=\"-24,0,0,10\"\n                                                 Style=\"{StaticResource CommonListBoxStyle}\" ItemContainerStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                                                 ItemTemplate=\"{StaticResource LocalAudioItemTemplate}\"\n                                                 HorizontalContentAlignment=\"Stretch\"\n                                                 ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\" ScrollViewer.VerticalScrollBarVisibility=\"Disabled\">\n                                <i:Interaction.Behaviors>\n                                    <behaviours1:IgnoreMouseWheelBehavior/>\n                                </i:Interaction.Behaviors>\n                            </ListBox>\n                        </Grid>\n                    </DataTemplate>\n                </ListBox.ItemTemplate>\n            </ListBox>\n\n        </DataTemplate>\n\n\n        <DataTemplate x:Key=\"ArtistTemplate\">\n            <Button Style=\"{StaticResource SimpleButtonStyle}\" Width=\"120\" Height=\"120\" ToolTip=\"{Binding Name}\" Command=\"{Binding DataContext.GoToArtistCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}\" CommandParameter=\"{Binding}\">\n                <Button.RenderTransform>\n                    <TranslateTransform />\n                </Button.RenderTransform>\n                <Button.Triggers>\n                    <EventTrigger RoutedEvent=\"FrameworkElement.Loaded\">\n                        <BeginStoryboard Storyboard=\"{StaticResource FriendLoadAnim}\" />\n                    </EventTrigger>\n                </Button.Triggers>\n                <Grid x:Name=\"RootGrid\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition />\n                        <RowDefinition Height=\"40\"/>\n                    </Grid.RowDefinitions>\n                    <Grid Grid.RowSpan=\"2\">\n                        <Rectangle Fill=\"{DynamicResource AccentBrush}\"/>\n                        <Image Source=\"/Resources/Images/cover_default.png\" Margin=\"25,25,25,40\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                        <Image helpers:ImageAsyncHelper.SourceUri=\"{Binding ImageLarge}\" Stretch=\"UniformToFill\" RenderOptions.BitmapScalingMode=\"HighQuality\" />\n                    </Grid>\n                    <Rectangle Grid.Row=\"1\" Fill=\"Black\" Opacity=\"0.8\" />\n                    <TextBlock Grid.Row=\"1\" VerticalAlignment=\"Center\" Text=\"{Binding Name}\" FontWeight=\"Normal\" FontSize=\"11\" Foreground=\"White\" TextWrapping=\"Wrap\"\n                               TextTrimming=\"CharacterEllipsis\" Margin=\"5\"/>\n                </Grid>\n            </Button>\n        </DataTemplate>\n\n        <converters:SearchResultTemplateSelector x:Key=\"SearchTemplateSelector\"\n                                                 TrackTemplate=\"{StaticResource AudioItemTemplate}\"\n                                                 LocalTrackTemplate=\"{StaticResource LocalAudioItemTemplate}\"\n                                                 AlbumTemplate=\"{StaticResource AlbumTemplate}\"\n                                                 LocalAlbumTemplate=\"{StaticResource LocalAlbumTemplate}\"\n                                                 ArtistTemplate=\"{StaticResource ArtistTemplate}\"\n                                                 LocalArtistTemplate=\"{StaticResource LocalArtistTemplate}\"/>\n\n        <converters:SearchResultStyleSelector x:Key=\"SearchStyleSelector\"\n                                              TrackStyle=\"{StaticResource AudioListBoxItemStyle}\"\n                                              AlbumStyle=\"{StaticResource FriendListBoxItemStyle}\"\n                                              ArtistStyle=\"{StaticResource FriendListBoxItemStyle}\"\n                                              LocalArtistStyle=\"{StaticResource GroupListBoxItemStyle}\"\n                                              SocietyStyle=\"{StaticResource FriendListBoxItemStyle}\"/>\n\n        <converters:SearchListBoxStyleSelector x:Key=\"SearchListBoxStyleSelector\"\n                                               TracksStyle=\"{StaticResource TracksListBoxStyle}\"\n                                               AlbumsStyle=\"{StaticResource AlbumsListBoxStyle}\"\n                                               ArtistsStyle=\"{StaticResource AlbumsListBoxStyle}\"\n                                               LocalArtistsStyle=\"{StaticResource ArtistsListBoxStyle}\"\n                                               SocietiesStyle=\"{StaticResource AlbumsListBoxStyle}\"/>\n\n        <CollectionViewSource x:Key=\"SearchMenuGroups\" Source=\"{Binding Sections}\">\n            <CollectionViewSource.GroupDescriptions>\n                <PropertyGroupDescription PropertyName=\"Group\"/>\n            </CollectionViewSource.GroupDescriptions>\n        </CollectionViewSource>\n\n    </Page.Resources>\n\n    <layout:TwoColumnPageLayout>\n        <layout:TwoColumnPageLayout.MainContent>\n            <controls:BusyIndicator Grid.Row=\"1\" BusyContent=\"{x:Static localization:MainResources.Searching}\" IsBusy=\"{Binding Tasks[results].IsWorking}\" Error=\"{Binding Tasks[results].Error}\">\n                <ListBox x:Name=\"SearchResultsList\" ItemsSource=\"{Binding SearchResults}\" VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 ItemContainerStyleSelector=\"{StaticResource SearchStyleSelector}\"\n                 ItemTemplateSelector=\"{StaticResource SearchTemplateSelector}\"\n                 Style=\"{Binding SelectedSectionIndex, Converter={StaticResource SearchListBoxStyleSelector}}\">\n                    <i:Interaction.Behaviors>\n                        <behaviours:AutoScrollToCurrentItemBehaviour />\n                    </i:Interaction.Behaviors>\n                </ListBox>\n            </controls:BusyIndicator>\n        </layout:TwoColumnPageLayout.MainContent>\n        <layout:TwoColumnPageLayout.RightContent>\n            <Grid>\n                <ListBox Margin=\"0,20,0,0\" Padding=\"0\" ItemsSource=\"{Binding Source={StaticResource SearchMenuGroups}}\" Style=\"{StaticResource CommonListBoxStyle}\" \n                 VirtualizingStackPanel.ScrollUnit=\"Pixel\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\"\n                 SelectedIndex=\"{Binding SelectedSectionIndex, Mode=TwoWay}\" ItemContainerStyle=\"{StaticResource AlbumListBoxItemStyle}\">\n                    <ListBox.ItemTemplate>\n                        <DataTemplate>\n                            <TextBlock Text=\"{Binding Title}\"/>\n                        </DataTemplate>\n                    </ListBox.ItemTemplate>\n                    <ListBox.GroupStyle>\n                        <GroupStyle>\n                            <GroupStyle.ContainerStyle>\n                                <Style TargetType=\"{x:Type GroupItem}\">\n                                    <Setter Property=\"Margin\" Value=\"0,0,0,0\"/>\n                                    <Setter Property=\"Template\">\n                                        <Setter.Value>\n                                            <ControlTemplate TargetType=\"{x:Type GroupItem}\">\n                                                <Grid Margin=\"0,0,0,20\">\n                                                    <Grid.ColumnDefinitions>\n                                                        <ColumnDefinition Width=\"Auto\"/>\n                                                        <ColumnDefinition />\n                                                    </Grid.ColumnDefinitions>\n                                                    <Grid.RowDefinitions>\n                                                        <RowDefinition Height=\"Auto\"/>\n                                                        <RowDefinition />\n                                                    </Grid.RowDefinitions>\n                                                    <Path Data=\"{Binding Items[0].GroupIcon}\" Stretch=\"Uniform\" Fill=\"{DynamicResource ForegroundBrush}\" Height=\"8\" Margin=\"17,1,-10,0\" Opacity=\"0.4\" VerticalAlignment=\"Center\"\n                                                          Visibility=\"{Binding Items[0].GroupIcon, Converter={StaticResource NullToVisibilityConverter}}\"/>\n                                                    <TextBlock Grid.Column=\"1\" FontWeight=\"SemiBold\" Text=\"{Binding Path=Name}\" Margin=\"17,0,0,0\" FontSize=\"12\" Foreground=\"{DynamicResource ForegroundBrush}\" Opacity=\"0.7\"/>\n                                                    <ItemsPresenter Grid.Row=\"1\" Grid.ColumnSpan=\"2\" Margin=\"0,5,0,0\"/>\n                                                </Grid>\n                                            </ControlTemplate>\n                                        </Setter.Value>\n                                    </Setter>\n                                </Style>\n                            </GroupStyle.ContainerStyle>\n\n                        </GroupStyle>\n                    </ListBox.GroupStyle>\n                </ListBox>\n            </Grid>\n        </layout:TwoColumnPageLayout.RightContent>\n    </layout:TwoColumnPageLayout>\n</layout:PageBase>\n"
  },
  {
    "path": "Meridian/View/Search/SearchResultsView.xaml.cs",
    "content": "﻿using Meridian.Layout;\nusing Meridian.ViewModel.Search;\n\nnamespace Meridian.View.Search\n{\n    /// <summary>\n    /// Interaction logic for SearchResultsView.xaml\n    /// </summary>\n    public partial class SearchResultsView : PageBase\n    {\n        private SearchViewModel _viewModel;\n\n        public SearchResultsView()\n        {\n            InitializeComponent();\n\n            _viewModel = new SearchViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        public override void OnNavigatedTo()\n        {\n            var query = (string)NavigationContext.Parameters[\"query\"];\n            _viewModel.Query = query;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsAboutView.xaml",
    "content": "﻿<Page x:Class=\"Meridian.View.Settings.SettingsAboutView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <TextBlock Text=\"{x:Static localization:MainResources.SettingsMenuAbout}\" FontSize=\"28\" FontWeight=\"Thin\" Margin=\"24,10,0,15\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <StackPanel Grid.Row=\"1\" Margin=\"24,20,0,0\" >\n            <TextBlock Text=\"Meridian Desktop\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <TextBlock Foreground=\"{DynamicResource ForegroundBrush}\">\n                <Run Text=\"Version:\" />\n                <Run Text=\"{Binding Version, Mode=OneWay}\" />\n                <Run Text=\"beta\" />\n            </TextBlock>\n            <TextBlock Text=\"Copyright © Artem Shuba 2011 ― 2020\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n\n            <StackPanel Orientation=\"Horizontal\" Margin=\"0,5,0,0\">\n                <TextBlock TextWrapping=\"Wrap\" Text=\"The information about artists and albums is provided by the\" HorizontalAlignment=\"Left\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                <TextBlock Name=\"LastFmLink\" Margin=\"4,0,0,0\" TextWrapping=\"Wrap\" Text=\"Last.FM\" HorizontalAlignment=\"Left\" ToolTip=\"http://last.fm\" MouseLeftButtonUp=\"LastFmLink_OnMouseLeftButtonUp\">\n                    <TextBlock.Style>\n                        <Style TargetType=\"{x:Type TextBlock}\">\n                            <Setter Property=\"Cursor\" Value=\"Hand\"/>\n                            <Setter Property=\"Foreground\" Value=\"{DynamicResource AccentBrush}\"/>\n                            <Style.Triggers>\n                                <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                                    <Setter Property=\"TextDecorations\" Value=\"Underline\"/>\n                                </Trigger>\n                            </Style.Triggers>\n                        </Style>\n                    </TextBlock.Style>\n                </TextBlock>\n            </StackPanel>\n            <StackPanel Orientation=\"Horizontal\">\n                <Image Source=\"/Resources/Images/lastfm_logo.gif\" Stretch=\"UniformToFill\" Width=\"60\" HorizontalAlignment=\"Left\" Margin=\"0,5,0,0\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n            </StackPanel>\n        </StackPanel>\n    </Grid>\n</Page>\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsAboutView.xaml.cs",
    "content": "﻿using System.Diagnostics;\nusing System.Windows.Controls;\nusing System.Windows.Input;\n\nnamespace Meridian.View.Settings\n{\n    /// <summary>\n    /// Interaction logic for SettingsAboutView.xaml\n    /// </summary>\n    public partial class SettingsAboutView : Page\n    {\n        public SettingsAboutView()\n        {\n            InitializeComponent();\n        }\n\n        private void SiteLink_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)\n        {\n            Process.Start(\"http://meridianvk.com\");\n        }\n\n        private void LastFmLink_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)\n        {\n            Process.Start(\"http://last.fm\");\n        }\n\n        private void EchonestLink_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)\n        {\n            Process.Start(\"http://echonest.com\");\n        }\n\n        private void NAudioLink_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)\n        {\n            Process.Start(\"http://naudio.codeplex.com\");\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsAccountsView.xaml",
    "content": "﻿<Page x:Class=\"Meridian.View.Settings.SettingsAccountsView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <TextBlock Text=\"{x:Static localization:MainResources.SettingsMenuAccounts}\" FontSize=\"28\" FontWeight=\"Thin\" Margin=\"24,10,0,15\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <StackPanel Grid.Row=\"1\" Margin=\"24,20,0,0\" Width=\"300\" HorizontalAlignment=\"Left\">\n            <!-- Vk-->\n            <TextBlock Text=\"{x:Static localization:MainResources.SettingsAccountsVk}\" Foreground=\"{DynamicResource AccentBrush}\" FontSize=\"18\" FontFamily=\"Segoe UI SemiLight\"/>\n            \n            <Button Style=\"{StaticResource CommonButtonStyle}\" Content=\"{x:Static localization:MainResources.LoginLoginButton}\" HorizontalAlignment=\"Left\" Margin=\"0,10,0,0\"\n                    Command=\"{Binding LoginVkCommand}\"\n                    Visibility=\"{Binding Main.User, Source={StaticResource Locator}, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=True}\"/>\n            \n            <StackPanel Visibility=\"{Binding Main.User, Source={StaticResource Locator}, Converter={StaticResource NullToVisibilityConverter}}\">\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsAccountsSignedAs}\" Margin=\"0,10,0,0\" Opacity=\"0.7\" FontSize=\"12\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                <Grid Margin=\"0,10,0,0\">\n                    <Grid.ColumnDefinitions>\n                        <ColumnDefinition Width=\"Auto\"/>\n                        <ColumnDefinition />\n                        <ColumnDefinition Width=\"Auto\"/>\n                    </Grid.ColumnDefinitions>\n                    <Grid Grid.Column=\"0\" Width=\"36\" Height=\"36\" Background=\"{DynamicResource AccentBrush}\">\n                        <Image Source=\"{Binding Main.User.Photo, Source={StaticResource Locator}}\" HorizontalAlignment=\"Right\" Grid.Column=\"1\" Width=\"36\" Height=\"36\"/>\n                    </Grid>\n                    <StackPanel Grid.Column=\"1\" Margin=\"5,0,0,0\" Opacity=\"0.8\">\n                        <TextBlock x:Name=\"UsernameTextBlock\" Text=\"{Binding Main.User.FirstName, Source={StaticResource Locator}}\" HorizontalAlignment=\"Left\" FontSize=\"14\" FontWeight=\"Medium\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                        <TextBlock  Text=\"{Binding Main.User.LastName, Source={StaticResource Locator}}\" HorizontalAlignment=\"Left\" FontSize=\"12\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    </StackPanel>\n                    <Button Grid.Column=\"2\" Margin=\"20,0,0,0\" Style=\"{StaticResource CommonButtonStyle}\" Content=\"{x:Static localization:MainResources.SettingsAccountsSignOut}\" VerticalAlignment=\"Center\" Command=\"{Binding SignOutVkCommand}\"/>\n                </Grid>\n                <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Style=\"{StaticResource CommonCheckBoxStyle}\" Content=\"{x:Static localization:MainResources.VkStatusBroadcasting}\" Margin=\"0,10,0,0\" IsChecked=\"{Binding Main.EnableStatusBroadcasting, Source={StaticResource Locator}, Mode=TwoWay}\"/>\n\n            </StackPanel>\n            \n            <!-- Last.FM-->\n            <TextBlock Text=\"{x:Static localization:MainResources.SettingsAccountsLastFm}\" Margin=\"0,10,0,0\" Foreground=\"Red\" FontSize=\"18\" FontFamily=\"Segoe UI SemiLight\"/>\n            <StackPanel Visibility=\"{Binding Main.LastFmUser, Source={StaticResource Locator}, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=True}\">\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsAccountsLastFmDescription}\" Margin=\"0,5,0,0\" FontWeight=\"Normal\" Opacity=\"0.6\" TextWrapping=\"Wrap\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                <Button Style=\"{StaticResource CommonButtonStyle}\" Content=\"{x:Static localization:MainResources.LoginLoginButton}\" HorizontalAlignment=\"Left\" Margin=\"0,10,0,0\"\n                        Command=\"{Binding LoginLastFmCommand}\"/>\n            </StackPanel>\n\n            <StackPanel Visibility=\"{Binding Main.LastFmUser, Source={StaticResource Locator}, Converter={StaticResource NullToVisibilityConverter}}\">\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsAccountsSignedAs}\" Margin=\"0,10,0,0\" Opacity=\"0.7\" FontSize=\"12\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                <Grid Margin=\"0,10,0,0\">\n                    <Grid.ColumnDefinitions>\n                        <ColumnDefinition />\n                        <ColumnDefinition Width=\"Auto\"/>\n                    </Grid.ColumnDefinitions>\n                    <StackPanel Grid.Column=\"0\" Margin=\"0,0,0,0\" Opacity=\"0.8\">\n                        <TextBlock Text=\"{Binding Main.LastFmUser, Source={StaticResource Locator}}\" HorizontalAlignment=\"Left\" FontSize=\"14\" FontWeight=\"Medium\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    </StackPanel>\n                    <Button Grid.Column=\"1\" Margin=\"20,0,0,0\" Style=\"{StaticResource CommonButtonStyle}\" Content=\"{x:Static localization:MainResources.SettingsAccountsSignOut}\" VerticalAlignment=\"Center\" Command=\"{Binding SignOutLastFmCommand}\"/>\n                </Grid>\n                <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Style=\"{StaticResource CommonCheckBoxStyle}\" Content=\"{x:Static localization:MainResources.LastFmScrobbling}\" Margin=\"0,10,0,0\" IsChecked=\"{Binding Main.EnableScrobbling, Source={StaticResource Locator}, Mode=TwoWay}\"/>\n            </StackPanel>\n        </StackPanel>\n    </Grid>\n</Page>\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsAccountsView.xaml.cs",
    "content": "﻿using System.Windows.Controls;\n\nnamespace Meridian.View.Settings\n{\n    /// <summary>\n    /// Interaction logic for SettingsAccountsView.xaml\n    /// </summary>\n    public partial class SettingsAccountsView : Page\n    {\n        public SettingsAccountsView()\n        {\n            InitializeComponent();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsHotkeysView.xaml",
    "content": "﻿<Page x:Class=\"Meridian.View.Settings.SettingsHotkeysView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\"\n      DataContextChanged=\"SettingsHotkeysView_OnDataContextChanged\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <TextBlock Text=\"{x:Static localization:MainResources.SettingsMenuHotkeys}\" FontSize=\"28\" FontWeight=\"Thin\" Margin=\"24,10,0,15\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <ScrollViewer Grid.Row=\"1\" Margin=\"24,0,0,0\">\n            <StackPanel Width=\"300\" HorizontalAlignment=\"Left\" Margin=\"0,10,0,20\">\n                <ItemsControl ItemsSource=\"{Binding Hotkeys}\">\n                    <ItemsControl.ItemTemplate>\n                        <DataTemplate>\n                            <StackPanel>\n                                <TextBlock Text=\"{Binding Title}\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                <Grid Margin=\"0,3,0,0\">\n                                    <Grid.ColumnDefinitions>\n                                        <ColumnDefinition Width=\"Auto\"/>\n                                        <ColumnDefinition Width=\"Auto\"/>\n                                        <ColumnDefinition Width=\"Auto\"/>\n                                        <ColumnDefinition Width=\"Auto\"/>\n                                        <ColumnDefinition />\n                                    </Grid.ColumnDefinitions>\n                                    <CheckBox Grid.Column=\"0\" Content=\"Ctrl\" VerticalAlignment=\"Center\" IsChecked=\"{Binding Ctrl, Mode=TwoWay}\" Click=\"CheckBoxOnClick\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                    <CheckBox Grid.Column=\"1\" Content=\"Alt\" Margin=\"10,0,0,0\" VerticalAlignment=\"Center\" IsChecked=\"{Binding Alt, Mode=TwoWay}\" Click=\"CheckBoxOnClick\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                    <CheckBox Grid.Column=\"2\" Content=\"Shift\" Margin=\"10,0,0,0\" VerticalAlignment=\"Center\" IsChecked=\"{Binding Shift, Mode=TwoWay}\" Click=\"CheckBoxOnClick\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                    <TextBlock Grid.Column=\"3\" Text=\"+\" Margin=\"10,0,10,0\" VerticalAlignment=\"Center\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                                    <TextBox Grid.Column=\"4\" Style=\"{StaticResource CommonTextBoxStyle}\" Text=\"{Binding Key, Mode=TwoWay}\" Width=\"120\" HorizontalAlignment=\"Left\"\n                                             PreviewKeyDown=\"HotkeyTextBoxOnPreviewKeyDown\" Background=\"Transparent\"/>\n                                </Grid>\n                            </StackPanel>\n                        </DataTemplate>\n                    </ItemsControl.ItemTemplate>\n                </ItemsControl>\n            </StackPanel>\n        </ScrollViewer>\n        <StackPanel Orientation=\"Horizontal\" Grid.Row=\"2\" HorizontalAlignment=\"Left\" Margin=\"24,0,0,10\">\n            <Button Style=\"{StaticResource HighlightedButtonStyle}\" Content=\"{x:Static localization:MainResources.SettingsSaveRestart}\" IsEnabled=\"{Binding CanSave}\" Command=\"{Binding SaveRestartCommand}\" Margin=\"0,0,0,0\"  Visibility=\"{Binding RestartRequired, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n            <Button Style=\"{StaticResource HighlightedButtonStyle}\" Content=\"{x:Static localization:MainResources.SettingsSave}\" IsEnabled=\"{Binding CanSave}\" Command=\"{Binding SaveCommand}\"  Visibility=\"{Binding RestartRequired, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\"/>\n            <Button Style=\"{StaticResource CommonButtonStyle}\" Content=\"{x:Static localization:MainResources.CancelButton}\" Margin=\"15,0,0,0\" Command=\"{Binding CloseSettingsCommand}\"/>\n            <TextBlock Text=\"{x:Static localization:MainResources.SettingsRestartMessage}\" VerticalAlignment=\"Center\" Margin=\"20,0,0,0\" Opacity=\"0.6\" Visibility=\"{Binding RestartRequired, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n        </StackPanel>\n    </Grid>\n</Page>\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsHotkeysView.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing Meridian.ViewModel;\n\nnamespace Meridian.View.Settings\n{\n    /// <summary>\n    /// Interaction logic for SettingsHotkeys.xaml\n    /// </summary>\n    public partial class SettingsHotkeysView : Page\n    {\n        private SettingsViewModel _viewModel;\n\n        public SettingsHotkeysView()\n        {\n            InitializeComponent();\n        }\n\n        private void SettingsHotkeysView_OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)\n        {\n            _viewModel = (SettingsViewModel)this.DataContext;\n        }\n\n        private void HotkeyTextBoxOnPreviewKeyDown(object sender, KeyEventArgs e)\n        {\n            if (e.Key == Key.System || e.Key == Key.LeftAlt || e.Key == Key.LeftCtrl || e.Key == Key.LeftShift || e.Key == Key.RightAlt || e.Key == Key.RightCtrl || e.Key == Key.RightShift\n                || e.Key == Key.Escape)\n            {\n                return;\n            }\n\n            var textBox = sender as TextBox;\n            if (textBox == null)\n                return;\n\n            _viewModel.CanSave = true;\n\n            if (e.Key == Key.Back)\n            {\n                textBox.Text = \"None\";\n                e.Handled = true;\n                return;\n            }\n\n            textBox.Text = e.Key.ToString();\n            e.Handled = true;\n        }\n\n        private void CheckBoxOnClick(object sender, RoutedEventArgs e)\n        {\n            _viewModel.CanSave = true;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsRemotePlayView.xaml",
    "content": "﻿<Page x:Class=\"Meridian.View.Settings.SettingsRemotePlayView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\" />\n        </Grid.RowDefinitions>\n        <TextBlock Text=\"{x:Static localization:MainResources.SettingsRemotePlay}\" FontSize=\"28\" FontWeight=\"Thin\" Margin=\"24,10,0,15\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <StackPanel Grid.Row=\"1\" Margin=\"20,20,20,0\">\n            <TextBlock TextWrapping=\"Wrap\" Opacity=\"0.6\" Margin=\"0,0,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                       Text=\"{x:Static localization:MainResources.SettingsRemotePlayDescription}\" />\n\n            <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsRemotePlayEnable}\" Margin=\"0,20,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\"\n                      IsChecked=\"{Binding EnableRemotePlay, Mode=TwoWay}\"/>\n\n            <StackPanel Orientation=\"Horizontal\" Margin=\"0,10,0,0\">\n                <StackPanel>\n                    <TextBlock Text=\"{x:Static localization:MainResources.SettingsRemotePlayAddress}\" FontSize=\"12\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <ComboBox Width=\"150\" Style=\"{StaticResource CommonComboBoxStyle}\" Margin=\"0,2,0,0\" HorizontalAlignment=\"Left\" ItemsSource=\"{Binding RemotePlayAddresses}\" \n                      SelectedValue=\"{Binding SelectedRemotePlayAddress, Mode=TwoWay}\"/>\n                </StackPanel>\n                <StackPanel Margin=\"20,0,0,0\">\n                    <TextBlock Text=\"{x:Static localization:MainResources.SettingsRemotePlayPort}\" FontSize=\"12\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                    <TextBox Margin=\"0,3,0,0\" Width=\"80\" Style=\"{StaticResource CommonTextBoxStyle}\" Text=\"{Binding RemotePlayPort}\"/>\n                </StackPanel>\n            </StackPanel>\n\n            <TextBlock TextWrapping=\"Wrap\" Opacity=\"0.6\" Margin=\"0,10,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"\n                       Text=\"{Binding RemotePlayHelp}\" />\n        </StackPanel>\n\n        <StackPanel Grid.Row=\"2\" HorizontalAlignment=\"Left\" Margin=\"24,0,0,10\">\n            <TextBlock Text=\"{x:Static localization:MainResources.SettingsRestartMessage}\" VerticalAlignment=\"Center\" Margin=\"0,0,0,5\" Opacity=\"0.6\" \n                       Visibility=\"{Binding RestartRequired, Converter={StaticResource BoolToVisibilityConverter}}\" Foreground=\"{DynamicResource ForegroundBrush}\" TextWrapping=\"Wrap\"/>\n\n            <StackPanel Orientation=\"Horizontal\">\n                <Button Style=\"{StaticResource HighlightedButtonStyle}\" Content=\"{x:Static localization:MainResources.SettingsSaveRestart}\" IsEnabled=\"{Binding CanSave}\" Command=\"{Binding SaveRestartCommand}\" Margin=\"0,0,0,0\"  Visibility=\"{Binding RestartRequired, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n                <Button Style=\"{StaticResource HighlightedButtonStyle}\" Content=\"{x:Static localization:MainResources.SettingsSave}\" IsEnabled=\"{Binding CanSave}\" Command=\"{Binding SaveCommand}\"  Visibility=\"{Binding RestartRequired, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\"/>\n                <Button Style=\"{StaticResource CommonButtonStyle}\" Content=\"{x:Static localization:MainResources.CancelButton}\" Margin=\"15,0,0,0\" Command=\"{Binding CloseSettingsCommand}\"/>\n            </StackPanel>\n        </StackPanel>\n    </Grid>\n</Page>\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsRemotePlayView.xaml.cs",
    "content": "﻿using System.Windows.Controls;\n\nnamespace Meridian.View.Settings\n{\n    /// <summary>\n    /// Interaction logic for SettingsUpdatesView.xaml\n    /// </summary>\n    public partial class SettingsRemotePlayView : Page\n    {\n        public SettingsRemotePlayView()\n        {\n            InitializeComponent();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsUIView.xaml",
    "content": "﻿<Page x:Class=\"Meridian.View.Settings.SettingsUIView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\" KeepAlive=\"False\"\n      Background=\"{DynamicResource MainBackgroundBrush}\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Page.Resources>\n        <Style x:Key=\"AccentColorListBoxItemStyle\" TargetType=\"{x:Type ListBoxItem}\">\n            <Setter Property=\"SnapsToDevicePixels\" Value=\"True\"/>\n            <Setter Property=\"Padding\" Value=\"0,0,3,3\"/>\n            <Setter Property=\"HorizontalContentAlignment\" Value=\"{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n            <Setter Property=\"VerticalContentAlignment\" Value=\"{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}\"/>\n            <Setter Property=\"Background\" Value=\"Transparent\"/>\n            <Setter Property=\"BorderBrush\" Value=\"Transparent\"/>\n            <Setter Property=\"BorderThickness\" Value=\"1\"/>\n            <Setter Property=\"FocusVisualStyle\" Value=\"{StaticResource FocusVisual}\"/>\n            <Setter Property=\"Template\">\n                <Setter.Value>\n                    <ControlTemplate TargetType=\"{x:Type ListBoxItem}\">\n                        <Border x:Name=\"Bd\" BorderBrush=\"{TemplateBinding BorderBrush}\" BorderThickness=\"{TemplateBinding BorderThickness}\" Background=\"{TemplateBinding Background}\" Padding=\"{TemplateBinding Padding}\" SnapsToDevicePixels=\"true\">\n                            <Grid>\n                                <ContentPresenter HorizontalAlignment=\"{TemplateBinding HorizontalContentAlignment}\" SnapsToDevicePixels=\"{TemplateBinding SnapsToDevicePixels}\" VerticalAlignment=\"{TemplateBinding VerticalContentAlignment}\"/>\n                                <Path x:Name=\"checkMark\" Visibility=\"Collapsed\" Data=\"{StaticResource CheckIcon}\" Fill=\"White\" Stretch=\"Fill\" Width=\"12\" Height=\"10\" VerticalAlignment=\"Top\" HorizontalAlignment=\"Right\" Margin=\"5\"/>\n                            </Grid>\n                        </Border>\n                        <ControlTemplate.Triggers>\n                            <MultiTrigger>\n                                <MultiTrigger.Conditions>\n                                    <Condition Property=\"IsMouseOver\" Value=\"True\"/>\n                                </MultiTrigger.Conditions>\n                                <Setter Property=\"Opacity\" TargetName=\"Bd\" Value=\"1\"/>\n                            </MultiTrigger>\n                            <MultiTrigger>\n                                <MultiTrigger.Conditions>\n                                    <Condition Property=\"Selector.IsSelectionActive\" Value=\"False\"/>\n                                    <Condition Property=\"IsSelected\" Value=\"True\"/>\n                                </MultiTrigger.Conditions>\n                                <Setter Property=\"Visibility\" TargetName=\"checkMark\" Value=\"Visible\"/>\n                                <Setter Property=\"Opacity\" TargetName=\"Bd\" Value=\"1\"/>\n                            </MultiTrigger>\n                            <MultiTrigger>\n                                <MultiTrigger.Conditions>\n                                    <Condition Property=\"Selector.IsSelectionActive\" Value=\"True\"/>\n                                    <Condition Property=\"IsSelected\" Value=\"True\"/>\n                                </MultiTrigger.Conditions>\n                                <Setter Property=\"Visibility\" TargetName=\"checkMark\" Value=\"Visible\"/>\n                                <Setter Property=\"Opacity\" TargetName=\"Bd\" Value=\"1\"/>\n                            </MultiTrigger>\n                            <Trigger Property=\"IsEnabled\" Value=\"False\">\n                                <Setter Property=\"TextElement.Foreground\" TargetName=\"Bd\" Value=\"{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}\"/>\n                            </Trigger>\n                        </ControlTemplate.Triggers>\n                    </ControlTemplate>\n                </Setter.Value>\n            </Setter>\n        </Style>\n    </Page.Resources>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <TextBlock Text=\"{x:Static localization:MainResources.SettingsMenuGeneral}\" FontSize=\"28\" FontWeight=\"Thin\" Margin=\"24,10,0,15\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <ScrollViewer Grid.Row=\"1\" Margin=\"24,0,0,20\">\n            <StackPanel Margin=\"0,10,0,20\" HorizontalAlignment=\"Left\">\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsUIBackgroundColor}\" FontSize=\"12\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                <ComboBox Width=\"200\" Style=\"{StaticResource CommonComboBoxStyle}\" Margin=\"0,3,0,0\" HorizontalAlignment=\"Left\" ItemsSource=\"{Binding Themes}\" \n                      SelectedValue=\"{Binding SelectedTheme, Mode=TwoWay}\"/>\n\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsUIAccentColor}\" FontSize=\"12\" Opacity=\"0.7\" Margin=\"0,15,0,3\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                <ListBox Style=\"{StaticResource CommonListBoxStyle}\" Padding=\"0\" ItemsSource=\"{Binding AccentColors}\" HorizontalAlignment=\"Left\" SelectedItem=\"{Binding SelectedColorScheme, Mode=TwoWay}\" \n                     ItemContainerStyle=\"{StaticResource AccentColorListBoxItemStyle}\">\n                    <ListBox.ItemsPanel>\n                        <ItemsPanelTemplate>\n                            <WrapPanel Orientation=\"Horizontal\" MaxWidth=\"300\"/>\n                        </ItemsPanelTemplate>\n                    </ListBox.ItemsPanel>\n                    <ListBox.ItemTemplate>\n                        <DataTemplate>\n                            <Grid>\n                                <Grid.RowDefinitions>\n                                    <RowDefinition />\n                                    <RowDefinition Height=\"Auto\"/>\n                                </Grid.RowDefinitions>\n                                <Rectangle Fill=\"{Binding Color}\" Height=\"50\" Width=\"50\" VerticalAlignment=\"Top\"/>\n                                <TextBlock Foreground=\"{DynamicResource ForegroundBrush}\" Text=\"{Binding Name}\" HorizontalAlignment=\"Center\" Grid.Row=\"1\" TextWrapping=\"Wrap\" VerticalAlignment=\"Top\" FontWeight=\"Regular\" Margin=\"0,5,0,0\"/>\n                            </Grid>\n                        </DataTemplate>\n                    </ListBox.ItemTemplate>\n                </ListBox>\n\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsUILanguage}\" FontSize=\"12\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\" Margin=\"0,15,0,0\"/>\n                <ComboBox Width=\"200\" Style=\"{StaticResource CommonComboBoxStyle}\" Margin=\"0,3,0,0\" HorizontalAlignment=\"Left\" ItemsSource=\"{Binding Languages}\" \n                      SelectedValue=\"{Binding SelectedLanguage, Mode=TwoWay}\" DisplayMemberPath=\"Title\"/>\n\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsUIBackgroundArtTitle}\" FontSize=\"12\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\" Margin=\"0,15,0,0\"/>\n                <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsUIShowBackgroundArt}\" Margin=\"0,5,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\" IsChecked=\"{Binding ShowBackgroundArt, Mode=TwoWay}\"/>\n                <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsUIShowBackgroundArtCompactMode}\" Margin=\"0,5,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\" IsChecked=\"{Binding ShowBackgroundArtCompactMode, Mode=TwoWay}\"/>\n                <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsUIEnabledBlur}\" Margin=\"0,5,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\" IsChecked=\"{Binding BlurBackground, Mode=TwoWay}\"/>\n                <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsUIDownloadArtistArt}\" Margin=\"0,5,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\" IsChecked=\"{Binding DownloadArtistArt, Mode=TwoWay}\"/>\n                <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsUIDownloadAlbumArt}\" Margin=\"0,5,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\" IsChecked=\"{Binding DownloadAlbumArt, Mode=TwoWay}\"/>\n\n                <StackPanel Orientation=\"Horizontal\" Margin=\"0,5,0,0\">\n                    <TextBlock FontSize=\"12\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\" VerticalAlignment=\"Center\">\n                        <Run Text=\"{x:Static localization:MainResources.SettingsUICacheSize}\" />\n                        <Run Text=\"{Binding CacheSize}\" />\n                    </TextBlock>\n                    <Button Margin=\"20,0,0,0\" Padding=\"20,3,20,3\" FontSize=\"11\" Style=\"{StaticResource CommonButtonStyle}\" Content=\"{x:Static localization:MainResources.SettingsUIClearCache}\" VerticalAlignment=\"Center\" Command=\"{Binding ClearCacheCommand}\"/>\n                </StackPanel>\n\n\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsUINotificationsTitle}\" FontSize=\"12\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\" Margin=\"0,15,0,0\"/>\n                <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsUINotifications}\" Margin=\"0,5,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\" IsChecked=\"{Binding EnableNotifications, Mode=TwoWay}\"/>\n\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsUITaskBarTitle}\" FontSize=\"12\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\" Margin=\"0,15,0,0\"/>\n                <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsUIShowTrayIcon}\" Margin=\"0,5,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\" IsChecked=\"{Binding EnableTrayIcon, Mode=TwoWay}\"/>\n\n                <TextBlock Text=\"{x:Static localization:MainResources.SettingsUIPlayUsing}\" FontSize=\"12\" Opacity=\"0.7\" Foreground=\"{DynamicResource ForegroundBrush}\" Margin=\"0,15,0,0\"/>\n                <ComboBox Width=\"200\" Style=\"{StaticResource CommonComboBoxStyle}\" Margin=\"0,3,0,0\" HorizontalAlignment=\"Left\" ItemsSource=\"{Binding Engines}\" \n                      SelectedValue=\"{Binding SelectedEngine, Mode=TwoWay}\" DisplayMemberPath=\"Title\"/>\n                <CheckBox IsEnabled=\"{Binding CanUseHttps}\" IsChecked=\"{Binding UseHttps, Mode=TwoWay}\" Content=\"{x:Static localization:MainResources.SettingsUseHttps}\"\n                          Margin=\"0,5,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            </StackPanel>\n        </ScrollViewer>\n        \n        <StackPanel Grid.Row=\"2\" HorizontalAlignment=\"Left\" Margin=\"24,0,0,10\">\n            <TextBlock Text=\"{x:Static localization:MainResources.SettingsRestartMessage}\" VerticalAlignment=\"Center\" Margin=\"0,0,0,5\" Opacity=\"0.6\" \n                       Visibility=\"{Binding RestartRequired, Converter={StaticResource BoolToVisibilityConverter}}\" Foreground=\"{DynamicResource ForegroundBrush}\" TextWrapping=\"Wrap\"/>\n\n            <StackPanel Orientation=\"Horizontal\">\n                <Button Style=\"{StaticResource HighlightedButtonStyle}\" Content=\"{x:Static localization:MainResources.SettingsSaveRestart}\" IsEnabled=\"{Binding CanSave}\" Command=\"{Binding SaveRestartCommand}\" Margin=\"0,0,0,0\"  Visibility=\"{Binding RestartRequired, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n                <Button Style=\"{StaticResource HighlightedButtonStyle}\" Content=\"{x:Static localization:MainResources.SettingsSave}\" IsEnabled=\"{Binding CanSave}\" Command=\"{Binding SaveCommand}\"  Visibility=\"{Binding RestartRequired, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\"/>\n                <Button Style=\"{StaticResource CommonButtonStyle}\" Content=\"{x:Static localization:MainResources.CancelButton}\" Margin=\"15,0,0,0\" Command=\"{Binding CloseSettingsCommand}\"/>\n            </StackPanel>\n        </StackPanel>\n    </Grid>\n</Page>\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsUIView.xaml.cs",
    "content": "﻿using System.Windows.Controls;\n\nnamespace Meridian.View.Settings\n{\n    /// <summary>\n    /// Interaction logic for SettingsUIView.xaml\n    /// </summary>\n    public partial class SettingsUIView : Page\n    {\n        public SettingsUIView()\n        {\n            InitializeComponent();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsUpdatesView.xaml",
    "content": "﻿<Page x:Class=\"Meridian.View.Settings.SettingsUpdatesView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\" \n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      Background=\"{DynamicResource MainBackgroundBrush}\">\n\n    <Page.RenderTransform>\n        <TranslateTransform />\n    </Page.RenderTransform>\n\n    <Page.Triggers>\n        <EventTrigger RoutedEvent=\"Page.Loaded\">\n            <BeginStoryboard Storyboard=\"{StaticResource PageLoadAnim}\" />\n        </EventTrigger>\n    </Page.Triggers>\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\"/>\n            <RowDefinition />\n        </Grid.RowDefinitions>\n        <TextBlock Text=\"{x:Static localization:MainResources.SettingsMenuUpdates}\" FontSize=\"28\" FontWeight=\"Thin\" Margin=\"24,10,0,15\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n        <Rectangle Height=\"1\" Grid.ColumnSpan=\"2\" VerticalAlignment=\"Bottom\" Fill=\"{DynamicResource ForegroundBrush}\" SnapsToDevicePixels=\"True\" Margin=\"0,0,0,0\" Opacity=\"0.15\"/>\n        <StackPanel Grid.Row=\"1\" Margin=\"24,20,0,0\">\n            <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsUpdatesCheckForUpdates}\" Margin=\"0,0,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\" IsChecked=\"{Binding CheckForUpdates, Mode=TwoWay}\"/>\n            <CheckBox Foreground=\"{DynamicResource ForegroundBrush}\" Content=\"{x:Static localization:MainResources.SettingsUpdatesInstallDevUpdates}\" Margin=\"0,3,0,0\" Style=\"{StaticResource CommonCheckBoxStyle}\" IsChecked=\"{Binding InstallDevUpdates, Mode=TwoWay}\"/>\n            <TextBlock Text=\"{x:Static localization:MainResources.SettingsUpdatesDevUpdatesDescription}\" TextWrapping=\"Wrap\" Opacity=\"0.6\" Margin=\"20,0,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <Button IsEnabled=\"{Binding UpdateService.IsCheckingUpdates, Source={StaticResource Locator}, Converter={StaticResource InvertBoolConverter}}\" Content=\"{x:Static localization:MainResources.SettingsUpdatesCheck}\" Style=\"{StaticResource CommonButtonStyle}\" HorizontalAlignment=\"Left\" Margin=\"0,15,0,0\" Command=\"{Binding CheckUpdatesCommand}\" Visibility=\"{Binding UpdateService.IsUpdateInstalled, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}\"/>\n            <Button Content=\"{x:Static localization:MainResources.SettingsUpdatesRestart}\" Style=\"{StaticResource CommonButtonStyle}\" HorizontalAlignment=\"Left\" Margin=\"0,5,0,0\" Command=\"{Binding Main.RestartCommand, Source={StaticResource Locator}}\" Visibility=\"{Binding UpdateService.IsUpdateInstalled, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\"/>\n            <ProgressBar Value=\"{Binding UpdateService.UpdateProgress, Source={StaticResource Locator}}\" IsIndeterminate=\"{Binding UpdateService.IsCheckingUpdates, Source={StaticResource Locator}}\" Style=\"{StaticResource CommonProgressBarStyle}\" HorizontalAlignment=\"Left\" Width=\"150\" Padding=\"0\" Margin=\"0,5,0,0\" Background=\"Transparent\"/>\n            <TextBlock Text=\"{x:Static localization:MainResources.SettingsUpdatesUpdated}\" FontWeight=\"Regular\" Opacity=\"0.6\" TextWrapping=\"Wrap\" Visibility=\"{Binding UpdateService.IsUpdateInstalled, Source={StaticResource Locator}, Converter={StaticResource BoolToVisibilityConverter}}\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n            <TextBlock Text=\"{Binding UpdateService.UpdateDescription, Source={StaticResource Locator}}\" FontWeight=\"Regular\" Opacity=\"0.6\" TextWrapping=\"Wrap\" Foreground=\"{DynamicResource ForegroundBrush}\" Margin=\"0,10,0,0\"/>\n\n        </StackPanel>\n    </Grid>\n</Page>\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsUpdatesView.xaml.cs",
    "content": "﻿using System.Windows.Controls;\n\nnamespace Meridian.View.Settings\n{\n    /// <summary>\n    /// Interaction logic for SettingsUpdatesView.xaml\n    /// </summary>\n    public partial class SettingsUpdatesView : Page\n    {\n        public SettingsUpdatesView()\n        {\n            InitializeComponent();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsView.xaml",
    "content": "﻿<controls:PageBase x:Class=\"Meridian.View.Settings.SettingsView\"\n      xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n      xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n      xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n      xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n      xmlns:i=\"http://schemas.microsoft.com/xaml/behaviors\"\n      xmlns:behaviours=\"clr-namespace:Meridian.Behaviours\"\n      xmlns:controls=\"clr-namespace:Meridian.Controls\"\n      xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n      mc:Ignorable=\"d\"\n      KeepAlive=\"False\"\n      d:DesignHeight=\"600\" d:DesignWidth=\"600\"\n      x:Name=\"pageRoot\" Background=\"{DynamicResource MainBackgroundBrush}\"\n      Loaded=\"SettingsView_OnLoaded\">\n\n    <Grid>\n        <Grid.ColumnDefinitions>\n            <ColumnDefinition Width=\"Auto\"/>\n            <ColumnDefinition />\n        </Grid.ColumnDefinitions>\n        <Grid.RowDefinitions>\n            <RowDefinition />\n            <RowDefinition Height=\"Auto\"/>\n        </Grid.RowDefinitions>\n        <!-- Menu -->\n        <Rectangle Fill=\"Black\" Grid.RowSpan=\"2\"/>\n        <Grid Width=\"200\" Background=\"{DynamicResource SidebarBackgroundBrush}\">\n            <StackPanel>\n                <Button x:Name=\"MeridianButton\" HorizontalAlignment=\"Left\" Margin=\"0,5,0,0\"\n                        Command=\"{Binding CloseSettingsCommand}\" ToolTip=\"{x:Static localization:MainResources.BackButton}\">\n                    <Button.Template>\n                        <ControlTemplate TargetType=\"{x:Type Button}\">\n                            <StackPanel x:Name=\"rootPanel\" Opacity=\"0.7\" Orientation=\"Horizontal\" Background=\"Transparent\">\n                                <Path Data=\"{StaticResource BackIcon}\" Fill=\"{DynamicResource SidebarForegroundBrush}\" Stretch=\"Uniform\" Width=\"5\" Margin=\"18,3,0,0\"/>\n                                <TextBlock VerticalAlignment=\"Center\" HorizontalAlignment=\"Left\" Foreground=\"{DynamicResource SidebarForegroundBrush}\" Opacity=\"1\" FontSize=\"13\" Margin=\"6,1,0,0\" \n                                           Text=\"{x:Static localization:MainResources.Settings}\" FontWeight=\"Regular\" TextOptions.TextFormattingMode=\"Display\"/>\n                            </StackPanel>\n                            <ControlTemplate.Triggers>\n                                <Trigger Property=\"IsMouseOver\" Value=\"True\">\n                                    <Setter Property=\"Opacity\" Value=\"1\" TargetName=\"rootPanel\"/>\n                                </Trigger>\n                                <Trigger Property=\"IsPressed\" Value=\"True\">\n                                    <Setter Property=\"Opacity\" Value=\"0.6\" TargetName=\"rootPanel\"/>\n                                </Trigger>\n                            </ControlTemplate.Triggers>\n                        </ControlTemplate>\n                    </Button.Template>\n                </Button>\n\n                <ListBox x:Name=\"MenuListBox\" Margin=\"0,30,0,0\" Padding=\"0,10,0,10\" ScrollViewer.HorizontalScrollBarVisibility=\"Disabled\" ItemsSource=\"{Binding MenuItems}\"\n                         Foreground=\"White\" Style=\"{StaticResource CommonListBoxStyle}\" ItemContainerStyle=\"{StaticResource MainMenuListBoxItemStyle}\"\n                         SelectedIndex=\"0\">\n                    <i:Interaction.Behaviors>\n                        <behaviours:TransitionBehaviour Transition=\"{StaticResource MainMenuLoadAnim}\" TransitionDelay=\"40\"/>\n                    </i:Interaction.Behaviors>\n                    <ListBox.ItemTemplate>\n                        <DataTemplate>\n                            <TextBlock Text=\"{Binding Key}\" FontFamily=\"Segoe UI SemiLight\"/>\n                        </DataTemplate>\n                    </ListBox.ItemTemplate>\n                </ListBox>\n            </StackPanel>\n        </Grid>\n        <Frame x:Name=\"SettingsFrame\" Grid.Column=\"1\" Source=\"{Binding SelectedItem.Value, ElementName=MenuListBox}\" JournalOwnership=\"OwnsJournal\"\n               NavigationUIVisibility=\"Hidden\" Navigated=\"SettingsFrame_OnNavigated\"/>\n        <Rectangle Fill=\"{DynamicResource SidebarForegroundBrush}\" Width=\"1\" HorizontalAlignment=\"Right\" Opacity=\"0.1\" Grid.RowSpan=\"2\"/>\n    </Grid>\n</controls:PageBase>\n"
  },
  {
    "path": "Meridian/View/Settings/SettingsView.xaml.cs",
    "content": "﻿using System.Linq;\nusing System.Windows;\nusing System.Windows.Navigation;\nusing Meridian.Controls;\nusing Meridian.ViewModel;\n\nnamespace Meridian.View.Settings\n{\n    /// <summary>\n    /// Interaction logic for SettingsView.xaml\n    /// </summary>\n    public partial class SettingsView : PageBase\n    {\n        private SettingsViewModel _viewModel;\n        private bool _isSidebarOpened = ViewModelLocator.Main.ShowSidebar;\n\n        public SettingsView()\n        {\n            InitializeComponent();\n\n            _viewModel = new SettingsViewModel();\n            this.DataContext = _viewModel;\n        }\n\n        private void SettingsView_OnLoaded(object sender, RoutedEventArgs e)\n        {\n            _viewModel.Activate();\n        }\n\n        public override void OnNavigatedTo()\n        {\n            ViewModelLocator.Main.ShowSidebar = false;\n\n            var p = NavigationContext.Parameters;\n            if (p.ContainsKey(\"section\"))\n            {\n                if ((string)p[\"section\"] == \"accounts\")\n                {\n                    MenuListBox.SelectedItem = _viewModel.MenuItems.First(i => i.Value.EndsWith(\"SettingsAccountsView.xaml\"));\n                }\n            }\n        }\n\n        public override void OnNavigatedFrom()\n        {\n            ViewModelLocator.Main.ShowSidebar = _isSidebarOpened;\n        }\n\n        private void SettingsFrame_OnNavigated(object sender, NavigationEventArgs e)\n        {\n            SettingsFrame.RemoveBackEntry();\n\n            var content = SettingsFrame.Content as FrameworkElement;\n            if (content == null)\n                return;\n\n            content.DataContext = _viewModel;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/View/TrackNotifcationView.xaml",
    "content": "﻿<Window x:Class=\"Meridian.View.TrackNotifcationView\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:localization=\"clr-namespace:Meridian.Resources.Localization\"\n        xmlns:controls=\"clr-namespace:Meridian.Controls\"\n        Title=\"TrackNotifcationView\"\n        ResizeMode=\"NoResize\" WindowStyle=\"None\"\n        Height=\"90\" Width=\"320\" AllowsTransparency=\"True\" Topmost=\"True\" ShowInTaskbar=\"False\"\n        x:Name=\"rootElement\"\n        SourceInitialized=\"TrackNotifcationView_OnSourceInitialized\" MouseLeftButtonUp=\"TrackNotifcationView_OnMouseLeftButtonUp\">\n    <Window.RenderTransform>\n        <TranslateTransform />\n    </Window.RenderTransform>\n    <Window.Resources>\n        <Storyboard x:Key=\"LoadAnim\">\n            <Storyboard>\n                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                    <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"30\"/>\n                </DoubleAnimationUsingKeyFrames>\n                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"Opacity\">\n                    <DiscreteDoubleKeyFrame KeyTime=\"0\" Value=\"0\"/>\n                </DoubleAnimationUsingKeyFrames>\n            </Storyboard>\n            <Storyboard>\n                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty=\"(UIElement.RenderTransform).(TranslateTransform.X)\">\n                    <EasingDoubleKeyFrame KeyTime=\"0:0:0.5\" Value=\"0\">\n                        <EasingDoubleKeyFrame.EasingFunction>\n                            <ExponentialEase EasingMode=\"EaseOut\" Exponent=\"6\"/>\n                        </EasingDoubleKeyFrame.EasingFunction>\n                    </EasingDoubleKeyFrame>\n                </DoubleAnimationUsingKeyFrames>\n                <DoubleAnimation Storyboard.TargetProperty=\"Opacity\" To=\"1\" Duration=\"0:0:0.15\"/>\n            </Storyboard>\n        </Storyboard>\n        <Storyboard x:Key=\"CloseAnim\" Completed=\"CloseAnim_OnCompleted\">\n            <Storyboard>\n                <DoubleAnimation Storyboard.TargetProperty=\"Opacity\" To=\"0\" Duration=\"0:0:0.2\"/>\n            </Storyboard>\n        </Storyboard>\n    </Window.Resources>\n    <Border Background=\"{DynamicResource MainBackgroundBrush}\" BorderBrush=\"Gray\" BorderThickness=\"1\">\n        <Grid>\n            <Grid Margin=\"20,0,0,0\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\"/>\n                    <ColumnDefinition />\n                </Grid.ColumnDefinitions>\n                <Border Background=\"{DynamicResource AccentBrush}\" Width=\"40\" Height=\"40\">\n                    <Grid>\n                        <Image Source=\"/Resources/Images/cover_default.png\" Margin=\"8\" RenderOptions.BitmapScalingMode=\"HighQuality\"/>\n                        <controls:ImageTransitionControl Source=\"{Binding Main.TrackImage, Source={StaticResource Locator}}\"/>\n                    </Grid>\n                </Border>\n                <StackPanel Grid.Column=\"1\" VerticalAlignment=\"Center\" Margin=\"10,10,20,10\">\n                    <TextBlock Text=\"{Binding ElementName=rootElement, Path=Track.Artist}\" TextTrimming=\"CharacterEllipsis\"\n                       FontSize=\"14\" Opacity=\"0.6\" Foreground=\"{DynamicResource ForegroundBrush}\" Margin=\"0,0,0,-2\"/>\n                    <TextBlock Text=\"{Binding ElementName=rootElement, Path=Track.Title}\" FontFamily=\"Segoe UI Semilight\" TextTrimming=\"CharacterEllipsis\" FontSize=\"20\" Margin=\"0,0,0,0\" Foreground=\"{DynamicResource ForegroundBrush}\"/>\n                </StackPanel>\n            </Grid>\n\n            <Button Style=\"{StaticResource CloseButtonStyle}\" SnapsToDevicePixels=\"True\" Click=\"ButtonBase_OnClick\" ToolTip=\"{x:Static localization:MainResources.Close}\"\n                VerticalAlignment=\"Top\" HorizontalAlignment=\"Right\" Margin=\"0,10,10,0\"/>\n        </Grid>\n    </Border>\n</Window>\n"
  },
  {
    "path": "Meridian/View/TrackNotifcationView.xaml.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Windows;\nusing System.Windows.Input;\nusing System.Windows.Media.Animation;\nusing System.Windows.Threading;\nusing Meridian.Model;\n\nnamespace Meridian.View\n{\n    /// <summary>\n    /// Interaction logic for TrackNotifcationView.xaml\n    /// </summary>\n    public partial class TrackNotifcationView : Window, INotifyPropertyChanged\n    {\n        private DispatcherTimer _timer;\n        private Audio _track;\n\n        public Audio Track\n        {\n            get { return _track; }\n            set\n            {\n                if (_track == value)\n                    return;\n\n                _track = value;\n                ResetTimer();\n                OnPropertyChanged(\"Track\");\n            }\n        }\n\n        public TrackNotifcationView(Audio track)\n        {\n            _track = track;\n\n            InitializeComponent();\n\n            _timer = new DispatcherTimer();\n            _timer.Interval = TimeSpan.FromSeconds(7);\n            _timer.Tick += _timer_Tick;\n        }\n\n        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)\n        {\n            Close();\n        }\n\n        private new void Close()\n        {\n            _timer.Stop();\n            _timer.Tick -= _timer_Tick;\n\n            var s = (Storyboard)this.Resources[\"CloseAnim\"];\n            s.Begin(this);\n        }\n\n        private void ResetTimer()\n        {\n            _timer.Stop();\n            _timer.Start();\n        }\n\n        private void TrackNotifcationView_OnSourceInitialized(object sender, EventArgs e)\n        {\n            this.Left = SystemParameters.WorkArea.Width - this.Width - 10;\n            this.Top = SystemParameters.WorkArea.Height - this.Height - 10;\n\n            _timer.Start();\n           \n            var s = (Storyboard)this.Resources[\"LoadAnim\"];\n            s.Begin(this);\n        }\n\n\n        void _timer_Tick(object sender, EventArgs e)\n        {\n            Close();\n        }\n\n        private void CloseAnim_OnCompleted(object sender, EventArgs e)\n        {\n            base.Close();\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        protected virtual void OnPropertyChanged(string propertyName = null)\n        {\n            PropertyChangedEventHandler handler = PropertyChanged;\n            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));\n        }\n\n        private void TrackNotifcationView_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)\n        {\n            if (Application.Current.MainWindow.WindowState == WindowState.Minimized)\n                Application.Current.MainWindow.WindowState = WindowState.Normal;\n\n            Application.Current.MainWindow.Activate();\n\n            Close();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Flyouts/EditAudioViewModel.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Controls;\nusing Meridian.Model;\nusing Meridian.Services;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.ViewModel.Flyouts\n{\n    public class EditAudioViewModel : ViewModelBase\n    {\n        private VkAudio _track;\n        private string _title;\n        private string _artist;\n        private string _lyrics;\n        private bool _lyricsChanged;\n\n        #region Commands\n\n        public RelayCommand SaveCommand { get; private set; }\n\n        public RelayCommand CloseCommand { get; private set; }\n\n        #endregion\n\n        public VkAudio Track\n        {\n            get { return _track; }\n            set\n            {\n                if (Set(ref _track, value))\n                    Load();\n            }\n        }\n\n        public string Title\n        {\n            get { return _title; }\n            set { Set(ref _title, value); }\n        }\n\n        public string Artist\n        {\n            get { return _artist; }\n            set { Set(ref _artist, value); }\n        }\n\n        public string Lyrics\n        {\n            get { return _lyrics; }\n            set\n            {\n                if (Set(ref _lyrics, value))\n                    _lyricsChanged = true;\n            }\n        }\n\n        public EditAudioViewModel()\n        {\n            InitializeCommands();\n        }\n\n        private void InitializeCommands()\n        {\n            CloseCommand = new RelayCommand(Close);\n\n            SaveCommand = new RelayCommand(Save);\n        }\n\n        private async void Load()\n        {\n            Title = _track.Title;\n            Artist = _track.Artist;\n\n            if (_track.HasLyrics && string.IsNullOrEmpty(_track.Lyrics))\n                await LoadLyrics();\n            else\n            {\n                _lyrics = _track.Lyrics;\n                RaisePropertyChanged(\"Lyrics\");\n            }\n        }\n\n        private async Task LoadLyrics()\n        {\n            IsWorking = true;\n\n            try\n            {\n                _lyrics = await DataService.GetLyrics(_track.LyricsId.ToString());\n                RaisePropertyChanged(\"Lyrics\");\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n        private async void Save()\n        {\n            IsWorking = true;\n\n            try\n            {\n                var lyricsId = await DataService.EditAudio(_track.Id, _track.OwnerId.ToString(), Title, Artist, Lyrics);\n                if (lyricsId != null)\n                {\n                    _track.Title = Title;\n                    _track.Artist = Artist;\n                    if (lyricsId != \"0\")\n                        _track.LyricsId = long.Parse(lyricsId);\n                    else\n                        _track.LyricsId = 0;\n                    Close();\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n        private void Close()\n        {\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n                flyout.Close();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Flyouts/LoginLastFmViewModel.cs",
    "content": "﻿using System;\nusing System.Linq;\nusing System.Windows;\nusing GalaSoft.MvvmLight.Command;\nusing LastFmLib.Error;\nusing Meridian.Controls;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Neptune.UI.Extensions;\n\nnamespace Meridian.ViewModel.Flyouts\n{\n    public class LoginLastFmViewModel : ViewModelBase\n    {\n        private string _login;\n        private string _password;\n        private bool _canLogin;\n        private string _loginError;\n\n        #region Commands\n\n        public RelayCommand CancelCommand { get; private set; }\n\n        public RelayCommand LoginCommand { get; private set; }\n\n        #endregion\n\n        public string Login\n        {\n            get { return _login; }\n            set\n            {\n                if (_login == value)\n                    return;\n\n                _login = value;\n                UpdateCanLogin();\n                RaisePropertyChanged(\"Login\");\n            }\n        }\n\n        public string Password\n        {\n            get { return _password; }\n            set\n            {\n                if (_password == value)\n                    return;\n\n                _password = value;\n                UpdateCanLogin();\n                RaisePropertyChanged(\"Password\");\n            }\n        }\n\n        public bool CanLogin\n        {\n            get\n            {\n                return _canLogin;\n            }\n            set { Set(ref _canLogin, value); }\n        }\n\n        public string LoginError\n        {\n            get { return _loginError; }\n            set { Set(ref _loginError, value); }\n        }\n\n        public LoginLastFmViewModel()\n        {\n            InitalizeCommands();\n        }\n\n        private void InitalizeCommands()\n        {\n            CancelCommand = new RelayCommand(() =>\n            {\n                var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n                if (flyout != null)\n                    flyout.Close();\n            });\n\n            LoginCommand = new RelayCommand(DoLogin);\n        }\n\n        private void UpdateCanLogin()\n        {\n            if (string.IsNullOrEmpty(Login) || string.IsNullOrEmpty(Password))\n                CanLogin = false;\n            else\n                CanLogin = true;\n        }\n\n        private async void DoLogin()\n        {\n            if (string.IsNullOrWhiteSpace(Login) || string.IsNullOrWhiteSpace(Password))\n                return;\n\n            IsWorking = true;\n            CanLogin = false;\n\n            try\n            {\n                await AccountManager.LoginLastFm(Login, Password);\n\n                CancelCommand.Execute(null);\n            }\n            catch (LastFmLoginException ex)\n            {\n                LoggingService.Log(ex.ToString());\n\n                LoginError = ErrorResources.LoginErrorInvalidClient;\n                CanLogin = true;\n                IsWorking = false;\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex.ToString());\n\n                CanLogin = true;\n                IsWorking = false;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Flyouts/LyricsViewModel.cs",
    "content": "﻿using System;\nusing Meridian.Model;\nusing Meridian.Services;\n\nnamespace Meridian.ViewModel.Flyouts\n{\n    public class LyricsViewModel : ViewModelBase\n    {\n        private VkAudio _track;\n        private string _lyrics;\n\n        public VkAudio Track\n        {\n            get { return _track; }\n            set\n            {\n                if (Set(ref _track, value))\n                    LoadLyrics();\n            }\n        }\n\n        public string Lyrics\n        {\n            get { return _lyrics; }\n            set { Set(ref _lyrics, value); }\n        }\n\n        private async void LoadLyrics()\n        {\n            if (Track == null || !Track.HasLyrics)\n                return;\n\n            IsWorking = true;\n\n\n            try\n            {\n                Lyrics = await DataService.GetLyrics(Track.LyricsId.ToString());\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Flyouts/ShareViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing GalaSoft.MvvmLight.Command;\nusing GongSolutions.Wpf.DragDrop;\nusing Meridian.Controls;\nusing Meridian.Model;\nusing Meridian.Services;\nusing Meridian.View.Flyouts;\nusing Neptune.UI.Extensions;\nusing VkLib.Core.Attachments;\nusing VkLib.Core.Groups;\nusing VkLib.Core.Users;\nusing Application = System.Windows.Application;\nusing DragDropEffects = System.Windows.DragDropEffects;\nusing IDropTarget = GongSolutions.Wpf.DragDrop.IDropTarget;\n\nnamespace Meridian.ViewModel.Flyouts\n{\n    public class ShareViewModel : ViewModelBase, IDropTarget\n    {\n        private ObservableCollection<VkAudio> _tracks;\n        private bool _canGoNext;\n        private int _progress;\n        private int _progressMaximum;\n        private ImageSource _image;\n        private CancellationTokenSource _cancellationToken;\n\n        private bool _shareToUser;\n        private bool _shareToSociety;\n        private bool _shareAsSociety;\n        private bool _shareSigned;\n\n        private List<VkGroup> _societies;\n        private VkGroup _selectedSociety;\n\n        private List<VkProfile> _friends;\n        private VkProfile _selectedFriend;\n\n        #region Commands\n\n        public RelayCommand CancelCommand { get; private set; }\n\n        public RelayCommand CloseCommand { get; private set; }\n\n        public RelayCommand GoNextCommand { get; private set; }\n\n        public RelayCommand<VkAudio> RemoveTrackCommand { get; private set; }\n\n        public RelayCommand PublishCommand { get; private set; }\n\n        public RelayCommand ClearImageCommand { get; private set; }\n\n        public RelayCommand AddImageCommand { get; private set; }\n\n        #endregion\n\n        public ObservableCollection<VkAudio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public bool CanGoNext\n        {\n            get { return _canGoNext; }\n            set { Set(ref _canGoNext, value); }\n        }\n\n        public string ImagePath { get; set; }\n\n        public ImageSource Image\n        {\n            get { return _image; }\n            set { Set(ref _image, value); }\n        }\n\n        public int Progress\n        {\n            get { return _progress; }\n            set { Set(ref _progress, value); }\n        }\n\n\n        public int ProgressMaximum\n        {\n            get { return _progressMaximum; }\n            set { Set(ref _progressMaximum, value); }\n        }\n\n        public bool ShareToUser\n        {\n            get { return _shareToUser; }\n            set\n            {\n                if (_shareToUser == value)\n                    return;\n\n                _shareToUser = value;\n                RaisePropertyChanged(\"ShareToUser\");\n            }\n        }\n\n        public bool ShareToSociety\n        {\n            get { return _shareToSociety; }\n            set { Set(ref _shareToSociety, value); }\n        }\n\n        public List<VkGroup> Societies\n        {\n            get { return _societies; }\n            set { Set(ref _societies, value); }\n        }\n\n        public bool ShareSigned\n        {\n            get { return _shareSigned; }\n            set { Set(ref _shareSigned, value); }\n        }\n\n        public bool ShareAsSociety\n        {\n            get { return _shareAsSociety; }\n            set\n            {\n                if (Set(ref _shareAsSociety, value))\n                    ShareSigned = false;\n            }\n        }\n\n        public VkGroup SelectedSociety\n        {\n            get { return _selectedSociety; }\n            set\n            {\n                if (Set(ref _selectedSociety, value))\n                {\n                    if (value != null && value.IsAdmin)\n                        ShareAsSociety = true;\n                    else\n                        ShareAsSociety = false;\n                }\n            }\n        }\n\n        public VkProfile SelectedFriend\n        {\n            get { return _selectedFriend; }\n            set { Set(ref _selectedFriend, value); }\n        }\n\n        public List<VkProfile> Friends\n        {\n            get { return _friends; }\n            set { Set(ref _friends, value); }\n        }\n\n        public ShareViewModel()\n        {\n            _tracks = new ObservableCollection<VkAudio>();\n            _tracks.CollectionChanged += Tracks_CollectionChanged;\n\n            _cancellationToken = new CancellationTokenSource();\n\n            InitializeCommands();\n        }\n\n        public void InitializeCommands()\n        {\n            CancelCommand = new RelayCommand(() =>\n            {\n                Tracks.Clear();\n                ViewModelLocator.Main.ShowShareBar = false;\n            });\n\n            CloseCommand = new RelayCommand(() =>\n            {\n                Close();\n            });\n\n            GoNextCommand = new RelayCommand(() =>\n            {\n                ViewModelLocator.Main.ShowShareBar = false;\n\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new ShareView() { DataContext = this };\n                flyout.Show();\n\n                Activate();\n            });\n\n            RemoveTrackCommand = new RelayCommand<VkAudio>(track => Tracks.Remove(track));\n\n            PublishCommand = new RelayCommand(() =>\n            {\n                if (ShareToSociety && SelectedSociety == null)\n                    return;\n\n                if (ShareToUser && SelectedFriend == null)\n                    return;\n\n                var progress = new Progress<int>(p =>\n                {\n                    Progress += p;\n                });\n\n                Share(progress, _cancellationToken.Token);\n            });\n\n            ClearImageCommand = new RelayCommand(() =>\n            {\n                Image = null;\n                ImagePath = null;\n            });\n\n            AddImageCommand = new RelayCommand(() =>\n            {\n                var fileOpenDialog = new OpenFileDialog();\n                fileOpenDialog.Filter = \"Images|*.png;*.jpg\";\n                if (fileOpenDialog.ShowDialog() == DialogResult.OK)\n                {\n                    ImagePath = fileOpenDialog.FileName;\n                    Image = new BitmapImage(new Uri(ImagePath));\n                }\n            });\n        }\n\n        public void Activate()\n        {\n            LoadFriends();\n            LoadSocieties();\n        }\n\n        public void DragOver(IDropInfo dropInfo)\n        {\n            if (dropInfo.Data is Audio && Tracks.Count < 15 && Tracks.All(t => t.Id != ((Audio)dropInfo.Data).Id))\n                dropInfo.Effects = DragDropEffects.All;\n        }\n\n        public void Drop(IDropInfo dropInfo)\n        {\n            if (dropInfo.Data is Audio && Tracks.Count < 15 && Tracks.All(t => t.Id != ((Audio)dropInfo.Data).Id))\n            {\n                Tracks.Add((VkAudio)dropInfo.Data);\n            }\n        }\n\n        private void Tracks_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)\n        {\n            UpdateCanGoNext();\n        }\n\n        private void UpdateCanGoNext()\n        {\n            if (Tracks.Count == 0)\n                CanGoNext = false;\n            else\n                CanGoNext = true;\n        }\n\n        private async void LoadFriends()\n        {\n            try\n            {\n                var response = await ViewModelLocator.Vkontakte.Friends.Get(0, \"photo\", null, 0, 0);\n                if (response.Items != null)\n                    Friends = response.Items;\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private void Close()\n        {\n            CancelAsync();\n            Tracks.Clear();\n\n            var flyout = Application.Current.MainWindow.GetVisualDescendents().FirstOrDefault(c => c is FlyoutControl) as FlyoutControl;\n            if (flyout != null)\n            {\n                flyout.Close();\n            }\n        }\n\n        private async void LoadSocieties()\n        {\n            try\n            {\n                var response = await ViewModelLocator.Vkontakte.Groups.Get(0, fields: null, filter: \"editor\", count: 0, offset: 0);\n                if (response.Items != null)\n                    Societies = response.Items;\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private async void Share(IProgress<int> progress, CancellationToken token)\n        {\n            Progress = 0;\n            if (Tracks != null)\n                ProgressMaximum = Tracks.Count;\n\n            IsWorking = true;\n            CanGoNext = false;\n\n            VkPhotoAttachment photoAttachment = null;\n            if (!string.IsNullOrEmpty(ImagePath))\n            {\n                try\n                {\n                    var server = await ViewModelLocator.Vkontakte.Photos.GetWallUploadServer(0, ShareToSociety ? _selectedSociety.Id : 0);\n                    var o = await ViewModelLocator.Vkontakte.Photos.UploadPhoto(server, Path.GetFileName(ImagePath), File.OpenRead(ImagePath));\n                    if (o != null)\n                    {\n                        var photo = await ViewModelLocator.Vkontakte.Photos.SaveWallPhoto(o.Server, o.Photo, o.Hash, ShareToUser ? _selectedFriend.Id : 0, ShareToSociety ? _selectedSociety.Id : 0);\n                        if (photo != null)\n                            photoAttachment = new VkPhotoAttachment(photo);\n                    }\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n            }\n\n            if (token.IsCancellationRequested)\n                return;\n\n            progress.Report(1);\n            try\n            {\n                var attachments = new List<VkAttachment>();\n                if (photoAttachment != null)\n                    attachments.Add(photoAttachment);\n\n                if (Tracks != null)\n                {\n                    var audioAttachments = await GetAudioList(progress, token);\n                    if (audioAttachments != null)\n                        attachments.AddRange(audioAttachments);\n                }\n\n                if (token.IsCancellationRequested)\n                    return;\n\n                long targetId = 0;\n                if (ShareToSociety)\n                    targetId = -_selectedSociety.Id;\n                else if (ShareToUser)\n                    targetId = _selectedFriend.Id;\n\n                var postId = await ViewModelLocator.Vkontakte.Wall.Post(targetId, null, attachments, _shareAsSociety, _shareSigned);\n                if (postId > 0)\n                {\n                    Close();\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n            CanGoNext = true;\n        }\n\n        private async Task<List<VkAudioAttachment>> GetAudioList(IProgress<int> progress, CancellationToken token)\n        {\n            if (Tracks == null)\n                return null;\n\n            var result = new List<VkAudioAttachment>();\n            int requestsCount = 0;\n            foreach (var audio in Tracks)\n            {\n                if (token.IsCancellationRequested)\n                    return null;\n\n                if (audio.Source == null)\n                {\n                    VkAudio vkAudio = null;\n                    try\n                    {\n                        vkAudio = await DataService.GetAudioByArtistAndTitle(audio.Artist, audio.Title);\n                    }\n                    catch (Exception ex)\n                    {\n                        LoggingService.Log(ex);\n                    }\n\n                    if (vkAudio != null)\n                    {\n                        var audioAttachment = new VkAudioAttachment();\n                        audioAttachment.Id = long.Parse(vkAudio.Id);\n                        audioAttachment.OwnerId = vkAudio.OwnerId;\n                        result.Add(audioAttachment);\n                    }\n                    else\n                    {\n                        LoggingService.Log(\"Failed to find audio \" + audio.Artist + \" - \" + audio.Title);\n                    }\n\n                    requestsCount++;\n\n                    if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                    {\n                        requestsCount = 0;\n                        await Task.Delay(1000);\n                    }\n                }\n                else\n                {\n                    var audioAttachment = new VkAudioAttachment();\n                    audioAttachment.Id = long.Parse(audio.Id);\n                    audioAttachment.OwnerId = audio.OwnerId;\n                    result.Add(audioAttachment);\n                }\n\n                if (token.IsCancellationRequested)\n                    return null;\n\n                progress.Report(1);\n            }\n\n            return result;\n        }\n\n        private void CancelAsync()\n        {\n            if (_cancellationToken != null)\n                _cancellationToken.Cancel();\n\n            IsWorking = false;\n            CanGoNext = true;\n\n            _cancellationToken = new CancellationTokenSource();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Local/LocalAlbumViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Model;\nusing Meridian.Services;\n\nnamespace Meridian.ViewModel.Local\n{\n    public class LocalAlbumViewModel : ViewModelBase\n    {\n        private AudioAlbum _album;\n        private List<LocalAudio> _tracks;\n\n        #region Commands\n\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        #endregion\n\n        public AudioAlbum Album\n        {\n            get { return _album; }\n            set { Set(ref _album, value); }\n        }\n\n        public List<LocalAudio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public LocalAlbumViewModel()\n        {\n            InitializeCommands();\n\n            RegisterTasks(\"tracks\");\n        }\n\n        public override void Activate()\n        {\n            Load();\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n                AudioService.SetCurrentPlaylist(Tracks);\n            });\n        }\n\n        private async void Load()\n        {\n            OnTaskStarted(\"tracks\");\n\n            try\n            {\n                Tracks = await ServiceLocator.LocalMusicService.GetAlbumTracks(Album.Id);\n            }\n            catch (Exception ex)\n            {\n                OnTaskError(\"tracks\", \"~Unable to load tracks\");\n\n                LoggingService.Log(ex);\n            }\n\n            OnTaskFinished(\"tracks\");\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Local/LocalMusicViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Controls;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.View.Flyouts.Local;\nusing Meridian.ViewModel.Messages;\nusing Neptune.Extensions;\nusing Neptune.Messages;\n\nnamespace Meridian.ViewModel.Local\n{\n    public class LocalMusicViewModel : ViewModelBase\n    {\n        private List<LocalAudio> _tracks;\n        private List<AudioAlbum> _albums;\n        private List<AudioArtist> _albumGroups;\n        private List<AudioArtist> _artists;\n        private AudioArtist _selectedArtist;\n        private List<AudioAlbum> _selectedArtistAlbums;\n        private List<LocalAudio> _selectedArtistTracks;\n        private double _progress;\n        private int _selectedTabIndex;\n\n        #region Commands\n\n        /// <summary>\n        /// Play audio command\n        /// </summary>\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        /// <summary>\n        /// Go to album command\n        /// </summary>\n        public RelayCommand<AudioAlbum> GoToAlbumCommand { get; private set; }\n\n        /// <summary>\n        /// Refresh command\n        /// </summary>\n        public RelayCommand RefreshCommand { get; private set; }\n\n        #endregion\n\n        public List<LocalAudio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public List<AudioAlbum> Albums\n        {\n            get { return _albums; }\n            set { Set(ref _albums, value); }\n        }\n\n        public List<AudioArtist> AlbumGroups\n        {\n            get { return _albumGroups; }\n            set { Set(ref _albumGroups, value); }\n        }\n\n        public List<AudioArtist> Artists\n        {\n            get { return _artists; }\n            set { Set(ref _artists, value); }\n        }\n\n        public AudioArtist SelectedArtist\n        {\n            get { return _selectedArtist; }\n            set\n            {\n                if (Set(ref _selectedArtist, value))\n                    LoadSelectedArtist();\n            }\n        }\n\n        public List<AudioAlbum> SelectedArtistAlbums\n        {\n            get { return _selectedArtistAlbums; }\n            set { Set(ref _selectedArtistAlbums, value); }\n        }\n\n        public List<LocalAudio> SelectedArtistTracks\n        {\n            get { return _selectedArtistTracks; }\n            set { Set(ref _selectedArtistTracks, value); }\n        }\n\n        public double Progress\n        {\n            get { return _progress; }\n            set { Set(ref _progress, value); }\n        }\n\n        public int SelectedTabIndex\n        {\n            get { return _selectedTabIndex; }\n            set\n            {\n                if (Set(ref _selectedTabIndex, value))\n                {\n                    switch (value)\n                    {\n                        case 1:\n                            if (Albums.IsNullOrEmpty())\n                                LoadAlbums();\n                            break;\n\n                        case 2:\n                            if (Artists.IsNullOrEmpty())\n                            {\n                                LoadArtists();\n                            }\n                            break;\n                    }\n                }\n            }\n        }\n\n        public LocalMusicViewModel()\n        {\n            InitializeMessages();\n            InitializeCommands();\n\n            RegisterTasks(\"tracks\", \"albums\", \"artists\");\n\n            Load();\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n\n                if (SelectedTabIndex == 0)\n                {\n                    var searchControl = LocalSearchControl.GetForCurrentView();\n                    if (searchControl != null && searchControl.IsFiltering)\n                    {\n                        AudioService.SetCurrentPlaylist((searchControl.Source.View).Cast<Audio>());\n                    }\n                    else\n                        AudioService.SetCurrentPlaylist(Tracks);\n                }\n                else if (SelectedArtistAlbums != null)\n                {\n                    AudioService.SetCurrentPlaylist(SelectedArtistAlbums.Where(a => !a.Tracks.IsNullOrEmpty()).SelectMany(a => a.Tracks).ToList());\n                }\n            });\n\n            GoToAlbumCommand = new RelayCommand<AudioAlbum>(album =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Local.LocalAlbumView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"album\", album}\n                    }\n                });\n            });\n\n            RefreshCommand = new RelayCommand(() =>\n            {\n                Refresh();\n            });\n        }\n\n        private void InitializeMessages()\n        {\n            MessengerInstance.Register<LocalRepositoryUpdatedMessage>(this, OnLocalRepositoryUpdated);\n        }\n\n        private async void Load()\n        {\n            await LoadTracks();\n\n            if (Tracks == null || Tracks.Count == 0)\n            {\n                Refresh();\n            }\n        }\n\n        private async void Refresh()\n        {\n            await ServiceLocator.LocalMusicService.Clear();\n\n            if (Tracks != null)\n                Tracks.Clear();\n\n            if (Artists != null)\n                Artists.Clear();\n\n            if (Albums != null)\n                Albums.Clear();\n\n            if (AlbumGroups != null)\n                AlbumGroups.Clear();\n\n            if (SelectedArtistAlbums != null)\n                SelectedArtistAlbums.Clear();\n\n            var flyout = new FlyoutControl();\n            flyout.FlyoutContent = new MusicScanView();\n            await flyout.ShowAsync();\n\n            switch (SelectedTabIndex)\n            {\n                case 0:\n                    LoadTracks();\n                    break;\n                case 1:\n                    LoadAlbums();\n                    break;\n\n                case 2:\n                    LoadArtists();\n                    break;\n            }\n        }\n\n        private async Task LoadTracks()\n        {\n            OnTaskStarted(\"tracks\");\n\n            try\n            {\n                var tracks = await ServiceLocator.LocalMusicService.GetTracks();\n\n                if (tracks.IsNullOrEmpty())\n                {\n                    OnTaskError(\"tracks\", ErrorResources.LoadAudiosErrorEmpty);\n                }\n                else\n                    Tracks = tracks;\n            }\n            catch (Exception ex)\n            {\n                OnTaskError(\"tracks\", ErrorResources.LoadAudiosErrorCommon);\n\n                LoggingService.Log(ex);\n            }\n\n            OnTaskFinished(\"tracks\");\n        }\n\n        private async Task LoadAlbums()\n        {\n            OnTaskStarted(\"albums\");\n\n            try\n            {\n                var albums = await ServiceLocator.LocalMusicService.GetAlbums();\n                if (albums.IsNullOrEmpty())\n                {\n                    OnTaskError(\"albums\", ErrorResources.LoadAlbumsErrorEmpty);\n                }\n                else\n                {\n                    AlbumGroups = albums.GroupBy(a => a.Artist).Select(g => new AudioArtist() { Title = g.Key, Albums = g.OrderBy(a => a.Year).ToList() }).OrderBy(a => a.Title).ToList();\n                    Albums = albums;\n                }\n            }\n            catch (Exception ex)\n            {\n                OnTaskError(\"albums\", ErrorResources.LoadAlbumsErrorCommon);\n\n                LoggingService.Log(ex);\n            }\n\n            OnTaskFinished(\"albums\");\n        }\n\n        private async Task LoadArtists()\n        {\n            OnTaskStarted(\"artists\");\n\n            try\n            {\n                var artists = await ServiceLocator.LocalMusicService.GetArtists();\n                if (artists.IsNullOrEmpty())\n                {\n                    OnTaskError(\"artists\", ErrorResources.LoadArtistsErrorEmpty);\n                }\n                else\n                {\n                    Artists = artists.OrderBy(a => a.Title).ToList();\n                    SelectedArtist = Artists.FirstOrDefault();\n                }\n            }\n            catch (Exception ex)\n            {\n                OnTaskError(\"artists\", ErrorResources.LoadArtistsErrorCommon);\n\n                LoggingService.Log(ex);\n            }\n\n            OnTaskFinished(\"artists\");\n        }\n\n        private async Task LoadSelectedArtist()\n        {\n            if (SelectedArtist == null)\n                return;\n\n            OnTaskStarted(\"artists\");\n\n            try\n            {\n                if (Albums.IsNullOrEmpty())\n                    await LoadAlbums();\n\n                var albums = await ServiceLocator.LocalMusicService.GetArtistAlbums(SelectedArtist.Id);\n\n                if (!albums.IsNullOrEmpty())\n                {\n                    foreach (var album in albums)\n                    {\n                        var tracks = await ServiceLocator.LocalMusicService.GetAlbumTracks(album.Id);\n                        if (!tracks.IsNullOrEmpty())\n                            album.Tracks = tracks.Cast<Audio>().ToList();\n                    }\n                }\n                else\n                {\n                    albums = new List<AudioAlbum>();\n                }\n\n                if (SelectedArtist == null)\n                    return;\n\n                var unsortedTracks = await ServiceLocator.LocalMusicService.GetArtistUnsortedTracks(SelectedArtist.Id);\n                if (!unsortedTracks.IsNullOrEmpty())\n                {\n                    var unsortedAlbum = new AudioAlbum() { Tracks = unsortedTracks.OfType<Audio>().ToList() };\n                    albums.Insert(0, unsortedAlbum);\n                }\n\n                SelectedArtistAlbums = albums;\n                SelectedArtistTracks = albums.SelectMany(a => a.Tracks).Cast<LocalAudio>().ToList();\n            }\n            catch (Exception ex)\n            {\n                OnTaskError(\"artists\", ErrorResources.LoadArtistsErrorCommon);\n\n                LoggingService.Log(ex);\n            }\n\n            OnTaskFinished(\"artists\");\n        }\n\n        private void OnLocalRepositoryUpdated(LocalRepositoryUpdatedMessage message)\n        {\n            if (message.RepositoryType == typeof(LocalAudio))\n                LoadTracks();\n            else if (message.RepositoryType == typeof(AudioAlbum))\n                LoadAlbums();\n            else if (message.RepositoryType == typeof (AudioArtist))\n                LoadArtists();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Main/FeedViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Controls;\nusing Meridian.Flyouts;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Neptune.Extensions;\nusing VkLib.Core.Groups;\n\nnamespace Meridian.ViewModel.Main\n{\n    public class FeedViewModel : ViewModelBase\n    {\n        private ObservableCollection<VkGroup> _societies = new ObservableCollection<VkGroup>();\n        private ObservableCollection<Audio> _tracks;\n        private const int MAX_NEWS_AUDIOS = 100;\n        private CancellationTokenSource _cancellationToken = new CancellationTokenSource();\n        private VkGroup _selectedSociety;\n\n        #region Commands\n\n        /// <summary>\n        /// Add society to feed command\n        /// </summary>\n        public RelayCommand AddSocietyCommand { get; private set; }\n\n        /// <summary>\n        /// Remove society from feed command\n        /// </summary>\n        public RelayCommand<VkGroup> RemoveSocietyCommand { get; private set; }\n\n        /// <summary>\n        /// Play audio command\n        /// </summary>\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        #endregion\n\n        public ObservableCollection<VkGroup> Societies\n        {\n            get { return _societies; }\n            set { Set(ref _societies, value); }\n        }\n\n        public ObservableCollection<Audio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public VkGroup SelectedSociety\n        {\n            get { return _selectedSociety; }\n            set\n            {\n                if (Set(ref _selectedSociety, value))\n                {\n                    CancelAsync();\n\n                    LoadFeed(_cancellationToken.Token);\n                }\n            }\n        }\n\n        public FeedViewModel()\n        {\n            RegisterTasks(\"feed\");\n\n            InitializeCommands();\n\n            LoadSocieties();\n        }\n\n        private void InitializeCommands()\n        {\n            AddSocietyCommand = new RelayCommand(async () =>\n            {\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new AddSocietyFlyout();\n                var result = await flyout.ShowAsync();\n                if (result != null)\n                {\n                    CancelAsync();\n\n                    if (Societies.Count == 0)\n                    {\n                        _societies.Add(new VkGroup() { Name = MainResources.AllSocieties });\n                    }\n\n                    Societies.Add((VkGroup)result);\n                    SaveSocieties();\n\n                    if (SelectedSociety == null)\n                        SelectedSociety = _societies.First();\n                    else if (SelectedSociety.Id == 0)\n                        LoadFeed(_cancellationToken.Token);\n                }\n            });\n\n            RemoveSocietyCommand = new RelayCommand<VkGroup>(society =>\n            {\n                bool isActiveSociety = false;\n                if (society == SelectedSociety)\n                    isActiveSociety = true;\n\n                CancelAsync();\n                Societies.Remove(society);\n\n                if (Societies.Count == 1)\n                    Societies.Clear();\n\n                SaveSocieties();\n\n                if (!isActiveSociety && (SelectedSociety != null && SelectedSociety.Id != 0))\n                {\n                    return;\n                }\n\n                if (isActiveSociety)\n                {\n                    if (Societies.Any())\n                        SelectedSociety = Societies.First();\n                }\n\n                //if (SelectedSociety != null && SelectedSociety.Id == 0)\n                //{\n                    CancelAsync();\n\n                    LoadFeed(_cancellationToken.Token);\n                //}\n\n                //if (isActiveSociety && Societies.Any())\n                //    SelectedSociety = Societies.First();\n                //else if (isActiveSociety)\n                //    LoadFeed(_cancellationToken.Token);\n            });\n\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n                AudioService.SetCurrentPlaylist(Tracks);\n            });\n        }\n\n        private void LoadSocieties()\n        {\n            if (Domain.Settings.Instance.FeedSocieties != null)\n            {\n                _societies = new ObservableCollection<VkGroup>(Domain.Settings.Instance.FeedSocieties);\n\n                if (_societies.Count > 0)\n                {\n                    _societies.Insert(0, new VkGroup() { Name = MainResources.AllSocieties });\n                    SelectedSociety = _societies.First();\n                }\n\n                LoadFeed(_cancellationToken.Token);\n            }\n        }\n\n        private void SaveSocieties()\n        {\n            Domain.Settings.Instance.FeedSocieties = _societies.Skip(1).ToList();\n        }\n\n        private async void LoadFeed(CancellationToken token)\n        {\n            if (Societies.Count == 0)\n            {\n                Tracks = null;\n\n                OnTaskError(\"feed\", ErrorResources.FeedSocietiesEmpty);\n                return;\n            }\n\n            if (SelectedSociety == null)\n                return;\n\n            OnTaskStarted(\"feed\");\n\n            Tracks = new ObservableCollection<Audio>();\n\n            try\n            {\n                var nextFrom = string.Empty;\n                int count = 150;\n                int requestsCount = 0;\n\n                while (Tracks != null && Tracks.Count < MAX_NEWS_AUDIOS)\n                {\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"News audio cancelled\");\n                        break;\n                    }\n\n                    var sourceIds = SelectedSociety.Id != 0\n                        ? new List<long>() { -SelectedSociety.Id }\n                        : Societies.Skip(1).Select(s => -s.Id).ToList();\n\n                    var a = await DataService.GetNewsAudio(count, nextFrom, token, sourceIds);\n                    if (a.Items.IsNullOrEmpty())\n                        break;\n                    else if (a.Items.Count > 0)\n                    {\n                        OnTaskFinished(\"feed\");\n                    }\n\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"News audio cancelled\");\n                        break;\n                    }\n\n                    nextFrom = a.NextFrom;\n\n                    foreach (var audio in a.Items)\n                    {\n                        Tracks.Add(audio);\n                    }\n\n                    requestsCount++;\n\n                    if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                    {\n                        requestsCount = 0;\n                        await Task.Delay(1000);\n                    }\n\n                    Debug.WriteLine(\"Loading more audios from news\");\n                }\n\n                if ((Tracks == null || Tracks.Count == 0) && !token.IsCancellationRequested)\n                    OnTaskError(\"feed\", ErrorResources.LoadAudiosErrorEmpty);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n                OnTaskError(\"feed\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            OnTaskFinished(\"feed\");\n        }\n\n        private void CancelAsync()\n        {\n            if (_cancellationToken != null)\n                _cancellationToken.Cancel();\n\n            _cancellationToken = new CancellationTokenSource();\n        }\n\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Main/LoginViewModel.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Controls;\nusing Meridian.Domain;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.View.Flyouts;\nusing Neptune.Messages;\nusing VkLib.Core.Auth;\nusing VkLib.Error;\nusing System.Collections.Generic;\n\nnamespace Meridian.ViewModel.Main\n{\n    public class LoginViewModel : ViewModelBase\n    {\n        private string _login;\n        private string _password;\n        private bool _canLogin;\n        private bool _isLoginFormVisible;\n\n        private string _captchaImg;\n        private string _captchaSid;\n        private string _captchaKey;\n        private bool _showCaptcha;\n        private string _loginError;\n\n        #region Commands\n\n        /// <summary>\n        /// Команда авторизации\n        /// </summary>\n        public RelayCommand LoginCommand { get; private set; }\n\n        /// <summary>\n        /// Команда перехода к регистрации ВКонтакте\n        /// </summary>\n        public RelayCommand SignUpVkCommand { get; private set; }\n\n        /// <summary>\n        /// Команда перехода к форме авторизации\n        /// </summary>\n        public RelayCommand LoginVkCommand { get; private set; }\n\n        /// <summary>\n        /// Команда отмены авторизации\n        /// </summary>\n        public RelayCommand CancelLoginVkCommand { get; private set; }\n\n        #endregion\n\n        /// <summary>\n        /// Логин\n        /// </summary>\n        public string Login\n        {\n            get { return _login; }\n            set\n            {\n                if (_login == value)\n                    return;\n\n                _login = value;\n                UpdateCanLogin();\n                RaisePropertyChanged(\"Login\");\n            }\n        }\n\n        /// <summary>\n        /// Пароль\n        /// </summary>\n        public string Password\n        {\n            get { return _password; }\n            set\n            {\n                if (_password == value)\n                    return;\n\n                _password = value;\n                UpdateCanLogin();\n                RaisePropertyChanged(\"Password\");\n            }\n        }\n\n        /// <summary>\n        /// Доступна ли кнопка авторизации\n        /// </summary>\n        public bool CanLogin\n        {\n            get\n            {\n                return _canLogin;\n            }\n            set\n            {\n                if (_canLogin == value)\n                    return;\n\n                _canLogin = value;\n\n                RaisePropertyChanged(\"CanLogin\");\n            }\n        }\n\n        /// <summary>\n        /// Отображается ли форма авторизации\n        /// </summary>\n        public bool IsLoginFormVisible\n        {\n            get { return _isLoginFormVisible; }\n            set\n            {\n                if (_isLoginFormVisible == value)\n                    return;\n\n                _isLoginFormVisible = value;\n                RaisePropertyChanged(\"IsLoginFormVisible\");\n            }\n        }\n\n        /// <summary>\n        /// Ссылка на капчу\n        /// </summary>\n        public string CaptchaImg\n        {\n            get { return _captchaImg; }\n            set\n            {\n                Set(ref _captchaImg, value);\n            }\n        }\n\n        /// <summary>\n        /// Ключ капчи\n        /// </summary>\n        public string CaptchaKey\n        {\n            get { return _captchaKey; }\n            set\n            {\n                Set(ref _captchaKey, value);\n            }\n        }\n\n        /// <summary>\n        /// Отображается ли капча\n        /// </summary>\n        public bool ShowCaptcha\n        {\n            get { return _showCaptcha; }\n            set\n            {\n                Set(ref _showCaptcha, value);\n            }\n        }\n\n        public string LoginError\n        {\n            get { return _loginError; }\n            set { Set(ref _loginError, value); }\n        }\n\n        public LoginViewModel()\n        {\n            InitiailizeCommands();\n        }\n\n        private void InitiailizeCommands()\n        {\n            LoginCommand = new RelayCommand(DoLogin);\n            SignUpVkCommand = new RelayCommand(DoSignUp);\n\n            LoginVkCommand = new RelayCommand(() => IsLoginFormVisible = true);\n            CancelLoginVkCommand = new RelayCommand(() =>\n            {\n                IsLoginFormVisible = false;\n                LoginError = null;\n            });\n        }\n\n        private void UpdateCanLogin()\n        {\n            if (string.IsNullOrEmpty(Login) || string.IsNullOrEmpty(Password))\n                CanLogin = false;\n            else\n                CanLogin = true;\n        }\n\n        private async void DoLogin()\n        {\n            if (string.IsNullOrWhiteSpace(Login) || string.IsNullOrWhiteSpace(Password))\n                return;\n\n            IsWorking = true;\n            LoginError = null;\n\n            try\n            {\n                await AccountManager.LoginVk(Login, Password, _captchaSid, _captchaKey);\n\n                MessengerInstance.Send(new NavigateToPageMessage() {Page = \"/Main.MusicView\"});\n            }\n            catch (VkCaptchaNeededException ex)\n            {\n                CaptchaImg = ex.CaptchaImg;\n                _captchaSid = ex.CaptchaSid;\n\n                ShowCaptcha = true;\n\n                IsWorking = false;\n                IsLoginFormVisible = true;\n            }\n            catch (VkInvalidClientException ex)\n            {\n                LoginError = ErrorResources.LoginErrorInvalidClient;\n                IsWorking = false;\n\n                LoggingService.Log(ex.ToString());\n            }\n            catch (VkNeedValidationException ex)\n            {\n                LoginError = ErrorResources.LoginErrorNeedValidation;\n                IsWorking = false;\n\n                ValidateUser(ex.RedirectUri);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex.ToString());\n\n                //var message = ErrorResources.LoginCommonError;\n                //MessageBoxHelper.Show(message);\n\n                IsWorking = false;\n            }\n        }\n\n        private void DoSignUp()\n        {\n            var uri = new Uri(\"http://vk.com\");\n\n            Process.Start(uri.OriginalString);\n        }\n\n        private async void ValidateUser(Uri redirectUri)\n        {\n            var flyout = new FlyoutControl();\n            flyout.FlyoutContent = new WebValidationView(redirectUri);\n            var token = await flyout.ShowAsync() as VkAccessToken;\n            if (token != null)\n            {\n                AccountManager.SetLoginVk(token);\n\n                MessengerInstance.Send(new NavigateToPageMessage() { Page = \"/Main.MusicView\" });\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Main/MusicViewModel.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Data;\nusing GalaSoft.MvvmLight.Command;\nusing GongSolutions.Wpf.DragDrop;\nusing Meridian.Controls;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.View.Flyouts;\nusing Meridian.ViewModel.Messages;\nusing Neptune.Extensions;\nusing VkLib.Core.Audio;\n\nnamespace Meridian.ViewModel.Main\n{\n    public class MusicViewModel : ViewModelBase, IDropTarget\n    {\n        private const int MAX_WALL_AUDIOS = 300;\n        private const int MAX_NEWS_AUDIOS = 300;\n\n        private ObservableCollection<VkPlaylist> _albums;\n        private ObservableCollection<Audio> _tracks;\n        private ObservableCollection<AudioArtist> _artists;\n        private ObservableCollection<Audio> _newsTracks;\n        private ObservableCollection<Audio> _wallTracks;\n        private ObservableCollection<Audio> _favoritesTracks;\n        private VkPlaylist _selectedAlbum;\n        private CancellationTokenSource _cancellationToken;\n        private int _totalAlbumsCount;\n        private int _selectedTabIndex;\n        private AudioArtist _selectedArtist;\n\n        #region Commands\n\n        /// <summary>\n        /// Команда воспроизведения аудиозаписи\n        /// </summary>\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        /// <summary>\n        /// Команда дозагрузки альбомов\n        /// </summary>\n        public RelayCommand LoadMoreAlbumsCommand { get; private set; }\n\n        /// <summary>\n        /// Команда добавления нового альбома\n        /// </summary>\n        public RelayCommand AddAlbumCommand { get; private set; }\n\n        /// <summary>\n        /// Команда редактирования альбома\n        /// </summary>\n        public RelayCommand<VkPlaylist> EditAlbumCommand { get; private set; }\n\n        /// <summary>\n        /// Команда удаления альбома\n        /// </summary>\n        public RelayCommand<VkAudioAlbum> RemoveAlbumCommand { get; private set; }\n\n        /// <summary>\n        /// Команда обновления списка аудиозаписей\n        /// </summary>\n        public RelayCommand RefreshCommand { get; private set; }\n\n        /// <summary>\n        /// Команда воспроизведения альбома\n        /// </summary>\n        public RelayCommand<VkAudioAlbum> PlayAlbumCommand { get; private set; }\n\n        /// <summary>\n        /// Команда добавления альбома в NowPlaying\n        /// </summary>\n        public RelayCommand<VkAudioAlbum> AddAlbumToNowPlayingCommand { get; private set; }\n\n        /// <summary>\n        /// Команда воспроизведения исполнителя\n        /// </summary>\n        public RelayCommand<AudioArtist> PlayArtistCommand { get; private set; }\n\n        /// <summary>\n        /// Команда добавления исполнителя в NowPlaying\n        /// </summary>\n        public RelayCommand<AudioArtist> AddArtistToNowPlayingCommand { get; private set; }\n\n        #endregion\n\n        /// <summary>\n        /// Albums list\n        /// </summary>\n        public ObservableCollection<VkPlaylist> Albums\n        {\n            get { return _albums; }\n            set { Set(ref _albums, value); }\n        }\n\n        /// <summary>\n        /// Tracks list\n        /// </summary>\n        public ObservableCollection<Audio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        /// <summary>\n        /// Artists list\n        /// </summary>\n        public ObservableCollection<AudioArtist> Artists\n        {\n            get { return _artists; }\n            set { Set(ref _artists, value); }\n        }\n\n\n        /// <summary>\n        /// Selected album\n        /// </summary>\n        public VkPlaylist SelectedAlbum\n        {\n            get { return _selectedAlbum; }\n            set\n            {\n                if (Set(ref _selectedAlbum, value))\n                {\n                    CancelAsync();\n\n                    if (value != null)\n                    {\n                        switch ((int)value.Id)\n                        {\n                            case -100:\n                                LoadNewsAudios(_cancellationToken.Token);\n                                break;\n                            case -101:\n                                LoadWallAudios(_cancellationToken.Token);\n                                break;\n                            case -102:\n                                LoadFavoritesAudios(_cancellationToken.Token);\n                                break;\n                            default:\n                                LoadTracks(_cancellationToken.Token);\n                                break;\n                        }\n                    }\n                }\n            }\n        }\n\n        public int SelectedTabIndex\n        {\n            get { return _selectedTabIndex; }\n            set\n            {\n                if (Set(ref _selectedTabIndex, value))\n                {\n                    CancelAsync();\n\n                    switch (_selectedTabIndex)\n                    {\n                        case 2:\n                            LoadNewsAudios(_cancellationToken.Token);\n                            break;\n\n                        case 3:\n                            LoadWallAudios(_cancellationToken.Token);\n                            break;\n\n                        case 4:\n                            LoadFavoritesAudios(_cancellationToken.Token);\n                            break;\n                    }\n                }\n            }\n        }\n\n        public AudioArtist SelectedArtist\n        {\n            get { return _selectedArtist; }\n            set { Set(ref _selectedArtist, value); }\n        }\n\n        public ObservableCollection<Audio> NewsTracks\n        {\n            get { return _newsTracks; }\n            set { Set(ref _newsTracks, value); }\n        }\n\n        public ObservableCollection<Audio> WallTracks\n        {\n            get { return _wallTracks; }\n            set { Set(ref _wallTracks, value); }\n        }\n\n        public ObservableCollection<Audio> FavoritesTracks\n        {\n            get { return _favoritesTracks; }\n            set { Set(ref _favoritesTracks, value); }\n        }\n\n        public MusicViewModel()\n        {\n            _cancellationToken = new CancellationTokenSource();\n\n            InitializeCommands();\n            InitializeMessageInterception();\n\n            RegisterTasks(\"audio\", \"albums\", \"news\", \"wall\", \"favorites\");\n        }\n\n        public override async void Activate()\n        {\n            if (Albums.IsNullOrEmpty())\n                await LoadAlbums();\n\n            if (Artists.IsNullOrEmpty())\n                await LoadArtists(_cancellationToken.Token);\n        }\n\n        public override void Deactivate()\n        {\n            CancelAsync();\n\n            MessengerInstance.Unregister<UserTracksChangedMessage>(this, OnUserTracksChanged);\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n\n                switch (SelectedTabIndex)\n                {\n                    case 0:\n                        var searchControl = LocalSearchControl.GetForCurrentView();\n                        if (searchControl != null && searchControl.IsFiltering)\n                        {\n                            AudioService.SetCurrentPlaylist((searchControl.Source.View).Cast<Audio>());\n                        }\n                        else\n                            AudioService.SetCurrentPlaylist(Tracks);\n                        break;\n\n                    case 1:\n                        if (SelectedArtist != null)\n                            AudioService.SetCurrentPlaylist(SelectedArtist.Tracks);\n                        break;\n\n                    case 2:\n                        AudioService.SetCurrentPlaylist(NewsTracks);\n                        break;\n\n                    case 3:\n                        AudioService.SetCurrentPlaylist(WallTracks);\n                        break;\n\n                    case 4:\n                        AudioService.SetCurrentPlaylist(FavoritesTracks);\n                        break;\n                }\n            });\n\n            LoadMoreAlbumsCommand = new RelayCommand(() => LoadMoreAlbums());\n\n            RefreshCommand = new RelayCommand(() =>\n            {\n                CancelAsync();\n                LoadTracks(_cancellationToken.Token);\n                LoadArtists(_cancellationToken.Token);\n            });\n\n            AddAlbumCommand = new RelayCommand(AddNewAlbum);\n\n            EditAlbumCommand = new RelayCommand<VkPlaylist>(EditAlbum);\n\n            RemoveAlbumCommand = new RelayCommand<VkAudioAlbum>(RemoveAlbum);\n\n            PlayAlbumCommand = new RelayCommand<VkAudioAlbum>(PlayAlbum);\n\n            AddAlbumToNowPlayingCommand = new RelayCommand<VkAudioAlbum>(AddAlbumToNowPlaying);\n\n            PlayArtistCommand = new RelayCommand<AudioArtist>(artist =>\n            {\n                AudioService.Play(artist.Tracks.First());\n                AudioService.SetCurrentPlaylist(artist.Tracks);\n            });\n\n            AddArtistToNowPlayingCommand = new RelayCommand<AudioArtist>(artist =>\n            {\n                foreach (var track in artist.Tracks)\n                {\n                    AudioService.Playlist.Add(track);\n                }\n            });\n        }\n\n        private void InitializeMessageInterception()\n        {\n            MessengerInstance.Register<UserTracksChangedMessage>(this, OnUserTracksChanged);\n        }\n\n        private async void OnUserTracksChanged(UserTracksChangedMessage message)\n        {\n            if (SelectedAlbum.Id == -1)\n            {\n                CancelAsync();\n                await LoadTracks(_cancellationToken.Token);\n            }\n        }\n\n        private async Task LoadAlbums()\n        {\n            IsWorking = true;\n            OnTaskStarted(\"albums\");\n\n            try\n            {\n                var response = await DataService.GetUserAlbums(count: 100);\n\n                var albums = response.Items;\n\n                _totalAlbumsCount = response.TotalCount;\n\n                if (albums == null)\n                    albums = new List<VkPlaylist>();\n\n                albums.Insert(0, new VkPlaylist() { Id = -1, Title = MainResources.MyMusicAllTracks });\n                //albums.Insert(1, new VkAudioAlbum() { Id = -100, Title = MainResources.MyMusicNews });\n                //albums.Insert(2, new VkAudioAlbum() { Id = -101, Title = MainResources.MyMusicWall });\n                //albums.Insert(3, new VkAudioAlbum() { Id = -102, Title = MainResources.MyMusicFavorites });\n                //albums.Insert(4, new VkAudioAlbum() { Id = int.MinValue }); //separator\n\n\n                Albums = new ObservableCollection<VkPlaylist>(albums);\n\n                SelectedAlbum = albums.First();\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"albums\", ErrorResources.LoadAlbumsErrorCommon);\n            }\n\n            IsWorking = false;\n            OnTaskFinished(\"albums\");\n        }\n\n        private async Task LoadMoreAlbums()\n        {\n            if (Albums == null || Albums.Count - 5 >= _totalAlbumsCount)\n                return;\n\n            IsWorking = true;\n\n            try\n            {\n                var response = await DataService.GetUserAlbums(0, Albums.Count - 5);\n\n\n                if (response.Items != null)\n                {\n                    foreach (var album in response.Items)\n                    {\n                        Albums.Add(album);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n        private async Task LoadTracks(CancellationToken token)\n        {\n            if (SelectedAlbum == null)\n                return;\n\n            IsWorking = true;\n            OnTaskStarted(\"audio\");\n\n            try\n            {\n                var response = await DataService.GetUserTracks(0, 0, SelectedAlbum.Id != 0 ? SelectedAlbum.Id : 0);\n                if (response.Items != null && response.Items.Count > 0)\n                {\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"Tracks load cancelled\");\n                        return;\n                    }\n\n                    Tracks = new ObservableCollection<Audio>(response.Items);\n\n                    if (AudioService.CurrentAudio == null)\n                    {\n                        AudioService.SetCurrentPlaylist(Tracks.ToList());\n                        AudioService.CurrentAudio = Tracks.First();\n                        AudioService.CurrentAudio.IsPlaying = true;\n                    }\n                }\n                else\n                {\n                    OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorEmpty);\n                    Tracks = null;\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            IsWorking = false;\n            OnTaskFinished(\"audio\");\n        }\n\n        private async void LoadNewsAudios(CancellationToken token)\n        {\n            IsWorking = true;\n            OnTaskStarted(\"news\");\n\n            NewsTracks = new ObservableCollection<Audio>();\n\n            try\n            {\n                var nextFrom = string.Empty;\n                int count = 150;\n                int requestsCount = 0;\n\n                while (NewsTracks != null && NewsTracks.Count < MAX_NEWS_AUDIOS)\n                {\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"News audio cancelled\");\n                        break;\n                    }\n\n                    var a = await DataService.GetNewsAudio(count, nextFrom, token);\n                    if (a.Items.IsNullOrEmpty())\n                        break;\n                    else if (a.Items.Count > 0)\n                    {\n                        OnTaskFinished(\"news\");\n                    }\n\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"News audio cancelled\");\n                        break;\n                    }\n\n                    nextFrom = a.NextFrom;\n\n                    foreach (var audio in a.Items)\n                    {\n                        NewsTracks.Add(audio);\n                    }\n\n                    requestsCount++;\n\n                    if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                    {\n                        requestsCount = 0;\n                        await Task.Delay(1000);\n                    }\n\n                    Debug.WriteLine(\"Loading more audios from news\");\n                }\n\n                if (NewsTracks.IsNullOrEmpty() && !token.IsCancellationRequested)\n                    OnTaskError(\"news\", ErrorResources.LoadAudiosErrorEmpty);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n                OnTaskError(\"news\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            IsWorking = false;\n            OnTaskFinished(\"news\");\n        }\n\n        private async void LoadWallAudios(CancellationToken token)\n        {\n            IsWorking = true;\n            OnTaskStarted(\"wall\");\n\n            WallTracks = new ObservableCollection<Audio>();\n\n            try\n            {\n                int offset = 0;\n                int count = 50;\n                int requestsCount = 0;\n\n                while (WallTracks != null && WallTracks.Count < MAX_WALL_AUDIOS)\n                {\n                    var a = await DataService.GetWallAudio(count, offset, 0, token);\n                    if (a == null || a.Count == 0)\n                        break;\n                    else if (a.Count > 0)\n                    {\n                        OnTaskFinished(\"wall\");\n                    }\n\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"Wall audios cancelled\");\n                        break;\n                    }\n\n                    offset += count;\n\n                    foreach (var audio in a)\n                    {\n                        WallTracks.Add(audio);\n                    }\n\n                    requestsCount++;\n\n                    if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                    {\n                        requestsCount = 0;\n                        await Task.Delay(1000);\n                    }\n\n                    Debug.WriteLine(\"Loading more audios from wall\");\n                }\n\n                if (WallTracks.IsNullOrEmpty() && !token.IsCancellationRequested)\n                    OnTaskError(\"wall\", ErrorResources.LoadAudiosErrorEmpty);\n            }\n            catch (Exception ex)\n            {\n                OnTaskError(\"wall\", ErrorResources.LoadAudiosErrorCommon);\n\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n            OnTaskFinished(\"wall\");\n        }\n\n        private async void LoadFavoritesAudios(CancellationToken token)\n        {\n            IsWorking = true;\n            OnTaskStarted(\"favorites\");\n\n            FavoritesTracks = new ObservableCollection<Audio>();\n\n            try\n            {\n                int offset = 0;\n                int count = 50;\n                int requestsCount = 0;\n\n                while (FavoritesTracks != null && FavoritesTracks.Count < MAX_WALL_AUDIOS)\n                {\n                    var a = await DataService.GetFavoritesAudio(count, offset, 0, token);\n                    if (a == null || a.Count == 0)\n                        break;\n                    else if (a.Count > 0)\n                    {\n                        OnTaskFinished(\"favorites\");\n                    }\n\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"Favorites audios cancelled\");\n                        break;\n                    }\n\n                    offset += count;\n\n                    foreach (var audio in a)\n                    {\n                        FavoritesTracks.Add(audio);\n                    }\n\n                    requestsCount++;\n\n                    if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                    {\n                        requestsCount = 0;\n                        await Task.Delay(1000);\n                    }\n\n                    Debug.WriteLine(\"Loading more audios from favorites\");\n                }\n\n                if (FavoritesTracks.IsNullOrEmpty() && !token.IsCancellationRequested)\n                    OnTaskError(\"favorites\", ErrorResources.LoadAudiosErrorEmpty);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"favorites\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            IsWorking = false;\n            OnTaskFinished(\"favorites\");\n        }\n\n        private async Task LoadArtists(CancellationToken token)\n        {\n            try\n            {\n                var audio = await DataService.GetUserTracks();\n\n                if (audio.Items == null || token.IsCancellationRequested)\n                {\n                    return;\n                }\n\n                var tracks = audio.Items;\n\n                var artists = await DataService.GetArtistsFromTracks(tracks, token);\n                if (artists != null)\n                {\n                    Artists = new ObservableCollection<AudioArtist>(artists);\n\n                    SelectedArtist = Artists.FirstOrDefault();\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private void CancelAsync()\n        {\n            if (_cancellationToken != null)\n                _cancellationToken.Cancel();\n\n            _cancellationToken = new CancellationTokenSource();\n        }\n\n        private async void AddNewAlbum()\n        {\n            var album = new VkPlaylist() { Title = \"New album\" };\n\n            var flyout = new FlyoutControl();\n            flyout.FlyoutContent = new EditAlbumView(album);\n            var result = await flyout.ShowAsync();\n            if ((bool)result)\n            {\n                try\n                {\n                    var newAlbumId = await ViewModelLocator.Vkontakte.Audio.AddAlbum(album.Title);\n                    if (newAlbumId != 0)\n                    {\n                        album.Id = newAlbumId;\n                        album.OwnerId = ViewModelLocator.Vkontakte.AccessToken.UserId;\n                        Albums.Insert(5, album);\n                    }\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n            }\n        }\n\n        private async void EditAlbum(VkPlaylist album)\n        {\n            var flyout = new FlyoutControl();\n            flyout.FlyoutContent = new EditAlbumView(album);\n\n            var result = await flyout.ShowAsync();\n            if (result != null && (bool)result)\n            {\n                try\n                {\n                    if (await ViewModelLocator.Vkontakte.Audio.EditAlbum(album.Id.ToString(), album.Title))\n                    {\n                        Albums[Albums.IndexOf(album)].Title = album.Title;\n                    }\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n            }\n        }\n\n        private async void RemoveAlbum(VkAudioAlbum album)\n        {\n            try\n            {\n                var result = await ViewModelLocator.Vkontakte.Audio.DeleteAlbum(album.Id);\n                if (result)\n                {\n                    Albums.Remove(Albums.FirstOrDefault(a => a.Id == album.Id));\n\n                    SelectedAlbum = Albums.FirstOrDefault();\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private async void PlayAlbum(VkAudioAlbum album)\n        {\n            try\n            {\n                var audio = await DataService.GetUserTracks(albumId: album.Id, ownerId: album.OwnerId);\n                if (audio.Items != null && audio.Items.Count > 0)\n                {\n                    AudioService.Play(audio.Items.First());\n                    AudioService.SetCurrentPlaylist(audio.Items);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private async void AddAlbumToNowPlaying(VkAudioAlbum album)\n        {\n            try\n            {\n                var audio = await DataService.GetUserTracks(albumId: album.Id, ownerId: album.OwnerId);\n                if (audio.Items != null && audio.Items.Count > 0)\n                {\n                    foreach (var track in audio.Items)\n                    {\n                        AudioService.Playlist.Add(track);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        #region Drag&Drop\n\n        public void DragOver(IDropInfo dropInfo)\n        {\n            if (dropInfo.Data is Audio && !ViewModelLocator.Main.ShowShareBar)\n            {\n                if (dropInfo.TargetCollection == Tracks)\n                {\n                    dropInfo.Effects = DragDropEffects.Move;\n                    dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;\n                }\n                else if (dropInfo.TargetCollection is ListCollectionView)\n                {\n                    var c = (ListCollectionView)dropInfo.TargetCollection;\n                    if (c.SourceCollection == Tracks && c.IsLiveFiltering == false)\n                    {\n                        dropInfo.Effects = DragDropEffects.Move;\n                        dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;\n                    }\n                }\n                else if (dropInfo.TargetCollection == Albums && (dropInfo.TargetItem is VkAudioAlbum && ((VkAudioAlbum)dropInfo.TargetItem).Id >= -1))\n                {\n                    dropInfo.Effects = DragDropEffects.Move;\n                    dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;\n                }\n            }\n        }\n\n        public async void Drop(IDropInfo dropInfo)\n        {\n            if (dropInfo.Data is Audio)\n            {\n                var source = (Audio)dropInfo.Data;\n                IEnumerable targetCollection = dropInfo.TargetCollection;\n                IEnumerable sourceCollection = dropInfo.DragInfo.SourceCollection;\n\n                if (targetCollection is ListCollectionView)\n                {\n                    var c = (ListCollectionView)targetCollection;\n                    targetCollection = c.SourceCollection;\n                }\n\n                if (sourceCollection is ListCollectionView)\n                {\n                    var c = (ListCollectionView)sourceCollection;\n                    sourceCollection = c.SourceCollection;\n                }\n\n                if (targetCollection == Tracks)\n                {\n                    var target = (Audio)dropInfo.TargetItem;\n                    if (source == target)\n                        return;\n                    string afterAid, beforeAid;\n\n                    int index = Tracks.IndexOf(target);\n                    if (index > 0)\n                    {\n                        //проверяем куда вставлять: после taget или перед\n                        if (Tracks[index - 1] == source)\n                        {\n                            afterAid = target.Id;\n                            beforeAid = index == Tracks.Count - 1 ? \"0\" : Tracks[index + 1].Id;\n                        }\n                        else\n                        {\n                            afterAid = Tracks[index - 1].Id;\n                            beforeAid = target.Id;\n                        }\n                    }\n                    else if (index == 0)\n                    {\n                        afterAid = \"0\";\n                        beforeAid = target.Id;\n                    }\n                    else\n                        return;\n\n                    if (await ViewModelLocator.Vkontakte.Audio.Reorder(long.Parse(source.Id), long.Parse(afterAid), long.Parse(beforeAid)))\n                    {\n                        ((IList)sourceCollection).Remove(source);\n                        ((IList)targetCollection).Insert(index, source);\n                    }\n                    else\n                    {\n                        LoggingService.Log(\"Unable to reorder tracks.\");\n                    }\n                }\n                else\n                {\n                    var target = (VkAudioAlbum)dropInfo.TargetItem;\n                    long targetId = target.Id;\n                    //перемещаем в альбом\n                    try\n                    {\n                        if (targetId < 0)\n                            targetId = 0;\n\n                        if (await ViewModelLocator.Vkontakte.Audio.MoveToAlbum(targetId,\n                            new List<long>() { long.Parse(source.Id) }))\n                        {\n                            if (SelectedAlbum.Id > 0)\n                                ((ListCollectionView)dropInfo.DragInfo.SourceCollection).Remove(source);\n                        }\n                        else\n                        {\n                            LoggingService.Log(\"Unable to move track to album.\");\n                        }\n                    }\n                    catch (Exception ex)\n                    {\n                        LoggingService.Log(ex);\n                    }\n\n                }\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Main/NowPlayingViewModel.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Threading;\nusing System.Windows;\nusing System.Windows.Media;\nusing GalaSoft.MvvmLight.Command;\nusing GongSolutions.Wpf.DragDrop;\nusing Meridian.Domain;\nusing Meridian.Model;\nusing Meridian.Services;\nusing Meridian.ViewModel.Messages;\nusing Neptune.Desktop.Storage;\n\nnamespace Meridian.ViewModel.Main\n{\n    public class NowPlayingViewModel : ViewModelBase, IDropTarget\n    {\n        private ImageSource _artistImage;\n        private string _lastArtist;\n        private CancellationTokenSource _cancellationToken;\n        private bool _artRequested;\n\n        #region Commands\n\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        public RelayCommand ClearCommand { get; private set; }\n\n        #endregion\n\n        public ImageSource ArtistImage\n        {\n            get { return _artistImage; }\n            set { Set(ref _artistImage, value); }\n        }\n\n        public NowPlayingViewModel()\n        {\n            _cancellationToken = new CancellationTokenSource();\n\n            InitializeCommands();\n        }\n\n        public override void Activate()\n        {\n            ViewModelLocator.Main.ShowWindowButtons = false;\n\n            GetArtistImage(_cancellationToken.Token);\n\n            InitializeMessageInterception();\n        }\n\n        public override void Deactivate()\n        {\n            DeinitializeMessageInterception();\n\n            ViewModelLocator.Main.ShowWindowButtons = true;\n\n            CancelAsync();\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n            });\n\n            ClearCommand = new RelayCommand(() =>\n            {\n                AudioService.Playlist.Clear();\n            });\n        }\n\n        #region Messages\n\n        private void InitializeMessageInterception()\n        {\n            MessengerInstance.Register<PlayerPositionChangedMessage>(this, OnPlayerPositionChanged);\n            MessengerInstance.Register<CurrentAudioChangedMessage>(this, OnCurrentAudioChanged);\n        }\n\n        private void DeinitializeMessageInterception()\n        {\n            MessengerInstance.Unregister<PlayerPositionChangedMessage>(this, OnPlayerPositionChanged);\n            MessengerInstance.Unregister<CurrentAudioChangedMessage>(this, OnCurrentAudioChanged);\n        }\n\n        private void OnPlayerPositionChanged(PlayerPositionChangedMessage message)\n        {\n            if (message.NewPosition.TotalSeconds >= 3)\n            {\n                if (!_artRequested)\n                {\n                    CancelAsync();\n                    _artRequested = true;\n                    GetArtistImage(_cancellationToken.Token);\n                }\n            }\n        }\n\n        private void OnCurrentAudioChanged(CurrentAudioChangedMessage message)\n        {\n            _artRequested = false;\n        }\n\n        #endregion\n\n        private async void GetArtistImage(CancellationToken token)\n        {\n            var audio = AudioService.CurrentAudio;\n\n            if (audio == null)\n                return;\n\n            if (audio.Artist == _lastArtist)\n                return;\n\n            _lastArtist = audio.Artist;\n            string imageType = \"big\";\n\n            try\n            {\n                var cachedImage = await CacheService.GetCachedImage(\"artists/\" + CacheService.GetSafeFileName(audio.Artist + \"_\" + imageType + \".jpg\"));\n                if (cachedImage != null)\n                {\n                    var lastUpdateTime = FileStorage.GetFileUpdateTime(\"artists/\" + CacheService.GetSafeFileName(audio.Artist + \"_\" + imageType + \".jpg\"));\n                    if ((DateTime.Now - lastUpdateTime).TotalDays < 14)\n                    {\n                        //if image was downloaded less than 2 weeks ago, show it, else download newer\n                        ArtistImage = cachedImage;\n                        return;\n                    }\n                }\n\n                if (Settings.Instance.DownloadArtistArt)\n                {\n                    var imageUri = await DataService.GetArtistImage(audio.Artist, true);\n                    if (imageUri != null)\n                    {\n                        if (token.IsCancellationRequested)\n                            return;\n\n                        cachedImage = await CacheService.CacheImage(imageUri.OriginalString, \"artists/\" + CacheService.GetSafeFileName(audio.Artist + \"_\" + imageType + \".jpg\"));\n\n                        if (token.IsCancellationRequested)\n                            return;\n\n                        ArtistImage = cachedImage;\n                        return;\n                    }\n                }\n\n                ArtistImage = null;\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private void CancelAsync()\n        {\n            _cancellationToken.Cancel();\n\n            _cancellationToken = new CancellationTokenSource();\n        }\n\n        #region Drag&Drop\n\n        public void DragOver(IDropInfo dropInfo)\n        {\n            if (dropInfo.Data is Audio)\n            {\n                dropInfo.Effects = DragDropEffects.Move;\n                dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;\n            }\n        }\n\n        public void Drop(IDropInfo dropInfo)\n        {\n            if (dropInfo.Data is Audio)\n            {\n                var source = (Audio)dropInfo.Data;\n                var target = (Audio)dropInfo.TargetItem;\n                if (source == target)\n                    return;\n\n                int index = ViewModelLocator.Main.CurrentPlaylist.IndexOf(target);\n                if (index >= 0)\n                {\n                    ViewModelLocator.Main.CurrentPlaylist.Remove(source);\n                    ViewModelLocator.Main.CurrentPlaylist.Insert(index, source);\n                }\n            }\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Main/PopularAudioViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing VkLib.Core.Audio;\nusing VkAudio = Meridian.Model.VkAudio;\n\nnamespace Meridian.ViewModel.Main\n{\n    public class PopularAudioViewModel : ViewModelBase\n    {\n        private List<VkAudio> _tracks;\n        private List<VkGenre> _genres;\n        private VkGenre _selectedGenre;\n        private bool _foreignOnly;\n        private CancellationTokenSource _cancellationToken = new CancellationTokenSource();\n\n        #region Commands\n\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        public RelayCommand RefreshCommand { get; private set; }\n\n        #endregion\n\n        public List<VkAudio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public List<VkGenre> Genres\n        {\n            get { return _genres; }\n            set { Set(ref _genres, value); }\n        }\n\n        public VkGenre SelectedGenre\n        {\n            get { return _selectedGenre; }\n            set\n            {\n                if (Set(ref _selectedGenre, value))\n                {\n                    CancelAsync();\n\n                    LoadTracks(_cancellationToken.Token);\n                }\n            }\n        }\n\n        public bool ForeignOnly\n        {\n            get { return _foreignOnly; }\n            set\n            {\n                if (Set(ref _foreignOnly, value))\n                {\n                    CancelAsync();\n\n                    LoadTracks(_cancellationToken.Token);\n                }\n            }\n        }\n\n        public PopularAudioViewModel()\n        {\n            _genres = ViewModelLocator.Vkontakte.Audio.GetGenres();\n            _genres.Insert(0, new VkGenre() { Title = MainResources.PopularGenresAll });\n\n            _selectedGenre = _genres.First();\n\n            RegisterTasks(\"audio\");\n\n            InitializeCommands();\n        }\n\n        public override async void Activate()\n        {\n            if (Tracks == null || Tracks.Count == 0)\n                await LoadTracks(_cancellationToken.Token);\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n                AudioService.SetCurrentPlaylist(Tracks);\n            });\n\n            RefreshCommand = new RelayCommand(() =>\n            {\n                CancelAsync();\n                LoadTracks(_cancellationToken.Token);\n            });\n        }\n\n        private async Task LoadTracks(CancellationToken token)\n        {\n            OnTaskStarted(\"audio\");\n\n            try\n            {\n                var response = await DataService.GetPopularTracks(SelectedGenre.Id, ForeignOnly);\n                if (!token.IsCancellationRequested)\n                {\n                    if (response.Items != null && response.Items.Count > 0)\n                    {\n                        Tracks = response.Items;\n\n                        if (AudioService.CurrentAudio == null)\n                        {\n                            AudioService.CurrentAudio = Tracks.First();\n                            AudioService.SetCurrentPlaylist(Tracks);\n                        }\n                    }\n                    else\n                    {\n                        OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorEmpty);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            OnTaskFinished(\"audio\");\n        }\n\n        private void CancelAsync()\n        {\n            _cancellationToken.Cancel();\n\n            _cancellationToken = new CancellationTokenSource();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Main/RecommendationsViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.ObjectModel;\nusing System.Diagnostics;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\n\nnamespace Meridian.ViewModel.Main\n{\n    public class RecommendationsViewModel : ViewModelBase\n    {\n        private const int MAX_AUDIO_RECOMMENDATIONS = 100;\n\n        #region Groups\n\n        private readonly RecommendationsCollection _recommendationsCollection = new RecommendationsCollection()\n        {\n            new Recommendation() { Title = MainResources.RecommendationsMusicGeneral, Key = \"vk\", Group = MainResources.RecommendationsMusicGroup },\n            //new Recommendation() { Title = MainResources.RecommendationsMusicAdvanced, Key = \"echonest\", Group = MainResources.RecommendationsMusicGroup, GroupOrder = 1},\n\n            new MoodRecommendation() { Title =  MainResources.MoodsVintage, Key = \"vintage\" },\n            new MoodRecommendation() { Title = MainResources.MoodsUrban, Key = \"urban\" },\n            new MoodRecommendation() { Title = MainResources.MoodsSad, Key = \"sad\" },\n            new MoodRecommendation() { Title = MainResources.MoodsCool, Key = \"cool\" },\n            new MoodRecommendation() { Title = MainResources.MoodsDreamy, Key = \"dreamy\" },\n            new MoodRecommendation() { Title = MainResources.MoodsNostalgia, Key = \"nostalgia\" },\n            new MoodRecommendation() { Title = MainResources.MoodsLoneliness, Key = \"loneliness\" },\n            new MoodRecommendation() { Title = MainResources.MoodsOptimism, Key = \"optimism\" },\n            new MoodRecommendation() { Title = MainResources.MoodsPsychedelic, Key = \"psychedelic\" },\n            new MoodRecommendation() { Title = MainResources.MoodsRomantic, Key = \"romantic\" },\n            new MoodRecommendation() { Title = MainResources.MoodsFreedom, Key = \"freedom\" },\n            new MoodRecommendation() { Title = MainResources.MoodsSexy, Key = \"sexy\" },\n            new MoodRecommendation() { Title = MainResources.MoodsNight, Key = \"night\" },\n            new MoodRecommendation() { Title = MainResources.MoodsHappy, Key = \"happy\" },\n            new MoodRecommendation() { Title = MainResources.MoodsExtreme, Key = \"extreme\" },\n            new MoodRecommendation() { Title = MainResources.MoodsEnergy, Key = \"energy\" },\n            new MoodRecommendation() { Title = MainResources.MoodsEpic, Key = \"epic\" },\n            new MoodRecommendation() { Title = MainResources.MoodsSport, Key = \"sport\" },\n\n            new GenreRecommendation() { Title = \"acoustic\", Key = \"acoustic\" },\n            new GenreRecommendation() { Title = \"alternative\", Key = \"alternative\" },\n            new GenreRecommendation() { Title = \"ambient\", Key = \"ambient\" },\n            new GenreRecommendation() { Title = \"blues\", Key = \"blues\" },\n            new GenreRecommendation() { Title = \"classic\", Key = \"classic\" },\n            new GenreRecommendation() { Title = \"drum & bass\", Key = \"drum & bass\" },\n            new GenreRecommendation() { Title = \"dubstep\", Key = \"dubstep\" },\n            new GenreRecommendation() { Title = \"dance\", Key = \"dance\" },\n            new GenreRecommendation() { Title = \"electronic\", Key = \"electronic\" },\n            new GenreRecommendation() { Title = \"folk\", Key = \"folk\" },\n            new GenreRecommendation() { Title = \"funk\", Key = \"funk\" },\n            new GenreRecommendation() { Title = \"grunge\", Key = \"grunge\" },\n            new GenreRecommendation() { Title = \"hard rock\", Key = \"hard rock\" },\n            new GenreRecommendation() { Title = \"hardcore\", Key = \"hardcore\" },\n            new GenreRecommendation() { Title = \"hip-hop\", Key = \"hip-hop\" },\n            new GenreRecommendation() { Title = \"house\", Key = \"house\" },\n            new GenreRecommendation() { Title = \"indie rock\", Key = \"indie rock\" },\n            new GenreRecommendation() { Title = \"industrial\", Key = \"industrial\" },\n            new GenreRecommendation() { Title = \"instrumental\", Key = \"instrumental\" },\n            new GenreRecommendation() { Title = \"jazz\", Key = \"jazz\" },\n            new GenreRecommendation() { Title = \"latin\", Key = \"latin\" },\n            new GenreRecommendation() { Title = \"metal\", Key = \"metal\" },\n            new GenreRecommendation() { Title = \"old school\", Key = \"old school\" },\n            new GenreRecommendation() { Title = \"progressive\", Key = \"progressive\" },\n            new GenreRecommendation() { Title = \"pop\", Key = \"pop\" },\n            new GenreRecommendation() { Title = \"punk\", Key = \"punk\" },\n            new GenreRecommendation() { Title = \"r&b\", Key = \"r&b\" },\n            new GenreRecommendation() { Title = \"rap\", Key = \"rap\" },\n            new GenreRecommendation() { Title = \"rap core\", Key = \"rap core\" },\n            new GenreRecommendation() { Title = \"russian rap\", Key = \"russian rap\" },\n            new GenreRecommendation() { Title = \"russian pop\", Key = \"russian pop\" },\n            new GenreRecommendation() { Title = \"reggae\", Key = \"reggae\" },\n            new GenreRecommendation() { Title = \"rock\", Key = \"rock\" },\n            new GenreRecommendation() { Title = \"soul\", Key = \"soul\" },\n            new GenreRecommendation() { Title = \"soundtrack\", Key = \"soundtrack\" },\n            new GenreRecommendation() { Title = \"trip-hop\", Key = \"trip-hop\" },\n            new GenreRecommendation() { Title = \"trance\", Key = \"trance\" },\n            new GenreRecommendation() { Title = \"underground\", Key = \"underground\" },\n        };\n\n        #endregion\n\n        private Recommendation _selectedRecommendation;\n        private int _selectedRecommendationIndex;\n        private ObservableCollection<Audio> _tracks;\n        private CancellationTokenSource _cancellationToken;\n\n        #region Commands\n\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        public RelayCommand RefreshCommand { get; private set; }\n\n        #endregion\n\n        public RecommendationsCollection RecommendationsCollection\n        {\n            get { return _recommendationsCollection; }\n        }\n\n        public Recommendation SelectedRecommendation\n        {\n            get { return _selectedRecommendation; }\n            set\n            {\n                if (Set(ref _selectedRecommendation, value))\n                {\n                    CancelAsync();\n\n                    if (value.Group != MainResources.RecommendationsMusicGroup)\n                        LoadRecommendationsByTag(value.Key, _cancellationToken.Token);\n                    else\n                    {\n                        LoadGeneralRecommendations(_cancellationToken.Token);\n                    }\n                }\n            }\n        }\n\n        public int SelectedRecommendationIndex\n        {\n            get { return _selectedRecommendationIndex; }\n            set { Set(ref _selectedRecommendationIndex, value); }\n        }\n\n        public ObservableCollection<Audio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public RecommendationsViewModel()\n        {\n            _cancellationToken = new CancellationTokenSource();\n\n            RegisterTasks(\"audio\");\n\n            InitializeCommands();\n        }\n\n        public void Activate()\n        {\n            //LoadGeneralRecommendations(new CancellationToken());\n        }\n\n        public void Deactivate()\n        {\n            CancelAsync();\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n                AudioService.SetCurrentPlaylist(Tracks);\n            });\n\n            RefreshCommand = new RelayCommand(() =>\n            {\n                CancelAsync();\n\n                if (SelectedRecommendation.Group != MainResources.RecommendationsMusicGroup)\n                    LoadRecommendationsByTag(SelectedRecommendation.Key, _cancellationToken.Token);\n                else\n                {\n                    LoadGeneralRecommendations(_cancellationToken.Token);\n                }\n            });\n        }\n\n        private async void LoadGeneralRecommendations(CancellationToken token)\n        {\n            OnTaskStarted(\"audio\");\n\n            Tracks = new ObservableCollection<Audio>();\n\n            try\n            {\n                int offset = 0;\n                const int count = 50;\n                int requestsCount = 0;\n\n                while (Tracks != null && Tracks.Count < MAX_AUDIO_RECOMMENDATIONS)\n                {\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"My recommendations cancelled\");\n                        break;\n                    }\n\n                    var a = await DataService.GetRecommendations();\n                    if (a == null || a.Count == 0)\n                        break;\n\n                    else if (a.Count > 0)\n                    {\n                        OnTaskFinished(\"audio\");\n                    }\n\n                    offset += count;\n\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"My recommendations cancelled\");\n                        break;\n                    }\n\n                    foreach (var audio in a)\n                    {\n                        Tracks.Add(audio);\n                    }\n\n                    requestsCount++;\n\n                    if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                    {\n                        requestsCount = 0;\n                        await Task.Delay(1000);\n                    }\n\n                    Debug.WriteLine(\"Load more recommendations\");\n                }\n\n                if ((Tracks == null || Tracks.Count == 0) && !token.IsCancellationRequested)\n                    OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorEmpty);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            OnTaskFinished(\"audio\");\n        }\n\n        private async void LoadRecommendationsByTag(string tag, CancellationToken token)\n        {\n            OnTaskStarted(\"audio\");\n\n            Tracks = null;\n\n            try\n            {\n                var a = await DataService.GetTagTopTracks(tag, 150);\n\n                if (token.IsCancellationRequested)\n                {\n                    Debug.WriteLine(\"Tag recommendations cancelled\");\n                    return;\n                }\n\n\n                if (a != null && a.Count > 0)\n                {\n                    Tracks = new ObservableCollection<Audio>(a);\n                }\n                else\n                {\n                    OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            OnTaskFinished(\"audio\");\n        }\n\n        private void CancelAsync()\n        {\n            if (_cancellationToken != null)\n                _cancellationToken.Cancel();\n\n            _cancellationToken = new CancellationTokenSource();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/MainViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing System.Windows.Interop;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing GalaSoft.MvvmLight.Command;\nusing GongSolutions.Wpf.DragDrop.Utilities;\nusing Meridian.Controls;\nusing Meridian.Domain;\nusing Meridian.Helpers;\nusing Meridian.Model;\nusing Meridian.RemotePlay;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.View;\nusing Meridian.View.Compact;\nusing Meridian.View.Flyouts;\nusing Meridian.ViewModel.Flyouts;\nusing Meridian.ViewModel.Messages;\nusing Neptune.Messages;\nusing Neptune.UI.Extensions;\nusing VkLib.Core.Users;\nusing VkLib.Error;\nusing Yandex.Metrica;\n\nnamespace Meridian.ViewModel\n{\n    public class MainViewModel : ViewModelBase\n    {\n        private readonly MenuItemsCollection _mainMenuItems = new MenuItemsCollection()\n        {\n            new MainMenuItem() {Group = MainResources.MainMenuLocalTitle, GroupIcon = Application.Current.Resources[\"DeviceIcon\"], Page = \"/Local.LocalCollectionView\", Title =  MainResources.MainMenuCollection},\n            new MainMenuItem() {Group = MainResources.MainMenuLocalTitle, GroupIcon = Application.Current.Resources[\"DeviceIcon\"], Page = \"/Main.NowPlayingView\", Title = MainResources.MainMenuNowPlaying, Icon = Application.Current.Resources[\"NowPlayingIcon\"]},\n\n            new MainMenuItem() {Group = MainResources.MainMenuVkTitle, GroupIcon = Application.Current.Resources[\"VkIcon\"], Page = \"/Main.MusicView\", Title = MainResources.MainMenuMyMusic},\n            new MainMenuItem() {Group = MainResources.MainMenuVkTitle, GroupIcon = Application.Current.Resources[\"VkIcon\"], Page = \"/Main.FeedView\", Title = MainResources.MainMenuFeed},\n            new MainMenuItem() {Group = MainResources.MainMenuVkTitle, GroupIcon = Application.Current.Resources[\"VkIcon\"], Page = \"/Main.PopularAudioView\", Title = MainResources.MainMenuPopular},\n            new MainMenuItem() {Group = MainResources.MainMenuVkTitle, GroupIcon = Application.Current.Resources[\"VkIcon\"], Page = \"/Main.RecommendationsView\", Title = MainResources.MainMenuRecommendations},\n\n            new MainMenuItem() {Group = MainResources.MainMenuVkTitle, GroupIcon = Application.Current.Resources[\"VkIcon\"], Page = \"/People.FriendsView\", Title = MainResources.MainMenuFriends},\n            new MainMenuItem() {Group = MainResources.MainMenuVkTitle, GroupIcon = Application.Current.Resources[\"VkIcon\"], Page = \"/People.SocietiesView\", Title = MainResources.MainMenuSocieties},\n            new MainMenuItem() {Group = MainResources.MainMenuVkTitle, GroupIcon = Application.Current.Resources[\"VkIcon\"], Page = \"/People.SubscriptionsView\", Title = MainResources.MainMenuSubscriptions},\n        };\n\n        private bool _showSidebar;\n        private bool _showShareBar;\n        private bool _showWindowButtons = true;\n        private MainMenuItem _selectedMainMenuItem;\n        private int _selectedMainMenuItemIndex;\n        private WindowState _windowState;\n        private ImageSource _artistImage;\n        private ImageSource _trackImage;\n        private bool _artRequested;\n        private VkProfile _user;\n        private bool _canNavigate = true;\n        private HotKeyManager _hotKeyManager;\n        private bool _statusUpdated;\n        private bool _nowPlayingUpdated;\n        private bool _scrobbled;\n        private UIMode _currentUIMode;\n        private string _lastArtist;\n        private CancellationTokenSource _artCancellationToken = new CancellationTokenSource();\n        private CancellationTokenSource _coverCancellationToken = new CancellationTokenSource();\n\n        #region Commands\n\n        public RelayCommand CloseWindowCommand { get; private set; }\n\n        public RelayCommand MinimizeWindowCommand { get; private set; }\n\n        public RelayCommand MaximizeWindowCommand { get; private set; }\n\n        public RelayCommand<string> GoToPageCommand { get; private set; }\n\n        public RelayCommand GoBackCommand { get; private set; }\n\n        public RelayCommand GoToSettingsCommand { get; private set; }\n\n        public RelayCommand<string> SearchCommand { get; private set; }\n\n        public RelayCommand<KeyEventArgs> SearchKeyUpCommand { get; private set; }\n\n        public RelayCommand NextAudioCommand { get; private set; }\n\n        public RelayCommand PrevAudioCommand { get; private set; }\n\n        public RelayCommand PlayPauseCommand { get; private set; }\n\n        public RelayCommand RestartCommand { get; private set; }\n\n        public RelayCommand SwitchUIModeCommand { get; private set; }\n\n        public RelayCommand<string> SwitchToUIModeCommand { get; private set; }\n\n        public RelayCommand<VkAudio> AddRemoveAudioCommand { get; private set; }\n\n        public RelayCommand<VkAudio> EditAudioCommand { get; private set; }\n\n        public RelayCommand<VkAudio> ShareAudioCommand { get; private set; }\n\n        public RelayCommand<VkAudio> ShowLyricsCommand { get; private set; }\n\n        public RelayCommand<Audio> CopyInfoCommand { get; private set; }\n\n        public RelayCommand<Audio> PlayAudioNextCommand { get; private set; }\n\n        public RelayCommand<Audio> AddToNowPlayingCommand { get; private set; }\n\n        public RelayCommand<Audio> RemoveFromNowPlayingCommand { get; private set; }\n\n        public RelayCommand<string> ShowArtistInfoCommand { get; private set; }\n\n        public RelayCommand<Audio> StartTrackRadioCommand { get; private set; }\n\n        public RelayCommand<VkAudio> AddToAlbumCommand { get; private set; }\n\n        public RelayCommand ShowLocalSearchCommand { get; private set; }\n\n        #endregion\n\n        #region Window\n\n        public WindowState WindowState\n        {\n            get { return _windowState; }\n            set\n            {\n                if (_windowState == value)\n                    return;\n\n                _windowState = value;\n                if (value == WindowState.Maximized)\n                    Settings.Instance.IsWindowMaximized = true;\n                else\n                    Settings.Instance.IsWindowMaximized = false;\n                RaisePropertyChanged(\"WindowState\");\n                RaisePropertyChanged(\"IsWindowMaximized\");\n            }\n        }\n\n        public bool IsWindowMaximized\n        {\n            get { return WindowState == WindowState.Maximized; }\n        }\n\n        public double WindowLeft\n        {\n            get\n            {\n                return Settings.Instance.Left;\n            }\n            set\n            {\n                Settings.Instance.Left = value;\n            }\n        }\n\n        public double WindowTop\n        {\n            get { return Settings.Instance.Top; }\n            set { Settings.Instance.Top = value; }\n        }\n\n        public double WindowWidth\n        {\n            get { return Settings.Instance.Width; }\n            set { Settings.Instance.Width = value; }\n        }\n\n        public double WindowHeight\n        {\n            get { return Settings.Instance.Height; }\n            set\n            {\n                Settings.Instance.Height = value;\n            }\n        }\n\n        public string WindowTitle\n        {\n            get\n            {\n                if (CurrentAudio != null)\n                    return CurrentAudio.Title + \" (\" + CurrentAudio.Artist + \")\";\n                else\n                    return \"Meridian\";\n            }\n        }\n\n        #endregion\n\n        public bool CanGoBack\n        {\n            get\n            {\n                var frame = Application.Current.MainWindow.GetVisualDescendents().OfType<Frame>().FirstOrDefault();\n                if (frame == null)\n                    return false;\n                return frame.CanGoBack;\n            }\n        }\n\n        public MenuItemsCollection MainMenuItems\n        {\n            get { return _mainMenuItems; }\n        }\n\n        public bool ShowSidebar\n        {\n            get\n            {\n                if (IsInDesignMode)\n                    return true;\n                return _showSidebar;\n            }\n            set\n            {\n                Set(ref _showSidebar, value);\n            }\n        }\n\n        public bool ShowShareBar\n        {\n            get\n            {\n                return _showShareBar;\n            }\n            set\n            {\n                Set(ref _showShareBar, value);\n            }\n        }\n\n\n        public bool ShowWindowButtons\n        {\n            get\n            {\n                return _showWindowButtons;\n            }\n            set\n            {\n                Set(ref _showWindowButtons, value);\n            }\n        }\n\n        public VkProfile User\n        {\n            get { return _user; }\n            set\n            {\n                if (_user == value)\n                    return;\n\n                _user = value;\n                RaisePropertyChanged(\"User\");\n            }\n        }\n\n        public string LastFmUser\n        {\n            get { return Settings.Instance.LastFmUsername; }\n            set\n            {\n                if (Settings.Instance.LastFmUsername == value)\n                    return;\n\n                Settings.Instance.LastFmUsername = value;\n                RaisePropertyChanged(\"LastFmUser\");\n            }\n        }\n\n        public MainMenuItem SelectedMainMenuItem\n        {\n            get { return _selectedMainMenuItem; }\n            set\n            {\n                if (Set(ref _selectedMainMenuItem, value) && value != null && _canNavigate)\n                    OnNavigateToPage(new NavigateToPageMessage() { Page = value.Page });\n            }\n        }\n\n        public int SelectedMainMenuItemIndex\n        {\n            get\n            {\n                return _selectedMainMenuItemIndex;\n            }\n            set\n            {\n                Set(ref _selectedMainMenuItemIndex, value);\n            }\n        }\n\n        public Audio CurrentAudio\n        {\n            get\n            {\n                if (!IsInDesignMode)\n                    return AudioService.CurrentAudio;\n                else\n                {\n                    var a = new Audio() { Artist = \"Artist\", Title = \"Title\" };\n                    return a;\n                }\n            }\n        }\n\n        public TimeSpan CurrentAudioPosition\n        {\n            get\n            {\n                if (IsInDesignMode)\n                    return TimeSpan.Zero;\n                return AudioService.CurrentAudioPosition;\n            }\n        }\n\n        public double CurrentAudioPositionSeconds\n        {\n            get\n            {\n                if (IsInDesignMode)\n                    return 0;\n                return AudioService.CurrentAudioPosition.TotalSeconds;\n            }\n            set\n            {\n                AudioService.CurrentAudioPosition = TimeSpan.FromSeconds(value);\n            }\n        }\n\n        public TimeSpan CurrentAudioDuration\n        {\n            get\n            {\n                if (AudioService.CurrentAudioDuration == TimeSpan.Zero)\n                    return TimeSpan.FromMilliseconds(1000);\n                return AudioService.CurrentAudioDuration;\n            }\n        }\n\n        public bool IsPlaying\n        {\n            get { return AudioService.IsPlaying; }\n            set\n            {\n                //leave empty, used to avoid binding errors\n            }\n        }\n\n        public bool Shuffle\n        {\n            get { return AudioService.Shuffle; }\n            set\n            {\n                if (AudioService.Shuffle == value)\n                    return;\n\n                AudioService.Shuffle = value;\n                RaisePropertyChanged(\"Shuffle\");\n            }\n        }\n\n        public bool Repeat\n        {\n            get { return AudioService.Repeat; }\n            set\n            {\n                if (AudioService.Repeat == value)\n                    return;\n\n                AudioService.Repeat = value;\n                RaisePropertyChanged(\"Repeat\");\n            }\n        }\n\n        public float Volume\n        {\n            get { return (float)Math.Round(AudioService.Volume * 100.0f); }\n            set\n            {\n                if (AudioService.Volume * 100 == value)\n                    return;\n\n                AudioService.Volume = value / 100;\n                RaisePropertyChanged(\"Volume\");\n            }\n        }\n\n        public IList<Audio> CurrentPlaylist\n        {\n            get { return AudioService.Playlist; }\n        }\n\n        public ImageSource ArtistImage\n        {\n            get { return _artistImage; }\n            set { Set(ref _artistImage, value); }\n        }\n\n        public ImageSource TrackImage\n        {\n            get { return _trackImage; }\n            set { Set(ref _trackImage, value); }\n        }\n\n        public HotKeyManager HotKeyManager\n        {\n            get { return _hotKeyManager; }\n        }\n\n        public bool EnableStatusBroadcasting\n        {\n            get { return Settings.Instance.EnableStatusBroadcasting; }\n            set\n            {\n                if (Settings.Instance.EnableStatusBroadcasting == value)\n                    return;\n\n                Settings.Instance.EnableStatusBroadcasting = value;\n                if (!value)\n                {\n                    DataService.SetMusicStatus(null);\n                    _statusUpdated = false;\n                }\n                RaisePropertyChanged(\"EnableStatusBroadcasting\");\n            }\n        }\n\n        public bool EnableScrobbling\n        {\n            get { return Settings.Instance.EnableScrobbling; }\n            set\n            {\n                if (Settings.Instance.EnableScrobbling == value)\n                    return;\n\n                if (value && !AccountManager.IsLoggedInLastFm())\n                {\n                    var flyout = new FlyoutControl();\n                    flyout.FlyoutContent = new LoginLastFmMessageView();\n                    flyout.Show();\n                }\n                else\n                {\n                    Settings.Instance.EnableScrobbling = value;\n\n                    RaisePropertyChanged(\"EnableScrobbling\");\n                }\n            }\n        }\n\n        public UIMode CurrentUIMode\n        {\n            get { return _currentUIMode; }\n            set { Set(ref _currentUIMode, value); }\n        }\n\n        public bool ShowTrayIcon\n        {\n            get { return Settings.Instance.EnableTrayIcon; }\n        }\n\n        public bool ShowBackgroundArt\n        {\n            get { return Settings.Instance.ShowBackgroundArt; }\n            set\n            {\n                if (Settings.Instance.ShowBackgroundArt == value)\n                    return;\n\n                Settings.Instance.ShowBackgroundArt = value;\n                RaisePropertyChanged(\"ShowBackgroundArt\");\n            }\n        }\n\n        public bool ShowBackgroundArtCompactMode\n        {\n            get { return Settings.Instance.ShowBackgroundArtCompactMode; }\n            set\n            {\n                if (Settings.Instance.ShowBackgroundArtCompactMode == value)\n                    return;\n\n                Settings.Instance.ShowBackgroundArtCompactMode = value;\n                RaisePropertyChanged(\"ShowBackgroundArtCompactMode\");\n            }\n        }\n\n        public bool CanBroadcast\n        {\n            get { return CurrentAudio is VkAudio; }\n        }\n\n        public MainViewModel()\n        {\n            InitializeCommands();\n            InitializeMessageInterception();\n        }\n\n        public void Initialize()\n        {\n            WindowState = Settings.Instance.IsWindowMaximized\n                              ? WindowState.Maximized\n                              : WindowState.Normal;\n\n            _hotKeyManager = new HotKeyManager(new WindowInteropHelper(Application.Current.MainWindow).Handle);\n            _hotKeyManager.InitializeHotkeys();\n            ViewModelLocator.LastFm.SessionKey = Settings.Instance.LastFmSession;\n\n            if (Settings.Instance.EnableRemotePlay)\n                RemotePlayService.Instance.Start();\n        }\n\n        public async void LoadUserInfo()\n        {\n            try\n            {\n                User = await DataService.GetUserInfo();\n\n                //Track user for stats\n                await ViewModelLocator.Vkontakte.Stats.TrackVisitor();\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private void InitializeCommands()\n        {\n            CloseWindowCommand = new RelayCommand(() => Application.Current.MainWindow.Close());\n\n            MinimizeWindowCommand = new RelayCommand(() => WindowState = WindowState.Minimized);\n\n            MaximizeWindowCommand = new RelayCommand(() => WindowState = IsWindowMaximized ? WindowState.Normal : WindowState.Maximized);\n\n            GoToPageCommand = new RelayCommand<string>(page => OnNavigateToPage(new NavigateToPageMessage() { Page = page }));\n\n            GoToSettingsCommand = new RelayCommand(() =>\n            {\n                OnNavigateToPage(new NavigateToPageMessage() { Page = \"/Settings.SettingsView\" });\n                ShowSidebar = false;\n            });\n\n            PrevAudioCommand = new RelayCommand(AudioService.Prev);\n\n            NextAudioCommand = new RelayCommand(AudioService.SkipNext);\n\n            PlayPauseCommand = new RelayCommand(() =>\n            {\n                if (IsPlaying)\n                    AudioService.Pause();\n                else\n                    AudioService.Play();\n            });\n\n            GoBackCommand = new RelayCommand(() =>\n            {\n                var frame = Application.Current.MainWindow.GetVisualDescendents().OfType<Frame>().FirstOrDefault(f => f.Name == \"RootFrame\");\n                if (frame == null)\n                    return;\n\n                if (frame.CanGoBack)\n                    frame.GoBack();\n\n                UpdateCanGoBack();\n            });\n\n            SearchCommand = new RelayCommand<string>(query =>\n            {\n                if (!string.IsNullOrWhiteSpace(query))\n                {\n                    MessengerInstance.Send(new NavigateToPageMessage()\n                    {\n                        Page = \"/Search.SearchResultsView\",\n                        Parameters = new Dictionary<string, object>()\n                                {\n                                    {\"query\", query}\n                                }\n                    });\n                }\n            });\n\n            SearchKeyUpCommand = new RelayCommand<KeyEventArgs>(args =>\n            {\n                if (args.Key == Key.Enter)\n                {\n                    var textBox = args.Source as TextBox;\n                    if (textBox != null && !string.IsNullOrWhiteSpace(textBox.Text))\n                        SearchCommand.Execute(textBox.Text);\n                }\n            });\n\n            RestartCommand = new RelayCommand(() =>\n            {\n                Process.Start(Application.ResourceAssembly.Location);\n                Application.Current.Shutdown();\n            });\n\n            AddRemoveAudioCommand = new RelayCommand<VkAudio>(audio =>\n            {\n                audio.IsAddedByCurrentUser = !audio.IsAddedByCurrentUser;\n                LikeDislikeAudio(audio);\n            });\n\n            EditAudioCommand = new RelayCommand<VkAudio>(audio =>\n            {\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new EditAudioView(audio);\n                flyout.Show();\n            });\n\n            ShowLyricsCommand = new RelayCommand<VkAudio>(audio =>\n            {\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new LyricsView(audio);\n                flyout.Show();\n            });\n\n            CopyInfoCommand = new RelayCommand<Audio>(audio =>\n            {\n                if (audio == null)\n                    return;\n\n                try\n                {\n                    Clipboard.SetData(DataFormats.UnicodeText, audio.Artist + \" - \" + audio.Title);\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n            });\n\n            PlayAudioNextCommand = new RelayCommand<Audio>(track =>\n            {\n                AudioService.PlayNext(track);\n            });\n\n            AddToNowPlayingCommand = new RelayCommand<Audio>(track =>\n            {\n                NotificationService.Notify(MainResources.NotificationAddedToNowPlaying);\n                AudioService.Playlist.Add(track);\n            });\n\n            RemoveFromNowPlayingCommand = new RelayCommand<Audio>(track =>\n            {\n                AudioService.Playlist.Remove(track);\n            });\n\n            ShareAudioCommand = new RelayCommand<VkAudio>(audio =>\n            {\n                ShowShareBar = true;\n\n                //костыль #2\n                var shareControl = Application.Current.MainWindow.GetVisualDescendent<ShareBarControl>();\n                if (shareControl == null)\n                    return;\n\n                var shareViewModel = ((ShareViewModel)((FrameworkElement)shareControl.Content).DataContext);\n                shareViewModel.Tracks.Add(audio);\n            });\n\n            SwitchUIModeCommand = new RelayCommand(() =>\n            {\n                if (CurrentUIMode == UIMode.Normal)\n                    SwitchUIMode(Settings.Instance.LastCompactMode == UIMode.CompactLandscape ? UIMode.CompactLandscape : UIMode.Compact);\n                else\n                    SwitchUIMode(UIMode.Normal);\n            });\n\n            SwitchToUIModeCommand = new RelayCommand<string>(s =>\n            {\n                UIMode mode;\n                if (Enum.TryParse(s, true, out mode))\n                    SwitchUIMode(mode);\n            });\n\n            ShowArtistInfoCommand = new RelayCommand<string>(async artist =>\n            {\n                NotificationService.Notify(MainResources.NotificationLookingArtist);\n\n                try\n                {\n                    var response = await DataService.GetArtistInfo(null, artist);\n                    if (response != null)\n                    {\n                        MessengerInstance.Send(new NavigateToPageMessage()\n                        {\n                            Page = \"/Search.ArtistView\",\n                            Parameters = new Dictionary<string, object>()\n                            {\n                                {\"artist\", response}\n                            }\n                        });\n                    }\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                    NotificationService.Notify(MainResources.NotificationArtistNotFound);\n                }\n            });\n\n            ShowLocalSearchCommand = new RelayCommand(() =>\n            {\n                var frame = Application.Current.MainWindow.GetVisualDescendents().OfType<Frame>().FirstOrDefault();\n                if (frame == null)\n                    return;\n\n                var page = (Page)frame.Content;\n                if (page != null)\n                {\n                    var localSearchBox = page.GetVisualDescendents().OfType<LocalSearchControl>().FirstOrDefault();\n                    if (localSearchBox != null)\n                        localSearchBox.IsActive = true;\n                }\n            });\n\n            AddToAlbumCommand = new RelayCommand<VkAudio>(track =>\n            {\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new AddToAlbumView(track);\n                flyout.Show();\n            });\n        }\n\n        private void InitializeMessageInterception()\n        {\n            MessengerInstance.Register<NavigateToPageMessage>(this, OnNavigateToPage);\n            MessengerInstance.Register<LoginMessage>(this, OnLoginMessage);\n            MessengerInstance.Register<CurrentAudioChangedMessage>(this, OnCurrentAudioChanged);\n            MessengerInstance.Register<PlayerPositionChangedMessage>(this, OnPlayerPositionChanged);\n            MessengerInstance.Register<PlayStateChangedMessage>(this, OnPlayStateChanged);\n        }\n\n        private void OnNavigateToPage(NavigateToPageMessage message)\n        {\n            Type type = Type.GetType(\"Meridian.View.\" + message.Page.Substring(1), false);\n            if (type == null)\n            {\n                if (Debugger.IsAttached)\n                    Debugger.Break();\n                return;\n            }\n\n            var frame = Application.Current.MainWindow.GetVisualDescendents().OfType<Frame>().FirstOrDefault();\n            if (frame == null)\n                return;\n\n            if (Settings.Instance.SendStats)\n                YandexMetrica.ReportEvent(\"page\" + message.Page);\n\n            if (typeof(Layout.PageBase).IsAssignableFrom(type))\n            {\n                var page = (Layout.PageBase)Activator.CreateInstance(type);\n                page.NavigationContext.Parameters = message.Parameters;\n                frame.Navigate(page);\n            }\n            else if (typeof(PageBase).IsAssignableFrom(type))\n            {\n                var page = (PageBase)Activator.CreateInstance(type);\n                page.NavigationContext.Parameters = message.Parameters;\n                frame.Navigate(page);\n            }\n            else if (typeof(Page).IsAssignableFrom(type))\n            {\n                frame.Navigate(Activator.CreateInstance(type));\n            }\n\n            UpdateCanGoBack();\n        }\n\n        private void OnLoginMessage(LoginMessage message)\n        {\n            if (message.Type == LoginType.LogIn)\n            {\n                if (message.Service == \"vk\")\n                {\n                    ShowSidebar = true;\n                    LoadUserInfo();\n                }\n\n                if (message.Service == \"lastfm\")\n                    RaisePropertyChanged(\"LastFmUser\");\n            }\n            else if (message.Type == LoginType.LogOut)\n            {\n                if (message.Service == \"lastfm\")\n                    RaisePropertyChanged(\"LastFmUser\");\n            }\n        }\n\n        private void OnCurrentAudioChanged(CurrentAudioChangedMessage message)\n        {\n            RaisePropertyChanged(\"CurrentAudio\");\n            RaisePropertyChanged(\"IsPlaying\");\n            RaisePropertyChanged(\"CurrentPlaylist\");\n            RaisePropertyChanged(\"WindowTitle\");\n            RaisePropertyChanged(\"CanBroadcast\");\n\n            _artRequested = false;\n            _statusUpdated = false;\n            _nowPlayingUpdated = false;\n            _scrobbled = false;\n\n            CancelCover();\n            GetTrackImage(_coverCancellationToken.Token);\n\n            if (Settings.Instance.ShowTrackNotifications && message.OldAudio != null)\n                //disable show on first start by checking for null\n            {\n                Application.Current.Dispatcher.BeginInvoke(new Action(() =>\n                {\n                    ShowTrackNotification(message.NewAudio);\n                }));\n            }\n        }\n\n        private async void OnPlayerPositionChanged(PlayerPositionChangedMessage message)\n        {\n            RaisePropertyChanged(\"CurrentAudioPosition\");\n            RaisePropertyChanged(\"CurrentAudioPositionSeconds\");\n            RaisePropertyChanged(\"CurrentAudioDuration\");\n\n\n            if (message.NewPosition.TotalSeconds >= 3)\n            {\n                if (!_statusUpdated)\n                {\n                    if (Settings.Instance.EnableStatusBroadcasting)\n                    {\n                        _statusUpdated = true;\n\n                        try\n                        {\n                            await DataService.SetMusicStatus(CurrentAudio as VkAudio);\n                        }\n                        catch (VkAccessDeniedException ex)\n                        {\n                            //ViewModelLocator.AuthService.LogOutVk();\n                            LoggingService.Log(ex);\n                        }\n                        catch (VkStatusBroadcastDisabledException ex)\n                        {\n                            LoggingService.Log(ex);\n                        }\n                        catch (Exception ex)\n                        {\n                            LoggingService.Log(ex);\n                        }\n                    }\n                }\n\n                if (!_nowPlayingUpdated && EnableScrobbling)\n                {\n                    _nowPlayingUpdated = true;\n\n                    try\n                    {\n                        await DataService.UpdateNowPlaying(CurrentAudio);\n                    }\n                    catch (Exception ex)\n                    {\n                        Debug.WriteLine(ex);\n                    }\n                }\n\n                if (!_artRequested)\n                {\n                    CancelArt();\n                    _artRequested = true;\n                    GetArtistImage(_artCancellationToken.Token);\n                }\n            }\n\n            if (CurrentAudio != null && message.NewPosition.TotalSeconds >= CurrentAudio.Duration.TotalSeconds / 3)\n            {\n                if (!_scrobbled && EnableScrobbling)\n                {\n                    _scrobbled = true;\n                    try\n                    {\n                        await DataService.Scrobble(CurrentAudio);\n                    }\n                    catch (Exception ex)\n                    {\n                        Debug.WriteLine(ex);\n                    }\n                }\n            }\n        }\n\n        private void OnPlayStateChanged(PlayStateChangedMessage message)\n        {\n            RaisePropertyChanged(\"IsPlaying\");\n        }\n\n        public void UpdateCanGoBack()\n        {\n            RaisePropertyChanged(\"CanGoBack\");\n\n\n            var frame = Application.Current.MainWindow.GetVisualDescendents().OfType<Frame>().FirstOrDefault(f => f.Name == \"RootFrame\");\n            if (frame != null && frame.Content != null)\n            {\n                var source = frame.Content.GetType().Name;\n                _canNavigate = false;\n                SelectedMainMenuItemIndex = _mainMenuItems.IndexOf(_mainMenuItems.FirstOrDefault(t => t.Page.EndsWith(source)));\n                _canNavigate = true;\n            }\n        }\n\n        private async void GetArtistImage(CancellationToken token)\n        {\n            if (CurrentAudio == null)\n                return;\n\n            if (CurrentAudio.Artist == _lastArtist)\n                return;\n\n            _lastArtist = CurrentAudio.Artist;\n            string imageType = Settings.Instance.ShowBackgroundArt ? \"big\" : \"medium\";\n\n            try\n            {\n                var cachedImage = await CacheService.GetCachedImage(\"artists/\" + CacheService.GetSafeFileName(CurrentAudio.Artist + \"_\" + imageType + \".jpg\"));\n                if (cachedImage != null)\n                {\n                    ArtistImage = cachedImage;\n                    return;\n                }\n\n                if (Settings.Instance.DownloadArtistArt)\n                {\n                    var imageUri =\n                        await DataService.GetArtistImage(CurrentAudio.Artist, Settings.Instance.ShowBackgroundArt);\n                    if (imageUri != null)\n                    {\n                        if (token.IsCancellationRequested)\n                            return;\n\n                        cachedImage = await CacheService.CacheImage(imageUri.OriginalString, \"artists/\" + CacheService.GetSafeFileName(CurrentAudio.Artist + \"_\" + imageType + \".jpg\"));\n\n                        if (token.IsCancellationRequested)\n                            return;\n\n                        ArtistImage = cachedImage;\n                        return;\n                    }\n                }\n\n                ArtistImage = null;\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private async void GetTrackImage(CancellationToken token)\n        {\n            if (CurrentAudio == null)\n                return;\n\n            if (CurrentAudio is LocalAudio)\n            {\n                try\n                {\n                    using (var audioFile = TagLib.File.Create(CurrentAudio.Source))\n                    {\n                        var image = audioFile.Tag.Pictures.FirstOrDefault();\n                        if (image != null)\n                        {\n                            var ms = new MemoryStream();\n                            await ms.WriteAsync(image.Data.Data, 0, image.Data.Data.Length, token);\n                            if (token.IsCancellationRequested)\n                                return;\n\n                            ms.Seek(0, SeekOrigin.Begin);\n\n                            BitmapImage bi = null;\n                            bi = new BitmapImage();\n                            bi.BeginInit();\n                            bi.StreamSource = ms;\n                            bi.EndInit();\n                            TrackImage = bi;\n                            return;\n                        }\n                    }\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n            }\n\n            if (Settings.Instance.DownloadAlbumArt)\n            {\n                try\n                {\n                    var artist = CurrentAudio.Artist;\n                    var title = CurrentAudio.Title;\n\n                    Uri imageUri = null;\n\n                    if (CurrentAudio.AlbumCover != null)\n                        imageUri = CurrentAudio.AlbumCover;\n                    else\n                    {\n                        imageUri = await DataService.GetTrackImage(artist, title);\n                        if (token.IsCancellationRequested)\n                            return;\n\n                        if (imageUri == null)\n                        {\n                            if (Settings.Instance.DownloadArtistArt)\n                            {\n                                imageUri = await DataService.GetArtistImage(artist, Settings.Instance.ShowBackgroundArt);\n\n                                if (token.IsCancellationRequested)\n                                    return;\n                            }\n                        }\n                    }\n\n                    if (imageUri == null)\n                    {\n                        TrackImage = null;\n                        return;\n                    }\n\n                    //http://stackoverflow.com/questions/11326528/error-hresult-0x88982f72-when-trying-streaming-image-file\n                    var bi = new BitmapImage();\n                    bi.BeginInit();\n                    bi.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;\n                    bi.UriSource = imageUri;\n                    bi.EndInit();\n\n\n                    TrackImage = bi;\n                }\n                catch (Exception ex)\n                {\n\n                    LoggingService.Log(ex);\n                }\n            }\n            else\n            {\n                TrackImage = null;\n            }\n        }\n\n        private async Task LikeDislikeAudio(VkAudio audio, bool captchaNeeded = false, string captchaSid = null, string captchaImg = null)\n        {\n            if (audio == null)\n                return;\n\n            IsWorking = true;\n\n            string captchaKey = null;\n            if (captchaNeeded)\n            {\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new CaptchaRequestView(captchaSid, captchaImg);\n                var result = await flyout.ShowAsync();\n                if (string.IsNullOrEmpty((string)result))\n                {\n                    IsWorking = false;\n                    return;\n                }\n                else\n                {\n                    captchaKey = (string)result;\n                }\n            }\n\n            try\n            {\n                bool result;\n\n                if (!audio.IsAddedByCurrentUser)\n                {\n                    result = await DataService.RemoveAudio(audio);\n                }\n                else\n                    result = await DataService.AddAudio(audio, captchaSid, captchaKey);\n\n                if (result)\n                {\n                    //нужно, чтобы обновить список треков пользователя, если он открыт в данный момент\n                    MessengerInstance.Send(new UserTracksChangedMessage());\n                }\n                else\n                {\n                    audio.IsAddedByCurrentUser = !audio.IsAddedByCurrentUser;\n                    LoggingService.Log(\"Can't add/remove audio \" + audio.Id + \" owner: \" + audio.OwnerId + \".\");\n                }\n            }\n            catch (VkCaptchaNeededException ex)\n            {\n                LikeDislikeAudio(audio, true, ex.CaptchaSid, ex.CaptchaImg);\n            }\n            catch (Exception ex)\n            {\n                audio.IsAddedByCurrentUser = !audio.IsAddedByCurrentUser;\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n        private void ShowTrackNotification(Audio track)\n        {\n            if (track == null)\n                return;\n\n            Window w;\n\n            if (CurrentUIMode == UIMode.Normal)\n                w = Application.Current.MainWindow;\n            else\n            {\n                var t = CurrentUIMode == UIMode.CompactLandscape ? typeof(CompactLandscapeView) : typeof(CompactView);\n                w = CurrentUIMode == UIMode.CompactLandscape\n                    ? (Window)Application.Current.Windows.OfType<CompactLandscapeView>().FirstOrDefault()\n                    : (Window)Application.Current.Windows.OfType<CompactView>().FirstOrDefault();\n            }\n\n            if (w == null)\n                return;\n\n            if (w.IsActive &&\n                w.WindowState != WindowState.Minimized)\n                return;\n\n            var notificationView = Application.Current.Windows.OfType<TrackNotifcationView>().FirstOrDefault();\n            if (notificationView == null)\n            {\n                notificationView = new TrackNotifcationView(track);\n                notificationView.Show();\n            }\n            else\n            {\n                notificationView.Track = track;\n            }\n        }\n\n        private void SwitchUIMode(UIMode mode)\n        {\n            switch (mode)\n            {\n                case UIMode.Compact:\n                    foreach (var window in Application.Current.Windows)\n                    {\n                        if (window is CompactLandscapeView)\n                        {\n                            ((Window)window).Close();\n                        }\n                    }\n\n                    Application.Current.MainWindow.Hide();\n\n                    var compactView = new CompactView();\n                    compactView.Show();\n\n                    Settings.Instance.LastCompactMode = UIMode.Compact;\n                    Settings.Instance.Save();\n                    break;\n\n                case UIMode.CompactLandscape:\n                    foreach (var window in Application.Current.Windows)\n                    {\n                        if (window is CompactView)\n                        {\n                            ((Window)window).Close();\n                        }\n                    }\n\n                    Application.Current.MainWindow.Hide();\n\n                    var compactLandscapeView = new CompactLandscapeView();\n                    compactLandscapeView.Show();\n                    Settings.Instance.LastCompactMode = UIMode.CompactLandscape;\n                    Settings.Instance.Save();\n                    break;\n\n                default:\n                    foreach (var window in Application.Current.Windows)\n                    {\n                        if (window is CompactLandscapeView || window is CompactView)\n                        {\n                            ((Window)window).Close();\n                        }\n                    }\n\n                    Application.Current.MainWindow.Show();\n                    break;\n            }\n\n            CurrentUIMode = mode;\n        }\n\n        private void CancelArt()\n        {\n            _artCancellationToken.Cancel();\n            _artCancellationToken = new CancellationTokenSource();\n        }\n\n        private void CancelCover()\n        {\n            _coverCancellationToken.Cancel();\n            _coverCancellationToken = new CancellationTokenSource();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Messages/CurrentAudioChangedMessage.cs",
    "content": "﻿using Meridian.Model;\n\nnamespace Meridian.ViewModel.Messages\n{\n    public class CurrentAudioChangedMessage\n    {\n        public Audio OldAudio { get; set; }\n\n        public Audio NewAudio { get; set; }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Messages/LocalRepositoryUpdatedMessage.cs",
    "content": "﻿using System;\n\nnamespace Meridian.ViewModel.Messages\n{\n    public class LocalRepositoryUpdatedMessage\n    {\n        public Type RepositoryType { get; set; }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Messages/LoginMessage.cs",
    "content": "﻿namespace Meridian.ViewModel.Messages\n{\n    public enum LoginType\n    {\n        LogIn,\n        LogOut\n    }\n\n    public class LoginMessage\n    {\n        public LoginType Type { get; set; }\n\n        public string Service { get; set; }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Messages/PlayStateChangedMessage.cs",
    "content": "﻿namespace Meridian.ViewModel.Messages\n{\n    public enum PlayerPlayState\n    {\n        Opening,\n        Playing,\n        Paused,\n        Stopped,\n        Buffering\n    }\n\n    public class PlayStateChangedMessage\n    {\n        public PlayerPlayState NewState { get; set; }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Messages/PlayerPositionChangedMessage.cs",
    "content": "﻿using System;\n\nnamespace Meridian.ViewModel.Messages\n{\n    public class PlayerPositionChangedMessage\n    {\n        public TimeSpan NewPosition { get; set; }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Messages/UserTracksChangedMessage.cs",
    "content": "﻿namespace Meridian.ViewModel.Messages\n{\n    public class UserTracksChangedMessage\n    {\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/People/FriendAudioViewModel.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing VkLib.Core.Audio;\nusing VkLib.Core.Users;\nusing VkLib.Error;\n\nnamespace Meridian.ViewModel.People\n{\n    public class FriendAudioViewModel : ViewModelBase\n    {\n        private const int MAX_WALL_AUDIOS = 100;\n\n        private VkProfile _selectedFriend;\n        private ObservableCollection<Audio> _tracks;\n        private ObservableCollection<VkPlaylist> _albums;\n        private VkPlaylist _selectedAlbum;\n        private CancellationTokenSource _cancellationToken;\n        private int _totalAlbumsCount;\n\n        #region Commands\n\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        public RelayCommand LoadMoreAlbumsCommand { get; private set; }\n\n        public RelayCommand RefreshCommand { get; private set; }\n\n        public RelayCommand<VkAudioAlbum> PlayAlbumCommand { get; private set; }\n\n        public RelayCommand<VkAudioAlbum> AddAlbumToNowPlayingCommand { get; private set; }\n\n        public RelayCommand<VkAudioAlbum> CopyAlbumCommand { get; private set; } \n\n        #endregion\n\n        public VkProfile SelectedFriend\n        {\n            get { return _selectedFriend; }\n            set { Set(ref _selectedFriend, value); }\n        }\n\n        public ObservableCollection<VkPlaylist> Albums\n        {\n            get { return _albums; }\n            set { Set(ref _albums, value); }\n        }\n\n        public ObservableCollection<Audio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public VkPlaylist SelectedAlbum\n        {\n            get { return _selectedAlbum; }\n            set\n            {\n                if (Set(ref _selectedAlbum, value))\n                {\n                    CancelAsync();\n\n                    if (value != null)\n                    {\n                        switch ((int)value.Id)\n                        {\n                            case -101:\n                                LoadWallAudios(_cancellationToken.Token);\n                                break;\n                            default:\n                                LoadTracks(_cancellationToken.Token);\n                                break;\n                        }\n                    }\n                }\n            }\n        }\n\n        public async void Activate()\n        {\n            await LoadAlbums();\n        }\n\n        public void Deactivate()\n        {\n            CancelAsync();\n        }\n\n        public FriendAudioViewModel()\n        {\n            _cancellationToken = new CancellationTokenSource();\n\n            RegisterTasks(\"audio\", \"albums\");\n\n            InitializeCommands();\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n                AudioService.SetCurrentPlaylist(Tracks);\n            });\n\n            LoadMoreAlbumsCommand = new RelayCommand(() => LoadMoreAlbums());\n\n            RefreshCommand = new RelayCommand(() => LoadTracks(_cancellationToken.Token));\n\n            PlayAlbumCommand = new RelayCommand<VkAudioAlbum>(PlayAlbum);\n\n            AddAlbumToNowPlayingCommand = new RelayCommand<VkAudioAlbum>(AddAlbumToNowPlaying);\n\n            CopyAlbumCommand = new RelayCommand<VkAudioAlbum>(CopyAlbum);\n        }\n\n        private async Task LoadAlbums()\n        {\n            OnTaskStarted(\"albums\");\n\n            try\n            {\n                var response = await DataService.GetUserAlbums(SelectedFriend.Id, 0, 0);\n\n                var albums = response.Items;\n\n                _totalAlbumsCount = response.TotalCount;\n\n                if (albums == null)\n                    albums = new List<VkPlaylist>();\n\n                albums.Insert(0, new VkPlaylist() { Id = -1, Title = MainResources.MyMusicAllTracks });\n                albums.Insert(1, new VkPlaylist() { Id = -101, Title = MainResources.MyMusicWall });\n                albums.Insert(2, new VkPlaylist() { Id = int.MinValue }); //separator\n\n                Albums = new ObservableCollection<VkPlaylist>(albums);\n\n                SelectedAlbum = albums.First();\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"albums\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            OnTaskFinished(\"albums\");\n        }\n\n        private async Task LoadMoreAlbums()\n        {\n            if (Albums == null || Albums.Count - 3 >= _totalAlbumsCount)\n                return;\n\n            IsWorking = true;\n\n            try\n            {\n                var response = await DataService.GetUserAlbums(SelectedFriend.Id, 0, Albums.Count - 3);\n\n                if (response.Items != null)\n                {\n                    foreach (var album in response.Items)\n                    {\n                        Albums.Add(album);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n        private async void LoadTracks(CancellationToken token)\n        {\n            if (SelectedAlbum == null)\n                return;\n\n            OnTaskStarted(\"audio\");\n\n            try\n            {\n                var response = await DataService.GetUserTracks(0, 0, SelectedAlbum.Id != 0 ? SelectedAlbum.Id : 0, SelectedFriend.Id);\n                if (response.Items != null && response.Items.Count > 0)\n                {\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"Tracks load cancelled\");\n                        return;\n                    }\n\n                    Tracks = new ObservableCollection<Audio>(response.Items);\n\n                    if (AudioService.CurrentAudio == null)\n                    {\n                        AudioService.CurrentAudio = Tracks.First();\n                        AudioService.SetCurrentPlaylist(Tracks);\n                    }\n                }\n                else\n                {\n                    OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorEmpty);\n                }\n            }\n            catch (VkAccessDeniedException ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorAccessDenied);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            OnTaskFinished(\"audio\");\n        }\n\n        private async void LoadWallAudios(CancellationToken token)\n        {\n            IsWorking = true;\n            OnTaskStarted(\"audio\");\n\n            Tracks = new ObservableCollection<Audio>();\n\n            try\n            {\n                int offset = 0;\n                int count = 50;\n                int requestsCount = 0;\n\n                while (Tracks != null && Tracks.Count < MAX_WALL_AUDIOS)\n                {\n                    var a = await DataService.GetWallAudio(count, offset, SelectedFriend.Id, token);\n                    if (a == null || a.Count == 0)\n                        break;\n                    else if (a.Count > 0)\n                    {\n                        OnTaskFinished(\"audio\");\n                    }\n\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"Wall audios cancelled\");\n                        break;\n                    }\n\n                    offset += count;\n\n                    foreach (var audio in a)\n                    {\n                        Tracks.Add(audio);\n                    }\n\n                    requestsCount++;\n\n                    if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                    {\n                        requestsCount = 0;\n                        await Task.Delay(1000, token);\n                    }\n\n                    Debug.WriteLine(\"Loading more audios from wall\");\n                }\n\n                if ((Tracks == null || Tracks.Count == 0) && !token.IsCancellationRequested)\n                    OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorEmpty);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            OnTaskFinished(\"audio\");\n        }\n\n        private async void PlayAlbum(VkAudioAlbum album)\n        {\n            try\n            {\n                var audio = await DataService.GetUserTracks(albumId: album.Id, ownerId: album.OwnerId);\n                if (audio.Items != null && audio.Items.Count > 0)\n                {\n                    AudioService.Play(audio.Items.First());\n                    AudioService.SetCurrentPlaylist(audio.Items);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private async void AddAlbumToNowPlaying(VkAudioAlbum album)\n        {\n            try\n            {\n                var audio = await DataService.GetUserTracks(albumId: album.Id, ownerId: album.OwnerId);\n                if (audio.Items != null && audio.Items.Count > 0)\n                {\n                    foreach (var track in audio.Items)\n                    {\n                        AudioService.Playlist.Add(track);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private async void CopyAlbum(VkAudioAlbum album)\n        {\n            try\n            {\n                await DataService.CopyAlbum(album.Title, album.Id, album.OwnerId);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private void CancelAsync()\n        {\n            if (_cancellationToken != null)\n                _cancellationToken.Cancel();\n\n            _cancellationToken = new CancellationTokenSource();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/People/FriendsViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Neptune.Messages;\nusing VkLib.Core.Users;\n\nnamespace Meridian.ViewModel.People\n{\n    public class FriendsViewModel : ViewModelBase\n    {\n        private List<VkProfile> _friends;\n\n        #region Commands\n\n        public RelayCommand<VkProfile> GoToFriendCommand { get; private set; }\n\n        #endregion\n\n        public List<VkProfile> Friends\n        {\n            get { return _friends; }\n            set { Set(ref _friends, value); }\n        }\n\n        public void Activate()\n        {\n            if (Friends == null || Friends.Count == 0)\n                LoadFriends();\n        }\n\n        public FriendsViewModel()\n        {\n            RegisterTasks(\"friends\");\n\n            InitializeCommands();\n        }\n\n        private void InitializeCommands()\n        {\n            GoToFriendCommand = new RelayCommand<VkProfile>(friend =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/People.FriendAudioView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"friend\", friend}\n                    }\n                });\n            });\n        }\n\n        private async void LoadFriends()\n        {\n            OnTaskStarted(\"friends\");\n\n            try\n            {\n                var friends = await DataService.GetFriends(0, 0, 0, \"photo,photo_100,photo_400_orig\");\n                if (friends.Items != null && friends.Items.Count > 0)\n                {\n                    Friends = friends.Items;\n                }\n                else\n                {\n                    OnTaskError(\"friends\", ErrorResources.LoadFriendsErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"friends\", ErrorResources.LoadFriendsErrorCommon);\n            }\n\n            OnTaskFinished(\"friends\");\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/People/SocietiesViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Neptune.Messages;\nusing VkLib.Core.Groups;\n\nnamespace Meridian.ViewModel.People\n{\n    public class SocietiesViewModel : ViewModelBase\n    {\n        private List<VkGroup> _societies;\n\n        #region\n\n        public RelayCommand<VkGroup> GoToSocietyCommand { get; private set; }\n\n        #endregion\n\n        public List<VkGroup> Societies\n        {\n            get { return _societies; }\n            set\n            {\n                if (_societies == value)\n                    return;\n\n                _societies = value;\n                RaisePropertyChanged(\"Societies\");\n            }\n        }\n\n        public void Activate()\n        {\n            if (Societies == null || Societies.Count == 0)\n                LoadSocieties();\n        }\n\n        public SocietiesViewModel()\n        {\n            RegisterTasks(\"groups\");\n\n            InitializeCommands();\n        }\n\n        private void InitializeCommands()\n        {\n            GoToSocietyCommand = new RelayCommand<VkGroup>(society =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/People.SocietyAudioView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"society\", society}\n                    }\n                });\n            });\n        }\n\n        private async void LoadSocieties()\n        {\n            OnTaskStarted(\"groups\");\n\n            try\n            {\n                var societies = await DataService.GetSocieties(0, 0, 0, \"photo,photo_100\");\n                if (societies.Items != null && societies.Items.Count > 0)\n                {\n                    Societies = societies.Items;\n                }\n                else\n                {\n                    OnTaskError(\"groups\", ErrorResources.LoadSocietiesErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"groups\", ErrorResources.LoadSocietiesErrorCommon);\n\n            }\n\n            OnTaskFinished(\"groups\");\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/People/SocietyAudioViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing VkLib.Core.Audio;\nusing VkLib.Core.Groups;\nusing VkLib.Error;\n\nnamespace Meridian.ViewModel.People\n{\n    public class SocietyAudioViewModel : ViewModelBase\n    {\n        private const int MAX_WALL_AUDIOS = 100;\n\n        private VkGroup _selectedSociety;\n        private ObservableCollection<Audio> _tracks;\n        private ObservableCollection<VkPlaylist> _albums;\n        private VkPlaylist _selectedAlbum;\n        private CancellationTokenSource _cancellationToken;\n        private int _totalAlbumsCount;\n\n        #region Commands\n\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        public RelayCommand LoadMoreAlbumsCommand { get; private set; }\n\n        public RelayCommand RefreshCommand { get; private set; }\n\n        public RelayCommand<VkAudioAlbum> PlayAlbumCommand { get; private set; }\n\n        public RelayCommand<VkAudioAlbum> AddAlbumToNowPlayingCommand { get; private set; }\n\n        public RelayCommand<VkAudioAlbum> CopyAlbumCommand { get; private set; }\n\n        #endregion\n\n        public VkGroup SelectedSociety\n        {\n            get { return _selectedSociety; }\n            set { Set(ref _selectedSociety, value); }\n        }\n\n        public ObservableCollection<VkPlaylist> Albums\n        {\n            get { return _albums; }\n            set { Set(ref _albums, value); }\n        }\n\n        public ObservableCollection<Audio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public VkPlaylist SelectedAlbum\n        {\n            get { return _selectedAlbum; }\n            set\n            {\n                if (Set(ref _selectedAlbum, value))\n                {\n                    CancelAsync();\n\n                    if (value != null)\n                    {\n                        switch ((int)value.Id)\n                        {\n                            case -101:\n                                LoadWallAudios(_cancellationToken.Token);\n                                break;\n                            default:\n                                LoadTracks(_cancellationToken.Token);\n                                break;\n                        }\n                    }\n                }\n            }\n        }\n\n        public async void Activate()\n        {\n            await LoadAlbums();\n        }\n\n        public void Deactivate()\n        {\n            CancelAsync();\n        }\n\n        public SocietyAudioViewModel()\n        {\n            _cancellationToken = new CancellationTokenSource();\n\n            RegisterTasks(\"audio\", \"albums\");\n\n            InitializeCommands();\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n                AudioService.SetCurrentPlaylist(Tracks);\n            });\n\n            LoadMoreAlbumsCommand = new RelayCommand(() => LoadMoreAlbums());\n\n            RefreshCommand = new RelayCommand(() => LoadTracks(_cancellationToken.Token));\n\n            PlayAlbumCommand = new RelayCommand<VkAudioAlbum>(PlayAlbum);\n\n            AddAlbumToNowPlayingCommand = new RelayCommand<VkAudioAlbum>(AddAlbumToNowPlaying);\n\n            CopyAlbumCommand = new RelayCommand<VkAudioAlbum>(CopyAlbum);\n        }\n\n        private async Task LoadAlbums()\n        {\n            OnTaskStarted(\"albums\");\n\n            try\n            {\n                var response = await DataService.GetUserAlbums(-SelectedSociety.Id, 0, 0);\n\n                var albums = response.Items;\n\n                _totalAlbumsCount = response.TotalCount;\n\n                if (albums == null)\n                    albums = new List<VkPlaylist>();\n\n                albums.Insert(0, new VkPlaylist() { Id = -1, Title = MainResources.MyMusicAllTracks });\n                albums.Insert(1, new VkPlaylist() { Id = -101, Title = MainResources.MyMusicWall });\n                albums.Insert(2, new VkPlaylist() { Id = int.MinValue }); //separator\n\n                Albums = new ObservableCollection<VkPlaylist>(albums);\n\n                SelectedAlbum = albums.First();\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"albums\", ErrorResources.LoadAlbumsErrorCommon);\n            }\n\n            OnTaskFinished(\"albums\");\n        }\n\n        private async Task LoadMoreAlbums()\n        {\n            if (Albums == null || Albums.Count - 3 >= _totalAlbumsCount)\n                return;\n\n            IsWorking = true;\n\n            try\n            {\n                var response = await DataService.GetUserAlbums(-SelectedSociety.Id, 0, Albums.Count - 3);\n\n                if (response.Items != null)\n                {\n                    foreach (var album in response.Items)\n                    {\n                        Albums.Add(album);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n\n        private async void LoadTracks(CancellationToken token)\n        {\n            if (SelectedAlbum == null)\n                return;\n\n            OnTaskStarted(\"audio\");\n\n            try\n            {\n                var response =\n                    await\n                        DataService.GetUserTracks(0, 0, SelectedAlbum.Id != 0 ? SelectedAlbum.Id : 0,\n                            -SelectedSociety.Id);\n                if (response.Items != null && response.Items.Count > 0)\n                {\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"Tracks load cancelled\");\n                        return;\n                    }\n\n                    Tracks = new ObservableCollection<Audio>(response.Items);\n\n                    if (AudioService.CurrentAudio == null)\n                    {\n                        AudioService.CurrentAudio = Tracks.First();\n                        AudioService.SetCurrentPlaylist(Tracks);\n                    }\n                }\n                else\n                {\n                    OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorEmpty);\n                }\n            }\n            catch (VkAccessDeniedException ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorAccessDenied);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorCommon);\n            }\n\n            OnTaskFinished(\"audio\");\n        }\n\n        private async void LoadWallAudios(CancellationToken token)\n        {\n            OnTaskStarted(\"audio\");\n\n            Tracks = new ObservableCollection<Audio>();\n\n            try\n            {\n                int offset = 0;\n                int count = 50;\n                int requestsCount = 0;\n\n                while (Tracks != null && Tracks.Count < MAX_WALL_AUDIOS)\n                {\n                    var a = await DataService.GetWallAudio(count, offset, -SelectedSociety.Id, token);\n                    if (a == null || a.Count == 0)\n                        break;\n                    else if (a.Count > 0)\n                    {\n                        OnTaskFinished(\"audio\");\n                    }\n\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"Wall audios cancelled\");\n                        break;\n                    }\n\n                    offset += count;\n\n                    foreach (var audio in a)\n                    {\n                        Tracks.Add(audio);\n                    }\n\n                    requestsCount++;\n\n                    if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                    {\n                        requestsCount = 0;\n                        await Task.Delay(1000, token);\n                    }\n\n                    Debug.WriteLine(\"Loading more audios from wall\");\n                }\n\n                if ((Tracks == null || Tracks.Count == 0) && !token.IsCancellationRequested)\n                    OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorEmpty);\n            }\n            catch (Exception ex)\n            {\n                OnTaskError(\"audio\", ErrorResources.LoadAudiosErrorCommon);\n\n                LoggingService.Log(ex);\n            }\n\n            OnTaskFinished(\"audio\");\n        }\n\n        private void CancelAsync()\n        {\n            if (_cancellationToken != null)\n                _cancellationToken.Cancel();\n\n            _cancellationToken = new CancellationTokenSource();\n        }\n\n        private async void PlayAlbum(VkAudioAlbum album)\n        {\n            try\n            {\n                var audio = await DataService.GetUserTracks(albumId: album.Id, ownerId: -album.OwnerId);\n                if (audio.Items != null && audio.Items.Count > 0)\n                {\n                    AudioService.Play(audio.Items.First());\n                    AudioService.SetCurrentPlaylist(audio.Items);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private async void AddAlbumToNowPlaying(VkAudioAlbum album)\n        {\n            try\n            {\n                var audio = await DataService.GetUserTracks(albumId: album.Id, ownerId: -album.OwnerId);\n                if (audio.Items != null && audio.Items.Count > 0)\n                {\n                    foreach (var track in audio.Items)\n                    {\n                        AudioService.Playlist.Add(track);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n\n        private async void CopyAlbum(VkAudioAlbum album)\n        {\n            try\n            {\n                await DataService.CopyAlbum(album.Title, album.Id, -album.OwnerId);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/People/SubscriptionsViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Neptune.Messages;\nusing VkLib.Core.Users;\n\nnamespace Meridian.ViewModel.People\n{\n    public class SubscriptionsViewModel : ViewModelBase\n    {\n        private List<VkProfile> _subscrptions;\n\n        #region\n\n        public RelayCommand<VkProfile> GoToSubscriptionCommand { get; private set; }\n\n        #endregion\n\n        public List<VkProfile> Subscriptions\n        {\n            get { return _subscrptions; }\n            set\n            {\n                if (_subscrptions == value)\n                    return;\n\n                _subscrptions = value;\n                RaisePropertyChanged(\"Subscriptions\");\n            }\n        }\n\n        public void Activate()\n        {\n            if (Subscriptions == null || Subscriptions.Count == 0)\n                LoadSubscriptions();\n        }\n\n        public SubscriptionsViewModel()\n        {\n            RegisterTasks(\"subscriptions\");\n\n            InitializeCommands();\n        }\n\n        private void InitializeCommands()\n        {\n            GoToSubscriptionCommand = new RelayCommand<VkProfile>(subscription =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/People.FriendAudioView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"friend\", subscription}\n                    }\n                });\n            });\n        }\n\n        private async void LoadSubscriptions()\n        {\n            OnTaskStarted(\"subscriptions\");\n\n            try\n            {\n                var subscriptions = await DataService.GetSubscriptions(0, 0, \"photo,photo_100,photo_400_orig\");\n                if (subscriptions.Items != null && subscriptions.Items.Count > 0)\n                {\n                    Subscriptions = subscriptions.Items;\n                }\n                else\n                {\n                    OnTaskError(\"subscriptions\", ErrorResources.LoadSubscriptionsErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n                OnTaskError(\"subscriptions\", ErrorResources.LoadSubscriptionsErrorCommon);\n            }\n\n            OnTaskFinished(\"subscriptions\");\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Search/AlbumViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows.Media.Imaging;\nusing GalaSoft.MvvmLight.Command;\nusing LastFmLib.Core.Album;\nusing Meridian.Controls;\nusing Meridian.Extensions;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.View.Flyouts;\nusing Meridian.ViewModel.Flyouts;\nusing VkLib.Core.Audio;\nusing VkLib.Error;\nusing VkAudio = Meridian.Model.VkAudio;\n\nnamespace Meridian.ViewModel.Search\n{\n    public class AlbumViewModel : ViewModelBase\n    {\n        private LastFmAlbum _album;\n        private List<VkAudio> _tracks;\n        private ObservableCollection<LastFmAlbum> _artistAlbums;\n        private int _selectedAlbumIndex = -1;\n\n        #region Commands\n\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        public RelayCommand SaveCommand { get; private set; }\n\n        public RelayCommand ShareCommand { get; private set; }\n\n        #endregion\n\n        public LastFmAlbum Album\n        {\n            get { return _album; }\n            set { Set(ref _album, value); }\n        }\n\n        public List<VkAudio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public ObservableCollection<LastFmAlbum> ArtistAlbums\n        {\n            get { return _artistAlbums; }\n            set { Set(ref _artistAlbums, value); }\n        }\n\n        public int SelectedAlbumIndex\n        {\n            get { return _selectedAlbumIndex; }\n            set\n            {\n                if (Set(ref _selectedAlbumIndex, value))\n                {\n                    Album = ArtistAlbums[value];\n                    LoadTracks();\n                }\n            }\n        }\n\n        public AlbumViewModel()\n        {\n            InitializeCommands();\n        }\n\n        public void Activate()\n        {\n            //LoadTracks();\n            LoadArtistInfo();\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n                AudioService.SetCurrentPlaylist(Tracks);\n            });\n\n            SaveCommand = new RelayCommand(Save);\n\n            ShareCommand = new RelayCommand(() =>\n            {\n                var shareViewModel = new ShareViewModel();\n                if (Tracks != null && Tracks.Count > 0)\n                {\n                    foreach (var track in Tracks.Take(15))\n                    {\n                        shareViewModel.Tracks.Add(track);\n\n                    }\n                }\n\n                if (File.Exists(App.Root + \"/Cache/artists/\" + Album.Artist + \".jpg\"))\n                {\n                    shareViewModel.ImagePath = App.Root + \"/Cache/artists/\" + Album.Artist + \".jpg\";\n                    shareViewModel.Image = new BitmapImage(new Uri(shareViewModel.ImagePath));\n                }\n\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new ShareView() { DataContext = shareViewModel };\n                flyout.Show();\n\n                shareViewModel.Activate();\n            });\n        }\n\n        private async void LoadTracks()\n        {\n            IsWorking = true;\n            Tracks = null;\n\n            try\n            {\n                var info = await DataService.GetAlbumInfo(Album.Mbid, Album.Name, Album.Artist);\n                if (info == null)\n                    info = await DataService.GetAlbumInfo(Album.Mbid, Album.Name, Album.Artist, true, false); //иногда автокоррекция тупит и альбом не находится, пробуем без нее\n                if (info != null)\n                {\n                    if (info.Tracks != null)\n                    {\n                        var tracks = new List<VkAudio>();\n\n                        for (var i = 0; i < info.Tracks.Count; i++)\n                        {\n                            var track = info.Tracks[i].ToAudio();\n                            track.Order = i + 1;\n                            tracks.Add(track);\n                        }\n\n                        Tracks = tracks;\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n\n        private async void LoadArtistInfo()\n        {\n            IsWorking = true;\n\n            try\n            {\n                var topAlbums = await DataService.GetArtistAlbums(null, Album.Artist, 10);\n                if (topAlbums != null)\n                {\n                    ArtistAlbums = new ObservableCollection<LastFmAlbum>(topAlbums);\n\n                    if (topAlbums.Count > 0)\n                    {\n                        var album = topAlbums.FirstOrDefault(x => x.Name == Album.Name);\n                        if (album != null)\n                        {\n                            SelectedAlbumIndex = topAlbums.IndexOf(album);\n                        }\n                        else\n                        {\n                            ArtistAlbums.Insert(0, Album);\n                            SelectedAlbumIndex = 0;\n                        }\n                    }\n                }\n                else\n                {\n                    ArtistAlbums = new ObservableCollection<LastFmAlbum>() { Album };\n                    SelectedAlbumIndex = 0;\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n        private async void Save()\n        {\n            var album = new VkPlaylist() { Title = _album.Artist + \" - \" + _album.Name };\n\n            var flyout = new FlyoutControl();\n            flyout.FlyoutContent = new EditAlbumView(album);\n            var result = await flyout.ShowAsync();\n            if ((bool)result)\n            {\n                try\n                {\n                    Debug.WriteLine(\"Creating new album...\");\n\n\n                    NotificationService.NotifyProgressStarted(MainResources.NotificationSaving);\n\n                    var newAlbumId = await ViewModelLocator.Vkontakte.Audio.AddAlbum(album.Title);\n\n                    Debug.WriteLine(\"Album created. Id: \" + newAlbumId);\n                    Debug.WriteLine(\"Gettings audios...\");\n\n                    var progress = new Progress<int>(p => NotificationService.NotifyProgressChanged((int)(p / 2.0f)));\n\n                    var audios = await GetAudioList(progress);\n\n                    Debug.WriteLine(\"Got audios. Count: \" + audios.Count);\n                    Debug.WriteLine(\"Saving audios.\");\n\n                    int requestsCount = 0;\n                    var audioIds = new List<long>();\n\n                    bool captchaNeeded = false;\n                    string captchaImg = string.Empty;\n                    string captchaSid = string.Empty;\n                    string captchaKey = string.Empty;\n\n                    int progressStep = (int)(100.0f / (audios.Count + 1));\n\n                    for (var i = audios.Count - 1; i > 0; i--)\n                    {\n                        var vkAudio = audios[i];\n\n                        try\n                        {\n                            var newAudioId = await ViewModelLocator.Vkontakte.Audio.Add(long.Parse(vkAudio.Id), vkAudio.OwnerId, captchaSid: captchaSid, captchaKey: captchaKey);\n                            if (newAudioId != 0)\n                            {\n                                audioIds.Add(newAudioId);\n\n                                captchaNeeded = false;\n                                captchaKey = null;\n                                captchaSid = null;\n                            }\n                        }\n                        catch (VkCaptchaNeededException ex)\n                        {\n                            captchaNeeded = true;\n                            captchaImg = ex.CaptchaImg;\n                            captchaSid = ex.CaptchaSid;\n                        }\n\n                        if (captchaNeeded)\n                        {\n                            flyout = new FlyoutControl();\n                            flyout.FlyoutContent = new CaptchaRequestView(captchaSid, captchaImg);\n                            result = await flyout.ShowAsync();\n                            if (!string.IsNullOrEmpty((string)result))\n                            {\n                                captchaKey = (string)result;\n                                i = i - 1;\n                                continue;\n                            }\n                            else\n                            {\n                                NotificationService.NotifyProgressFinished();\n                                return;\n                            }\n                        }\n\n                        NotificationService.NotifyProgressChanged((int)(progressStep / 2.0f));\n\n                        requestsCount++;\n\n                        if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                        {\n                            requestsCount = 0;\n                            await Task.Delay(1000);\n                        }\n                    }\n\n                    Debug.WriteLine(\"Audios saved. Moving to album...\");\n\n                    if (audioIds.Count > 0)\n                    {\n                        if (await ViewModelLocator.Vkontakte.Audio.MoveToAlbum(newAlbumId, audioIds))\n                        {\n                            Debug.WriteLine(\"Album saved!\");\n\n                            NotificationService.NotifyProgressFinished(MainResources.NotificationSaved);\n                        }\n                    }\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n            }\n        }\n\n        private async Task<List<VkAudio>> GetAudioList(IProgress<int> progress)\n        {\n            if (Tracks == null)\n                return null;\n\n            var result = new List<VkAudio>();\n            int requestsCount = 0;\n            int progressStep = (int)(100.0f / Tracks.Count);\n            foreach (var audio in Tracks)\n            {\n                //if (token.IsCancellationRequested)\n                //    return null;\n\n\n                VkAudio vkAudio = null;\n                try\n                {\n                    vkAudio = await DataService.GetAudioByArtistAndTitle(audio.Artist, audio.Title);\n                }\n                catch (Exception ex)\n                {\n                    LoggingService.Log(ex);\n                }\n\n                if (vkAudio == null)\n                {\n                    LoggingService.Log(\"Failed to find audio \" + audio.Artist + \" - \" + audio.Title);\n                }\n                else\n                {\n                    result.Add(new VkAudio()\n                    {\n                        Id = vkAudio.Id,\n                        OwnerId = vkAudio.OwnerId,\n                        Title = vkAudio.Title,\n                        Artist = vkAudio.Artist,\n                        Duration = vkAudio.Duration\n                    });\n                }\n\n                requestsCount++;\n\n                if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                {\n                    requestsCount = 0;\n                    await Task.Delay(1000);\n                }\n\n                //if (token.IsCancellationRequested)\n                //    return null;\n\n                progress.Report(progressStep);\n            }\n\n            return result;\n        }\n\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Search/ArtistViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing GalaSoft.MvvmLight.Command;\nusing LastFmLib.Core.Album;\nusing LastFmLib.Core.Artist;\nusing Meridian.Controls;\nusing Meridian.Model;\nusing Meridian.Services;\nusing Meridian.View.Flyouts;\nusing Meridian.ViewModel.Flyouts;\nusing Neptune.Messages;\n\nnamespace Meridian.ViewModel.Search\n{\n    public class ArtistViewModel : ViewModelBase\n    {\n        private const int MAX_TRACKS_COUNT = 100;\n\n        private LastFmArtist _artist;\n        private List<VkAudio> _tracks;\n        private List<VkAudio> _allTracks;\n        private List<LastFmAlbum> _albums;\n        private List<LastFmAlbum> _allAlbums;\n        private List<LastFmArtist> _similarArtists;\n        private ImageSource _artistImage;\n        private List<string> _tags; \n\n        #region Commands\n\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        public RelayCommand ShowAllTracksCommand { get; private set; }\n\n        public RelayCommand ShowAllAlbumsCommand { get; private set; }\n\n        public RelayCommand<LastFmAlbum> GoToAlbumCommand { get; private set; }\n\n        public RelayCommand<LastFmArtist> GoToArtistCommand { get; private set; }\n\n        public RelayCommand ShareCommand { get; private set; }\n\n        #endregion\n\n        public LastFmArtist Artist\n        {\n            get { return _artist; }\n            set { Set(ref _artist, value); }\n        }\n\n        public List<VkAudio> Tracks\n        {\n            get { return _tracks; }\n            set { Set(ref _tracks, value); }\n        }\n\n        public List<VkAudio> AllTracks\n        {\n            get { return _allTracks; }\n            set { Set(ref _allTracks, value); }\n        }\n\n        public List<LastFmAlbum> Albums\n        {\n            get { return _albums; }\n            set { Set(ref _albums, value); }\n        }\n\n        public List<LastFmAlbum> AllAlbums\n        {\n            get { return _allAlbums; }\n            set { Set(ref _allAlbums, value); }\n        }\n\n        public List<LastFmArtist> SimilarArtists\n        {\n            get { return _similarArtists; }\n            set { Set(ref _similarArtists, value); }\n        }\n\n        public ImageSource ArtistImage\n        {\n            get { return _artistImage; }\n            set { Set(ref _artistImage, value); }\n        }\n\n        public List<string> Tags\n        {\n            get { return _tags; }\n            set\n            {\n                if (Set(ref _tags, value))\n                    RaisePropertyChanged(\"TagsString\");\n            }\n        }\n\n        public string TagsString\n        {\n            get\n            {\n                if (_tags != null)\n                    return string.Join(\", \", _tags);\n\n                return null;\n            }\n        }\n\n        public ArtistViewModel()\n        {\n            InitializeCommands();\n        }\n\n        public void Activate()\n        {\n            LoadTopTracks();\n            LoadAlbums();\n            LoadInfo();\n            GetArtistImage();\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n                AudioService.SetCurrentPlaylist(AllTracks);\n            });\n\n            ShowAllTracksCommand = new RelayCommand(() =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Search.ArtistAudioView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"viewModel\", this}\n                    }\n                });\n            });\n\n            ShowAllAlbumsCommand = new RelayCommand(() =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Search.ArtistAlbumsView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"viewModel\", this}\n                    }\n                });\n            });\n\n\n            GoToAlbumCommand = new RelayCommand<LastFmAlbum>(album =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Search.AlbumView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"album\", album}\n                    }\n                });\n            });\n\n            GoToArtistCommand = new RelayCommand<LastFmArtist>(artist =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Search.ArtistView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"artist\", artist}\n                    }\n                });\n            });\n\n            ShareCommand = new RelayCommand(() =>\n            {\n                var shareViewModel = new ShareViewModel();\n                if (Tracks != null && Tracks.Count > 0)\n                {\n                    foreach (var track in AllTracks.Take(15))\n                    {\n                        shareViewModel.Tracks.Add(track);\n                    }\n                }\n\n                if (File.Exists(App.Root + \"/Cache/artists/\" + Artist.Name + \".jpg\"))\n                {\n                    shareViewModel.ImagePath = App.Root + \"/Cache/artists/\" + Artist.Name + \".jpg\";\n                    shareViewModel.Image = new BitmapImage(new Uri(shareViewModel.ImagePath));\n                }\n\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new ShareView() { DataContext = shareViewModel };\n                flyout.Show();\n\n                shareViewModel.Activate();\n            });\n        }\n\n\n        private async void LoadTopTracks()\n        {\n            IsWorking = true;\n\n            try\n            {\n                var tracks =\n                    await DataService.GetArtistTopTracks(Artist.Mbid, Artist.Name, MAX_TRACKS_COUNT);\n                if (tracks != null)\n                {\n                    for (var i = 0; i < tracks.Count; i++)\n                        tracks[i].Order = i + 1;\n                    _allTracks = tracks;\n                    Tracks = tracks.Take(5).ToList();\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n        private async void LoadAlbums()\n        {\n            IsWorking = true;\n\n            try\n            {\n                _allAlbums = await DataService.GetArtistAlbums(Artist.Mbid, Artist.Name);\n                if (_allAlbums != null && _allAlbums.Count > 0)\n                    Albums = _allAlbums.Take(10).ToList();\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n        private async void LoadInfo()\n        {\n            IsWorking = true;\n\n            try\n            {\n                var info = await DataService.GetArtistInfo(Artist.Mbid, Artist.Name);\n                if (info != null)\n                {\n                    //info.Bio = ProccessBio(info.Bio);\n                    if (info.SimilarArtists != null)\n                        SimilarArtists = info.SimilarArtists.ToList();\n                    Artist = info;\n                    Tags = info.TopTags;\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n\n            IsWorking = false;\n        }\n\n        private async void GetArtistImage()\n        {\n            if (Artist == null)\n                return;\n\n            try\n            {\n                var cachedImage = await CacheService.GetCachedImage(\"artists/\" + CacheService.GetSafeFileName(Artist.Name + \"_big.jpg\"));\n                if (cachedImage != null)\n                {\n                    ArtistImage = cachedImage;\n                    return;\n                }\n\n                var imageUri = await DataService.GetArtistImage(Artist.Name, true);\n                if (imageUri != null)\n                {\n                    cachedImage = await CacheService.CacheImage(imageUri.OriginalString, \"artists/\" + CacheService.GetSafeFileName(Artist.Name + \"_big.jpg\"));\n\n                    ArtistImage = cachedImage;\n                    return;\n                }\n\n                ArtistImage = null;\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/Search/SearchViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing GalaSoft.MvvmLight.Command;\nusing LastFmLib.Core.Album;\nusing LastFmLib.Core.Artist;\nusing Meridian.Model;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Neptune.Extensions;\nusing Neptune.Messages;\n\nnamespace Meridian.ViewModel.Search\n{\n    public class SearchViewModel : ViewModelBase\n    {\n        private const int MAX_AUDIO_SEARCH = 300;\n\n        private readonly List<SearchMenuItem> _sections = new List<SearchMenuItem>\n        {\n            new SearchMenuItem() {Group = MainResources.MainMenuVkTitle, Title = MainResources.SearchSectionTracks, GroupIcon = Application.Current.Resources[\"VkIcon\"]},\n            new SearchMenuItem() {Group = MainResources.MainMenuVkTitle, Title = MainResources.SearchSectionAlbums, GroupIcon = Application.Current.Resources[\"VkIcon\"]},\n            new SearchMenuItem() {Group = MainResources.MainMenuVkTitle, Title = MainResources.SearchSectionArtists, GroupIcon = Application.Current.Resources[\"VkIcon\"]},\n\n            new SearchMenuItem() {Group = MainResources.MainMenuLocalTitle, GroupIcon = Application.Current.Resources[\"DeviceIcon\"], Title = MainResources.SearchSectionTracks},\n            new SearchMenuItem() {Group = MainResources.MainMenuLocalTitle, GroupIcon = Application.Current.Resources[\"DeviceIcon\"], Title = MainResources.SearchSectionAlbums},\n            new SearchMenuItem() {Group = MainResources.MainMenuLocalTitle, GroupIcon = Application.Current.Resources[\"DeviceIcon\"], Title = MainResources.SearchSectionArtists}\n        };\n        private string _query;\n        private int _selectedSectionIndex;\n        private ObservableCollection<object> _searchResults;\n        private CancellationTokenSource _cancellationToken;\n\n        #region Commands\n\n        public RelayCommand<Audio> PlayAudioCommand { get; private set; }\n\n        public RelayCommand<LastFmAlbum> GoToAlbumCommand { get; private set; }\n\n        public RelayCommand<AudioAlbum> GoToLocalAlbumCommand { get; private set; }\n\n        public RelayCommand<LastFmArtist> GoToArtistCommand { get; private set; }\n\n        #endregion\n\n        public List<SearchMenuItem> Sections\n        {\n            get { return _sections; }\n        }\n\n        public string Header\n        {\n            get { return MainResources.SearchResultsTitle + \" \\\"\" + Query + \"\\\"\"; }\n        }\n\n        public string Query\n        {\n            get { return _query; }\n            set\n            {\n                if (Set(ref _query, value))\n                {\n                    RaisePropertyChanged(\"Header\");\n                    Search();\n                }\n            }\n        }\n\n        public int SelectedSectionIndex\n        {\n            get { return _selectedSectionIndex; }\n            set\n            {\n                if (Set(ref _selectedSectionIndex, value))\n                    Search();\n            }\n        }\n\n        public ObservableCollection<object> SearchResults\n        {\n            get { return _searchResults; }\n            set { Set(ref _searchResults, value); }\n        }\n\n        public SearchViewModel()\n        {\n            _cancellationToken = new CancellationTokenSource();\n\n            RegisterTasks(\"results\");\n\n            InitializeCommands();\n        }\n\n        private void InitializeCommands()\n        {\n            PlayAudioCommand = new RelayCommand<Audio>(audio =>\n            {\n                AudioService.Play(audio);\n                switch (SelectedSectionIndex)\n                {\n                    //tracks\n                    case 0:\n                        AudioService.SetCurrentPlaylist(SearchResults.Cast<Audio>());\n                        break;\n\n                    //local artists\n                    case 5:\n                        AudioService.SetCurrentPlaylist(SearchResults.Cast<AudioArtist>().Where(a => a.Albums != null).SelectMany(a => a.Albums).SelectMany(a => a.Tracks).ToList());\n                        break;\n                }\n            });\n\n            GoToAlbumCommand = new RelayCommand<LastFmAlbum>(album =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Search.AlbumView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"album\", album}\n                    }\n                });\n            });\n\n            GoToLocalAlbumCommand = new RelayCommand<AudioAlbum>(album =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Local.LocalAlbumView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"album\", album}\n                    }\n                });\n            });\n\n            GoToArtistCommand = new RelayCommand<LastFmArtist>(artist =>\n            {\n                MessengerInstance.Send(new NavigateToPageMessage()\n                {\n                    Page = \"/Search.ArtistView\",\n                    Parameters = new Dictionary<string, object>()\n                    {\n                        {\"artist\", artist}\n                    }\n                });\n            });\n        }\n\n        private void Search()\n        {\n            CancelAsync();\n\n            switch (_selectedSectionIndex)\n            {\n                case 0:\n                    SearchTracks(_cancellationToken.Token);\n                    break;\n\n                case 1:\n                    SearchAlbums(_cancellationToken.Token);\n                    break;\n\n                case 2:\n                    SearchArtists(_cancellationToken.Token);\n                    break;\n\n                case 3:\n                    SearchLocalTracks(_cancellationToken.Token);\n                    break;\n\n                case 4:\n                    SearchLocalAlbums(_cancellationToken.Token);\n                    break;\n\n                case 5:\n                    SearchLocalArtists(_cancellationToken.Token);\n                    break;\n            }\n        }\n\n        private async void SearchTracks(CancellationToken token)\n        {\n            OnTaskStarted(\"results\");\n            SearchResults = new ObservableCollection<object>();\n\n            try\n            {\n                int offset = 0;\n                const int count = 100;\n                int requestsCount = 0;\n\n                while (SearchResults != null && SearchResults.Count < MAX_AUDIO_SEARCH)\n                {\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"Tracks search cancelled\");\n                        break;\n                    }\n\n                    var a = await DataService.SearchAudio(Query, count, offset);\n                    if (a == null || a.Count == 0)\n                        break;\n                    else if (a.Count > 0)\n                    {\n                        OnTaskFinished(\"results\");\n                    }\n\n                    offset += count;\n\n                    if (token.IsCancellationRequested)\n                    {\n                        Debug.WriteLine(\"Music search cancelled\");\n                        break;\n                    }\n\n                    foreach (var audio in a)\n                    {\n                        SearchResults.Add(audio);\n                    }\n\n                    requestsCount++;\n\n                    if (requestsCount >= 2) //не больше 2-х запросов в секунду\n                    {\n                        requestsCount = 0;\n                        await Task.Delay(1000);\n                    }\n                }\n\n                if ((SearchResults == null || SearchResults.Count == 0) && !token.IsCancellationRequested)\n                    OnTaskError(\"results\", ErrorResources.LoadSearchErrorEmpty);\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"results\", ErrorResources.LoadSearchErrorCommon);\n            }\n\n            OnTaskFinished(\"results\");\n        }\n\n        private async void SearchAlbums(CancellationToken token)\n        {\n            SearchResults = null;\n            OnTaskStarted(\"results\");\n\n            SearchResults = null;\n\n            try\n            {\n                var albums = await DataService.SearchAlbums(_query);\n\n                if (token.IsCancellationRequested)\n                {\n                    Debug.WriteLine(\"Albums search cancelled\");\n                    return;\n                }\n\n                if (albums != null && albums.Count > 0)\n                {\n                    SearchResults = new ObservableCollection<object>(albums);\n                }\n                else\n                {\n                    OnTaskError(\"results\", ErrorResources.LoadSearchErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"results\", ErrorResources.LoadSearchErrorCommon);\n            }\n\n            OnTaskFinished(\"results\");\n        }\n\n        private async void SearchArtists(CancellationToken token)\n        {\n            SearchResults = null;\n            OnTaskStarted(\"results\");\n\n            SearchResults = null;\n\n            try\n            {\n                var artists = await DataService.SearchArtists(_query);\n\n                if (token.IsCancellationRequested)\n                {\n                    Debug.WriteLine(\"Artists search cancelled\");\n                    return;\n                }\n\n                if (artists != null && artists.Count > 0)\n                {\n                    string q = Query.ToLower();\n                    artists = artists.OrderByDescending(a => a.Name.ToLower() == q).ThenByDescending(a => a.Name.ToLower().StartsWith(q)).ToList();\n                    SearchResults = new ObservableCollection<object>(artists);\n                }\n                else\n                {\n                    OnTaskError(\"results\", ErrorResources.LoadSearchErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"results\", ErrorResources.LoadSearchErrorCommon);\n            }\n\n            OnTaskFinished(\"results\");\n        }\n\n        private async void SearchLocalTracks(CancellationToken token)\n        {\n            SearchResults = null;\n            OnTaskStarted(\"results\");\n\n            SearchResults = null;\n\n            try\n            {\n                var tracks = await ServiceLocator.LocalMusicService.SearchTracks(_query);\n\n                if (token.IsCancellationRequested)\n                {\n                    Debug.WriteLine(\"Local tracks search cancelled\");\n                    return;\n                }\n\n                if (tracks != null && tracks.Count > 0)\n                {\n                    SearchResults = new ObservableCollection<object>(tracks);\n                }\n                else\n                {\n                    OnTaskError(\"results\", ErrorResources.LoadSearchErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"results\", ErrorResources.LoadSearchErrorCommon);\n            }\n\n            OnTaskFinished(\"results\");\n        }\n\n        private async void SearchLocalAlbums(CancellationToken token)\n        {\n            SearchResults = null;\n            OnTaskStarted(\"results\");\n\n            SearchResults = null;\n\n            try\n            {\n                var albums = await ServiceLocator.LocalMusicService.SearchAlbums(_query);\n\n                if (token.IsCancellationRequested)\n                {\n                    Debug.WriteLine(\"Local albums search cancelled\");\n                    return;\n                }\n\n                if (albums != null && albums.Count > 0)\n                {\n                    SearchResults = new ObservableCollection<object>(albums);\n                }\n                else\n                {\n                    OnTaskError(\"results\", ErrorResources.LoadSearchErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"results\", ErrorResources.LoadSearchErrorCommon);\n            }\n\n            OnTaskFinished(\"results\");\n        }\n\n        private async void SearchLocalArtists(CancellationToken token)\n        {\n            SearchResults = null;\n            OnTaskStarted(\"results\");\n\n            SearchResults = null;\n\n            try\n            {\n                var artists = await ServiceLocator.LocalMusicService.SearchArtists(_query);\n\n                if (token.IsCancellationRequested)\n                {\n                    Debug.WriteLine(\"Local artists search cancelled\");\n                    return;\n                }\n\n                if (artists != null && artists.Count > 0)\n                {\n                    var results = new List<AudioArtist>();\n                    foreach (var artist in artists)\n                    {\n                        var a = new AudioArtist(){Title = artist.Title};\n\n                        var albums = await ServiceLocator.LocalMusicService.GetArtistAlbums(artist.Id);\n\n                        if (token.IsCancellationRequested)\n                        {\n                            Debug.WriteLine(\"Local artists search cancelled\");\n                            return;\n                        }\n\n                        if (!albums.IsNullOrEmpty())\n                        {\n                            foreach (var album in albums)\n                            {\n                                var tracks = await ServiceLocator.LocalMusicService.GetAlbumTracks(album.Id);\n                                if (token.IsCancellationRequested)\n                                {\n                                    Debug.WriteLine(\"Local artists search cancelled\");\n                                    return;\n                                }\n\n                                if (!tracks.IsNullOrEmpty())\n                                    album.Tracks = tracks.Cast<Audio>().ToList();\n                            }\n                        }\n\n                        a.Albums = albums;\n                        results.Add(a);\n                    }\n\n                    SearchResults = new ObservableCollection<object>(results);\n                }\n                else\n                {\n                    OnTaskError(\"results\", ErrorResources.LoadSearchErrorEmpty);\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n\n                OnTaskError(\"results\", ErrorResources.LoadSearchErrorCommon);\n            }\n\n            OnTaskFinished(\"results\");\n        }\n\n        private void CancelAsync()\n        {\n            if (_cancellationToken != null)\n                _cancellationToken.Cancel();\n\n            _cancellationToken = new CancellationTokenSource();\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/SettingsViewModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Sockets;\nusing System.Reflection;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Input;\nusing System.Windows.Media.Effects;\nusing GalaSoft.MvvmLight.Command;\nusing Meridian.Controls;\nusing Meridian.Helpers;\nusing Meridian.Model;\nusing Meridian.Model.Settings;\nusing Meridian.RemotePlay;\nusing Meridian.Resources.Localization;\nusing Meridian.Services;\nusing Meridian.Services.Media.Core;\nusing Meridian.View.Flyouts;\nusing VkLib.Core.Attachments;\nusing GalaSoft.MvvmLight.Messaging;\nusing Neptune.Messages;\n\nnamespace Meridian.ViewModel\n{\n    public class SettingsViewModel : ViewModelBase\n    {\n        private readonly Dictionary<string, string> _menuItems = new Dictionary<string, string>()\n        {\n            {MainResources.SettingsMenuGeneral, \"/View/Settings/SettingsUIView.xaml\"},\n            {MainResources.SettingsMenuHotkeys, \"/View/Settings/SettingsHotkeysView.xaml\"},\n            {MainResources.SettingsRemotePlay, \"/View/Settings/SettingsRemotePlayView.xaml\"},\n            {MainResources.SettingsMenuAccounts, \"/View/Settings/SettingsAccountsView.xaml\"},\n            {MainResources.SettingsMenuAbout, \"/View/Settings/SettingsAboutView.xaml\"}\n        };\n\n        private readonly List<string> _themes = new List<string>()\n        {\n            \"Light\", \"Dark\", \"Graphite\", \"Accent\"\n        };\n\n        private readonly List<ColorScheme> _colors = new List<ColorScheme>()\n                                                         {\n                                                             new ColorScheme(\"Blue\", \"#006ac1\"),\n                                                             new ColorScheme(\"Red\", \"#e51400\"),\n                                                             new ColorScheme(\"Sky\", \"#1ba1e2\"),\n                                                             new ColorScheme(\"Emerald\", \"#059f01\"),\n                                                             new ColorScheme(\"Mango\", \"#fe6f11\"),\n                                                             new ColorScheme(\"Magenta\", \"#d80073\"),\n                                                             new ColorScheme(\"Sea\", \"#009f9f\"),\n                                                             new ColorScheme(\"Purple\", \"#6800d3\"),\n                                                             new ColorScheme(\"Pink\", \"#e671b8\")\n                                                         };\n\n        private readonly List<SettingsLanguage> _languages = new List<SettingsLanguage>()\n        {\n            new SettingsLanguage() {LanguageCode = \"en\", Title = CultureInfo.GetCultureInfo(\"en\").NativeName},\n            new SettingsLanguage() {LanguageCode = \"ru\", Title = CultureInfo.GetCultureInfo(\"ru\").NativeName}\n        };\n\n        private readonly List<SettingsEngine> _engines = new List<SettingsEngine>()\n                {\n                    new SettingsEngine() { Title = \"Windows Media Player\", Engine = MediaEngine.Wmp },\n                    new SettingsEngine() { Title = \"NAudio\", Engine = MediaEngine.NAudio },\n                    new SettingsEngine() { Title = \"UWP (Windows 10)\", Engine = MediaEngine.Uwp }\n                };\n\n        private readonly List<SettingsHotkey> _hotkeys = new List<SettingsHotkey>();\n        private string _selectedTheme;\n        private ColorScheme _selectedColorScheme;\n        private bool _restartRequired;\n        private bool _canSave;\n        private bool _checkForUpdates;\n        private bool _enableNotifications;\n        private bool _enableTrayIcon;\n        private bool _showBackgroundArt;\n        private bool _showBackgroundArtCompactMode;\n        private bool _blurBackground;\n        private bool _downloadArtistArt;\n        private bool _downloadAlbumArt;\n        private SettingsLanguage _selectedLanguage;\n        private string _cacheSize;\n        private SettingsEngine _selectedEngine;\n        private string _selectedRemotePlayAddress;\n        private string _remotePlayPort;\n        private bool _enableRemotePlay;\n        private bool _useHttps;\n\n        private bool _isSidebarOpened;\n\n        #region Commands\n\n        public RelayCommand CloseSettingsCommand { get; private set; }\n\n        public RelayCommand SaveCommand { get; private set; }\n\n        public RelayCommand SaveRestartCommand { get; private set; }\n\n        public RelayCommand SignOutVkCommand { get; private set; }\n\n        public RelayCommand LoginLastFmCommand { get; private set; }\n\n        public RelayCommand LoginVkCommand { get; private set; }\n\n        public RelayCommand SignOutLastFmCommand { get; private set; }\n\n        public RelayCommand CheckUpdatesCommand { get; private set; }\n\n        public RelayCommand ClearCacheCommand { get; private set; }\n\n        public RelayCommand TellCommand { get; private set; }\n\n        #endregion\n\n        public Dictionary<string, string> MenuItems\n        {\n            get { return _menuItems; }\n        }\n\n        public string Version\n        {\n            get\n            {\n                if (IsInDesignMode)\n                    return \"5.0.700.0\";\n                else\n                    return Assembly.GetExecutingAssembly().GetName().Version.ToString();\n            }\n        }\n\n        public List<string> Themes\n        {\n            get { return _themes; }\n        }\n\n        public string SelectedTheme\n        {\n            get { return _selectedTheme; }\n            set\n            {\n                if (Set(ref _selectedTheme, value))\n                {\n                    CanSave = true;\n                    //if (value != Domain.Settings.Instance.AccentColor)\n                    //    RestartRequired = true;\n                }\n            }\n        }\n\n        public List<ColorScheme> AccentColors\n        {\n            get { return _colors; }\n        }\n\n        public ColorScheme SelectedColorScheme\n        {\n            get { return _selectedColorScheme; }\n            set\n            {\n                if (Set(ref _selectedColorScheme, value))\n                {\n                    CanSave = true;\n                }\n            }\n        }\n\n        public bool RestartRequired\n        {\n            get { return _restartRequired; }\n            set { Set(ref _restartRequired, value); }\n        }\n\n        public bool CanSave\n        {\n            get { return _canSave; }\n            set { Set(ref _canSave, value); }\n        }\n\n        public bool CheckForUpdates\n        {\n            get { return _checkForUpdates; }\n            set\n            {\n                if (Set(ref _checkForUpdates, value))\n                    CanSave = true;\n            }\n        }\n\n        public bool InstallDevUpdates\n        {\n            get { return Domain.Settings.Instance.InstallDevUpdates; }\n            set { Domain.Settings.Instance.InstallDevUpdates = value; }\n        }\n\n        public bool EnableNotifications\n        {\n            get { return _enableNotifications; }\n            set\n            {\n                if (Set(ref _enableNotifications, value))\n                    CanSave = true;\n            }\n        }\n\n        public bool EnableTrayIcon\n        {\n            get { return _enableTrayIcon; }\n            set\n            {\n                if (Set(ref _enableTrayIcon, value))\n                {\n                    CanSave = true;\n\n                    if (value != Domain.Settings.Instance.EnableTrayIcon)\n                        RestartRequired = true;\n                }\n            }\n        }\n\n        public bool ShowBackgroundArt\n        {\n            get { return _showBackgroundArt; }\n            set\n            {\n                if (Set(ref _showBackgroundArt, value))\n                {\n                    CanSave = true;\n                }\n            }\n        }\n\n        public bool ShowBackgroundArtCompactMode\n        {\n            get { return _showBackgroundArtCompactMode; }\n            set\n            {\n                if (Set(ref _showBackgroundArtCompactMode, value))\n                {\n                    CanSave = true;\n                }\n            }\n        }\n\n        public bool BlurBackground\n        {\n            get { return _blurBackground; }\n            set\n            {\n                if (Set(ref _blurBackground, value))\n                {\n                    CanSave = true;\n                }\n            }\n        }\n\n        public bool DownloadArtistArt\n        {\n            get { return _downloadArtistArt; }\n            set\n            {\n                if (Set(ref _downloadArtistArt, value))\n                {\n                    CanSave = true;\n                }\n            }\n        }\n\n        public bool DownloadAlbumArt\n        {\n            get { return _downloadAlbumArt; }\n            set\n            {\n                if (Set(ref _downloadAlbumArt, value))\n                {\n                    CanSave = true;\n                }\n            }\n        }\n\n        public string CacheSize\n        {\n            get { return _cacheSize; }\n            set { Set(ref _cacheSize, value); }\n        }\n\n        public List<SettingsHotkey> Hotkeys\n        {\n            get { return _hotkeys; }\n        }\n\n        public List<SettingsLanguage> Languages\n        {\n            get { return _languages; }\n        }\n\n        public SettingsLanguage SelectedLanguage\n        {\n            get { return _selectedLanguage; }\n            set\n            {\n                if (Set(ref _selectedLanguage, value))\n                {\n                    CanSave = true;\n\n                    if (value.LanguageCode != Domain.Settings.Instance.Language)\n                        RestartRequired = true;\n                }\n            }\n        }\n\n        public List<SettingsEngine> Engines\n        {\n            get { return _engines; }\n        }\n\n        public SettingsEngine SelectedEngine\n        {\n            get { return _selectedEngine; }\n            set\n            {\n                if (Set(ref _selectedEngine, value))\n                {\n                    CanSave = true;\n\n                    if (value.Engine != Domain.Settings.Instance.MediaEngine)\n                        RestartRequired = true;\n\n                    if (value.Engine == MediaEngine.Wmp)\n                        UseHttps = false;\n                    RaisePropertyChanged(\"CanUseHttps\");\n                }\n            }\n        }\n\n        public bool EnableRemotePlay\n        {\n            get { return _enableRemotePlay; }\n            set\n            {\n                if (Set(ref _enableRemotePlay, value))\n                {\n                    CanSave = true;\n                }\n            }\n        }\n\n        public List<string> RemotePlayAddresses\n        {\n            get { return NetworkHelper.GetLocalIpAddresses(); }\n        }\n\n        public string SelectedRemotePlayAddress\n        {\n            get { return _selectedRemotePlayAddress; }\n            set\n            {\n                if (Set(ref _selectedRemotePlayAddress, value))\n                {\n                    CanSave = true;\n                    RaisePropertyChanged(\"RemotePlayHelp\");\n                }\n            }\n        }\n\n\n        public string RemotePlayPort\n        {\n            get { return _remotePlayPort; }\n            set\n            {\n                if (Set(ref _remotePlayPort, value))\n                {\n                    CanSave = true;\n                    RaisePropertyChanged(\"RemotePlayHelp\");\n                }\n            }\n        }\n\n        public string RemotePlayHelp\n        {\n            get\n            {\n                if (!string.IsNullOrEmpty(_selectedRemotePlayAddress))\n                    return string.Format(MainResources.SettingsRemotePlayHelp,\n                        \"http://\" + _selectedRemotePlayAddress + \":\" + _remotePlayPort);\n\n                return null;\n            }\n        }\n\n        public bool CanUseHttps\n        {\n            //https currently works only in NAudio\n            get { return SelectedEngine.Engine == MediaEngine.NAudio; }\n        }\n\n        public bool UseHttps\n        {\n            get { return _useHttps;}\n            set\n            {\n                if (Set(ref _useHttps, value))\n                {\n                    CanSave = true;\n                    RestartRequired = true;\n                }\n            }\n        }\n\n        public SettingsViewModel()\n        {\n            InitializeCommands();\n\n            _selectedTheme = Domain.Settings.Instance.Theme;\n            _selectedColorScheme = _colors.FirstOrDefault(c => c.Name == Domain.Settings.Instance.AccentColor);\n            _checkForUpdates = Domain.Settings.Instance.CheckForUpdates;\n            _enableNotifications = Domain.Settings.Instance.ShowTrackNotifications;\n            _enableTrayIcon = Domain.Settings.Instance.EnableTrayIcon;\n            _showBackgroundArt = Domain.Settings.Instance.ShowBackgroundArt;\n            _showBackgroundArtCompactMode = Domain.Settings.Instance.ShowBackgroundArtCompactMode;\n            _blurBackground = Domain.Settings.Instance.BlurBackground;\n            _downloadArtistArt = Domain.Settings.Instance.DownloadArtistArt;\n            _downloadAlbumArt = Domain.Settings.Instance.DownloadAlbumArt;\n            _selectedEngine = Engines.FirstOrDefault(e => e.Engine == Domain.Settings.Instance.MediaEngine);\n            _enableRemotePlay = Domain.Settings.Instance.EnableRemotePlay;\n            _remotePlayPort = Domain.Settings.Instance.RemotePlayPort.ToString();\n            _useHttps = Domain.Settings.Instance.UseHttps;\n\n            if (string.IsNullOrEmpty(Domain.Settings.Instance.RemotePlayAddress))\n            {\n                var addresses = NetworkHelper.GetLocalIpAddresses();\n                if (addresses != null && addresses.Count > 0)\n                    _selectedRemotePlayAddress = addresses.First();\n            }\n            else\n                _selectedRemotePlayAddress = Domain.Settings.Instance.RemotePlayAddress;\n\n            var lang = _languages.FirstOrDefault(l => l.LanguageCode == Domain.Settings.Instance.Language);\n            if (lang != null)\n                _selectedLanguage = lang;\n            else\n                _selectedLanguage = _languages.First();\n\n            _isSidebarOpened = ViewModelLocator.Main.ShowSidebar;\n\n            #region Hotkeys\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"Next\",\n                Title = MainResources.SettingsHotkeyNext,\n                Ctrl = Domain.Settings.Instance.NextHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.NextHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.NextHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.NextHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"Prev\",\n                Title = MainResources.SettingsHotkeyPrev,\n                Ctrl = Domain.Settings.Instance.PrevHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.PrevHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.PrevHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.PrevHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"PlayPause\",\n                Title = MainResources.SettingsHotkeyPlayPause,\n                Ctrl = Domain.Settings.Instance.PlayPauseHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.PlayPauseHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.PlayPauseHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.PlayPauseHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"FastForward\",\n                Title = MainResources.SettingsHotkeyFastForward,\n                Ctrl = Domain.Settings.Instance.FastForwardHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.FastForwardHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.FastForwardHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.FastForwardHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"Rewind\",\n                Title = MainResources.SettingsHotkeyRewind,\n                Ctrl = Domain.Settings.Instance.RewindHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.RewindHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.RewindHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.RewindHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"LikeDislike\",\n                Title = MainResources.SettingsHotkeyAddRemove,\n                Ctrl = Domain.Settings.Instance.LikeDislikeHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.LikeDislikeHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.LikeDislikeHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.LikeDislikeHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"Shuffle\",\n                Title = MainResources.SettingsHotkeyShuffle,\n                Ctrl = Domain.Settings.Instance.ShuffleHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.ShuffleHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.ShuffleHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.ShuffleHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"Repeat\",\n                Title = MainResources.SettingsHotkeyRepeat,\n                Ctrl = Domain.Settings.Instance.RepeatHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.RepeatHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.RepeatHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.RepeatHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"IncreaseVolume\",\n                Title = MainResources.SettingsHotkeyIncreaseVolume,\n                Ctrl = Domain.Settings.Instance.IncreaseVolumeHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.IncreaseVolumeHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.IncreaseVolumeHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.IncreaseVolumeHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"DecreaseVolume\",\n                Title = MainResources.SettingsHotkeyDecreaseVolume,\n                Ctrl = Domain.Settings.Instance.DecreaseVolumeHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.DecreaseVolumeHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.DecreaseVolumeHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.DecreaseVolumeHotKey.ToString()\n            });\n\n            _hotkeys.Add(new SettingsHotkey()\n            {\n                Id = \"ShowHide\",\n                Title = MainResources.SettingsHotkeyShowHide,\n                Ctrl = Domain.Settings.Instance.ShowHideHotKeyModifier.HasFlag(ModifierKeys.Control),\n                Alt = Domain.Settings.Instance.ShowHideHotKeyModifier.HasFlag(ModifierKeys.Alt),\n                Shift = Domain.Settings.Instance.ShowHideHotKeyModifier.HasFlag(ModifierKeys.Shift),\n                Key = Domain.Settings.Instance.ShowHideHotKey.ToString()\n            });\n\n            #endregion\n        }\n\n        public async void Activate()\n        {\n            //check cache\n            if (Directory.Exists(\"Cache\"))\n            {\n                var cacheSize = await CalculateFolderSizeAsync(\"Cache\");\n                CacheSize = StringHelper.FormatSize(Math.Round(cacheSize, 1));\n            }\n        }\n\n        private void InitializeCommands()\n        {\n            CloseSettingsCommand = new RelayCommand(() =>\n            {\n                ViewModelLocator.Main.ShowSidebar = _isSidebarOpened;\n                ViewModelLocator.Main.GoBackCommand.Execute(null);\n            });\n\n            SaveCommand = new RelayCommand(SaveSettings);\n\n            SaveRestartCommand = new RelayCommand(() =>\n            {\n                SaveSettings();\n\n                Process.Start(Application.ResourceAssembly.Location);\n                Application.Current.Shutdown();\n            });\n\n            SignOutVkCommand = new RelayCommand(AccountManager.LogOutVk);\n\n            LoginLastFmCommand = new RelayCommand(() =>\n            {\n                var flyout = new FlyoutControl();\n                flyout.FlyoutContent = new LoginLastFmView();\n                flyout.Show();\n            });\n\n            LoginVkCommand = new RelayCommand(() =>\n            {\n                Messenger.Default.Send(new NavigateToPageMessage() { Page = \"/Main.LoginView\" });\n            });\n\n            SignOutLastFmCommand = new RelayCommand(AccountManager.LogoutLastFm);\n\n            ClearCacheCommand = new RelayCommand(async () =>\n            {\n                if (!Directory.Exists(\"Cache\"))\n                    return;\n\n                foreach (var file in Directory.EnumerateFiles(\"Cache\"))\n                {\n                    try\n                    {\n                        File.Delete(file);\n                    }\n                    catch (Exception ex)\n                    {\n                        Debug.WriteLine(ex);\n                    }\n                }\n\n                foreach (var dir in Directory.EnumerateDirectories(\"Cache\"))\n                {\n                    try\n                    {\n                        Directory.Delete(dir, true);\n                    }\n                    catch (Exception ex)\n                    {\n                        Debug.WriteLine(ex);\n                    }\n                }\n\n                var cacheSize = await CalculateFolderSizeAsync(\"Cache\");\n                CacheSize = StringHelper.FormatSize(Math.Round(cacheSize, 1));\n            });\n\n            TellCommand = new RelayCommand(Tell);\n        }\n\n        private void SaveSettings()\n        {\n            switch (SelectedTheme)\n            {\n                case \"Light\":\n                case \"Dark\":\n                case \"Graphite\":\n                case \"Accent\":\n                    Application.Current.Resources.MergedDictionaries[1].Source = new Uri(string.Format(\"/Resources/Themes/{0}.xaml\", SelectedTheme), UriKind.Relative);\n                    break;\n\n                default:\n                    Application.Current.Resources.MergedDictionaries[1].Source = new Uri(\"/Resources/Themes/Light.xaml\", UriKind.Relative);\n                    break;\n            }\n\n            switch (SelectedColorScheme.Name)\n            {\n                case \"Red\":\n                case \"Emerald\":\n                case \"Magenta\":\n                case \"Mango\":\n                case \"Sea\":\n                case \"Sky\":\n                case \"Purple\":\n                case \"Pink\":\n                    Application.Current.Resources.MergedDictionaries[0].Source = new Uri(string.Format(\"/Resources/Themes/Accents/{0}.xaml\", SelectedColorScheme.Name), UriKind.Relative);\n                    break;\n\n                default:\n                    Application.Current.Resources.MergedDictionaries[0].Source = new Uri(\"/Resources/Themes/Accents/Blue.xaml\", UriKind.Relative);\n                    break;\n            }\n\n            Domain.Settings.Instance.AccentColor = SelectedColorScheme.Name;\n\n            Domain.Settings.Instance.Theme = SelectedTheme;\n\n            Domain.Settings.Instance.Language = SelectedLanguage.LanguageCode;\n\n            Domain.Settings.Instance.CheckForUpdates = CheckForUpdates;\n\n            Domain.Settings.Instance.ShowTrackNotifications = EnableNotifications;\n\n            Domain.Settings.Instance.EnableTrayIcon = EnableTrayIcon;\n\n            ViewModelLocator.Main.ShowBackgroundArt = ShowBackgroundArt;\n\n            ViewModelLocator.Main.ShowBackgroundArtCompactMode = ShowBackgroundArtCompactMode;\n\n            Domain.Settings.Instance.DownloadArtistArt = DownloadArtistArt;\n\n            Domain.Settings.Instance.BlurBackground = BlurBackground;\n\n            Domain.Settings.Instance.DownloadAlbumArt = DownloadAlbumArt;\n\n            Domain.Settings.Instance.MediaEngine = SelectedEngine.Engine;\n\n            Domain.Settings.Instance.UseHttps = UseHttps;\n\n            if (BlurBackground)\n            {\n                ((MainWindow)Application.Current.MainWindow).BackgroundArtControl.Effect = new BlurEffect() { RenderingBias = RenderingBias.Quality, Radius = 35 };\n            }\n            else\n            {\n                ((MainWindow)Application.Current.MainWindow).BackgroundArtControl.Effect = null;\n            }\n\n            Domain.Settings.Instance.EnableRemotePlay = _enableRemotePlay;\n            Domain.Settings.Instance.RemotePlayAddress = _selectedRemotePlayAddress;\n            Domain.Settings.Instance.RemotePlayPort = int.Parse(_remotePlayPort);\n\n            if (EnableRemotePlay)\n            {\n                RemotePlayService.Instance.Start();\n            }\n            else\n            {\n                RemotePlayService.Instance.Stop();\n            }\n\n            foreach (var settingsHotkey in _hotkeys)\n            {\n                var modifier = ModifierKeys.None;\n                if (settingsHotkey.Ctrl)\n                    modifier |= ModifierKeys.Control;\n\n                if (settingsHotkey.Alt)\n                    modifier |= ModifierKeys.Alt;\n\n                if (settingsHotkey.Shift)\n                    modifier |= ModifierKeys.Shift;\n\n                var key = (Key)Enum.Parse(typeof(Key), settingsHotkey.Key);\n\n                switch (settingsHotkey.Id)\n                {\n                    case \"Next\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.NextHotKeyModifier, Domain.Settings.Instance.NextHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.NextHotKeyModifier, Domain.Settings.Instance.NextHotKey);\n                        }\n\n                        Domain.Settings.Instance.NextHotKey = key;\n                        Domain.Settings.Instance.NextHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h => AudioService.SkipNext());\n\n\n                        break;\n\n                    case \"Prev\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.PrevHotKeyModifier, Domain.Settings.Instance.PrevHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.PrevHotKeyModifier, Domain.Settings.Instance.PrevHotKey);\n                        }\n\n                        Domain.Settings.Instance.PrevHotKey = key;\n                        Domain.Settings.Instance.PrevHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h => AudioService.Prev());\n                        break;\n\n                    case \"PlayPause\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.PlayPauseHotKeyModifier, Domain.Settings.Instance.PlayPauseHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.PlayPauseHotKeyModifier, Domain.Settings.Instance.PlayPauseHotKey);\n                        }\n\n                        Domain.Settings.Instance.PlayPauseHotKey = key;\n                        Domain.Settings.Instance.PlayPauseHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h =>\n                            {\n                                if (AudioService.IsPlaying)\n                                    AudioService.Pause();\n                                else AudioService.Play();\n                            });\n                        break;\n\n                    case \"LikeDislike\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.LikeDislikeHotKeyModifier, Domain.Settings.Instance.LikeDislikeHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.LikeDislikeHotKeyModifier, Domain.Settings.Instance.LikeDislikeHotKey);\n                        }\n\n                        Domain.Settings.Instance.LikeDislikeHotKey = key;\n                        Domain.Settings.Instance.LikeDislikeHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h =>\n                            {\n                                if (AudioService.CurrentAudio is VkAudio)\n                                {\n                                    ((VkAudio)AudioService.CurrentAudio).IsAddedByCurrentUser =\n                                        !((VkAudio)AudioService.CurrentAudio).IsAddedByCurrentUser;\n                                    ViewModelLocator.Main.AddRemoveAudioCommand.Execute(AudioService.CurrentAudio);\n                                }\n                            });\n                        break;\n\n                    case \"Shuffle\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.ShuffleHotKeyModifier, Domain.Settings.Instance.ShuffleHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.ShuffleHotKeyModifier, Domain.Settings.Instance.ShuffleHotKey);\n                        }\n\n                        Domain.Settings.Instance.ShuffleHotKey = key;\n                        Domain.Settings.Instance.ShuffleHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h =>\n                            {\n                                ViewModelLocator.Main.Shuffle = !ViewModelLocator.Main.Shuffle;\n                            });\n                        break;\n\n\n                    case \"Repeat\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.RepeatHotKeyModifier, Domain.Settings.Instance.RepeatHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.RepeatHotKeyModifier, Domain.Settings.Instance.RepeatHotKey);\n                        }\n\n                        Domain.Settings.Instance.RepeatHotKey = key;\n                        Domain.Settings.Instance.RepeatHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h =>\n                            {\n                                ViewModelLocator.Main.Repeat = !ViewModelLocator.Main.Repeat;\n                            });\n                        break;\n\n                    case \"IncreaseVolume\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.IncreaseVolumeHotKeyModifier, Domain.Settings.Instance.IncreaseVolumeHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.IncreaseVolumeHotKeyModifier, Domain.Settings.Instance.IncreaseVolumeHotKey);\n                        }\n\n                        Domain.Settings.Instance.IncreaseVolumeHotKey = key;\n                        Domain.Settings.Instance.IncreaseVolumeHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h =>\n                            {\n                                ViewModelLocator.Main.Volume += 5;\n                            });\n                        break;\n\n                    case \"DecreaseVolume\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.DecreaseVolumeHotKeyModifier, Domain.Settings.Instance.DecreaseVolumeHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.DecreaseVolumeHotKeyModifier, Domain.Settings.Instance.DecreaseVolumeHotKey);\n                        }\n\n                        Domain.Settings.Instance.DecreaseVolumeHotKey = key;\n                        Domain.Settings.Instance.DecreaseVolumeHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h =>\n                            {\n                                ViewModelLocator.Main.Volume -= 5;\n                            });\n                        break;\n\n                    case \"ShowHide\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.ShowHideHotKeyModifier, Domain.Settings.Instance.ShowHideHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.ShowHideHotKeyModifier, Domain.Settings.Instance.ShowHideHotKey);\n                        }\n\n                        Domain.Settings.Instance.ShowHideHotKey = key;\n                        Domain.Settings.Instance.ShowHideHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h =>\n                            {\n                                if (Application.Current.MainWindow.WindowState != WindowState.Minimized)\n                                    Application.Current.MainWindow.WindowState = WindowState.Minimized;\n                                else\n                                    Application.Current.MainWindow.WindowState = WindowState.Normal;\n                            });\n                        break;\n\n                    case \"FastForward\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.FastForwardHotKeyModifier, Domain.Settings.Instance.FastForwardHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.FastForwardHotKeyModifier, Domain.Settings.Instance.FastForwardHotKey);\n                        }\n\n                        Domain.Settings.Instance.FastForwardHotKey = key;\n                        Domain.Settings.Instance.FastForwardHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h => AudioService.FastForward(7));\n                        break;\n\n                    case \"Rewind\":\n                        if (ViewModelLocator.Main.HotKeyManager.IsRegistered(Domain.Settings.Instance.RewindHotKeyModifier, Domain.Settings.Instance.RewindHotKey))\n                        {\n                            ViewModelLocator.Main.HotKeyManager.UnregisterHotkey(Domain.Settings.Instance.RewindHotKeyModifier, Domain.Settings.Instance.RewindHotKey);\n                        }\n\n                        Domain.Settings.Instance.RewindHotKey = key;\n                        Domain.Settings.Instance.RewindHotKeyModifier = modifier;\n\n                        if (key != Key.None)\n                            ViewModelLocator.Main.HotKeyManager.RegisterHotkey(modifier, key, h => AudioService.Rewind(7));\n                        break;\n                }\n            }\n\n            Domain.Settings.Instance.Save();\n\n            CloseSettingsCommand.Execute(null);\n        }\n\n        private static Task<float> CalculateFolderSizeAsync(string folder)\n        {\n            return Task.Run(() =>\n            {\n                return CalculateFolderSize(folder);\n            });\n        }\n\n        private static float CalculateFolderSize(string folder)\n        {\n            float folderSize = 0.0f;\n            try\n            {\n                //Checks if the path is valid or not\n                if (!Directory.Exists(folder))\n                    return folderSize;\n                else\n                {\n                    try\n                    {\n                        foreach (string file in Directory.EnumerateFiles(folder))\n                        {\n                            if (File.Exists(file))\n                            {\n                                var finfo = new FileInfo(file);\n                                folderSize += finfo.Length;\n                            }\n                        }\n\n                        folderSize += Directory.GetDirectories(folder).Sum(dir => CalculateFolderSize(dir));\n                    }\n                    catch (NotSupportedException ex)\n                    {\n                        LoggingService.Log(string.Format(\"Unable to calculate folder size: {0}\", ex.Message));\n                    }\n                }\n            }\n            catch (UnauthorizedAccessException ex)\n            {\n                LoggingService.Log(string.Format(\"Unable to calculate folder size: {0}\", ex.Message));\n            }\n            return folderSize;\n        }\n\n        private async void Tell()\n        {\n            try\n            {\n                var posId = await ViewModelLocator.Vkontakte.Wall.Post(message: MainResources.AboutTellMessage, attachments:\n                    new[] { new VkLinkAttachment() { Url = \"http://meridianvk.com\" } });\n\n                if (posId != 0)\n                {\n                    var flyout = new FlyoutControl();\n                    flyout.FlyoutContent = new TellResultView(posId);\n                    flyout.Show();\n                }\n            }\n            catch (Exception ex)\n            {\n                LoggingService.Log(ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/ViewModelBase.cs",
    "content": "﻿using System.Collections.Generic;\nusing Meridian.Helpers;\n\nnamespace Meridian.ViewModel\n{\n    public class ViewModelBase : GalaSoft.MvvmLight.ViewModelBase\n    {\n        private bool _isWorking;\n        private readonly Dictionary<string, LongRunningOperation> _tasks = new Dictionary<string, LongRunningOperation>();\n\n        public bool IsWorking\n        {\n            get { return _isWorking; }\n            set\n            {\n                Set(ref _isWorking, value);\n            }\n        }\n\n        /// <summary>\n        /// Calls when viewmodel is activated\n        /// </summary>\n        public virtual void Activate()\n        {\n            \n        }\n\n        /// <summary>\n        /// Calls when viewmodel is deactivated\n        /// </summary>\n        public virtual void Deactivate()\n        {\n\n        }\n\n        public Dictionary<string, LongRunningOperation> Tasks\n        {\n            get { return _tasks; }\n        }\n\n        #region Long Running Operations helpers\n\n        private void RegisterTask(string id)\n        {\n            _tasks.Add(id, new LongRunningOperation());\n        }\n\n        protected void RegisterTasks(params string[] ids)\n        {\n            foreach (var id in ids)\n            {\n                RegisterTask(id);\n            }\n        }\n\n        protected void OnTaskStarted(string id)\n        {\n            _tasks[id].Error = null;\n            _tasks[id].IsWorking = true;\n        }\n\n        protected void OnTaskFinished(string id)\n        {\n            _tasks[id].IsWorking = false;\n        }\n\n        protected void OnTaskError(string id, string error)\n        {\n            _tasks[id].Error = error;\n            _tasks[id].IsWorking = false;\n        }\n\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "Meridian/ViewModel/ViewModelLocator.cs",
    "content": "﻿using System;\nusing LastFmLib;\nusing Meridian.Services;\nusing Meridian.ViewModel.Main;\nusing VkLib;\n\nnamespace Meridian.ViewModel\n{\n    public class ViewModelLocator\n    {\n        private static Lazy<MainViewModel> _main = new Lazy<MainViewModel>(() => new MainViewModel());\n        private static Lazy<NowPlayingViewModel> _nowPlaying = new Lazy<NowPlayingViewModel>(() => new NowPlayingViewModel());\n        private static readonly Vk _vkontakte = new Vk(appId: \"2274003\", clientSecret: \"hHbZxrka2uZ6jB1inYsH\", apiVersion: \"5.116\", userAgent: \"VKAndroidApp/5.52-4543 (Android 5.1.1; SDK 22; x86_64; unknown Android SDK built for x86_64; en; 320x240)\");\n        private static readonly LastFm _lastFm = new LastFm(\"a012acc1e5f8a61bc7e58238ce3021d8\", \"86776d4f43a72633fb37fb28713a7798\");\n        private static readonly UpdateService _updateService = new UpdateService();\n\n        public static MainViewModel Main\n        {\n            get { return _main.Value; }\n        }\n\n        public static NowPlayingViewModel NowPlaying\n        {\n            get { return _nowPlaying.Value; }\n        }\n\n        public static Vk Vkontakte\n        {\n            get { return _vkontakte; }\n        }\n\n        public static LastFm LastFm\n        {\n            get { return _lastFm; }\n        }\n\n        public static UpdateService UpdateService\n        {\n            get { return _updateService; }\n        }\n\n        public ViewModelLocator()\n        {\n\n        }\n    }\n}\n"
  },
  {
    "path": "Meridian.Core/Services/AccountsService.cs",
    "content": "﻿namespace Meridian.Core.Services\n{\n    /// <summary>\n    /// Contains registered accounts and associated data sources\n    /// </summary>\n    public class AccountsService\n    {\n\n    }\n}\n"
  },
  {
    "path": "MeridianDesktop.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.29911.84\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Meridian\", \"Meridian\\Meridian.csproj\", \"{C769D3C7-9A2F-440D-8CA1-25FE0BE98135}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \".nuget\", \".nuget\", \"{904094CC-4301-4E2F-9B1B-D8D4BB03735F}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t.nuget\\NuGet.Config = .nuget\\NuGet.Config\n\t\t.nuget\\NuGet.exe = .nuget\\NuGet.exe\n\t\t.nuget\\NuGet.targets = .nuget\\NuGet.targets\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"LastFmLibPortable\", \"LastFmLibPortable\\Trunk\\LastFmLibPortable.csproj\", \"{476C6B20-3ACF-4C71-8847-AFCD90E29FBD}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Neptune\", \"Neptune\", \"{E66C0B37-0DC3-4B21-B3B7-E783BBA48554}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Neptune.Base\", \"Neptune\\Trunk\\Neptune.Base\\Neptune.Base.csproj\", \"{D914B630-6F50-47DE-9719-6CD7644C6908}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Neptune.Desktop\", \"Neptune\\Trunk\\Neptune.Desktop\\Neptune.Desktop.csproj\", \"{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{C7A02AB8-DB3F-4EE1-AC38-5D7285D14019}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tLICENSE.txt = LICENSE.txt\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"libs\", \"libs\", \"{285F580B-F600-46BE-A1B6-F4F3BA669C4F}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tMeridian\\bin\\Debug\\sqlite3.dll = Meridian\\bin\\Debug\\sqlite3.dll\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"VkLib\", \"VkLib\\VkLib.csproj\", \"{0437F114-685A-4F79-8A75-F4690672AFAB}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{C769D3C7-9A2F-440D-8CA1-25FE0BE98135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C769D3C7-9A2F-440D-8CA1-25FE0BE98135}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C769D3C7-9A2F-440D-8CA1-25FE0BE98135}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{C769D3C7-9A2F-440D-8CA1-25FE0BE98135}.Debug|x86.Build.0 = Debug|x86\n\t\t{C769D3C7-9A2F-440D-8CA1-25FE0BE98135}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C769D3C7-9A2F-440D-8CA1-25FE0BE98135}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C769D3C7-9A2F-440D-8CA1-25FE0BE98135}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{C769D3C7-9A2F-440D-8CA1-25FE0BE98135}.Release|x86.Build.0 = Release|Any CPU\n\t\t{476C6B20-3ACF-4C71-8847-AFCD90E29FBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{476C6B20-3ACF-4C71-8847-AFCD90E29FBD}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{476C6B20-3ACF-4C71-8847-AFCD90E29FBD}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{476C6B20-3ACF-4C71-8847-AFCD90E29FBD}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{476C6B20-3ACF-4C71-8847-AFCD90E29FBD}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{476C6B20-3ACF-4C71-8847-AFCD90E29FBD}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{476C6B20-3ACF-4C71-8847-AFCD90E29FBD}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{476C6B20-3ACF-4C71-8847-AFCD90E29FBD}.Release|x86.Build.0 = Release|Any CPU\n\t\t{D914B630-6F50-47DE-9719-6CD7644C6908}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{D914B630-6F50-47DE-9719-6CD7644C6908}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{D914B630-6F50-47DE-9719-6CD7644C6908}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{D914B630-6F50-47DE-9719-6CD7644C6908}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{D914B630-6F50-47DE-9719-6CD7644C6908}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{D914B630-6F50-47DE-9719-6CD7644C6908}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{D914B630-6F50-47DE-9719-6CD7644C6908}.Release|x86.ActiveCfg = Release|x86\n\t\t{D914B630-6F50-47DE-9719-6CD7644C6908}.Release|x86.Build.0 = Release|x86\n\t\t{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2}.Release|x86.Build.0 = Release|Any CPU\n\t\t{0437F114-685A-4F79-8A75-F4690672AFAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{0437F114-685A-4F79-8A75-F4690672AFAB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{0437F114-685A-4F79-8A75-F4690672AFAB}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{0437F114-685A-4F79-8A75-F4690672AFAB}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{0437F114-685A-4F79-8A75-F4690672AFAB}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{0437F114-685A-4F79-8A75-F4690672AFAB}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{0437F114-685A-4F79-8A75-F4690672AFAB}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{0437F114-685A-4F79-8A75-F4690672AFAB}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{476C6B20-3ACF-4C71-8847-AFCD90E29FBD} = {285F580B-F600-46BE-A1B6-F4F3BA669C4F}\n\t\t{E66C0B37-0DC3-4B21-B3B7-E783BBA48554} = {285F580B-F600-46BE-A1B6-F4F3BA669C4F}\n\t\t{D914B630-6F50-47DE-9719-6CD7644C6908} = {E66C0B37-0DC3-4B21-B3B7-E783BBA48554}\n\t\t{4AA2609B-B5E4-4F3E-95FD-47C1A27929B2} = {E66C0B37-0DC3-4B21-B3B7-E783BBA48554}\n\t\t{0437F114-685A-4F79-8A75-F4690672AFAB} = {285F580B-F600-46BE-A1B6-F4F3BA669C4F}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {47DA62B6-EA98-4CA0-9B70-F177B0CD2335}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/Collections/IAsyncCollection.cs",
    "content": "﻿using System.Threading.Tasks;\n\nnamespace Neptune.Collections\n{\n    public interface IAsyncCollection\n    {\n        bool IsWorking { get; }\n\n        // Summary:\n        //     Gets a sentinel value that supports incremental loading implementations.\n        //\n        // Returns:\n        //     true if additional unloaded items remain in the view; otherwise, false.\n        bool HasMoreItems { get; }\n\n        // Summary:\n        //     Initializes incremental loading from the view.\n        //\n        // Parameters:\n        //   count:\n        //     The number of items to load.\n        //\n        // Returns:\n        //     The wrapped results of the load operation.\n        Task<uint> LoadMoreItemsAsync(uint count);\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/Extensions/CommonExtensions.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace Neptune.Extensions\n{\n    public static class CommonExtensions\n    {\n        public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)\n        {\n            if (source == null)\n                throw new ArgumentNullException(\"source\");\n            if (action == null)\n                throw new ArgumentNullException(\"action\");\n\n            foreach (var item in source)\n            {\n                action(item);\n            }\n        }\n\n        public static bool IsNullOrEmpty(this IList source)\n        {\n            return source == null || source.Count == 0;\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/Extensions/StreamExtensions.cs",
    "content": "﻿using System;\nusing System.IO;\n\nnamespace Neptune.Extensions\n{\n    public static class StreamExtensions\n    {\n        public static void WriteText(this Stream stream, string text)\n        {\n            if (!stream.CanWrite)\n                throw new Exception(\"Stream is not writeable.\");\n\n            using (var writer = new StreamWriter(stream))\n            {\n                writer.Write(text);\n                writer.Flush();\n            }\n        }\n\n        public static string ReadText(this Stream stream)\n        {\n            if (!stream.CanRead)\n                throw new Exception(\"Stream is not readable.\");\n\n            using (var reader = new StreamReader(stream))\n            {\n                return reader.ReadToEnd();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/Helpers/TaskQueue.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\nnamespace Neptune.Helpers\n{\n    /// <summary>\n    /// A simple task queue\n    /// </summary>\n    public class TaskQueue\n    {\n        private readonly Queue<Task> _queue;\n        private bool _isBusy;\n\n        public int Count\n        {\n            get { return _queue.Count; }\n        }\n\n        public TaskQueue()\n        {\n            _queue = new Queue<Task>();\n        }\n\n        public void Enqueue(Task t)\n        {\n            EnqueuInternal(t);\n        }\n\n        public void Enqueue(Func<Task> action)\n        {\n            var t = new Task(() => action.Invoke().Wait());\n            EnqueuInternal(t);\n        }\n\n        private void EnqueuInternal(Task t)\n        {\n            t.ContinueWith(TaskCallback);\n\n            if (!_isBusy)\n            {\n                _isBusy = true;\n                if (t.Status == TaskStatus.Created)\n                {\n                    t.Start();\n                    return;\n                }\n            }\n\n            _queue.Enqueue(t);\n        }\n\n        private void TaskCallback(Task t)\n        {\n            Debug.WriteLine(\"Task \" + t.Id + \" completed.\");\n            if (_queue.Count > 0)\n            {\n                var nextTask = _queue.Dequeue();\n                t.ContinueWith(t1 => nextTask);\n                if (nextTask.Status == TaskStatus.Created)\n                {\n                    Debug.WriteLine(\"Starting next \" + nextTask.Id + \" task.\");\n                    nextTask.Start();\n                }\n            }\n            else\n            {\n                _isBusy = false;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/Messages/GoHomeMessage.cs",
    "content": "﻿namespace Neptune.Messages\n{\n    /// <summary>\n    /// Uses for navigation to start page with removing all navigation history\n    /// </summary>\n    public class GoHomeMessage\n    {\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/Messages/NavigateToPageMessage.cs",
    "content": "﻿using System.Collections.Generic;\n\nnamespace Neptune.Messages\n{\n    /// <summary>\n    /// Uses for navigation to page\n    /// </summary>\n    public class NavigateToPageMessage\n    {\n        /// <summary>\n        /// Page\n        /// </summary>\n        public string Page { get; set; }\n\n        /// <summary>\n        /// Params\n        /// </summary>\n        public Dictionary<string, object> Parameters { get; set; }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/Neptune.Base.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{D914B630-6F50-47DE-9719-6CD7644C6908}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Neptune</RootNamespace>\n    <AssemblyName>Neptune.Base</AssemblyName>\n    <TargetFrameworkVersion>v5.0</TargetFrameworkVersion>\n    <TargetFrameworkProfile>\n    </TargetFrameworkProfile>\n    <FileAlignment>512</FileAlignment>\n    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n    <SccProjectName>SAK</SccProjectName>\n    <SccLocalPath>SAK</SccLocalPath>\n    <SccAuxPath>SAK</SccAuxPath>\n    <SccProvider>SAK</SccProvider>\n    <SolutionDir Condition=\"$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'\">..\\</SolutionDir>\n    <RestorePackages>true</RestorePackages>\n    <FileUpgradeFlags>\n    </FileUpgradeFlags>\n    <UpgradeBackupLocation>\n    </UpgradeBackupLocation>\n    <OldToolsVersion>12.0</OldToolsVersion>\n    <PublishUrl>publish\\</PublishUrl>\n    <Install>true</Install>\n    <InstallFrom>Disk</InstallFrom>\n    <UpdateEnabled>false</UpdateEnabled>\n    <UpdateMode>Foreground</UpdateMode>\n    <UpdateInterval>7</UpdateInterval>\n    <UpdateIntervalUnits>Days</UpdateIntervalUnits>\n    <UpdatePeriodically>false</UpdatePeriodically>\n    <UpdateRequired>false</UpdateRequired>\n    <MapFileExtensions>true</MapFileExtensions>\n    <ApplicationRevision>0</ApplicationRevision>\n    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>\n    <IsWebBootstrapper>false</IsWebBootstrapper>\n    <UseApplicationTrust>false</UseApplicationTrust>\n    <BootstrapperEnabled>true</BootstrapperEnabled>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|x86'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>bin\\x86\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <DebugType>full</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <ErrorReport>prompt</ErrorReport>\n    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|x86'\">\n    <OutputPath>bin\\x86\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <Optimize>true</Optimize>\n    <DebugType>pdbonly</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <ErrorReport>prompt</ErrorReport>\n    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\n  </PropertyGroup>\n  <ItemGroup>\n    <Compile Include=\"Collections\\IAsyncCollection.cs\" />\n    <Compile Include=\"Extensions\\CommonExtensions.cs\" />\n    <Compile Include=\"Extensions\\StreamExtensions.cs\" />\n    <Compile Include=\"Helpers\\TaskQueue.cs\" />\n    <Compile Include=\"Messages\\GoHomeMessage.cs\" />\n    <Compile Include=\"Messages\\NavigateToPageMessage.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Storage\\IFileStorage.cs\" />\n    <Compile Include=\"View\\IVisualViewModel.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"app.config\" />\n    <None Include=\"project.json\" />\n  </ItemGroup>\n  <ItemGroup>\n    <BootstrapperPackage Include=\"Microsoft.Net.Client.3.5\">\n      <Visible>False</Visible>\n      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>\n      <Install>false</Install>\n    </BootstrapperPackage>\n    <BootstrapperPackage Include=\"Microsoft.Net.Framework.3.5.SP1\">\n      <Visible>False</Visible>\n      <ProductName>.NET Framework 3.5 SP1</ProductName>\n      <Install>false</Install>\n    </BootstrapperPackage>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildExtensionsPath32)\\Microsoft\\Portable\\$(TargetFrameworkVersion)\\Microsoft.Portable.CSharp.targets\" />\n  <Import Project=\"$(SolutionDir)\\.nuget\\NuGet.targets\" Condition=\"Exists('$(SolutionDir)\\.nuget\\NuGet.targets')\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Resources;\nusing System.Reflection;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Neptune.Base\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Neptune.Base\")]\n[assembly: AssemblyCopyright(\"Copyright © Stealth 2013\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: NeutralResourcesLanguage(\"en\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"2.0.0.0\")]\n[assembly: AssemblyFileVersion(\"2.0.0.0\")]\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/Storage/IFileStorage.cs",
    "content": "﻿using System.IO;\nusing System.Threading.Tasks;\n\nnamespace Neptune.Storage\n{\n    /// <summary>\n    /// Service for working with files and folders\n    /// </summary>\n    public interface IFileStorage\n    {\n        /// <summary>\n        /// Opens file for read/write. If file is not exists it will be created.\n        /// </summary>\n        /// <param name=\"path\">Path</param>\n        /// <returns><see cref=\"Stream\"/></returns>\n        Task<Stream> OpenFile(string path);\n\n        /// <summary>\n        /// Reads all text from the file. If file is not exists returns null.\n        /// </summary>\n        /// <param name=\"path\">Path</param>\n        /// <returns>File content or null</returns>\n        Task<string> GetText(string path);\n\n        /// <summary>\n        /// Writes text to the file. If file is not exists creates it.\n        /// </summary>\n        /// <param name=\"path\">Path</param>\n        /// <param name=\"text\">Text</param>\n        Task WriteText(string path, string text);\n\n        /// <summary>\n        /// Checks if file exists\n        /// </summary>\n        /// <param name=\"path\">Path</param>\n        /// <returns>True if file exists</returns>\n        Task<bool> FileExists(string path);\n\n        /// <summary>\n        /// Deletes file. If file is not exists throws exception.\n        /// </summary>\n        /// <param name=\"path\">Path</param>\n        /// <returns></returns>\n        Task DeleteFile(string path);\n\n\n        /// <summary>\n        /// Checks if folder exists\n        /// </summary>\n        /// <param name=\"path\">Path</param>\n        /// <returns>True if folder exists</returns>\n        Task<bool> FolderExists(string path);\n\n        /// <summary>\n        /// Creates folder and all subfolders in specified path.\n        /// </summary>\n        /// <param name=\"path\">Path</param>\n        /// <returns></returns>\n        Task CreateFolder(string path);\n\n        /// <summary>\n        /// Deletes folder and all subfolders and files in specified path. Throws exception if folder is not exists.\n        /// </summary>\n        /// <param name=\"path\">Path</param>\n        /// <returns></returns>\n        Task DeleteFolder(string path);\n\n        bool UserRoaming { get; set; }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/View/IVisualViewModel.cs",
    "content": "﻿namespace Neptune.View\n{\n    public interface IVisualViewModel\n    {\n        void Activate();\n\n        void Deactivate();\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Runtime\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-2.5.19.0\" newVersion=\"2.5.19.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Threading.Tasks\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-2.5.19.0\" newVersion=\"2.5.19.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>"
  },
  {
    "path": "Neptune/Trunk/Neptune.Base/project.json",
    "content": "﻿{\n  \"supports\": {\n    \"net46.app\": {},\n    \"dnxcore50.app\": {}\n  },\n  \"dependencies\": {\n    \"Microsoft.NETCore\": \"5.0.0\",\n    \"Microsoft.NETCore.Portable.Compatibility\": \"1.0.0\"\n  },\n  \"frameworks\": {\n    \"dotnet\": {\n      \"imports\": \"portable-net452\"\n    }\n  }\n}"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Behaviours/IgnoreMouseWheelBehavior.cs",
    "content": "﻿using Microsoft.Xaml.Behaviors;\nusing System.Windows;\nusing System.Windows.Input;\n\nnamespace Neptune.UI.Desktop.Behaviours\n{\n    /// <summary>\n    /// Captures and eats MouseWheel events so that a nested ListBox does not\n    /// prevent an outer scrollable control from scrolling.\n    /// </summary>\n    public sealed class IgnoreMouseWheelBehavior : Behavior<UIElement>\n    {\n\n        protected override void OnAttached()\n        {\n            base.OnAttached();\n            AssociatedObject.PreviewMouseWheel += AssociatedObject_PreviewMouseWheel;\n        }\n\n        protected override void OnDetaching()\n        {\n            AssociatedObject.PreviewMouseWheel -= AssociatedObject_PreviewMouseWheel;\n            base.OnDetaching();\n        }\n\n        void AssociatedObject_PreviewMouseWheel(object sender, MouseWheelEventArgs e)\n        {\n            e.Handled = true;\n\n            var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);\n            e2.RoutedEvent = UIElement.MouseWheelEvent;\n\n            AssociatedObject.RaiseEvent(e2);\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Behaviours/TriggerTransitionBehaviour.cs",
    "content": "﻿#if DESKTOP || PHONE\nusing Microsoft.Xaml.Behaviors;\nusing System.Windows;\nusing System.Windows.Media.Animation;\n#elif MODERN\nusing Windows.UI.Interactivity;\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Media.Animation;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Behaviours\n{\n    public class TriggerTransitionBehaviour : Behavior<FrameworkElement>\n    {\n\n        public static readonly DependencyProperty ValueProperty =\n            DependencyProperty.Register(\"Value\", typeof(bool), typeof(TriggerTransitionBehaviour), new PropertyMetadata(default(bool), PropertyChangedCallback));\n\n        public bool Value\n        {\n            get { return (bool)GetValue(ValueProperty); }\n            set { SetValue(ValueProperty, value); }\n        }\n\n        private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var b = (TriggerTransitionBehaviour)d;\n\n            if ((bool)e.NewValue)\n                b.TransitionIn();\n            else\n                b.TransitionOut();\n        }\n\n\n        public static readonly DependencyProperty AnimationOutProperty =\n            DependencyProperty.Register(\"AnimationOut\", typeof(Storyboard), typeof(TriggerTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationOut\n        {\n            get { return (Storyboard)GetValue(AnimationOutProperty); }\n            set { SetValue(AnimationOutProperty, value); }\n        }\n\n        public static readonly DependencyProperty AnimationInProperty =\n            DependencyProperty.Register(\"AnimationIn\", typeof(Storyboard), typeof(TriggerTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationIn\n        {\n            get { return (Storyboard)GetValue(AnimationInProperty); }\n            set { SetValue(AnimationInProperty, value); }\n        }\n\n        private void TransitionOut()\n        {\n            if (AssociatedObject == null)\n                return;\n\n            if (AnimationOut == null)\n            {\n                return;\n            }\n\n            AnimationOut.Stop();\n            Storyboard.SetTarget(AnimationOut, AssociatedObject);\n            AnimationOut.Begin();\n        }\n\n        private void TransitionIn()\n        {\n            if (AssociatedObject == null)\n                return;\n\n            if (AnimationIn != null)\n            {\n#if DESKTOP\n                if (Storyboard.GetTarget(AnimationIn) == AssociatedObject)\n#endif\n                    AnimationIn.Stop();\n\n                Storyboard.SetTarget(AnimationIn, AssociatedObject);\n                AnimationIn.Begin();\n\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Behaviours/UpdateTextBindingOnPropertyChanged.cs",
    "content": "﻿#if DESKTOP || PHONE\nusing Microsoft.Xaml.Behaviors;\nusing System.Windows.Controls;\nusing System;\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Interactivity;\nusing Windows.UI.Xaml.Controls;\nusing Windows.UI.Xaml.Data;\n#endif\n\n// ReSharper disable once CheckNamespace\n\nnamespace Neptune.UI.Behaviours\n{\n    /// <summary>\n    /// Custom behavior that updates the source of a binding on a text box as the text changes.\n    /// </summary>\n    public class UpdateTextBindingOnPropertyChanged : Behavior<TextBox>\n    {\n        private BindingExpression _expression;\n\n        /// <summary>\n        /// Called after the behavior is attached to an AssociatedObject.\n        /// </summary>\n        /// <remarks>\n        /// Override this to hook up functionality to the AssociatedObject.\n        /// </remarks>\n        protected override void OnAttached()\n        {\n            base.OnAttached();\n\n            this._expression = this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);\n            this.AssociatedObject.TextChanged += this.OnTextChanged;\n        }\n\n        /// <summary>\n        /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.\n        /// </summary>\n        /// <remarks>\n        /// Override this to unhook functionality from the AssociatedObject.\n        /// </remarks>\n        protected override void OnDetaching()\n        {\n            base.OnDetaching();\n\n            this.AssociatedObject.TextChanged -= this.OnTextChanged;\n            this._expression = null;\n        }\n\n#if DESKTOP || PHONE\n        private void OnTextChanged(object sender, EventArgs args)\n#elif MODERN\n       private void OnTextChanged(object sender, TextChangedEventArgs args)\n#endif\n        {\n            if (_expression != null)\n                this._expression.UpdateSource();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Behaviours/VisiblityTransitionBehaviour.cs",
    "content": "﻿#if DESKTOP || PHONE\nusing Microsoft.Xaml.Behaviors;\nusing System.Windows;\nusing System.Windows.Media.Animation;\n#elif MODERN\nusing Windows.UI.Interactivity;\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Media.Animation;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Behaviours\n{\n    public class VisibilityTransitionBehaviour : Behavior<FrameworkElement>\n    {\n\n        public static readonly DependencyProperty ValueProperty =\n            DependencyProperty.Register(\"Value\", typeof(Visibility), typeof(VisibilityTransitionBehaviour), new PropertyMetadata(default(Visibility), PropertyChangedCallback));\n\n        public Visibility Value\n        {\n            get { return (Visibility)GetValue(ValueProperty); }\n            set { SetValue(ValueProperty, value); }\n        }\n\n        private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var b = (VisibilityTransitionBehaviour)d;\n\n            b.TransitionOut((Visibility)e.OldValue);\n        }\n\n\n        public static readonly DependencyProperty AnimationOutProperty =\n            DependencyProperty.Register(\"AnimationOut\", typeof(Storyboard), typeof(VisibilityTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationOut\n        {\n            get { return (Storyboard)GetValue(AnimationOutProperty); }\n            set { SetValue(AnimationOutProperty, value); }\n        }\n\n        public static readonly DependencyProperty AnimationInProperty =\n            DependencyProperty.Register(\"AnimationIn\", typeof(Storyboard), typeof(VisibilityTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationIn\n        {\n            get { return (Storyboard)GetValue(AnimationInProperty); }\n            set { SetValue(AnimationInProperty, value); }\n        }\n\n        protected override void OnAttached()\n        {\n            AssociatedObject.Visibility = Value;\n\n            base.OnAttached();\n        }\n\n        private void TransitionOut(Visibility oldValue)\n        {\n            if (AssociatedObject == null)\n                return;\n\n            if (AnimationOut == null || oldValue == Visibility.Collapsed)\n            {\n                TransitionIn();\n            }\n            else\n            {\n#if DESKTOP\n                AnimationOut.Completed += AnimationOutCompleted;\n                AnimationOut.Begin(AssociatedObject);\n#else\n                AnimationOut.Stop();\n                Storyboard.SetTarget(AnimationOut, AssociatedObject);\n                AnimationOut.Completed += AnimationOutCompleted;\n                AnimationOut.Begin();\n#endif\n            }\n        }\n\n        private void TransitionIn()\n        {\n            if (AssociatedObject == null)\n                return;\n\n            AssociatedObject.Visibility = Value;\n            if (AnimationIn != null)\n            {\n#if DESKTOP\n                if (Storyboard.GetTarget(AnimationIn) == AssociatedObject)\n#endif\n                AnimationIn.Stop();\n\n                Storyboard.SetTarget(AnimationIn, AssociatedObject);\n                AnimationIn.Begin();\n\n            }\n        }\n        void AnimationOutCompleted(object sender, object e)\n        {\n            AnimationOut.Completed -= AnimationOutCompleted;\n            TransitionIn();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Converters/BooleanToObjectConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class BooleanToObjectConverter : IValueConverter\n    {\n        public object TrueObject { get; set; }\n\n        public object FalseObject { get; set; }\n\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            bool flag = value is bool ? (bool)value : (value != null && !string.IsNullOrWhiteSpace(value.ToString()));\n\n            return flag ? TrueObject : FalseObject;\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Converters/BooleanToVisibilityConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Windows;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Converters\n{\n    public class BooleanToVisibilityConverter : IValueConverter\n    {\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            var flag = false;\n            if (value is bool)\n            {\n                flag = (bool)value;\n            }\n            else if (value is string)\n            {\n                Boolean.TryParse((string)value, out flag);\n            }\n            if (parameter != null)\n            {\n                bool bParam;\n                if (bool.TryParse((string)parameter, out bParam) && bParam)\n                {\n                    flag = !flag;\n                }\n            }\n            if (flag)\n            {\n                return Visibility.Visible;\n            }\n            else\n            {\n                return Visibility.Collapsed;\n            }\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible));\n            if (parameter != null)\n            {\n                if ((bool)parameter)\n                {\n                    back = !back;\n                }\n            }\n            return back;\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Converters/InvertBooleanConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Windows;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Converters\n{\n    public class InvertBooleanConverter : IValueConverter\n    {\n#if DESKTOP || PHONE\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, string language)\n#endif\n        {\n            if (value is bool)\n            {\n                return !(bool)value;\n            }\n            return false;\n        }\n\n#if DESKTOP || PHONE\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, string language)\n#endif\n        {\n            if (value is bool)\n            {\n                return !(bool)value;\n            }\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Converters/NullToBooleanConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class NullToBooleanConverter : IValueConverter\n    {\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            var invert = false;\n\n            if (parameter != null)\n            {\n                Boolean.TryParse(parameter.ToString(), out invert);\n            }\n\n            if (value == null) return invert;\n\n            if (value is string)\n            {\n                if (!string.IsNullOrWhiteSpace((string)value))\n                    return invert;\n                else\n                    return !invert;\n            }\n\n            return true;\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Converters/NullToVisibilityConverter.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Globalization;\nusing System.Windows;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class NullToVisibilityConverter : IValueConverter\n    {\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            var invert = false;\n            if (parameter != null)\n            {\n                Boolean.TryParse(parameter.ToString(), out invert);\n            }\n            if (value == null) return invert ? Visibility.Visible : Visibility.Collapsed;\n\n            if (value is string)\n                return string.IsNullOrWhiteSpace((string)value) || invert ? Visibility.Collapsed : Visibility.Visible;\n\n            if (value is IList)\n            {\n                bool empty = ((IList)value).Count == 0;\n                if (invert)\n                    empty = !empty;\n                if (empty)\n                    return Visibility.Collapsed;\n                else\n                    return Visibility.Visible;\n            }\n\n            decimal number;\n            if (Decimal.TryParse(value.ToString(), out number))\n            {\n                if (!invert)\n                    return number > 0 ? Visibility.Visible : Visibility.Collapsed;\n                else\n                    return number > 0 ? Visibility.Collapsed : Visibility.Visible;\n\n            }\n\n            return invert ? Visibility.Collapsed : Visibility.Visible;\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Converters/StringToUpperConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class StringToUpperConverter : IValueConverter\n    {\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            return value != null ? ((string)value).ToUpperInvariant() : null;\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Converters/TimeSpanConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class TimeSpanConverter : IValueConverter\n    {\n        public object Convert(object value, Type targetType, object parameter,\n#if !MODERN\n CultureInfo culture)\n#else\n string culture)\n#endif\n        {\n            var t = (TimeSpan)value;\n            return t.ToString((string)parameter);\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter,\n#if !MODERN\n CultureInfo culture)\n#else\n string culture)\n#endif\n        {\n            throw new NotSupportedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Domain/AppSettings.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\n#if MODERN\nusing Windows.Foundation.Collections;\nusing Windows.Storage;\n#elif PHONE\nusing System.IO.IsolatedStorage;\n#endif\n\nnamespace Neptune.Domain\n{\n    public class AppSettings\n    {\n#if MODERN\n        private readonly IPropertySet _settings = ApplicationData.Current.LocalSettings.Values;\n#elif PHONE\n        private readonly IsolatedStorageSettings _settings = IsolatedStorageSettings.ApplicationSettings;\n#elif DESKTOP\n#endif\n\n        protected void Set<TValue>(string settingName, TValue value)\n        {\n#if MODERN || PHONE\n            try\n            {\n                var serializer = new Newtonsoft.Json.JsonSerializer();\n                using (var writer = new System.IO.StringWriter())\n                {\n                    serializer.Serialize(writer, value);\n                    _settings[settingName] = writer.GetStringBuilder().ToString();\n                }\n            }\n            catch (Exception ex)\n            {\n                Debug.WriteLine(ex);\n            }\n#elif DESKTOP\n            throw new NotImplementedException();\n#endif\n        }\n\n        protected bool TryGet<TValue>(string settingName, out TValue value)\n        {\n#if MODERN || PHONE\n            object val;\n            if (_settings.TryGetValue(settingName, out val))\n            {\n\n                try\n                {\n                    var strValue = (string)val;\n                    using (var reader = new System.IO.StringReader(strValue))\n                    {\n                        using (var jsonReader = new Newtonsoft.Json.JsonTextReader(reader))\n                        {\n                            var serializer = new Newtonsoft.Json.JsonSerializer();\n                            value = serializer.Deserialize<TValue>(jsonReader);\n                            return true;\n                        }\n                    }\n                }\n                catch (Exception ex)\n                {\n                    value = default(TValue);\n                    Debug.WriteLine(ex);\n                }\n\n                return false;\n            }\n            else\n            {\n                value = default(TValue);\n                return false;\n            }\n\n#elif DESKTOP\n            throw new NotImplementedException();\n#endif\n        }\n\n        protected T Get<T>(string settingName, T defaultValue)\n        {\n            T obj;\n            if (TryGet<T>(settingName, out obj))\n                return obj;\n            else\n                return defaultValue;\n        }\n\n        public virtual void Load()\n        {\n\n        }\n\n        public virtual void Save()\n        {\n\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Extensions/VisualTreeHelperExtensions.cs",
    "content": "﻿using System.Collections.Generic;\n#if DESKTOP || PHONE\nusing System.Windows;\nusing System.Windows.Media;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Media;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Extensions\n{\n    public static class VisualTreeHelperExtensions\n    {\n        /// <summary>\n        /// Performs a breadth-first enumeration of all the descendents in the tree\n        /// </summary>\n        /// <param name=\"root\">The root node</param>\n        /// <returns>An enumerator of all the children</returns>\n        public static IEnumerable<FrameworkElement> GetVisualDescendents(this FrameworkElement root)\n        {\n\n            var toDo = new Queue<IEnumerable<FrameworkElement>>();\n\n            toDo.Enqueue(root.GetVisualChildren());\n            while (toDo.Count > 0)\n            {\n                IEnumerable<FrameworkElement> children = toDo.Dequeue();\n                foreach (FrameworkElement child in children)\n                {\n                    yield return child;\n                    toDo.Enqueue(child.GetVisualChildren());\n                }\n            }\n\n        }\n\n        /// <summary>\n        /// Gets all the visual children of the element\n        /// </summary>\n        /// <param name=\"root\">The element to get children of</param>\n        /// <returns>An enumerator of the children</returns>\n        public static IEnumerable<FrameworkElement> GetVisualChildren(this FrameworkElement root)\n        {\n            if (root == null)\n                yield break;\n\n            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)\n                yield return VisualTreeHelper.GetChild(root, i) as FrameworkElement;\n        }\n\n        /// <summary>\n        /// Gets the ancestors of the element, up to the root\n        /// </summary>\n        /// <param name=\"node\">The element to start from</param>\n        /// <returns>An enumerator of the ancestors</returns>\n        public static IEnumerable<FrameworkElement> GetVisualAncestors(this FrameworkElement node)\n        {\n            FrameworkElement parent = node.GetVisualParent();\n            while (parent != null)\n            {\n                yield return parent;\n                parent = parent.GetVisualParent();\n            }\n        }\n\n        /// <summary>\n        /// Gets the visual parent of the element\n        /// </summary>\n        /// <param name=\"node\">The element to check</param>\n        /// <returns>The visual parent</returns>\n        public static FrameworkElement GetVisualParent(this FrameworkElement node)\n        {\n            return VisualTreeHelper.GetParent(node) as FrameworkElement;\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Neptune.Desktop.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp3.1</TargetFramework>\n    <UseWPF>true</UseWPF>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <DefineConstants>TRACE;DESKTOP</DefineConstants>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Xaml.Behaviors.Wpf\" Version=\"1.1.19\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Neptune.Base\\Neptune.Base.csproj\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Folder Include=\"Properties\\\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.Desktop/Storage/FileStorage.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Neptune.Extensions;\n\nnamespace Neptune.Desktop.Storage\n{\n    public static class FileStorage\n    {\n        private static readonly Dictionary<string, SemaphoreSlim> _semaphores = new Dictionary<string, SemaphoreSlim>();\n\n        public static async Task<Stream> OpenFile(string path)\n        {\n            return await Task.Run(() => File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite));\n        }\n\n        public static Task<string> GetText(string path)\n        {\n            return Task.Run(() =>\n            {\n                if (File.Exists(path))\n                    return File.ReadAllText(path);\n\n                return null;\n            });\n        }\n\n        public static async Task WriteText(string path, string text)\n        {\n            var semaphore = GetSemaphore(path);\n            await semaphore.WaitAsync();\n\n            using (var stream = await OpenFile(path))\n            {\n                stream.SetLength(0);\n                stream.WriteText(text);\n            }\n\n            _semaphores.Remove(path);\n            semaphore.Release();\n        }\n\n        public static Task<bool> FileExists(string path)\n        {\n            return Task.Run(() => File.Exists(path));\n        }\n\n        public static Task DeleteFile(string path)\n        {\n            return Task.Run(() =>\n            {\n                if (!File.Exists(path))\n                    throw new FileNotFoundException();\n                File.Delete(path);\n            });\n        }\n\n        public static DateTime GetFileUpdateTime(string path)\n        {\n            return File.GetLastWriteTime(path);\n        }\n\n        public static Task<bool> FolderExists(string path)\n        {\n            return Task.Run(() =>\n            {\n                return Directory.Exists(path);\n            });\n        }\n\n        public static Task CreateFolder(string path)\n        {\n            return Task.Run(() =>\n            {\n                Directory.CreateDirectory(path);\n            });\n        }\n\n        public static Task DeleteFolder(string path)\n        {\n            return Task.Run(() => Directory.Delete(path, true));\n        }\n\n        private static SemaphoreSlim GetSemaphore(string fileName)\n        {\n            if (_semaphores.ContainsKey(fileName))\n                return _semaphores[fileName];\n\n            var semaphore = new SemaphoreSlim(1);\n            _semaphores[fileName] = semaphore;\n            return semaphore;\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Behaviours/IgnoreMouseWheelBehavior.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Input;\nusing System.Windows.Interactivity;\n\nnamespace Neptune.UI.Desktop.Behaviours\n{\n    /// <summary>\n    /// Captures and eats MouseWheel events so that a nested ListBox does not\n    /// prevent an outer scrollable control from scrolling.\n    /// </summary>\n    public sealed class IgnoreMouseWheelBehavior : Behavior<UIElement>\n    {\n\n        protected override void OnAttached()\n        {\n            base.OnAttached();\n            AssociatedObject.PreviewMouseWheel += AssociatedObject_PreviewMouseWheel;\n        }\n\n        protected override void OnDetaching()\n        {\n            AssociatedObject.PreviewMouseWheel -= AssociatedObject_PreviewMouseWheel;\n            base.OnDetaching();\n        }\n\n        void AssociatedObject_PreviewMouseWheel(object sender, MouseWheelEventArgs e)\n        {\n            e.Handled = true;\n\n            var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);\n            e2.RoutedEvent = UIElement.MouseWheelEvent;\n\n            AssociatedObject.RaiseEvent(e2);\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Behaviours/TriggerTransitionBehaviour.cs",
    "content": "﻿#if DESKTOP || PHONE\nusing System.Windows;\nusing System.Windows.Interactivity;\nusing System.Windows.Media.Animation;\n#elif MODERN\nusing Windows.UI.Interactivity;\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Media.Animation;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Behaviours\n{\n    public class TriggerTransitionBehaviour : Behavior<FrameworkElement>\n    {\n\n        public static readonly DependencyProperty ValueProperty =\n            DependencyProperty.Register(\"Value\", typeof(bool), typeof(TriggerTransitionBehaviour), new PropertyMetadata(default(bool), PropertyChangedCallback));\n\n        public bool Value\n        {\n            get { return (bool)GetValue(ValueProperty); }\n            set { SetValue(ValueProperty, value); }\n        }\n\n        private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var b = (TriggerTransitionBehaviour)d;\n\n            if ((bool)e.NewValue)\n                b.TransitionIn();\n            else\n                b.TransitionOut();\n        }\n\n\n        public static readonly DependencyProperty AnimationOutProperty =\n            DependencyProperty.Register(\"AnimationOut\", typeof(Storyboard), typeof(TriggerTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationOut\n        {\n            get { return (Storyboard)GetValue(AnimationOutProperty); }\n            set { SetValue(AnimationOutProperty, value); }\n        }\n\n        public static readonly DependencyProperty AnimationInProperty =\n            DependencyProperty.Register(\"AnimationIn\", typeof(Storyboard), typeof(TriggerTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationIn\n        {\n            get { return (Storyboard)GetValue(AnimationInProperty); }\n            set { SetValue(AnimationInProperty, value); }\n        }\n\n        private void TransitionOut()\n        {\n            if (AssociatedObject == null)\n                return;\n\n            if (AnimationOut == null)\n            {\n                return;\n            }\n\n            AnimationOut.Stop();\n            Storyboard.SetTarget(AnimationOut, AssociatedObject);\n            AnimationOut.Begin();\n        }\n\n        private void TransitionIn()\n        {\n            if (AssociatedObject == null)\n                return;\n\n            if (AnimationIn != null)\n            {\n#if DESKTOP\n                if (Storyboard.GetTarget(AnimationIn) == AssociatedObject)\n#endif\n                    AnimationIn.Stop();\n\n                Storyboard.SetTarget(AnimationIn, AssociatedObject);\n                AnimationIn.Begin();\n\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Behaviours/UpdateTextBindingOnPropertyChanged.cs",
    "content": "﻿#if DESKTOP || PHONE\nusing System;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Interactivity;\n#elif MODERN\nusing Windows.UI.Interactivity;\nusing Windows.UI.Xaml.Controls;\nusing Windows.UI.Xaml.Data;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Behaviours\n{\n    /// <summary>\n    /// Custom behavior that updates the source of a binding on a text box as the text changes.\n    /// </summary>\n    public class UpdateTextBindingOnPropertyChanged : Behavior<TextBox>\n    {\n        private BindingExpression _expression;\n\n        /// <summary>\n        /// Called after the behavior is attached to an AssociatedObject.\n        /// </summary>\n        /// <remarks>\n        /// Override this to hook up functionality to the AssociatedObject.\n        /// </remarks>\n        protected override void OnAttached()\n        {\n            base.OnAttached();\n\n            this._expression = this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);\n            this.AssociatedObject.TextChanged += this.OnTextChanged;\n        }\n\n        /// <summary>\n        /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.\n        /// </summary>\n        /// <remarks>\n        /// Override this to unhook functionality from the AssociatedObject.\n        /// </remarks>\n        protected override void OnDetaching()\n        {\n            base.OnDetaching();\n\n            this.AssociatedObject.TextChanged -= this.OnTextChanged;\n            this._expression = null;\n        }\n\n#if DESKTOP || PHONE\n        private void OnTextChanged(object sender, EventArgs args)\n#elif MODERN\n       private void OnTextChanged(object sender, TextChangedEventArgs args)\n#endif\n        {\n            if (_expression != null)\n                this._expression.UpdateSource();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Behaviours/VisiblityTransitionBehaviour.cs",
    "content": "﻿#if DESKTOP || PHONE\nusing System.Windows;\nusing System.Windows.Interactivity;\nusing System.Windows.Media.Animation;\n#elif MODERN\nusing Windows.UI.Interactivity;\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Media.Animation;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Behaviours\n{\n    public class VisibilityTransitionBehaviour : Behavior<FrameworkElement>\n    {\n\n        public static readonly DependencyProperty ValueProperty =\n            DependencyProperty.Register(\"Value\", typeof(Visibility), typeof(VisibilityTransitionBehaviour), new PropertyMetadata(default(Visibility), PropertyChangedCallback));\n\n        public Visibility Value\n        {\n            get { return (Visibility)GetValue(ValueProperty); }\n            set { SetValue(ValueProperty, value); }\n        }\n\n        private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)\n        {\n            var b = (VisibilityTransitionBehaviour)d;\n\n            b.TransitionOut((Visibility)e.OldValue);\n        }\n\n\n        public static readonly DependencyProperty AnimationOutProperty =\n            DependencyProperty.Register(\"AnimationOut\", typeof(Storyboard), typeof(VisibilityTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationOut\n        {\n            get { return (Storyboard)GetValue(AnimationOutProperty); }\n            set { SetValue(AnimationOutProperty, value); }\n        }\n\n        public static readonly DependencyProperty AnimationInProperty =\n            DependencyProperty.Register(\"AnimationIn\", typeof(Storyboard), typeof(VisibilityTransitionBehaviour), new PropertyMetadata(default(Storyboard)));\n\n        public Storyboard AnimationIn\n        {\n            get { return (Storyboard)GetValue(AnimationInProperty); }\n            set { SetValue(AnimationInProperty, value); }\n        }\n\n        protected override void OnAttached()\n        {\n            AssociatedObject.Visibility = Value;\n\n            base.OnAttached();\n        }\n\n        private void TransitionOut(Visibility oldValue)\n        {\n            if (AssociatedObject == null)\n                return;\n\n            if (AnimationOut == null || oldValue == Visibility.Collapsed)\n            {\n                TransitionIn();\n            }\n            else\n            {\n#if DESKTOP\n                AnimationOut.Completed += AnimationOutCompleted;\n                AnimationOut.Begin(AssociatedObject);\n#else\n                AnimationOut.Stop();\n                Storyboard.SetTarget(AnimationOut, AssociatedObject);\n                AnimationOut.Completed += AnimationOutCompleted;\n                AnimationOut.Begin();\n#endif\n            }\n        }\n\n        private void TransitionIn()\n        {\n            if (AssociatedObject == null)\n                return;\n\n            AssociatedObject.Visibility = Value;\n            if (AnimationIn != null)\n            {\n#if DESKTOP\n                if (Storyboard.GetTarget(AnimationIn) == AssociatedObject)\n#endif\n                AnimationIn.Stop();\n\n                Storyboard.SetTarget(AnimationIn, AssociatedObject);\n                AnimationIn.Begin();\n\n            }\n        }\n        void AnimationOutCompleted(object sender, object e)\n        {\n            AnimationOut.Completed -= AnimationOutCompleted;\n            TransitionIn();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Converters/BooleanToObjectConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class BooleanToObjectConverter : IValueConverter\n    {\n        public object TrueObject { get; set; }\n\n        public object FalseObject { get; set; }\n\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            bool flag = value is bool ? (bool)value : (value != null && !string.IsNullOrWhiteSpace(value.ToString()));\n\n            return flag ? TrueObject : FalseObject;\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Converters/BooleanToVisibilityConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Windows;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Converters\n{\n    public class BooleanToVisibilityConverter : IValueConverter\n    {\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            var flag = false;\n            if (value is bool)\n            {\n                flag = (bool)value;\n            }\n            else if (value is string)\n            {\n                Boolean.TryParse((string)value, out flag);\n            }\n            if (parameter != null)\n            {\n                bool bParam;\n                if (bool.TryParse((string)parameter, out bParam) && bParam)\n                {\n                    flag = !flag;\n                }\n            }\n            if (flag)\n            {\n                return Visibility.Visible;\n            }\n            else\n            {\n                return Visibility.Collapsed;\n            }\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible));\n            if (parameter != null)\n            {\n                if ((bool)parameter)\n                {\n                    back = !back;\n                }\n            }\n            return back;\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Converters/InvertBooleanConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\nusing System.Windows;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Converters\n{\n    public class InvertBooleanConverter : IValueConverter\n    {\n#if DESKTOP || PHONE\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, string language)\n#endif\n        {\n            if (value is bool)\n            {\n                return !(bool)value;\n            }\n            return false;\n        }\n\n#if DESKTOP || PHONE\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, string language)\n#endif\n        {\n            if (value is bool)\n            {\n                return !(bool)value;\n            }\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Converters/NullToBooleanConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class NullToBooleanConverter : IValueConverter\n    {\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            var invert = false;\n\n            if (parameter != null)\n            {\n                Boolean.TryParse(parameter.ToString(), out invert);\n            }\n\n            if (value == null) return invert;\n\n            if (value is string)\n            {\n                if (!string.IsNullOrWhiteSpace((string)value))\n                    return invert;\n                else\n                    return !invert;\n            }\n\n            return true;\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Converters/NullToVisibilityConverter.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.Globalization;\nusing System.Windows;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class NullToVisibilityConverter : IValueConverter\n    {\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            var invert = false;\n            if (parameter != null)\n            {\n                Boolean.TryParse(parameter.ToString(), out invert);\n            }\n            if (value == null) return invert ? Visibility.Visible : Visibility.Collapsed;\n\n            if (value is string)\n                return string.IsNullOrWhiteSpace((string)value) || invert ? Visibility.Collapsed : Visibility.Visible;\n\n            if (value is IList)\n            {\n                bool empty = ((IList)value).Count == 0;\n                if (invert)\n                    empty = !empty;\n                if (empty)\n                    return Visibility.Collapsed;\n                else\n                    return Visibility.Visible;\n            }\n\n            decimal number;\n            if (Decimal.TryParse(value.ToString(), out number))\n            {\n                if (!invert)\n                    return number > 0 ? Visibility.Visible : Visibility.Collapsed;\n                else\n                    return number > 0 ? Visibility.Collapsed : Visibility.Visible;\n\n            }\n\n            return Visibility.Visible;\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Converters/StringToUpperConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class StringToUpperConverter : IValueConverter\n    {\n#if MODERN\n        public object Convert(object value, Type targetType, object parameter, string culture)\n#else\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n        {\n            return value != null ? ((string)value).ToUpperInvariant() : null;\n        }\n\n#if MODERN\n        public object ConvertBack(object value, Type targetType, object parameter, string culture)\n#else\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n#endif\n\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Converters/TimeSpanConverter.cs",
    "content": "﻿using System;\nusing System.Globalization;\n\n#if DESKTOP\nusing System.Windows.Data;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Data;\n\n#elif PHONE\nusing System.Windows.Data;\n#endif\n\nnamespace Neptune.UI.Converters\n{\n    public class TimeSpanConverter : IValueConverter\n    {\n        public object Convert(object value, Type targetType, object parameter,\n#if !MODERN\n CultureInfo culture)\n#else\n string culture)\n#endif\n        {\n            var t = (TimeSpan)value;\n            return t.ToString((string)parameter);\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter,\n#if !MODERN\n CultureInfo culture)\n#else\n string culture)\n#endif\n        {\n            throw new NotSupportedException();\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Extensions/VisualTreeHelperExtensions.cs",
    "content": "﻿using System.Collections.Generic;\n#if DESKTOP || PHONE\nusing System.Windows;\nusing System.Windows.Media;\n#elif MODERN\nusing Windows.UI.Xaml;\nusing Windows.UI.Xaml.Media;\n#endif\n\n// ReSharper disable once CheckNamespace\nnamespace Neptune.UI.Extensions\n{\n    public static class VisualTreeHelperExtensions\n    {\n        /// <summary>\n        /// Performs a breadth-first enumeration of all the descendents in the tree\n        /// </summary>\n        /// <param name=\"root\">The root node</param>\n        /// <returns>An enumerator of all the children</returns>\n        public static IEnumerable<FrameworkElement> GetVisualDescendents(this FrameworkElement root)\n        {\n\n            var toDo = new Queue<IEnumerable<FrameworkElement>>();\n\n            toDo.Enqueue(root.GetVisualChildren());\n            while (toDo.Count > 0)\n            {\n                IEnumerable<FrameworkElement> children = toDo.Dequeue();\n                foreach (FrameworkElement child in children)\n                {\n                    yield return child;\n                    toDo.Enqueue(child.GetVisualChildren());\n                }\n            }\n\n        }\n\n        /// <summary>\n        /// Gets all the visual children of the element\n        /// </summary>\n        /// <param name=\"root\">The element to get children of</param>\n        /// <returns>An enumerator of the children</returns>\n        public static IEnumerable<FrameworkElement> GetVisualChildren(this FrameworkElement root)\n        {\n            if (root == null)\n                yield break;\n\n            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)\n                yield return VisualTreeHelper.GetChild(root, i) as FrameworkElement;\n        }\n\n        /// <summary>\n        /// Gets the ancestors of the element, up to the root\n        /// </summary>\n        /// <param name=\"node\">The element to start from</param>\n        /// <returns>An enumerator of the ancestors</returns>\n        public static IEnumerable<FrameworkElement> GetVisualAncestors(this FrameworkElement node)\n        {\n            FrameworkElement parent = node.GetVisualParent();\n            while (parent != null)\n            {\n                yield return parent;\n                parent = parent.GetVisualParent();\n            }\n        }\n\n        /// <summary>\n        /// Gets the visual parent of the element\n        /// </summary>\n        /// <param name=\"node\">The element to check</param>\n        /// <returns>The visual parent</returns>\n        public static FrameworkElement GetVisualParent(this FrameworkElement node)\n        {\n            return VisualTreeHelper.GetParent(node) as FrameworkElement;\n        }\n    }\n}\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Neptune.UI.Desktop.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{2097B5FE-54AB-4347-9B7C-B895F3657BE6}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Neptune.UI.Desktop</RootNamespace>\n    <AssemblyName>Neptune.UI.Desktop</AssemblyName>\n    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <SccProjectName>SAK</SccProjectName>\n    <SccLocalPath>SAK</SccLocalPath>\n    <SccAuxPath>SAK</SccAuxPath>\n    <SccProvider>SAK</SccProvider>\n    <SolutionDir Condition=\"$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'\">..\\</SolutionDir>\n    <RestorePackages>true</RestorePackages>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>TRACE;DEBUG;DESKTOP</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE;DESKTOP</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|x86'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>bin\\x86\\Debug\\</OutputPath>\n    <DefineConstants>TRACE;DEBUG;DESKTOP</DefineConstants>\n    <DebugType>full</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <ErrorReport>prompt</ErrorReport>\n    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|x86'\">\n    <OutputPath>bin\\x86\\Release\\</OutputPath>\n    <DefineConstants>TRACE;DESKTOP</DefineConstants>\n    <Optimize>true</Optimize>\n    <DebugType>pdbonly</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <ErrorReport>prompt</ErrorReport>\n    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Microsoft.Expression.Interactions, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Unofficial.Blend.Interactivity.1.0.0\\lib\\net45\\Microsoft.Expression.Interactions.dll</HintPath>\n    </Reference>\n    <Reference Include=\"PresentationCore\" />\n    <Reference Include=\"PresentationFramework\" />\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Unofficial.Blend.Interactivity.1.0.0\\lib\\net45\\System.Windows.Interactivity.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System.Xaml\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Xml\" />\n    <Reference Include=\"WindowsBase\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Behaviours\\IgnoreMouseWheelBehavior.cs\" />\n    <Compile Include=\"Behaviours\\TriggerTransitionBehaviour.cs\" />\n    <Compile Include=\"Behaviours\\UpdateTextBindingOnPropertyChanged.cs\" />\n    <Compile Include=\"Behaviours\\VisiblityTransitionBehaviour.cs\" />\n    <Compile Include=\"Converters\\BooleanToObjectConverter.cs\" />\n    <Compile Include=\"Converters\\BooleanToVisibilityConverter.cs\" />\n    <Compile Include=\"Converters\\InvertBooleanConverter.cs\" />\n    <Compile Include=\"Converters\\NullToBooleanConverter.cs\" />\n    <Compile Include=\"Converters\\NullToVisibilityConverter.cs\" />\n    <Compile Include=\"Converters\\StringToUpperConverter.cs\" />\n    <Compile Include=\"Converters\\TimeSpanConverter.cs\" />\n    <Compile Include=\"Extensions\\VisualTreeHelperExtensions.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Neptune.Base\\Neptune.Base.csproj\">\n      <Project>{d914b630-6f50-47de-9719-6cd7644c6908}</Project>\n      <Name>Neptune.Base</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <Import Project=\"$(SolutionDir)\\.nuget\\NuGet.targets\" Condition=\"Exists('$(SolutionDir)\\.nuget\\NuGet.targets')\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Neptune.UI.Desktop\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Neptune.UI.Desktop\")]\n[assembly: AssemblyCopyright(\"Copyright © Stealth 2013\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"14cfbe0a-e119-4148-8698-02e4e8554d22\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"2.0.0.0\")]\n[assembly: AssemblyFileVersion(\"2.0.0.0\")]\n"
  },
  {
    "path": "Neptune/Trunk/Neptune.UI.Desktop/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Unofficial.Blend.Interactivity\" version=\"1.0.0\" targetFramework=\"net45\" />\n</packages>"
  },
  {
    "path": "README.md",
    "content": "## Meridian\nMeridian is a music player which allows you to listen to music from popular russian social network [vk.com](https://vk.com). It communicates with some additional services like [echonest.com](http://the.echonest.com) and [last.fm](http://last.fm) to bring to you some advanced features: recommendations by genres, moods and your tastes, artists and albums search, artist radio and other. Meridian written in C# and WPF 4.5.\nThis is the old WPF desktop version. The source code for new UWP version for Windows 10 can be found [here](https://github.com/artemshuba/meridian-uwp).\n\n## Source code\nHere is a source code of Meridian starting 4 version.\nUnfortunately most parts of code isn't documented yet.\n\n## Contributing\nChanges and improvements are very welcome. Feel free to fork and open a pull request.\n\n## License\nThe source code is licensed under the [Apache License](LICENSE.txt).\n"
  },
  {
    "path": "refs/GongSolutions.Wpf.DragDrop.XML",
    "content": "<?xml version=\"1.0\"?>\n<doc>\n    <assembly>\n        <name>GongSolutions.Wpf.DragDrop</name>\n    </assembly>\n    <members>\n        <member name=\"T:GongSolutions.Wpf.DragDrop.IDragSource\">\n            <summary>\n            Interface implemented by Drag Handlers.\n            </summary>\n        </member>\n        <member name=\"M:GongSolutions.Wpf.DragDrop.IDragSource.StartDrag(GongSolutions.Wpf.DragDrop.IDragInfo)\">\n            <summary>\n            Queries whether a drag can be started.\n            </summary>\n            \n            <param name=\"dragInfo\">\n            Information about the drag.\n            </param>\n            \n            <remarks>\n            To allow a drag to be started, the <see cref=\"P:GongSolutions.Wpf.DragDrop.DragInfo.Effects\"/> property on <paramref name=\"dragInfo\"/> \n            should be set to a value other than <see cref=\"F:System.Windows.DragDropEffects.None\"/>. \n            </remarks>\n        </member>\n        <member name=\"M:GongSolutions.Wpf.DragDrop.IDragSource.Dropped(GongSolutions.Wpf.DragDrop.IDropInfo)\">\n            <summary>\n            Notifies the drag handler that a drop has occurred.\n            </summary>\n            \n            <param name=\"dropInfo\">\n              Information about the drop.\n            </param>\n        </member>\n        <member name=\"M:GongSolutions.Wpf.DragDrop.IDragSource.DragCancelled\">\n            <summary>\n            Notifies the drag handler that a drag has been aborted.\n            </summary>\n        </member>\n        <member name=\"T:GongSolutions.Wpf.DragDrop.IDropTarget\">\n            <summary>\n            Interface implemented by Drop Handlers.\n            </summary>\n        </member>\n        <member name=\"M:GongSolutions.Wpf.DragDrop.IDropTarget.DragOver(GongSolutions.Wpf.DragDrop.IDropInfo)\">\n            <summary>\n            Updates the current drag state.\n            </summary>\n            \n            <param name=\"dropInfo\">\n              Information about the drag.\n            </param>\n            \n            <remarks>\n            To allow a drop at the current drag position, the <see cref=\"P:GongSolutions.Wpf.DragDrop.DropInfo.Effects\"/> property on \n            <paramref name=\"dropInfo\"/> should be set to a value other than <see cref=\"F:System.Windows.DragDropEffects.None\"/>\n            and <see cref=\"P:GongSolutions.Wpf.DragDrop.DropInfo.Data\"/> should be set to a non-null value.\n            </remarks>\n        </member>\n        <member name=\"M:GongSolutions.Wpf.DragDrop.IDropTarget.Drop(GongSolutions.Wpf.DragDrop.IDropInfo)\">\n            <summary>\n            Performs a drop.\n            </summary>\n            \n            <param name=\"dropInfo\">\n              Information about the drop.\n            </param>\n        </member>\n        <member name=\"F:GongSolutions.Wpf.DragDrop.DragDrop.DragMouseAnchorPointProperty\">\n            <summary>\n            DragMouseAnchorPoint defines the horizontal and vertical proportion at which the pointer will anchor on the DragAdorner.\n            </summary>\n        </member>\n        <member name=\"T:GongSolutions.Wpf.DragDrop.DragInfo\">\n            <summary>\n            Holds information about a the source of a drag drop operation.\n            </summary>\n            \n            <remarks>\n            The <see cref=\"T:GongSolutions.Wpf.DragDrop.DragInfo\"/> class holds all of the framework's information about the source\n            of a drag. It is used by <see cref=\"M:GongSolutions.Wpf.DragDrop.IDragSource.StartDrag(GongSolutions.Wpf.DragDrop.IDragInfo)\"/> to determine whether a drag \n            can start, and what the dragged data should be.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.Data\">\n            <summary>\n            Gets or sets the drag data.\n            </summary>\n            \n            <remarks>\n            This must be set by a drag handler in order for a drag to start.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.DragStartPosition\">\n            <summary>\n            Gets the position of the click that initiated the drag, relative to <see cref=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.VisualSource\"/>.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.PositionInDraggedItem\">\n            <summary>\n            Gets the point where the cursor was relative to the item being dragged when the drag was started.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.Effects\">\n            <summary>\n            Gets or sets the allowed effects for the drag.\n            </summary>\n            \n            <remarks>\n            This must be set to a value other than <see cref=\"F:System.Windows.DragDropEffects.None\"/> by a drag handler in order \n            for a drag to start.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.MouseButton\">\n            <summary>\n            Gets the mouse button that initiated the drag.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.SourceCollection\">\n            <summary>\n            Gets the collection that the source ItemsControl is bound to.\n            </summary>\n            \n            <remarks>\n            If the control that initated the drag is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.SourceIndex\">\n            <summary>\n            Gets the position from where the item was dragged.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.SourceItem\">\n            <summary>\n            Gets the object that a dragged item is bound to.\n            </summary>\n            \n            <remarks>\n            If the control that initated the drag is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.SourceItems\">\n            <summary>\n            Gets a collection of objects that the selected items in an ItemsControl are bound to.\n            </summary>\n            \n            <remarks>\n            If the control that initated the drag is unbound or not an ItemsControl, this will be empty.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.VisualSource\">\n            <summary>\n            Gets the control that initiated the drag.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.VisualSourceItem\">\n            <summary>\n            Gets the item in an ItemsControl that started the drag.\n            </summary>\n            \n            <remarks>\n            If the control that initiated the drag is an ItemsControl, this property will hold the item\n            container of the clicked item. For example, if <see cref=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.VisualSource\"/> is a ListBox this\n            will hold a ListBoxItem.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.VisualSourceFlowDirection\">\n            <summary>\n            Gets the FlowDirection of the current drag source.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDragInfo.DataObject\">\n            <summary>\n            Gets the <see cref=\"T:System.Windows.IDataObject\"/> which is used by the drag and drop operation. Set it to\n            a custom instance if custom drag and drop behavior is needed.\n            </summary>\n        </member>\n        <member name=\"M:GongSolutions.Wpf.DragDrop.DragInfo.#ctor(System.Object,System.Windows.Input.MouseButtonEventArgs)\">\n            <summary>\n            Initializes a new instance of the DragInfo class.\n            </summary>\n            \n            <param name=\"sender\">\n            The sender of the mouse event that initiated the drag.\n            </param>\n            \n            <param name=\"e\">\n            The mouse event that initiated the drag.\n            </param>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.Data\">\n            <summary>\n            Gets or sets the drag data.\n            </summary>\n            \n            <remarks>\n            This must be set by a drag handler in order for a drag to start.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.DragStartPosition\">\n            <summary>\n            Gets the position of the click that initiated the drag, relative to <see cref=\"P:GongSolutions.Wpf.DragDrop.DragInfo.VisualSource\"/>.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.PositionInDraggedItem\">\n            <summary>\n            Gets the point where the cursor was relative to the item being dragged when the drag was started.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.Effects\">\n            <summary>\n            Gets or sets the allowed effects for the drag.\n            </summary>\n            \n            <remarks>\n            This must be set to a value other than <see cref=\"F:System.Windows.DragDropEffects.None\"/> by a drag handler in order \n            for a drag to start.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.MouseButton\">\n            <summary>\n            Gets the mouse button that initiated the drag.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.SourceCollection\">\n            <summary>\n            Gets the collection that the source ItemsControl is bound to.\n            </summary>\n            \n            <remarks>\n            If the control that initated the drag is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.SourceIndex\">\n            <summary>\n            Gets the position from where the item was dragged.\n            </summary>\n            <value>The index of the source.</value>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.SourceItem\">\n            <summary>\n            Gets the object that a dragged item is bound to.\n            </summary>\n            \n            <remarks>\n            If the control that initated the drag is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.SourceItems\">\n            <summary>\n            Gets a collection of objects that the selected items in an ItemsControl are bound to.\n            </summary>\n            \n            <remarks>\n            If the control that initated the drag is unbound or not an ItemsControl, this will be empty.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.VisualSource\">\n            <summary>\n            Gets the control that initiated the drag.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.VisualSourceItem\">\n            <summary>\n            Gets the item in an ItemsControl that started the drag.\n            </summary>\n            \n            <remarks>\n            If the control that initiated the drag is an ItemsControl, this property will hold the item\n            container of the clicked item. For example, if <see cref=\"P:GongSolutions.Wpf.DragDrop.DragInfo.VisualSource\"/> is a ListBox this\n            will hold a ListBoxItem.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.VisualSourceFlowDirection\">\n            <summary>\n            Gets the FlowDirection of the current drag source.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DragInfo.DataObject\">\n            <summary>\n            Gets the <see cref=\"T:System.Windows.IDataObject\"/> which is used by the drag and drop operation. Set it to\n            a custom instance if custom drag and drop behavior is needed.\n            </summary>\n        </member>\n        <member name=\"T:GongSolutions.Wpf.DragDrop.DropInfo\">\n            <summary>\n            Holds information about a the target of a drag drop operation.\n            </summary>\n            \n            <remarks>\n            The <see cref=\"T:GongSolutions.Wpf.DragDrop.DropInfo\"/> class holds all of the framework's information about the current \n            target of a drag. It is used by <see cref=\"M:GongSolutions.Wpf.DragDrop.IDropTarget.DragOver(GongSolutions.Wpf.DragDrop.IDropInfo)\"/> method to determine whether \n            the current drop target is valid, and by <see cref=\"M:GongSolutions.Wpf.DragDrop.IDropTarget.Drop(GongSolutions.Wpf.DragDrop.IDropInfo)\"/> to perform the drop.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.Data\">\n            <summary>\n            Gets the drag data.\n            </summary>\n            \n            <remarks>\n            If the drag came from within the framework, this will hold:\n            \n            - The dragged data if a single item was dragged.\n            - A typed IEnumerable if multiple items were dragged.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.DragInfo\">\n            <summary>\n            Gets a <see cref=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.DragInfo\"/> object holding information about the source of the drag, \n            if the drag came from within the framework.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.DropPosition\">\n            <summary>\n            Gets the mouse position relative to the VisualTarget\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.DropTargetAdorner\">\n            <summary>\n            Gets or sets the class of drop target to display.\n            </summary>\n            \n            <remarks>\n            The standard drop target adorner classes are held in the <see cref=\"T:GongSolutions.Wpf.DragDrop.DropTargetAdorners\"/>\n            class.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.Effects\">\n            <summary>\n            Gets or sets the allowed effects for the drop.\n            </summary>\n            \n            <remarks>\n            This must be set to a value other than <see cref=\"F:System.Windows.DragDropEffects.None\"/> by a drop handler in order \n            for a drop to be possible.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.InsertIndex\">\n            <summary>\n            Gets the current insert position within <see cref=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.TargetCollection\"/>.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.TargetCollection\">\n            <summary>\n            Gets the collection that the target ItemsControl is bound to.\n            </summary>\n            \n            <remarks>\n            If the current drop target is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.TargetItem\">\n            <summary>\n            Gets the object that the current drop target is bound to.\n            </summary>\n            \n            <remarks>\n            If the current drop target is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.TargetGroup\">\n            <summary>\n            Gets the current group target.\n            </summary>\n            \n            <remarks>\n            If the drag is currently over an ItemsControl with groups, describes the group that\n            the drag is currently over.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.VisualTarget\">\n            <summary>\n            Gets the control that is the current drop target.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.VisualTargetItem\">\n            <summary>\n            Gets the item in an ItemsControl that is the current drop target.\n            </summary>\n            \n            <remarks>\n            If the current drop target is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.VisualTargetOrientation\">\n            <summary>\n            Gets the orientation of the current drop target.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.VisualTargetFlowDirection\">\n            <summary>\n            Gets the FlowDirection of the current drop target.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.DestinationText\">\n            <summary>\n            Gets and sets the text displayed in the DropDropEffects adorner.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.InsertPosition\">\n            <summary>\n            Gets the relative position the item will be inserted to compared to the TargetItem\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.KeyStates\">\n            <summary>\n            Gets a flag enumeration indicating the current state of the SHIFT, CTRL, and ALT keys, as well as the state of the mouse buttons.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.IDropInfo.NotHandled\">\n            <summary>\n            Indicates if the drop info should be handled by itself (useful for child elements)\n            </summary>\n        </member>\n        <member name=\"M:GongSolutions.Wpf.DragDrop.DropInfo.#ctor(System.Object,System.Windows.DragEventArgs,GongSolutions.Wpf.DragDrop.DragInfo)\">\n            <summary>\n            Initializes a new instance of the DropInfo class.\n            </summary>\n            \n            <param name=\"sender\">\n            The sender of the drag event.\n            </param>\n            \n            <param name=\"e\">\n            The drag event.\n            </param>\n            \n            <param name=\"dragInfo\">\n            Information about the source of the drag, if the drag came from within the framework.\n            </param>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.Data\">\n            <summary>\n            Gets the drag data.\n            </summary>\n            \n            <remarks>\n            If the drag came from within the framework, this will hold:\n            \n            - The dragged data if a single item was dragged.\n            - A typed IEnumerable if multiple items were dragged.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.DragInfo\">\n            <summary>\n            Gets a <see cref=\"P:GongSolutions.Wpf.DragDrop.DropInfo.DragInfo\"/> object holding information about the source of the drag, \n            if the drag came from within the framework.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.DropPosition\">\n            <summary>\n            Gets the mouse position relative to the VisualTarget\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.DropTargetAdorner\">\n            <summary>\n            Gets or sets the class of drop target to display.\n            </summary>\n            \n            <remarks>\n            The standard drop target adorner classes are held in the <see cref=\"T:GongSolutions.Wpf.DragDrop.DropTargetAdorners\"/>\n            class.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.Effects\">\n            <summary>\n            Gets or sets the allowed effects for the drop.\n            </summary>\n            \n            <remarks>\n            This must be set to a value other than <see cref=\"F:System.Windows.DragDropEffects.None\"/> by a drop handler in order \n            for a drop to be possible.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.InsertIndex\">\n            <summary>\n            Gets the current insert position within <see cref=\"P:GongSolutions.Wpf.DragDrop.DropInfo.TargetCollection\"/>.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.TargetCollection\">\n            <summary>\n            Gets the collection that the target ItemsControl is bound to.\n            </summary>\n            \n            <remarks>\n            If the current drop target is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.TargetItem\">\n            <summary>\n            Gets the object that the current drop target is bound to.\n            </summary>\n            \n            <remarks>\n            If the current drop target is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.TargetGroup\">\n            <summary>\n            Gets the current group target.\n            </summary>\n            \n            <remarks>\n            If the drag is currently over an ItemsControl with groups, describes the group that\n            the drag is currently over.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.VisualTarget\">\n            <summary>\n            Gets the control that is the current drop target.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.VisualTargetItem\">\n            <summary>\n            Gets the item in an ItemsControl that is the current drop target.\n            </summary>\n            \n            <remarks>\n            If the current drop target is unbound or not an ItemsControl, this will be null.\n            </remarks>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.VisualTargetOrientation\">\n            <summary>\n            Gets the orientation of the current drop target.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.VisualTargetFlowDirection\">\n            <summary>\n            Gets the orientation of the current drop target.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.DestinationText\">\n            <summary>\n            Gets and sets the text displayed in the DropDropEffects adorner.\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.InsertPosition\">\n            <summary>\n            Gets the relative position the item will be inserted to compared to the TargetItem\n            </summary>\n        </member>\n        <member name=\"P:GongSolutions.Wpf.DragDrop.DropInfo.KeyStates\">\n            <summary>\n            Gets a flag enumeration indicating the current state of the SHIFT, CTRL, and ALT keys, as well as the state of the mouse buttons.\n            </summary>\n        </member>\n        <member name=\"T:GongSolutions.Wpf.DragDrop.Icons.IconFactory\">\n            <summary>\n            Static class to provide access to standard application images\n            </summary>\n        </member>\n        <member name=\"M:GongSolutions.Wpf.DragDrop.Icons.IconFactory.GetImage(System.String,System.Int32)\">\n            <summary>\n            Loads an image based on the name and size required.\n            Images need to be marked as 'Resource' in the project for them be loaded.\n            </summary>\n            <param name=\"iconName\">Name of the icon</param>\n            <param name=\"size\">The size of the icon</param>\n            <returns>The image to be displayed</returns>\n        </member>\n        <member name=\"M:GongSolutions.Wpf.DragDrop.Utilities.VisualTreeExtensions.GetVisualAncestor(System.Windows.DependencyObject,System.Type,System.Windows.Controls.ItemsControl)\">\n            <summary>\n            find the visual ancestor by type and go through the visual tree until the given itemsControl will be found\n            </summary>\n        </member>\n    </members>\n</doc>\n"
  }
]