/// <summary>
        /// 직렬화된 Json 텍스트로 <seealso cref="XPath"/>의 새 인스턴스를 초기화합니다. <paramref name="json"/>이 null일 경우 <seealso cref="ArgumentNullException"/>합니다.
        /// </summary>
        /// <param name="json">Json 텍스트입니다.</param>
        public XPath(string json)
        {
            if (string.IsNullOrEmpty(json))
            {
                throw new ArgumentNullException("json text가 null입니다.");
            }
            XPath xPath = JsonConvert.DeserializeObject <XPath>(json);

            LatestEpisode = xPath.LatestEpisode;
            ComicContent  = xPath.ComicContent;
            WebtoonTitle  = xPath.WebtoonTitle;
            EpisodeTitle  = xPath.EpisodeTitle;
            Date          = xPath.Date;
        }
        static void Main(string[] args)
        {
            string assemblyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();

            string[] assemsplit = assemblyVersion.Split('.');
            var      version    = $"{assemsplit[0]}.{assemsplit[1]}";
            var      build      = $"{assemsplit[2]}.{assemsplit[3]}";
            var      Title      = $"네이버 웹툰 다운로더 v{version} ({build})";

            Console.Title = Title;
            IO.Print($" 네이버 웹툰 다운로더 v{version} (빌드 {build})", false);
            CheckUpdate(assemblyVersion);
            IO.Print($" 홈페이지 : https://nwd.wrforest.com/");
            IO.Print($" 소스코드 : https://github.com/wr-rainforest/Naver-Webtoon-Downloader");
            IO.Print($" 연락처   : [email protected]");
            IO.Print(new string('-', 100));
            IO.Print(" 명령어   : download [$$titleId$green$] 웹툰을 다운로드합니다. / 단축 명령어 d");
            IO.Print("            예) download $$20853$green$ ");
            IO.Print("                d $$183559$green$ $$20853$green$ ");
            IO.Print("            ) comic.naver.com/webtoon/list.nhn?titleId=$$20853$green$");
            IO.Print("");
            IO.Print("            get [$$weekday$green$] 선택한 요일(mon/tue/wed/thu/fri/sat/sun)의 웹툰 목록을 불러옵니다.");
            IO.Print("            예) get $$mon$green$ ");
            IO.Print("");
            IO.Print("            merge [$$titleId$green$] 다운로드된 이미지를 하나의 파일로 병합합니다. / [$$titleId$green$] :병합할 웹툰의 $$titleId$green$입니다. ");
            IO.Print("            예) merge $$20853$green$ ");
            IO.Print("                merge $$183559$green$ $$20853$green$ $$703846$green$ ");
            IO.Print("            주의사항)  ");
            IO.Print("");
            IO.Print(" \r\n 키보드의 ↑ ↓ 버튼으로 이전에 입력했던 값을 불러올 수 있습니다. 프로그램 종료시 초기화됩니다.");
            IO.Print(new string('-', 100));
            cursorPosition = Console.CursorTop;

            string configFolderPath    = "Config";
            string configFileName      = "config.json";
            string xPathConfigFileName = "xpath.json";

            Parser.XPath xPath;
            Config       config;

            if (IO.Exists(configFolderPath, configFileName))
            {
                config = new Config(IO.ReadTextFile(configFolderPath, configFileName));
            }
            else
            {
                config = new Config();
                IO.WriteTextFile(configFolderPath, configFileName, config.ToJsonString());
            }
            if (IO.Exists(configFolderPath, xPathConfigFileName))
            {
                xPath = new Parser.XPath(IO.ReadTextFile(configFolderPath, xPathConfigFileName));
            }
            else
            {
                xPath = new Parser.XPath();
                IO.WriteTextFile(configFolderPath, xPathConfigFileName, xPath.ToJsonString());
            }
            Parser.Parser.Instance.SetXPath(xPath);
            Downloader.SetConfig(config);
            Downloader.ProgressChangedEvent += PrintProgess;
            Command command = new Command();

            string[] commands = command.GetCommandList();


            while (true)
            {
                Console.Write("[Command] : ");
                string userInput = Console.ReadLine();
                if (string.IsNullOrWhiteSpace(userInput))
                {
                    IO.PrintError("명령어를 입력해주세요.");
                    continue;
                }
                string[]      split = userInput.Trim().Split(' ');
                List <string> list  = new List <string>(split);
                if (command.Contains(list[0]))
                {
                    list.RemoveAt(0);
                    command.Start(split[0], list.ToArray());
                }
                else
                {
                    IO.PrintError("존재하지 않는 명령어입니다.");
                }
            }
        }