sungrouptech 10 달 전
커밋
25976c12ff
100개의 변경된 파일6160개의 추가작업 그리고 0개의 파일을 삭제
  1. 146 0
      .gitignore
  2. 25 0
      WebChallenge/Mzb_WebChallenge.sln
  3. 12 0
      WebChallenge/WebChallenge/.config/dotnet-tools.json
  4. 282 0
      WebChallenge/WebChallenge/Controllers/BaseController.cs
  5. 637 0
      WebChallenge/WebChallenge/Controllers/HomeController.cs
  6. 43 0
      WebChallenge/WebChallenge/Controllers/LanguageController.cs
  7. 31 0
      WebChallenge/WebChallenge/Extensions/ConfigAction.cs
  8. 10 0
      WebChallenge/WebChallenge/Extensions/DateTimeExtensions.cs
  9. 29 0
      WebChallenge/WebChallenge/Extensions/RewriteSubdomainRule.cs
  10. 29 0
      WebChallenge/WebChallenge/Extensions/SessionExtensions.cs
  11. 9 0
      WebChallenge/WebChallenge/Models/ErrorViewModel.cs
  12. 28 0
      WebChallenge/WebChallenge/Models/LoginRequest.cs
  13. 30 0
      WebChallenge/WebChallenge/Models/MpsRequest.cs
  14. 37 0
      WebChallenge/WebChallenge/Models/PlayHistory.cs
  15. 101 0
      WebChallenge/WebChallenge/Models/PlayRequest.cs
  16. 33 0
      WebChallenge/WebChallenge/Models/PlayTop.cs
  17. 10 0
      WebChallenge/WebChallenge/Models/Posting.cs
  18. 55 0
      WebChallenge/WebChallenge/Models/UserInfo.cs
  19. 58 0
      WebChallenge/WebChallenge/Models/Winner.cs
  20. 40 0
      WebChallenge/WebChallenge/Program.cs
  21. 22 0
      WebChallenge/WebChallenge/Properties/PublishProfiles/FolderProfile.pubxml
  22. 23 0
      WebChallenge/WebChallenge/Properties/PublishProfiles/FolderProfile1.pubxml
  23. 30 0
      WebChallenge/WebChallenge/Properties/launchSettings.json
  24. 93 0
      WebChallenge/WebChallenge/Startup.cs
  25. 697 0
      WebChallenge/WebChallenge/Texts/Lang.Designer.cs
  26. 332 0
      WebChallenge/WebChallenge/Texts/Lang.fr.resx
  27. 334 0
      WebChallenge/WebChallenge/Texts/Lang.resx
  28. 96 0
      WebChallenge/WebChallenge/Views/Home/BuyTurn.cshtml
  29. 162 0
      WebChallenge/WebChallenge/Views/Home/Guide0.cshtml
  30. 174 0
      WebChallenge/WebChallenge/Views/Home/Guide1.cshtml
  31. 93 0
      WebChallenge/WebChallenge/Views/Home/History.cshtml
  32. 204 0
      WebChallenge/WebChallenge/Views/Home/Index.cshtml
  33. 127 0
      WebChallenge/WebChallenge/Views/Home/Login.cshtml
  34. 255 0
      WebChallenge/WebChallenge/Views/Home/Playing.cshtml
  35. 107 0
      WebChallenge/WebChallenge/Views/Home/Ranking.cshtml
  36. 99 0
      WebChallenge/WebChallenge/Views/Home/Setting.cshtml
  37. 123 0
      WebChallenge/WebChallenge/Views/Home/Signup.cshtml
  38. 20 0
      WebChallenge/WebChallenge/Views/Home/Start.cshtml
  39. 57 0
      WebChallenge/WebChallenge/Views/Home/Winner.cshtml
  40. 89 0
      WebChallenge/WebChallenge/Views/Home/WinnerDaily.cshtml
  41. 91 0
      WebChallenge/WebChallenge/Views/Home/WinnerMonthly.cshtml
  42. 21 0
      WebChallenge/WebChallenge/Views/Home/_Navigation.cshtml
  43. 25 0
      WebChallenge/WebChallenge/Views/Shared/Error.cshtml
  44. 342 0
      WebChallenge/WebChallenge/Views/Shared/_Layout.cshtml
  45. 113 0
      WebChallenge/WebChallenge/Views/Shared/_LayoutLogin.cshtml
  46. 2 0
      WebChallenge/WebChallenge/Views/Shared/_ValidationScriptsPartial.cshtml
  47. 4 0
      WebChallenge/WebChallenge/Views/_ViewImports.cshtml
  48. 74 0
      WebChallenge/WebChallenge/Views/_ViewStart.cshtml
  49. 46 0
      WebChallenge/WebChallenge/WebChallenge.csproj
  50. 9 0
      WebChallenge/WebChallenge/appsettings.Development.json
  51. 33 0
      WebChallenge/WebChallenge/appsettings.json
  52. 21 0
      WebChallenge/WebChallenge/log4net.config
  53. 3 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/arrow-down.svg
  54. 3 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/arrow-to-left.svg
  55. 3 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/arrow-to-right.svg
  56. 41 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/arrow_1.svg
  57. 38 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/arrow_2.svg
  58. 7 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/close.svg
  59. 38 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/coin.svg
  60. 6 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/cup.svg
  61. 24 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/error.svg
  62. 3 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/exit.svg
  63. 3 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/guide.svg
  64. 3 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/history.svg
  65. 3 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/home.svg
  66. 3 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/icon_1.svg
  67. 21 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/icon_2.svg
  68. 22 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/icon_3.svg
  69. 3 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/icon_4.svg
  70. 6 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/lang-1.svg
  71. 6 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/lang-2.svg
  72. 66 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_1.svg
  73. BIN
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_1.zip
  74. 10 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_10.svg
  75. 10 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_2.svg
  76. 10 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_3.svg
  77. 66 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_4.svg
  78. 10 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_5.svg
  79. 10 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_6.svg
  80. 66 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_7.svg
  81. 10 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_8.svg
  82. 10 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/level_9.svg
  83. 11 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/logo.svg
  84. 5 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/logout.svg
  85. 9 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/number_10.svg
  86. 9 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/number_5.svg
  87. 5 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/setting.svg
  88. 6 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/start-fill.svg
  89. 10 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/start.svg
  90. 38 0
      WebChallenge/WebChallenge/wwwroot/assets/icons/success.svg
  91. BIN
      WebChallenge/WebChallenge/wwwroot/assets/icons/warning.png
  92. BIN
      WebChallenge/WebChallenge/wwwroot/assets/images/Frame_25.png
  93. BIN
      WebChallenge/WebChallenge/wwwroot/assets/images/Group-35.png
  94. BIN
      WebChallenge/WebChallenge/wwwroot/assets/images/Group_31.png
  95. BIN
      WebChallenge/WebChallenge/wwwroot/assets/images/avt.png
  96. BIN
      WebChallenge/WebChallenge/wwwroot/assets/images/bg_image.png
  97. BIN
      WebChallenge/WebChallenge/wwwroot/assets/images/bg_image_2.png
  98. BIN
      WebChallenge/WebChallenge/wwwroot/assets/images/bg_image_no_text.png
  99. BIN
      WebChallenge/WebChallenge/wwwroot/assets/images/bg_image_no_text_2.jpg
  100. BIN
      WebChallenge/WebChallenge/wwwroot/assets/images/bg_image_old.png

+ 146 - 0
.gitignore

@@ -0,0 +1,146 @@
+*.swp
+*.*~
+project.lock.json
+.DS_Store
+*.pyc
+nupkg/
+
+# Visual Studio Code
+.vscode/
+
+# Rider
+.idea/
+
+# Visual Studio
+.vs/
+
+# Fleet
+.fleet/
+
+# Code Rush
+.cr/
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+[Oo]ut/
+msbuild.log
+msbuild.err
+msbuild.wrn
+
+
+##############################
+## Java
+##############################
+.mtj.tmp/
+*.class
+#*.jar
+*.war
+*.ear
+*.nar
+hs_err_pid*
+replay_pid*
+
+##############################
+## Maven
+##############################
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+pom.xml.bak
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+.mvn/wrapper/maven-wrapper.jar
+
+##############################
+## Gradle
+##############################
+bin/
+build/
+.gradle
+.gradletasknamecache
+gradle-app.setting
+!gradle-wrapper.jar
+
+##############################
+## IntelliJ
+##############################
+out/
+.idea/
+.idea_modules/
+*.iml
+*.ipr
+*.iws
+
+##############################
+## Eclipse
+##############################
+.settings/
+bin/
+tmp/
+.metadata
+.classpath
+.project
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.loadpath
+.factorypath
+
+##############################
+## NetBeans
+##############################
+nbproject/
+build/
+nbbuild/
+dist/
+nbdist/
+nbactions.xml
+nb-configuration.xml
+build.xml
+manifest.mf
+
+##############################
+## Visual Studio Code
+##############################
+.vscode/
+.code-workspace
+
+##############################
+## OS X
+##############################
+.DS_Store
+
+##############################
+## Miscellaneous
+##############################
+*.log
+
+**/nbproject/private/
+**/nbproject/Makefile-*.mk
+**/nbproject/Package-*.bash
+build/
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/

+ 25 - 0
WebChallenge/Mzb_WebChallenge.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34723.18
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebChallenge", "WebChallenge\WebChallenge.csproj", "{BC25F25C-6C4F-4DF1-963A-F9DAA7CEA50D}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{BC25F25C-6C4F-4DF1-963A-F9DAA7CEA50D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BC25F25C-6C4F-4DF1-963A-F9DAA7CEA50D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BC25F25C-6C4F-4DF1-963A-F9DAA7CEA50D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BC25F25C-6C4F-4DF1-963A-F9DAA7CEA50D}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {E243C365-0419-44E8-828A-D9E37D10879B}
+	EndGlobalSection
+EndGlobal

+ 12 - 0
WebChallenge/WebChallenge/.config/dotnet-tools.json

@@ -0,0 +1,12 @@
+{
+  "version": 1,
+  "isRoot": true,
+  "tools": {
+    "dotnet-ef": {
+      "version": "9.0.0",
+      "commands": [
+        "dotnet-ef"
+      ]
+    }
+  }
+}

+ 282 - 0
WebChallenge/WebChallenge/Controllers/BaseController.cs

@@ -0,0 +1,282 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using WebChallenge;
+using WebChallenge.Extensions;
+using WebChallenge.Models;
+
+namespace WebChallenge.Controllers
+{
+    public class BaseController : Controller
+    {
+
+        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
+        private readonly IWebHostEnvironment webHostEnvironment;
+
+        protected IConfiguration configuration;
+        public static string CountryCode = "257";
+        public static string ServiceId = "2";
+
+        public BaseController() { }
+        public BaseController(IConfiguration _configuration, IWebHostEnvironment hostEnvironment)
+        {
+            configuration = _configuration;
+            webHostEnvironment = hostEnvironment;
+            CountryCode = configuration["countryCode"];
+            ServiceId = configuration["service_id"];
+
+        }
+
+        public string GetParameter(string key)
+        {
+            return configuration.GetSection(key).Value;
+        }
+
+        public string GetParameter(string parentKey, string key)
+        {
+            var configs = configuration.GetSection(parentKey).GetChildren();
+            foreach (IConfiguration config in configs)
+            {
+                if (config[key] != null)
+                {
+                    return config[key];
+                }
+            }
+            return "";
+        }
+
+
+        public string RandomString(int size, bool lowerCase)
+        {
+            StringBuilder builder = new StringBuilder();
+            Random random = new Random();
+            char ch;
+            for (int i = 0; i < size; i++)
+            {
+                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
+                builder.Append(ch);
+            }
+            if (lowerCase)
+                return builder.ToString().ToLower();
+            return builder.ToString();
+        }
+
+        protected string convertToDateTimeServer(string date)
+        {
+            // date: 
+            DateTime oDateFrom = DateTime.Parse(date);
+            string hour = oDateFrom.Hour < 10 ? "0" + oDateFrom.Hour : oDateFrom.Hour.ToString();
+            string minute = oDateFrom.Minute < 10 ? "0" + oDateFrom.Minute : oDateFrom.Minute.ToString();
+            string second = oDateFrom.Second < 10 ? "0" + oDateFrom.Second : oDateFrom.Second.ToString();
+            string month = oDateFrom.Month < 10 ? "0" + oDateFrom.Month : oDateFrom.Month.ToString();
+            string day = oDateFrom.Day < 10 ? "0" + oDateFrom.Day : oDateFrom.Day.ToString();
+            string fromCheck = day + "/" + month + "/" + oDateFrom.Year + " " + hour + ":" + minute + ":" + second;
+            return fromCheck; //MM/dd/yyyy HH24:mm:ss
+        }
+        public string SendPost(Posting obj, string url)
+        {
+            return SendPost(obj, ServiceId, url);
+
+        }
+
+        public string SendPost(Posting obj, string url, bool checkToken)
+        {
+            return SendPost(obj, ServiceId, url, checkToken, false);
+
+        }
+
+        public string SendPost(Posting obj, string serviceId, string url, bool checkToken)
+        {
+            return SendPost(obj, serviceId, url, checkToken, false);
+        }
+
+        public string SendPost(Posting obj, string serviceId, string url, bool checkToken, bool isRetry)
+        {
+            //obj.serviceId = serviceId;
+            //obj.SV_ID = serviceId;
+            //obj.service_id = serviceId;
+            //obj.key = GetParameter("keyPost"); 
+            using (var client = new HttpClient())
+            {
+
+                log.Debug("POST: " + url + ", checkToken: " + checkToken);
+                if (checkToken)
+                {
+                    UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+                    obj.token = userInfo.token;
+                }
+
+                obj.language = LanguageController.getCurrentLang();
+                var json = JsonConvert.SerializeObject(obj);
+                var data = new StringContent(json, Encoding.UTF8, "application/json");
+
+                log.Debug("Request: " + json);
+
+                var response = client.PostAsync(url, data).Result;
+                if (response.IsSuccessStatusCode)
+                {
+                    var responseContent = response.Content;
+                    // by calling .Result you are synchronously reading the result
+                    string responseString = responseContent.ReadAsStringAsync().Result;
+                    log.Debug("Response: " + responseString);
+                    return responseString;
+                }
+                else
+                {
+                    log.Error("Response: " + response.StatusCode.ToString());
+                    return response.StatusCode.ToString();
+                }
+            }
+        }
+
+        public string SendPost(Posting obj, string serviceId, string url)
+        {
+            return SendPost(obj, serviceId, url, true, false);
+        }
+        protected void CreateAuthToken(string account, object userObj)
+        {
+            // create session authen
+            // Create the random value we will use to secure the session.
+            string authId = GenerateAuthId();
+
+            // Store the value in both our Session and a Cookie.
+            HttpContext.Session.SetString("AuthorizationCookieId", authId);
+            string sessionValue = HttpContext.Session.GetString("AuthorizationCookieId");
+            log.Info("sessionValue: " + sessionValue);
+            //CookieOptions option = new CookieOptions
+            //{
+            //    Expires = DateTime.Now.AddMinutes(1)
+            //};
+            //Response.Cookies.Append("Key Name", "Value", option);
+            CookieOptions options = new CookieOptions()
+            {
+                Path = "/",
+                //HttpOnly = true,
+                //Secure = true,
+                //SameSite = SameSiteMode.None,
+                //IsEssential = true,
+                Expires = DateTime.Now.AddHours(5)
+            };
+            HttpContext.Response.Cookies.Append("AuthorizationCookie", authId, options);
+            //string cookieValue = HttpContext.Request.Cookies["AuthorizationCookie"];
+            ///log.Info("Cookie authen: " + cookieValue);
+
+            HttpContext.Session.SetString("account", account);
+            HttpContext.Session.SetComplexData("userInfo", userObj);
+        }
+
+        protected bool CheckAuthToken()
+        {
+            string cookieValue = HttpContext.Request.Cookies["AuthorizationCookie"];
+            string sessionValue = HttpContext.Session.GetString("AuthorizationCookieId");
+
+            if (cookieValue == null || sessionValue == null || cookieValue != sessionValue)
+            {
+                // Invalidate the session and log out the current user.
+                log.Warn("Cookie not match: cookieValue " + cookieValue + ", sessionValue: " + sessionValue);
+                return false;
+            }
+            if (sessionValue == null)
+            {
+                log.Warn("sessionValue null");
+                // Invalidate the session and log out the current user.
+                return false;
+            }
+            return true;
+        }
+
+        protected bool ClearCache()
+        {
+            log.Info("Clear cache");
+            HttpContext.Session.Clear();
+            foreach (var cookieKey in HttpContext.Request.Cookies.Keys)
+            {
+                HttpContext.Response.Cookies.Delete(cookieKey);
+            }
+            return true;
+        }
+
+        private string GenerateAuthId()
+        {
+            using (RandomNumberGenerator rng = new RNGCryptoServiceProvider())
+            {
+                byte[] tokenData = new byte[32];
+                rng.GetBytes(tokenData);
+                return Convert.ToBase64String(tokenData);
+            }
+        }
+
+        public static string HideMsisdn(string msisdn)
+        {
+            if (msisdn.Length > CountryCode.Length)
+            {
+                string isdn = msisdn.Substring(CountryCode.Length);
+                return isdn.Substring(0, 3) + "***" + isdn.Substring(6);
+            }
+            return "";
+        }
+
+        protected bool CheckRole(string path)
+        {
+            return true;
+        }
+
+        public static string ValidateMsisdn(string msisdn)
+        {
+            if (msisdn == null || msisdn.Trim().Length == 0)
+            {
+                return "";
+            }
+            if (msisdn.StartsWith("0"))
+            {
+                return CountryCode + msisdn.Substring(1);
+            }
+
+            if (msisdn.StartsWith(CountryCode))
+            {
+                return msisdn;
+            }
+
+            return CountryCode + msisdn;
+        }
+
+        //protected VsaValidateResult GetUserInfo()
+        //{
+        //    VsaValidateResult userInfo = HttpContext.Session.GetComplexData<VsaValidateResult>("userInfo");
+        //    return userInfo;
+        //}
+
+        public class WsType
+        {
+            public const string wsLogin = "wsLogin";
+            public const string usersCheckStatus = "usersCheckStatus";
+            public const string playGameCheck = "playGameCheck";
+            public const string playGameUpdate = "playGameUpdate";
+            public const string playTop = "playTop";
+            public const string getHisPlay = "getHisPlay";
+            public const string getWinDaily = "getWinDaily";
+            public const string getWinMonthly = "getWinMonthly";
+            public const string mpsRequest = "mpsRequest";
+            public const string subCheckStatus = "subCheckStatus";
+        }
+
+        public class ErrorCode
+        {
+            public const string SUCCESS = "0";
+            public const string OTP_SUCCESS = "100";
+        }
+    }
+}

+ 637 - 0
WebChallenge/WebChallenge/Controllers/HomeController.cs

@@ -0,0 +1,637 @@
+
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Web;
+using WebChallenge.Extensions;
+using WebChallenge.Models;
+using WebChallenge.Texts;
+using static System.Collections.Specialized.BitVector32;
+
+namespace WebChallenge.Controllers
+{
+    public class HomeController : BaseController
+    {
+
+        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
+
+        public HomeController(IConfiguration _configuration, IWebHostEnvironment hostEnvironment) : base(_configuration, hostEnvironment)
+        {
+            // init
+        }
+
+        public IActionResult Index()
+        {
+            string account = HttpContext.Session.GetString("account");
+            if (account == null)
+            {
+                return Redirect("/Home/Login");
+            }
+            else
+            {
+                //LoginResponse loginRes = HttpContext.Session.GetComplexData<LoginResponse>("userInfo");
+
+                return View();
+            }
+        }
+        public IActionResult Start()
+        {
+            return View();
+        }
+        public IActionResult Login()
+        {
+            return View();
+        }
+
+        public IActionResult Signup()
+        {
+            return View();
+        }
+
+        public IActionResult Setting()
+        {
+            string account = HttpContext.Session.GetString("account");
+            if (account == null)
+            {
+                return Redirect("/Home/Login");
+            }
+            else
+            {
+                UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+                //re load user info
+                userInfo = GetUserInfo(account, userInfo.token);
+                // get sub status
+                UserInfoReq req2 = new UserInfoReq();
+                req2.users = userInfo.msisdn;
+                req2.token = userInfo.token;
+                string rs = SendPost(req2, GetParameter(WsType.subCheckStatus), false);
+                SubInfoRes subRes = SubInfoRes.Parse(rs);
+                return View(subRes);
+            }
+        }
+
+        public IActionResult BuyTurn()
+        {
+            string account = HttpContext.Session.GetString("account");
+            if (account == null)
+            {
+                return Redirect("/Home/Login");
+            }
+            else
+            {
+                return View();
+            }
+        }
+
+        public IActionResult LoginAction(LoginRequest req)
+        {
+
+            if (req.msisdn == null || req.pass == null)
+            {
+                return Json(new
+                {
+                    error = "1",
+                    content = Lang.EnterPhonePassword
+                });
+            }
+
+            req.msisdn = ValidateMsisdn(req.msisdn);
+            req.users = req.msisdn;
+            string rs = SendPost(req, GetParameter(WsType.wsLogin), false);
+            LoginResponse loginRes = LoginResponse.Parse(rs);
+            if (loginRes.status == ErrorCode.SUCCESS)
+            {
+                // log
+                log.Info("Login success: " + req.users);
+                // load user info
+                UserInfo userInfo = GetUserInfo(req.users, loginRes.token);
+                CreateAuthToken(req.users, userInfo);
+
+                return Json(new
+                {
+                    error = "0",
+                    href = "/Home/Index"
+                });
+            }
+            else
+            {
+                return Json(new
+                {
+                    error = loginRes.status,
+                    content = loginRes.message
+                });
+            }
+        }
+
+        private UserInfo GetUserInfo(string msisdn, string token)
+        {
+            // load user info
+            UserInfoReq req2 = new UserInfoReq();
+            req2.users = msisdn;
+            req2.token = token;
+            string rs = SendPost(req2, GetParameter(WsType.usersCheckStatus), false);
+            UserInfoResponse res2 = UserInfoResponse.Parse(rs);
+            // create user info
+            UserInfo userInfo = new UserInfo();
+            userInfo.msisdn = msisdn;
+            userInfo.remain_turn = int.Parse(res2.cash_coin);
+            userInfo.token = token;
+            userInfo.score = int.Parse(res2.bet_coin);
+            userInfo.ranking = int.Parse(res2.ranking);
+            userInfo.isactive = res2.isactive;
+            HttpContext.Session.SetComplexData("userInfo", userInfo);
+            return userInfo;
+        }
+
+
+        public IActionResult ResetPasswordAction(LoginRequest req)
+        {
+
+            if (req.msisdn == null || req.users == null)
+            {
+                return Json(new
+                {
+                    error = "1",
+                    content = "Enter phone number"
+                });
+            }
+            req.msisdn = ValidateMsisdn(req.msisdn);
+            req.users = req.msisdn;
+            string rs = SendPost(req, GetParameter(WsType.wsLogin), false);
+            LoginResponse res = LoginResponse.Parse(rs);
+            if (res.status == ErrorCode.SUCCESS)
+            {
+                // log
+                log.Info("Reset password success: " + req.users);
+                HttpContext.Session.SetString("loginUser", req.msisdn);
+                return Json(new
+                {
+                    error = "0",
+                    content = Lang.PasswordSent
+                });
+            }
+            else
+            {
+                return Json(new
+                {
+                    error = res.status,
+                    content = res.message
+                });
+            }
+        }
+
+
+        public IActionResult CheckPlay(PlayGameCheckReq req)
+        {
+            string account = HttpContext.Session.GetString("account");
+            if (account == null)
+            {
+                return Redirect("/Home/Login");
+                //return Json(new
+                //{
+                //    error = "1",
+                //    content = "Login again",
+                //    href = "/Home/Login"
+                //});
+            }
+
+            UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+            req.users = account;
+            req.token = userInfo.token;
+            string rs = SendPost(req, GetParameter(WsType.playGameCheck), false);
+            PlayGameCheckResponse res = PlayGameCheckResponse.Parse(rs);
+            if (res.status == ErrorCode.SUCCESS)
+            {
+                log.Info("Check play success: " + req.users);
+                // update user info
+                GetUserInfo(account, userInfo.token);
+                // store play session
+                var gameInfo = res.listGame[0];
+                PlayingObj playingObj = new PlayingObj();
+                playingObj.playId = gameInfo.playId;
+                playingObj.playKey = gameInfo.playKey;
+                playingObj.listGame = res.listGame;
+                playingObj.score = 0;
+                playingObj.gameIndex = 0;
+                playingObj.started = false;
+                HttpContext.Session.SetComplexData("playing", playingObj);
+
+                return Redirect("/Home/Playing");
+                //return Json(new
+                //{
+                //    error = "0",
+                //    href = gameInfo.gameLink + "?playId=" + playingObj.playId
+                //                + "&playKey=" + playingObj.playKey
+                //                + "&token=" + HttpUtility.UrlEncode(userInfo.token)
+                //});
+            }
+            else
+            {
+                log.Error("Error check play: " + req.users + ", message: " + res.message);
+                return Redirect("/Home/Index");
+                //return Json(new
+                //{
+                //    error = res.status,
+                //    content = res.message
+                //});
+            }
+        }
+
+        public IActionResult Playing()
+        {
+            PlayingObj playingObj = HttpContext.Session.GetComplexData<PlayingObj>("playing");
+            if (playingObj == null)
+            {
+                return Redirect("/Home/Login");
+                //return Json(new
+                //{
+                //    error = "1",
+                //    content = "Login again",
+                //    href = "/Home/Login"
+                //});
+            }
+            if (!playingObj.shownGift)
+            {
+                playingObj.shownGift = true;
+                HttpContext.Session.SetComplexData("playing", playingObj);
+            }
+            else
+            {
+                if (playingObj.gameIndex < playingObj.listGame.Count)
+                {
+                    playingObj.gift = null;
+                    HttpContext.Session.SetComplexData("playing", playingObj);
+                }
+            }
+            return View(playingObj);
+        }
+
+
+        public IActionResult StartPlay()
+        {
+            UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+            PlayingObj playingObj = HttpContext.Session.GetComplexData<PlayingObj>("playing");
+            if (playingObj == null || playingObj.started)
+            {
+                return Json(new
+                {
+                    error = "2",
+                    href = "/Home/Index"
+                });
+            }
+
+            playingObj.started = true;
+            HttpContext.Session.SetComplexData("playing", playingObj);
+            return Json(new
+            {
+                error = "0"
+            });
+        }
+
+        public IActionResult Ping(string score, string level, string playId, string playKey, string token)
+        {
+            UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+            PlayingObj playingObj = HttpContext.Session.GetComplexData<PlayingObj>("playing");
+            if (playingObj == null)
+            {
+                return Json(new
+                {
+                    error = "1",
+                    content = "Login again",
+                    href = "/Home/Index"
+                });
+            }
+
+            // check value
+            if (playingObj.playKey != playKey || playingObj.playId != playId || userInfo.token != token)
+            {
+                // un synchronize
+                return Json(new
+                {
+                    error = "1",
+                    content = "Login again",
+                    href = "/Home/Index"
+                });
+            }
+
+            // success
+            return Json(new
+            {
+                error = "0",
+                content = "pong"
+            });
+        }
+
+        public IActionResult SubmitScore(string score, string level, string playId, string playKey,
+            string playDetailId, string playDetailKey, string token)
+        {
+            UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+            PlayingObj playingObj = HttpContext.Session.GetComplexData<PlayingObj>("playing");
+            if (playingObj == null)
+            {
+                return Json(new
+                {
+                    error = "1",
+                    content = "Login again",
+                    href = "/Home/Index"
+                });
+            }
+
+            if (playingObj.playKey != playKey || playingObj.playId != playId || userInfo.token != token)
+            {
+                // un synchronize
+                return Json(new
+                {
+                    error = "1",
+                    content = "Login again",
+                    href = "/Home/Index"
+                });
+            }
+
+            // check game detail
+            int gameIndex = playingObj.gameIndex;
+            var currentGameInfo = playingObj.listGame[gameIndex];
+            if (currentGameInfo.playDetailKey != playDetailKey || currentGameInfo.playDetailId != playDetailId)
+            {
+                // un synchronize
+                return Json(new
+                {
+                    error = "1",
+                    content = "Login again",
+                    href = "/Home/Index"
+                });
+            }
+
+            PlayGameUpdateResponse submitResult = checkScore(playingObj, currentGameInfo, score, userInfo.token);
+            // check pass challenge
+            if (submitResult.giftType == GiftType.NoGift)
+            {
+                // update user info
+                GetUserInfo(userInfo.msisdn, token);
+                // clear playing
+                HttpContext.Session.Remove("playing");
+                return Json(new
+                {
+                    error = "0",
+                    content = "Success",
+                    href = "/Home/Index?gameover=1&stage=" + (gameIndex + 1)
+                });
+            }
+            else
+            {
+                // pass challenge
+                GiftInfo giftInfo = new GiftInfo();
+                giftInfo.gift = submitResult.gift;
+                giftInfo.giftType = submitResult.giftType;
+                // update user info
+                GetUserInfo(userInfo.msisdn, token);
+
+                // next game
+                playingObj.gift = giftInfo;
+                playingObj.gameIndex++;
+                playingObj.started = false;
+                playingObj.shownGift = false;
+                HttpContext.Session.SetComplexData("playing", playingObj);
+                // return
+                return Json(new
+                {
+                    error = "0",
+                    content = "Success",
+                    href = "/Home/Playing?reward=1"
+                });
+            }
+        }
+
+        private PlayGameUpdateResponse checkScore(PlayingObj playObj, GameInfo gameInfo, string score, string token)
+        {
+            PlayGameUpdateReq req2 = new PlayGameUpdateReq();
+            req2.playId = playObj.playId;
+            req2.playKey = playObj.playKey;
+            req2.playDetailId = gameInfo.playDetailId;
+            req2.playDetailKey = gameInfo.playDetailKey;
+            req2.token = token;
+            req2.score = score + "";
+            string rs = SendPost(req2, GetParameter(WsType.playGameUpdate), false);
+            PlayGameUpdateResponse res2 = PlayGameUpdateResponse.Parse(rs);
+            //
+            return res2;
+        }
+
+
+        public IActionResult Guide()
+        {
+            string lang = LanguageController.getCurrentLang();
+            return View("Guide" + lang);
+        }
+
+        public IActionResult Logout()
+        {
+            // clear session
+            HttpContext.Session.Clear();
+
+            return Redirect("/Home/Login");
+        }
+
+        public IActionResult Ranking()
+        {
+            UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+            if (userInfo == null)
+            {
+                return Redirect("/Home/Login");
+            }
+            else
+            {
+                // reload user info
+                GetUserInfo(userInfo.msisdn, userInfo.token);
+
+                // get list ranking top 10
+                //DateTime startTime = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
+                //DateTime endTime = startTime.AddDays(6);
+                PlayTopReq topReq = new PlayTopReq();
+                topReq.language = LanguageController.getCurrentLang();
+                //topReq.fromdate = startTime.ToString("dd/MM/yyyy");
+                //topReq.todate = endTime.ToString("dd/MM/yyyy");
+                topReq.top = "10";
+                string rs = SendPost(topReq, GetParameter(WsType.playTop), true);
+                PlayTopResponse topPlayer = PlayTopResponse.Parse(rs);
+                return View(topPlayer.listTop);
+            }
+        }
+
+
+        public IActionResult History()
+        {
+            UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+            if (userInfo == null)
+            {
+                return Redirect("/Home/Login");
+            }
+            else
+            {
+                // get history play
+                DateTime startTime = DateTime.Now.AddDays(-30);
+                DateTime endTime = DateTime.Now;
+                PlayHisReq req = new PlayHisReq();
+                req.fromdate = startTime.ToString("dd/MM/yyyy 00:00:00");
+                req.todate = endTime.ToString("dd/MM/yyyy 23:59:59");
+                req.language = LanguageController.getCurrentLang();
+                req.top = "100";
+                req.msisdn = userInfo.msisdn;
+                string rs = SendPost(req, GetParameter(WsType.getHisPlay), true);
+                PlayHisResponse his = PlayHisResponse.Parse(rs);
+                return View(his.list);
+            }
+        }
+
+        public IActionResult Winner()
+        {
+            return View();
+        }
+
+        public IActionResult WinnerDaily()
+        {
+            UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+            if (userInfo == null)
+            {
+                return Redirect("/Home/Login");
+            }
+            else
+            {
+                // get winner daily
+                //DateTime startTime = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
+                //DateTime endTime = startTime.AddDays(6);
+                GetWinnerReq req = new GetWinnerReq();
+                //topReq.fromdate = startTime.ToString("dd/MM/yyyy");
+                //topReq.todate = endTime.ToString("dd/MM/yyyy");
+                req.language = LanguageController.getCurrentLang();
+                req.top = "50";
+                string rs = SendPost(req, GetParameter(WsType.getWinDaily), true);
+                WinnerDailyRes his = WinnerDailyRes.Parse(rs);
+                return View(his.list);
+            }
+        }
+
+        public IActionResult WinnerMonthly()
+        {
+            UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+            if (userInfo == null)
+            {
+                return Redirect("/Home/Login");
+            }
+            else
+            {
+                // get winner daily
+                //DateTime startTime = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
+                //DateTime endTime = startTime.AddDays(6);
+                GetWinnerReq req = new GetWinnerReq();
+                //topReq.fromdate = startTime.ToString("dd/MM/yyyy");
+                //topReq.todate = endTime.ToString("dd/MM/yyyy");
+                req.language = LanguageController.getCurrentLang();
+                req.top = "50";
+                string rs = SendPost(req, GetParameter(WsType.getWinMonthly), true);
+                WinnerMonthlyRes his = WinnerMonthlyRes.Parse(rs);
+                return View(his.list);
+            }
+        }
+
+        // request to MPS
+        public IActionResult RequestOtp(MpsReq req)
+        {
+
+            String account = HttpContext.Session.GetString("account");
+            if (account == null)
+            {
+                return Json(new
+                {
+                    error = "1",
+                    content = "Login again",
+                    href = "/Home/Login"
+                });
+            }
+
+            UserInfo userInfo = HttpContext.Session.GetComplexData<UserInfo>("userInfo");
+            req.msisdn = account;
+            req.token = userInfo.token;
+            req.otp = "-1";
+            req.requestId = DateTime.Now.Ticks + req.msisdn;
+            HttpContext.Session.SetComplexData("mpsRequest", req);
+            String rs = SendPost(req, GetParameter(WsType.mpsRequest), false);
+            MpsRes res = MpsRes.Parse(rs);
+            if (res.status == ErrorCode.OTP_SUCCESS)
+            {
+                // log
+                log.Info("Get OTP success: " + req.msisdn);
+                return Json(new
+                {
+                    error = ErrorCode.OTP_SUCCESS,
+                    content = res.message
+                });
+            }
+            else if (res.status == ErrorCode.SUCCESS)
+            {
+                // log
+                log.Info("success no need confirm otp: " + req.msisdn);
+                return Json(new
+                {
+                    error = "0",
+                    content = res.message
+                });
+            }
+            else
+            {
+                return Json(new
+                {
+                    error = res.status,
+                    content = res.message
+                });
+            }
+        }
+
+        public IActionResult ConfirmOtp(String otp)
+        {
+
+            String account = HttpContext.Session.GetString("account");
+            if (account == null)
+            {
+                return Json(new
+                {
+                    error = "1",
+                    content = "Login again",
+                    href = "/Home/Login"
+                });
+            }
+
+            MpsReq req = HttpContext.Session.GetComplexData<MpsReq>("mpsRequest");
+            req.otp = otp;
+
+            String rs = SendPost(req, GetParameter(WsType.mpsRequest), false);
+            MpsRes res = MpsRes.Parse(rs);
+            if (res.status == ErrorCode.SUCCESS)
+            {
+                // log
+                log.Info("Confirm OTP success: " + req.msisdn);
+
+                // update user info
+                GetUserInfo(account, req.token);
+
+                return Json(new
+                {
+                    error = "0",
+                    content = res.message
+                });
+            }
+            else
+            {
+                return Json(new
+                {
+                    error = res.status,
+                    content = res.message
+                });
+            }
+        }
+    }
+}

+ 43 - 0
WebChallenge/WebChallenge/Controllers/LanguageController.cs

@@ -0,0 +1,43 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Localization;
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Globalization;
+using System.Threading;
+
+namespace WebChallenge.Controllers
+{
+    public class LanguageController : Controller
+    {
+        [HttpPost]
+        public IActionResult ChangeLanguage(string LanguageAbbrevation, string returnUrl)
+        {
+            Response.Cookies.Append(
+               CookieRequestCultureProvider.DefaultCookieName,
+               CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(LanguageAbbrevation)),
+               new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
+            );
+            //return LocalRedirect(returnUrl);
+            return Json(new { error = "0" });
+        }
+        public static String getCurrentLang()
+        {
+            if (CultureInfo.CurrentCulture.Name.ToUpper() == "EN" || CultureInfo.CurrentCulture.Name.ToUpper() == "EN-US")
+            {
+                return "1";
+            }
+            return "0";
+        }
+        public String getCurrentLangTxt()
+        {
+            if (CultureInfo.CurrentCulture.Name.ToUpper() == "EN" || CultureInfo.CurrentCulture.Name.ToUpper() == "EN-US")
+            {
+                return "en";
+            }
+            return "fr";
+        }
+
+        public static string GLOBAL = "1";
+        public static string LOCAL = "0";
+    }
+}

+ 31 - 0
WebChallenge/WebChallenge/Extensions/ConfigAction.cs

@@ -0,0 +1,31 @@
+using Microsoft.AspNetCore.Mvc.Filters;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebChallenge.Extensions
+{
+    public class ConfigAction : IAsyncActionFilter
+    {
+        private MyConfig _options;
+        public ConfigAction(IConfiguration configuration)
+        {
+
+            _options = new MyConfig();
+            configuration.Bind(_options);
+        }
+
+        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
+        {
+            ((Microsoft.AspNetCore.Mvc.Controller)context.Controller).ViewBag.MyConfig = _options;
+            await next();
+        }
+    }
+
+    public class MyConfig
+    {
+        public string MyValue { get; set; }
+    }
+}

+ 10 - 0
WebChallenge/WebChallenge/Extensions/DateTimeExtensions.cs

@@ -0,0 +1,10 @@
+using System;
+
+internal static class DateTimeExtensions
+{
+    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
+    {
+        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
+        return dt.AddDays(-1 * diff).Date;
+    }
+}

+ 29 - 0
WebChallenge/WebChallenge/Extensions/RewriteSubdomainRule.cs

@@ -0,0 +1,29 @@
+using Microsoft.AspNetCore.Rewrite;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace WebChallenge.Extensions
+{
+    public class RewriteSubdomainRule : IRule
+    {
+        public void ApplyRule(RewriteContext context)
+        {
+            var request = context.HttpContext.Request;
+            var host = request.Host.Host;
+            // Check if the host is subdomain.domain.com or subdomain.localhost for debugging
+            if (Regex.IsMatch(host, @"^[A-Za-z\d]+\.(?:[A-Za-z\d]+\.[A-Za-z\d]+|localhost)$"))
+            {
+                string subdomain = host.Split('.')[0];
+                //modifying the request path to let the routing catch the subdomain
+                context.HttpContext.Request.Path = "/subdomain/" + subdomain + context.HttpContext.Request.Path;
+                context.Result = RuleResult.ContinueRules;
+                return;
+            }
+            context.Result = RuleResult.ContinueRules;
+            return;
+        }
+    }
+}

+ 29 - 0
WebChallenge/WebChallenge/Extensions/SessionExtensions.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebChallenge.Extensions
+{
+    using System;
+    using Microsoft.AspNetCore.Http;
+    using Newtonsoft.Json;
+
+    public static class SessionExtensions
+    {
+        public static T GetComplexData<T>(this ISession session, string key)
+        {
+            var data = session.GetString(key);
+            if (data == null)
+            {
+                return default;
+            }
+            return JsonConvert.DeserializeObject<T>(data);
+        }
+
+        public static void SetComplexData(this ISession session, string key, object value)
+        {
+            session.SetString(key, JsonConvert.SerializeObject(value));
+        }
+    }
+}

+ 9 - 0
WebChallenge/WebChallenge/Models/ErrorViewModel.cs

@@ -0,0 +1,9 @@
+namespace WebChallenge.Models
+{
+    public class ErrorViewModel
+    {
+        public string RequestId { get; set; }
+
+        public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
+    }
+}

+ 28 - 0
WebChallenge/WebChallenge/Models/LoginRequest.cs

@@ -0,0 +1,28 @@
+using Newtonsoft.Json;
+using System;
+
+namespace WebChallenge.Models
+{
+    public class LoginRequest : Posting
+    {
+        public string msisdn { get; set; }
+        public string users { get; set; }
+        public string pass { get; set; }
+        public string passnew { get; set; }
+        public string command { get; set; }
+    }
+
+    public class LoginResponse
+    {
+        public string role { get; set; }
+        public string token { get; set; }
+        public object function { get; set; }
+        public string status { get; set; }
+        public string message { get; set; }
+
+        public static new LoginResponse Parse(string json)
+        {
+            return JsonConvert.DeserializeObject<LoginResponse>(json);
+        }
+    }
+}

+ 30 - 0
WebChallenge/WebChallenge/Models/MpsRequest.cs

@@ -0,0 +1,30 @@
+using Newtonsoft.Json;
+using System;
+
+namespace WebChallenge.Models
+{
+    public class MpsReq : Posting
+    {
+        public string msisdn { get; set; }
+        public string subServiceCode { get; set; }
+        public string requestId { get; set; }
+        public string otp { get; set; }
+    }
+
+    public class MpsRes
+    {
+        public string status { get; set; }
+        public string message { get; set; }
+        public string requestID { get; set; }
+        public string responseCode { get; set; }
+        public string msisdn { get; set; }
+        public string cmd { get; set; }
+        public string money { get; set; }
+        public string source { get; set; }
+        public string otpType { get; set; }
+        public static MpsRes Parse(String json)
+        {
+            return JsonConvert.DeserializeObject<MpsRes>(json);
+        }
+    }
+}

+ 37 - 0
WebChallenge/WebChallenge/Models/PlayHistory.cs

@@ -0,0 +1,37 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WebChallenge.Models
+{
+    public class PlayHisReq : Posting
+    {
+        public string fromdate { get; set; }
+        public string todate { get; set; }
+        public string top { get; set; }
+        public string msisdn { get; set; }
+    }
+    public class PlayHistory
+    {
+        public string seq { get; set; }
+        public string msisdn { get; set; }
+        public string date { get; set; }
+        public string step { get; set; }
+        public string point { get; set; }
+        public string prize { get; set; }
+        public string data { get; set; }
+        public string mt { get; set; }
+    }
+
+    public class PlayHisResponse
+    {
+        public string status { get; set; }
+        public string message { get; set; }
+        public List<PlayHistory> list { get; set; }
+        public static PlayHisResponse Parse(string json)
+        {
+            return JsonConvert.DeserializeObject<PlayHisResponse>(json);
+        }
+    }
+}

+ 101 - 0
WebChallenge/WebChallenge/Models/PlayRequest.cs

@@ -0,0 +1,101 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WebChallenge.Models
+{
+
+    public class GiftType
+    {
+        public const string NoGift = "0";
+        public const string Point = "1";
+        public const string MB = "2";
+        public const string Money = "3";
+        public const string SMS = "4";
+    }
+
+    public class PlayGameCheckReq : Posting
+    {
+        public string users { get; set; }
+    }
+    public class PlayGameCheckResponse
+    {
+        public List<GameInfo> listGame { get; set; }
+        public string status { get; set; }
+        public string message { get; set; }
+        public static new PlayGameCheckResponse Parse(string json)
+        {
+            return JsonConvert.DeserializeObject<PlayGameCheckResponse>(json);
+        }
+    }
+
+    public class GameInfo
+    {
+        public string playId { get; set; }
+        public string playKey { get; set; }
+        public string playDetailId { get; set; }
+        public string playDetailKey { get; set; }
+        public string gameId { get; set; }
+        public string gameCode { get; set; }
+        public string gameNameGlobal { get; set; }
+        public string gameNameLocal { get; set; }
+        public string gameTitleGlobal { get; set; }
+        public string gameTitleLocal { get; set; }
+        public string gameDescriptionGlobal { get; set; }
+        public string gameDescriptionLocal { get; set; }
+        public string gameIcon { get; set; }
+        public string gameLink { get; set; }
+        public string gameLevel { get; set; }
+        public string gameScorePass { get; set; }
+        public string gameTimePass { get; set; }
+        public string step { get; set; }
+    }
+
+    public class PlayGameUpdateReq : Posting
+    {
+        public string playId { get; set; }
+        public string playKey { get; set; }
+        public string playDetailId { get; set; }
+        public string playDetailKey { get; set; }
+        public string score { get; set; }
+    }
+
+    public class PlayGameUpdateResponse
+    {
+        public string status { get; set; }
+        public string message { get; set; }
+        public string gift { get; set; }
+        public string giftType { get; set; }
+        public static new PlayGameUpdateResponse Parse(string json)
+        {
+            return JsonConvert.DeserializeObject<PlayGameUpdateResponse>(json);
+        }
+    }
+
+    public class GiftInfo
+    {
+        public string gift { get; set; }
+        public string giftType { get; set; }
+    }
+
+
+    public class PlayingObj
+    {
+        public GiftInfo gift { get; set; }
+        public bool started { get; set; }
+        public bool shownGift { get; set; }
+        public string playId { get; set; }
+        public string playKey { get; set; }
+        public int score { get; set; }
+        public int gameIndex { get; set; }
+        public List<GameInfo> listGame { get; set; }
+        //public string word { get; set; }
+        //public StringBuilder answer { get; set; }
+        //public string correctAnswer { get; set; }
+        //public string description { get; set; }
+        //public int heart { get; set; } = 5;
+        //public string answeredWrong { get; set; }
+        //public string answeredCorrect { get; set; }
+    }
+}

+ 33 - 0
WebChallenge/WebChallenge/Models/PlayTop.cs

@@ -0,0 +1,33 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WebChallenge.Models
+{
+    public class PlayTopReq : Posting
+    {
+        public string fromdate { get; set; }
+        public string todate { get; set; }
+        public string top { get; set; }
+    }
+    public class TopUser
+    {
+        public string msisdn { get; set; }
+        public string totalScore { get; set; }
+        public string totalTime { get; set; }
+        public string timeUpdate { get; set; }
+        public string seq { get; set; }
+    }
+
+    public class PlayTopResponse
+    {
+        public string status { get; set; }
+        public string message { get; set; }
+        public List<TopUser> listTop { get; set; }
+        public static new PlayTopResponse Parse(string json)
+        {
+            return JsonConvert.DeserializeObject<PlayTopResponse>(json);
+        }
+    }
+}

+ 10 - 0
WebChallenge/WebChallenge/Models/Posting.cs

@@ -0,0 +1,10 @@
+namespace WebChallenge.Models
+{
+    public class Posting
+    {
+        public string serviceId { get; set; } = "1";
+        public string channel { get; set; } = "WEB";
+        public string language { get; set; } = "0";
+        public string token { get; set; }
+    }
+}

+ 55 - 0
WebChallenge/WebChallenge/Models/UserInfo.cs

@@ -0,0 +1,55 @@
+using Newtonsoft.Json;
+
+namespace WebChallenge.Models
+{
+    public class UserInfoReq : Posting
+    {
+        public string users { get; set; }
+    }
+
+    public class UserInfoResponse
+    {
+        public string status { get; set; }
+        public object message { get; set; }
+        public string id { get; set; }
+        public string msisdn { get; set; }
+        public string users { get; set; }
+        public string pass { get; set; }
+        public string serviceid { get; set; }
+        public string dateregist { get; set; }
+        public string isactive { get; set; }
+        public string channel { get; set; }
+        public string bet_coin { get; set; }
+        public string cash_coin { get; set; }
+        public string role { get; set; }
+        public string ranking { get; set; }
+        public string language { get; set; }
+        public static UserInfoResponse Parse(string json)
+        {
+            return JsonConvert.DeserializeObject<UserInfoResponse>(json);
+        }
+    }
+
+    public class SubInfoRes
+    {
+        public string packetType { get; set; }
+        public string packetInfo { get; set; }
+        public string status { get; set; }
+        public string message { get; set; }
+        public static SubInfoRes Parse(string json)
+        {
+            return JsonConvert.DeserializeObject<SubInfoRes>(json);
+        }
+    }
+
+    public class UserInfo
+    {
+        public string msisdn { get; set; }
+        public int remain_turn { get; set; }
+        public int score { get; set; }
+        public int ranking { get; set; }
+        public string token { get; set; }
+        public string isactive { get; set; }
+
+    }
+}

+ 58 - 0
WebChallenge/WebChallenge/Models/Winner.cs

@@ -0,0 +1,58 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace WebChallenge.Models
+{
+    public class GetWinnerReq : Posting
+    {
+        public string fromdate { get; set; }
+        public string todate { get; set; }
+        public string top { get; set; }
+    }
+    public class WinnerDaily
+    {
+        public string msisdn { get; set; }
+        public string date { get; set; }
+        public string prize { get; set; }
+        public string seq { get; set; }
+    }
+
+    public class WinnerDailyRes
+    {
+        public string status { get; set; }
+        public string message { get; set; }
+        public List<WinnerDaily> list { get; set; }
+        public static WinnerDailyRes Parse(string json)
+        {
+            return JsonConvert.DeserializeObject<WinnerDailyRes>(json);
+        }
+    }
+     
+    public class WinnerMonthly
+    {
+        public string msisdn { get; set; }
+        public string date { get; set; }
+        public string status { get; set; }
+        public string errCode { get; set; }
+        public string errMsg { get; set; }
+        public string money { get; set; }
+        public string transCode { get; set; }
+        public string transDate { get; set; }
+        public string transAmount { get; set; }
+        public string transFee { get; set; }
+        public string serviceId { get; set; }
+    }
+
+    public class WinnerMonthlyRes
+    {
+        public string status { get; set; }
+        public string message { get; set; }
+        public List<WinnerMonthly> list { get; set; }
+        public static WinnerMonthlyRes Parse(string json)
+        {
+            return JsonConvert.DeserializeObject<WinnerMonthlyRes>(json);
+        }
+    }
+}

+ 40 - 0
WebChallenge/WebChallenge/Program.cs

@@ -0,0 +1,40 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace WebChallenge
+{
+    public class Program
+    {
+
+        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
+        public static void Main(string[] args)
+        {
+            XmlDocument log4netConfig = new XmlDocument();
+            log4netConfig.Load(File.OpenRead("log4net.config"));
+            var repo = log4net.LogManager.CreateRepository(
+                Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));
+
+            log4net.Config.XmlConfigurator.Configure(repo, log4netConfig["log4net"]);
+
+            log.Info("Application - Main is invoked");
+
+            CreateHostBuilder(args).Build().Run();
+        }
+
+        public static IHostBuilder CreateHostBuilder(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+                .ConfigureWebHostDefaults(webBuilder =>
+                {
+                    webBuilder.UseStartup<Startup>();
+                });
+    }
+}

+ 22 - 0
WebChallenge/WebChallenge/Properties/PublishProfiles/FolderProfile.pubxml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <DeleteExistingFiles>True</DeleteExistingFiles>
+    <ExcludeApp_Data>False</ExcludeApp_Data>
+    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
+    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
+    <LastUsedPlatform>Any CPU</LastUsedPlatform>
+    <PublishProvider>FileSystem</PublishProvider>
+    <PublishUrl>D:\Common\Publish</PublishUrl>
+    <WebPublishMethod>FileSystem</WebPublishMethod>
+    <_TargetId>Folder</_TargetId>
+    <SiteUrlToLaunchAfterPublish />
+    <TargetFramework>net5.0</TargetFramework>
+    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
+    <ProjectGuid>bc25f25c-6c4f-4df1-963a-f9daa7cea50d</ProjectGuid>
+    <SelfContained>true</SelfContained>
+  </PropertyGroup>
+</Project>

+ 23 - 0
WebChallenge/WebChallenge/Properties/PublishProfiles/FolderProfile1.pubxml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project>
+  <PropertyGroup>
+    <DeleteExistingFiles>true</DeleteExistingFiles>
+    <ExcludeApp_Data>false</ExcludeApp_Data>
+    <LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
+    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
+    <LastUsedPlatform>Any CPU</LastUsedPlatform>
+    <PublishProvider>FileSystem</PublishProvider>
+    <PublishUrl>D:\Common\Publish</PublishUrl>
+    <WebPublishMethod>FileSystem</WebPublishMethod>
+    <_TargetId>Folder</_TargetId>
+    <SiteUrlToLaunchAfterPublish />
+    <TargetFramework>net5.0</TargetFramework>
+    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
+    <ProjectGuid>bc25f25c-6c4f-4df1-963a-f9daa7cea50d</ProjectGuid>
+    <SelfContained>true</SelfContained>
+    <PublishSingleFile>false</PublishSingleFile>
+  </PropertyGroup>
+</Project>

+ 30 - 0
WebChallenge/WebChallenge/Properties/launchSettings.json

@@ -0,0 +1,30 @@
+{
+  "profiles": {
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchBrowser": true,
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development",
+        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
+      }
+    },
+    "WebChallenge": {
+      "commandName": "Project",
+      "launchBrowser": true,
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development",
+        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation"
+      },
+      "dotnetRunMessages": "true",
+      "applicationUrl": "https://localhost:5001;http://localhost:5000"
+    }
+  },
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:7894",
+      "sslPort": 0
+    }
+  }
+}

+ 93 - 0
WebChallenge/WebChallenge/Startup.cs

@@ -0,0 +1,93 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.HttpsPolicy;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace WebChallenge
+{
+    public class Startup
+    {
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+            //services.AddSession();
+            services.AddControllersWithViews();
+
+            // multilanguage
+            services.AddLocalization(options => options.ResourcesPath = "Resources");
+            services.AddMvc()
+                .AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)
+                .AddDataAnnotationsLocalization();
+
+            services.Configure<RequestLocalizationOptions>(options =>
+            {
+                var cultures = new List<CultureInfo> {
+                    new CultureInfo("en"),
+                    new CultureInfo("fr")
+               };
+                options.DefaultRequestCulture = new Microsoft.AspNetCore.Localization.RequestCulture("fr");
+                options.SupportedCultures = cultures;
+                options.SupportedUICultures = cultures;
+            });
+
+            services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
+            services.AddDistributedMemoryCache(); // Adds a default in-memory implementation of IDistributedCache
+            services.AddSession(options =>
+            {
+                options.IdleTimeout = TimeSpan.FromSeconds(600);
+                options.Cookie.HttpOnly = true;
+                options.Cookie.IsEssential = true;
+                //options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
+            });
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+            else
+            {
+                app.UseExceptionHandler("/Home/Error");
+                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+                app.UseHsts();
+            }
+            app.UseSession();
+            app.UseCookiePolicy();
+            app.UseHttpsRedirection();
+            app.UseDefaultFiles();
+            app.UseStaticFiles();
+
+
+            app.UseRequestLocalization(app.ApplicationServices.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value);
+
+            app.UseRouting();
+
+            app.UseAuthorization();
+
+            app.UseEndpoints(endpoints =>
+            {
+                endpoints.MapControllerRoute(
+                    name: "default",
+                    pattern: "{controller=Home}/{action=Start}/{id?}");
+            });
+        }
+    }
+}

+ 697 - 0
WebChallenge/WebChallenge/Texts/Lang.Designer.cs

@@ -0,0 +1,697 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebChallenge.Texts {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    public class Lang {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Lang() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        public static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WebChallenge.Texts.Lang", typeof(Lang).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        public static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Already have account?.
+        /// </summary>
+        public static string AlreadyHaveAccount {
+            get {
+                return ResourceManager.GetString("AlreadyHaveAccount", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Buy Turn.
+        /// </summary>
+        public static string BuyTurn {
+            get {
+                return ResourceManager.GetString("BuyTurn", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cancel.
+        /// </summary>
+        public static string Cancel {
+            get {
+                return ResourceManager.GetString("Cancel", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Don&apos;t want to Register anymore?.
+        /// </summary>
+        public static string CancelConfirm {
+            get {
+                return ResourceManager.GetString("CancelConfirm", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to To cancel the service, please do one of the following two ways:
+        ///
+        ///&lt;br&gt;1. Compose SMS: OFF send to 1541
+        ///
+        ///&lt;br&gt;2. USSD operation: Press *1541#, press 1 then press &quot;Confirm&quot; to cancel the daily package or Press *1541#, press 2 then press &quot;Confirm&quot; to cancel the weekly package..
+        /// </summary>
+        public static string CancelDetailInfo {
+            get {
+                return ResourceManager.GetString("CancelDetailInfo", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Challenge.
+        /// </summary>
+        public static string Challenge {
+            get {
+                return ResourceManager.GetString("Challenge", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Close.
+        /// </summary>
+        public static string Close {
+            get {
+                return ResourceManager.GetString("Close", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Coin.
+        /// </summary>
+        public static string Coin {
+            get {
+                return ResourceManager.GetString("Coin", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Confirm.
+        /// </summary>
+        public static string Confirm {
+            get {
+                return ResourceManager.GetString("Confirm", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Are you sure you want to exit the game?.
+        /// </summary>
+        public static string ConfirmExit {
+            get {
+                return ResourceManager.GetString("ConfirmExit", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Congratulation.
+        /// </summary>
+        public static string Congratulation {
+            get {
+                return ResourceManager.GetString("Congratulation", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Congratulations.
+        /// </summary>
+        public static string Congratulations {
+            get {
+                return ResourceManager.GetString("Congratulations", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Create an account.
+        /// </summary>
+        public static string CreateAccount {
+            get {
+                return ResourceManager.GetString("CreateAccount", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to MT.
+        /// </summary>
+        public static string Curency {
+            get {
+                return ResourceManager.GetString("Curency", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Daily.
+        /// </summary>
+        public static string Daily {
+            get {
+                return ResourceManager.GetString("Daily", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Daily Package.
+        /// </summary>
+        public static string DailyPackage {
+            get {
+                return ResourceManager.GetString("DailyPackage", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Daily Prize.
+        /// </summary>
+        public static string DailyPrize {
+            get {
+                return ResourceManager.GetString("DailyPrize", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Enter Otp.
+        /// </summary>
+        public static string EnterOtp {
+            get {
+                return ResourceManager.GetString("EnterOtp", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Enter number and password!.
+        /// </summary>
+        public static string EnterPhonePassword {
+            get {
+                return ResourceManager.GetString("EnterPhonePassword", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Error.
+        /// </summary>
+        public static string Error {
+            get {
+                return ResourceManager.GetString("Error", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Exit.
+        /// </summary>
+        public static string Exit {
+            get {
+                return ResourceManager.GetString("Exit", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Game over.
+        /// </summary>
+        public static string GameOver {
+            get {
+                return ResourceManager.GetString("GameOver", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Game Rules.
+        /// </summary>
+        public static string GameRules {
+            get {
+                return ResourceManager.GetString("GameRules", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Guide.
+        /// </summary>
+        public static string Guide {
+            get {
+                return ResourceManager.GetString("Guide", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Hello.
+        /// </summary>
+        public static string Hello {
+            get {
+                return ResourceManager.GetString("Hello", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to History.
+        /// </summary>
+        public static string History {
+            get {
+                return ResourceManager.GetString("History", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Home.
+        /// </summary>
+        public static string Home {
+            get {
+                return ResourceManager.GetString("Home", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Language.
+        /// </summary>
+        public static string Language {
+            get {
+                return ResourceManager.GetString("Language", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Login.
+        /// </summary>
+        public static string Login {
+            get {
+                return ResourceManager.GetString("Login", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Mini Game Information.
+        /// </summary>
+        public static string MiniGameInfo {
+            get {
+                return ResourceManager.GetString("MiniGameInfo", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Monthly Prize.
+        /// </summary>
+        public static string MonthlyPrize {
+            get {
+                return ResourceManager.GetString("MonthlyPrize", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to My coin.
+        /// </summary>
+        public static string MyCoin {
+            get {
+                return ResourceManager.GetString("MyCoin", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to My package.
+        /// </summary>
+        public static string MyPackage {
+            get {
+                return ResourceManager.GetString("MyPackage", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to My rank.
+        /// </summary>
+        public static string MyRank {
+            get {
+                return ResourceManager.GetString("MyRank", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to NextGame.
+        /// </summary>
+        public static string NextGame {
+            get {
+                return ResourceManager.GetString("NextGame", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Click Next game to continue playing 
///or Close to exit !.
+        /// </summary>
+        public static string NextGameOrClose {
+            get {
+                return ResourceManager.GetString("NextGameOrClose", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to No..
+        /// </summary>
+        public static string No {
+            get {
+                return ResourceManager.GetString("No", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Do not receive an OTP.
+        /// </summary>
+        public static string NotReceiveOtp {
+            get {
+                return ResourceManager.GetString("NotReceiveOtp", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to package.
+        /// </summary>
+        public static string package {
+            get {
+                return ResourceManager.GetString("package", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Password.
+        /// </summary>
+        public static string Password {
+            get {
+                return ResourceManager.GetString("Password", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Password has been sent to your phone!.
+        /// </summary>
+        public static string PasswordSent {
+            get {
+                return ResourceManager.GetString("PasswordSent", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Pay via basic account.
+        /// </summary>
+        public static string PayBasic {
+            get {
+                return ResourceManager.GetString("PayBasic", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Pay via e-Mola.
+        /// </summary>
+        public static string PayEmola {
+            get {
+                return ResourceManager.GetString("PayEmola", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Phone Number.
+        /// </summary>
+        public static string PhoneNumber {
+            get {
+                return ResourceManager.GetString("PhoneNumber", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Play.
+        /// </summary>
+        public static string Play {
+            get {
+                return ResourceManager.GetString("Play", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Click Play now to play a new round or click Close to exit..
+        /// </summary>
+        public static string PlayAgainOrClose {
+            get {
+                return ResourceManager.GetString("PlayAgainOrClose", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Play Now.
+        /// </summary>
+        public static string PlayNow {
+            get {
+                return ResourceManager.GetString("PlayNow", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Prize.
+        /// </summary>
+        public static string Prize {
+            get {
+                return ResourceManager.GetString("Prize", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Ranking coin.
+        /// </summary>
+        public static string RankingCoin {
+            get {
+                return ResourceManager.GetString("RankingCoin", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to To be ranked, please register for the service.
+        /// </summary>
+        public static string RegisterToBeRanked {
+            get {
+                return ResourceManager.GetString("RegisterToBeRanked", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Resend.
+        /// </summary>
+        public static string Resend {
+            get {
+                return ResourceManager.GetString("Resend", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Result.
+        /// </summary>
+        public static string Result {
+            get {
+                return ResourceManager.GetString("Result", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Select payment channel.
+        /// </summary>
+        public static string SelectPaymentChannel {
+            get {
+                return ResourceManager.GetString("SelectPaymentChannel", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Send OTP.
+        /// </summary>
+        public static string SendOtp {
+            get {
+                return ResourceManager.GetString("SendOtp", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Setting.
+        /// </summary>
+        public static string Setting {
+            get {
+                return ResourceManager.GetString("Setting", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Sign-up.
+        /// </summary>
+        public static string SignUp {
+            get {
+                return ResourceManager.GetString("SignUp", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Submit.
+        /// </summary>
+        public static string Submit {
+            get {
+                return ResourceManager.GetString("Submit", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Success.
+        /// </summary>
+        public static string Success {
+            get {
+                return ResourceManager.GetString("Success", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Time.
+        /// </summary>
+        public static string Time {
+            get {
+                return ResourceManager.GetString("Time", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Top.
+        /// </summary>
+        public static string Top {
+            get {
+                return ResourceManager.GetString("Top", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Total Coin.
+        /// </summary>
+        public static string TotalCoin {
+            get {
+                return ResourceManager.GetString("TotalCoin", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to turn.
+        /// </summary>
+        public static string turn {
+            get {
+                return ResourceManager.GetString("turn", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to turns.
+        /// </summary>
+        public static string turns {
+            get {
+                return ResourceManager.GetString("turns", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Warning.
+        /// </summary>
+        public static string Warning {
+            get {
+                return ResourceManager.GetString("Warning", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Weekly.
+        /// </summary>
+        public static string Weekly {
+            get {
+                return ResourceManager.GetString("Weekly", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Weekly Package.
+        /// </summary>
+        public static string WeeklyPackge {
+            get {
+                return ResourceManager.GetString("WeeklyPackge", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Win Challenge.
+        /// </summary>
+        public static string WinChallenge {
+            get {
+                return ResourceManager.GetString("WinChallenge", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Winners list.
+        /// </summary>
+        public static string Winner {
+            get {
+                return ResourceManager.GetString("Winner", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to WINNERS LIST.
+        /// </summary>
+        public static string WinnerList {
+            get {
+                return ResourceManager.GetString("WinnerList", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Congratulations you passed challenge %index% and got the reward:.
+        /// </summary>
+        public static string WinReward {
+            get {
+                return ResourceManager.GetString("WinReward", resourceCulture);
+            }
+        }
+    }
+}

+ 332 - 0
WebChallenge/WebChallenge/Texts/Lang.fr.resx

@@ -0,0 +1,332 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="AlreadyHaveAccount" xml:space="preserve">
+    <value>Já tem uma conta?</value>
+  </data>
+  <data name="BuyTurn" xml:space="preserve">
+    <value>Comprar chance</value>
+  </data>
+  <data name="Cancel" xml:space="preserve">
+    <value>Cancelar</value>
+  </data>
+  <data name="CancelConfirm" xml:space="preserve">
+    <value>Já não pretende registar?</value>
+  </data>
+  <data name="CancelDetailInfo" xml:space="preserve">
+    <value>Para anular o serviço, deve proceder de uma das duas formas seguintes
+&lt;br&gt;1. Compor SMS: enviar OFF para 154
+&lt;br&gt;2. Operação USSD: Digita *1541#, digita 1 e, em seguida, prima ”Confirmar“ para cancelar o pacote diário ou Digita *1541#, digita 2 e, em seguida, digita “Confirmar“ para cancelar o pacote semanal.”</value>
+  </data>
+  <data name="Challenge" xml:space="preserve">
+    <value>Desafio</value>
+  </data>
+  <data name="Close" xml:space="preserve">
+    <value>Fechar</value>
+  </data>
+  <data name="Coin" xml:space="preserve">
+    <value>Moeda</value>
+  </data>
+  <data name="Confirm" xml:space="preserve">
+    <value>Confirmar</value>
+  </data>
+  <data name="ConfirmExit" xml:space="preserve">
+    <value>Tens a certeza de que queres sair do jogo?</value>
+  </data>
+  <data name="Congratulation" xml:space="preserve">
+    <value>Parabéns</value>
+  </data>
+  <data name="Congratulations" xml:space="preserve">
+    <value>Parabéns</value>
+  </data>
+  <data name="CreateAccount" xml:space="preserve">
+    <value>Criar uma conta</value>
+  </data>
+  <data name="Curency" xml:space="preserve">
+    <value>MT</value>
+  </data>
+  <data name="Daily" xml:space="preserve">
+    <value>Diário</value>
+  </data>
+  <data name="DailyPackage" xml:space="preserve">
+    <value>Pacote diário</value>
+  </data>
+  <data name="DailyPrize" xml:space="preserve">
+    <value>Prémio diário</value>
+  </data>
+  <data name="EnterOtp" xml:space="preserve">
+    <value>Insira a OTP</value>
+  </data>
+  <data name="EnterPhonePassword" xml:space="preserve">
+    <value>Introduzir o número e a palavra-passe!</value>
+  </data>
+  <data name="Error" xml:space="preserve">
+    <value>Erro</value>
+  </data>
+  <data name="Exit" xml:space="preserve">
+    <value>Voltar</value>
+  </data>
+  <data name="GameOver" xml:space="preserve">
+    <value>Fim do jogo</value>
+  </data>
+  <data name="GameRules" xml:space="preserve">
+    <value>Regras do jogo</value>
+  </data>
+  <data name="Guide" xml:space="preserve">
+    <value>Guia</value>
+  </data>
+  <data name="Hello" xml:space="preserve">
+    <value>Ola</value>
+  </data>
+  <data name="History" xml:space="preserve">
+    <value>Histórico</value>
+  </data>
+  <data name="Home" xml:space="preserve">
+    <value>Início</value>
+  </data>
+  <data name="Language" xml:space="preserve">
+    <value>Língua</value>
+  </data>
+  <data name="Login" xml:space="preserve">
+    <value>Entrar</value>
+  </data>
+  <data name="MiniGameInfo" xml:space="preserve">
+    <value>Informações sobre o minijogo</value>
+  </data>
+  <data name="MonthlyPrize" xml:space="preserve">
+    <value>Prémio mensal</value>
+  </data>
+  <data name="MyCoin" xml:space="preserve">
+    <value>Minha moeda</value>
+  </data>
+  <data name="MyPackage" xml:space="preserve">
+    <value>Meu pacote</value>
+  </data>
+  <data name="MyRank" xml:space="preserve">
+    <value>Minha pontuação</value>
+  </data>
+  <data name="NextGame" xml:space="preserve">
+    <value>Próximo jogo</value>
+  </data>
+  <data name="NextGameOrClose" xml:space="preserve">
+    <value>Clica Próximo jogo para continuar a jogar ou Fechar para sair</value>
+  </data>
+  <data name="No" xml:space="preserve">
+    <value>No.</value>
+  </data>
+  <data name="NotReceiveOtp" xml:space="preserve">
+    <value>Não receber um OTP</value>
+  </data>
+  <data name="package" xml:space="preserve">
+    <value>pacote</value>
+  </data>
+  <data name="Password" xml:space="preserve">
+    <value>Palavra-passe</value>
+  </data>
+  <data name="PasswordSent" xml:space="preserve">
+    <value>A senha foi enviada para seu telefone!</value>
+  </data>
+  <data name="PayBasic" xml:space="preserve">
+    <value>Pagar através da conta básica</value>
+  </data>
+  <data name="PayEmola" xml:space="preserve">
+    <value>Pagar via e-Mola</value>
+  </data>
+  <data name="PhoneNumber" xml:space="preserve">
+    <value>Número de telefone</value>
+  </data>
+  <data name="Play" xml:space="preserve">
+    <value>Jogar</value>
+  </data>
+  <data name="PlayAgainOrClose" xml:space="preserve">
+    <value>Clica Jogar agora para jogar uma nova rodada ou clica Fechar para sair</value>
+  </data>
+  <data name="PlayNow" xml:space="preserve">
+    <value>Jogar agora</value>
+  </data>
+  <data name="Prize" xml:space="preserve">
+    <value>Prémio</value>
+  </data>
+  <data name="RankingCoin" xml:space="preserve">
+    <value>Moeda de classificação</value>
+  </data>
+  <data name="RegisterToBeRanked" xml:space="preserve">
+    <value>Para ser pontuado, por favor regista o serviço</value>
+  </data>
+  <data name="Resend" xml:space="preserve">
+    <value>Reenviar</value>
+  </data>
+  <data name="Result" xml:space="preserve">
+    <value>Resultados</value>
+  </data>
+  <data name="SelectPaymentChannel" xml:space="preserve">
+    <value>Selecionar o canal de pagamento</value>
+  </data>
+  <data name="SendOtp" xml:space="preserve">
+    <value>Enviar OTP</value>
+  </data>
+  <data name="Setting" xml:space="preserve">
+    <value>Definições</value>
+  </data>
+  <data name="SignUp" xml:space="preserve">
+    <value>Inscrever-se</value>
+  </data>
+  <data name="Submit" xml:space="preserve">
+    <value>Submeter</value>
+  </data>
+  <data name="Success" xml:space="preserve">
+    <value>Sucesso</value>
+  </data>
+  <data name="Time" xml:space="preserve">
+    <value>Tempo</value>
+  </data>
+  <data name="Top" xml:space="preserve">
+    <value>Topo</value>
+  </data>
+  <data name="TotalCoin" xml:space="preserve">
+    <value>Total de moedas</value>
+  </data>
+  <data name="turn" xml:space="preserve">
+    <value>rodada</value>
+  </data>
+  <data name="turns" xml:space="preserve">
+    <value>rodadas</value>
+  </data>
+  <data name="Warning" xml:space="preserve">
+    <value>Aviso</value>
+  </data>
+  <data name="Weekly" xml:space="preserve">
+    <value>Semanal</value>
+  </data>
+  <data name="WeeklyPackge" xml:space="preserve">
+    <value>Pacote semanal</value>
+  </data>
+  <data name="WinChallenge" xml:space="preserve">
+    <value>Ganha desafios</value>
+  </data>
+  <data name="Winner" xml:space="preserve">
+    <value>Vencedores</value>
+  </data>
+  <data name="WinnerList" xml:space="preserve">
+    <value>Lista de vencedores</value>
+  </data>
+  <data name="WinReward" xml:space="preserve">
+    <value>Parabéns passaste por %index% desafios e recebeste um prémio:</value>
+  </data>
+</root>

+ 334 - 0
WebChallenge/WebChallenge/Texts/Lang.resx

@@ -0,0 +1,334 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="AlreadyHaveAccount" xml:space="preserve">
+    <value>Already have account?</value>
+  </data>
+  <data name="BuyTurn" xml:space="preserve">
+    <value>Buy Turn</value>
+  </data>
+  <data name="Cancel" xml:space="preserve">
+    <value>Cancel</value>
+  </data>
+  <data name="CancelConfirm" xml:space="preserve">
+    <value>Don't want to Register anymore?</value>
+  </data>
+  <data name="CancelDetailInfo" xml:space="preserve">
+    <value>To cancel the service, please do one of the following two ways:
+
+&lt;br&gt;1. Compose SMS: OFF send to 1541
+
+&lt;br&gt;2. USSD operation: Press *1541#, press 1 then press "Confirm" to cancel the daily package or Press *1541#, press 2 then press "Confirm" to cancel the weekly package.</value>
+  </data>
+  <data name="Challenge" xml:space="preserve">
+    <value>Challenge</value>
+  </data>
+  <data name="Close" xml:space="preserve">
+    <value>Close</value>
+  </data>
+  <data name="Coin" xml:space="preserve">
+    <value>Coin</value>
+  </data>
+  <data name="Confirm" xml:space="preserve">
+    <value>Confirm</value>
+  </data>
+  <data name="ConfirmExit" xml:space="preserve">
+    <value>Are you sure you want to exit the game?</value>
+  </data>
+  <data name="Congratulation" xml:space="preserve">
+    <value>Congratulation</value>
+  </data>
+  <data name="Congratulations" xml:space="preserve">
+    <value>Congratulations</value>
+  </data>
+  <data name="CreateAccount" xml:space="preserve">
+    <value>Create an account</value>
+  </data>
+  <data name="Curency" xml:space="preserve">
+    <value>MT</value>
+  </data>
+  <data name="Daily" xml:space="preserve">
+    <value>Daily</value>
+  </data>
+  <data name="DailyPackage" xml:space="preserve">
+    <value>Daily Package</value>
+  </data>
+  <data name="DailyPrize" xml:space="preserve">
+    <value>Daily Prize</value>
+  </data>
+  <data name="EnterOtp" xml:space="preserve">
+    <value>Enter Otp</value>
+  </data>
+  <data name="EnterPhonePassword" xml:space="preserve">
+    <value>Enter number and password!</value>
+  </data>
+  <data name="Error" xml:space="preserve">
+    <value>Error</value>
+  </data>
+  <data name="Exit" xml:space="preserve">
+    <value>Exit</value>
+  </data>
+  <data name="GameOver" xml:space="preserve">
+    <value>Game over</value>
+  </data>
+  <data name="GameRules" xml:space="preserve">
+    <value>Game Rules</value>
+  </data>
+  <data name="Guide" xml:space="preserve">
+    <value>Guide</value>
+  </data>
+  <data name="Hello" xml:space="preserve">
+    <value>Hello</value>
+  </data>
+  <data name="History" xml:space="preserve">
+    <value>History</value>
+  </data>
+  <data name="Home" xml:space="preserve">
+    <value>Home</value>
+  </data>
+  <data name="Language" xml:space="preserve">
+    <value>Language</value>
+  </data>
+  <data name="Login" xml:space="preserve">
+    <value>Login</value>
+  </data>
+  <data name="MiniGameInfo" xml:space="preserve">
+    <value>Mini Game Information</value>
+  </data>
+  <data name="MonthlyPrize" xml:space="preserve">
+    <value>Monthly Prize</value>
+  </data>
+  <data name="MyCoin" xml:space="preserve">
+    <value>My coin</value>
+  </data>
+  <data name="MyPackage" xml:space="preserve">
+    <value>My package</value>
+  </data>
+  <data name="MyRank" xml:space="preserve">
+    <value>My rank</value>
+  </data>
+  <data name="NextGame" xml:space="preserve">
+    <value>NextGame</value>
+  </data>
+  <data name="NextGameOrClose" xml:space="preserve">
+    <value>Click Next game to continue playing 
or Close to exit !</value>
+  </data>
+  <data name="No" xml:space="preserve">
+    <value>No.</value>
+  </data>
+  <data name="NotReceiveOtp" xml:space="preserve">
+    <value>Do not receive an OTP</value>
+  </data>
+  <data name="package" xml:space="preserve">
+    <value>package</value>
+  </data>
+  <data name="Password" xml:space="preserve">
+    <value>Password</value>
+  </data>
+  <data name="PasswordSent" xml:space="preserve">
+    <value>Password has been sent to your phone!</value>
+  </data>
+  <data name="PayBasic" xml:space="preserve">
+    <value>Pay via basic account</value>
+  </data>
+  <data name="PayEmola" xml:space="preserve">
+    <value>Pay via e-Mola</value>
+  </data>
+  <data name="PhoneNumber" xml:space="preserve">
+    <value>Phone Number</value>
+  </data>
+  <data name="Play" xml:space="preserve">
+    <value>Play</value>
+  </data>
+  <data name="PlayAgainOrClose" xml:space="preserve">
+    <value>Click Play now to play a new round or click Close to exit.</value>
+  </data>
+  <data name="PlayNow" xml:space="preserve">
+    <value>Play Now</value>
+  </data>
+  <data name="Prize" xml:space="preserve">
+    <value>Prize</value>
+  </data>
+  <data name="RankingCoin" xml:space="preserve">
+    <value>Ranking coin</value>
+  </data>
+  <data name="RegisterToBeRanked" xml:space="preserve">
+    <value>To be ranked, please register for the service</value>
+  </data>
+  <data name="Resend" xml:space="preserve">
+    <value>Resend</value>
+  </data>
+  <data name="Result" xml:space="preserve">
+    <value>Result</value>
+  </data>
+  <data name="SelectPaymentChannel" xml:space="preserve">
+    <value>Select payment channel</value>
+  </data>
+  <data name="SendOtp" xml:space="preserve">
+    <value>Send OTP</value>
+  </data>
+  <data name="Setting" xml:space="preserve">
+    <value>Setting</value>
+  </data>
+  <data name="SignUp" xml:space="preserve">
+    <value>Sign-up</value>
+  </data>
+  <data name="Submit" xml:space="preserve">
+    <value>Submit</value>
+  </data>
+  <data name="Success" xml:space="preserve">
+    <value>Success</value>
+  </data>
+  <data name="Time" xml:space="preserve">
+    <value>Time</value>
+  </data>
+  <data name="Top" xml:space="preserve">
+    <value>Top</value>
+  </data>
+  <data name="TotalCoin" xml:space="preserve">
+    <value>Total Coin</value>
+  </data>
+  <data name="turn" xml:space="preserve">
+    <value>turn</value>
+  </data>
+  <data name="turns" xml:space="preserve">
+    <value>turns</value>
+  </data>
+  <data name="Warning" xml:space="preserve">
+    <value>Warning</value>
+  </data>
+  <data name="Weekly" xml:space="preserve">
+    <value>Weekly</value>
+  </data>
+  <data name="WeeklyPackge" xml:space="preserve">
+    <value>Weekly Package</value>
+  </data>
+  <data name="WinChallenge" xml:space="preserve">
+    <value>Win Challenge</value>
+  </data>
+  <data name="Winner" xml:space="preserve">
+    <value>Winners list</value>
+  </data>
+  <data name="WinnerList" xml:space="preserve">
+    <value>WINNERS LIST</value>
+  </data>
+  <data name="WinReward" xml:space="preserve">
+    <value>Congratulations you passed challenge %index% and got the reward:</value>
+  </data>
+</root>

+ 96 - 0
WebChallenge/WebChallenge/Views/Home/BuyTurn.cshtml

@@ -0,0 +1,96 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions;
+@using WebChallenge.Texts;
+@using WebChallenge.Controllers;
+
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+}
+
+
+<div class="main-content logo-background glass-background h-dvh relative z-0">
+    <div class="h-full">
+        <div class="h-full flex flex-col">
+            <div class="overflow-auto flex-grow-1 relative z-10 h-full flex flex-col">
+                <div class="mt-4 mx-4 px-1 rounded-3xl">
+                    <div class="flex justify-between">
+                        <button id="exitBtn" onclick="showModal('exitModal')"
+                                class="w-10 h-10 rounded-full flex justify-center items-center bg-[#F20] border border-white">
+                            <img src="../assets/icons/exit.svg" alt="exit" />
+                        </button>
+                        <a href="/Home/Setting"
+                           class="w-10 h-10 rounded-full flex justify-center items-center bg-[#2EA929] border border-white">
+                            <img src="../assets/icons/setting.svg" alt="setting" />
+                        </a>
+                    </div>
+                </div>
+
+                <div class="flex flex-col flex-grow justify-center max-h-[750px]">
+                    <div class="flex justify-center -mt-1">
+                        <img src="../assets/images/movitel_challenges.png" alt="movitel_challenges.png"
+                             class="max-w-[14.125rem] max-h-[7.5625rem]" />
+                    </div>
+
+                    <div class="mt-[2.31rem] flex flex-col gap-5 items-center">
+                        <a href="/Home/CheckPlay"
+                           class="play-button max-w-[17.375rem] w-full py-5 text-[#5A5A5A] text-[2.5rem] leading-[2.025rem] font-Alatsi text-center pulse-animation">
+                            @Lang.Play
+                        </a>
+                    </div>
+
+                    <div class="buy-turn h-[41px] flex items-center justify-center mt-5">
+                        <p class="text-2xl font-Alatsi text-white">@Lang.BuyTurn</p>
+                    </div>
+
+                    <div class="mt-[2.87rem] grid grid-cols-3 gap-[0.72rem] max-w-[393px] px-5 mx-auto">
+                        <div class="buy-turn-btn buy-turn-btn-1 " packg="MAIN_CHARGE_2">
+                            <p class="text-[2.1875rem] font-black uppercase">2MT</p>
+                            <p class="text-xl font-extrabold">1 @Lang.turn</p>
+                        </div>
+                        <div class="buy-turn-btn buy-turn-btn-2 active" packg="MAIN_CHARGE_4">
+                            <p class="text-[2.1875rem] font-black uppercase">4MT</p>
+                            <p class="text-xl font-extrabold">2 @Lang.turns</p>
+                        </div>
+                        <div class="buy-turn-btn buy-turn-btn-3" packg="MAIN_CHARGE_10">
+                            <p class="text-[2.1875rem] font-black uppercase">10mt</p>
+                            <p class="text-xl font-extrabold">5 @Lang.turns</p>
+                        </div>
+                    </div>
+
+                    <div class="mt-[2.62rem] flex justify-between mx-5 mb-2">
+                        <button onclick="BuyTurn();"
+                                class="btn-confirm font-Alatsi text-xl text-center w-full max-w-[137px] px-2 text-white">
+                            @Lang.Confirm
+                        </button>
+                        <a href="/Home/Index"
+                           class="btn-close font-Alatsi text-xl text-center w-full max-w-[137px] px-2 text-white">
+                            @Lang.Close
+                        </a>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+
+    <!-- Bottom Navigation -->
+    @Html.Partial("_Navigation")
+</div>
+
+@section Scripts {
+    <script>
+        $(".buy-turn-btn").click(function () {
+            $(".buy-turn-btn").removeClass('active');
+            $(this).addClass('active');
+        });
+
+        function BuyTurn() {
+            var packg = $(".buy-turn-btn.active").attr("packg");
+            console.log(packg);
+            buyMore(packg);
+        }
+    </script>
+}

+ 162 - 0
WebChallenge/WebChallenge/Views/Home/Guide0.cshtml

@@ -0,0 +1,162 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions
+@using WebChallenge.Texts;
+
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+}
+
+
+<div class="main-content logo-background glass-background h-dvh relative z-0">
+    <div class="h-full">
+        <div class="h-full flex flex-col">
+            <div class="overflow-auto flex-grow-1 relative z-10 h-full flex flex-col">
+                <div class="flex flex-col h-full">
+                    <div class="mt-3 mx-5 relative">
+                        <div class="image-light absolute w-full top-[2px]">
+                            <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                                 class="-translate-y-1/2 w-full">
+                        </div>
+                        <img src="../assets/images/his.png" alt="his frame"
+                             class="shadow-1 rounded-[2.5rem] max-h-[360px]" />
+                        <div class="image-light absolute bottom-0 w-full">
+                            <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                                 class="translate-y-1/2 w-full">
+                        </div>
+                        <div class="absolute top-0 h-full w-full rounded-[2.5rem] flex justify-center items-center px-6 text-white font-normal uppercase font-Alatsi text-[1.375rem]">
+                            GUIDE
+                        </div>
+                    </div>
+                    <div class="flex-grow overflow-auto mt-4 px-9 flex flex-col gap-3 text-white leading-[22.4px]">
+                        <p class="text-justify">
+                            O “Movitel challenges” é um serviço onde os clientes podem participar em muitos jogos diferentes e com conteúdos diversificados, tais como: ovo tiro ao ovo, tiro ao arco, futebol... Além de experimentar muitos jogos atraentes, o serviço também traz muitas oportunidades para receber prémios valiosos e utilidades para os jogadores, tais como: SMS/Dados/Credito e dinheiro adicionado à Carteira.
+                        </p>
+                        <div class="flex justify-center">
+                            <img src="../assets/icons/arrow-down.svg" alt="arrow down" class="w-[17px]" />
+                        </div>
+                        <p class="text-justify">
+                            Para participar no jogo, pode inscrever-se em pacotes diários, semanais ou comprar turnos da seguinte forma:
+                        </p>
+                        <div class="bg-7 min-h-[30px] font-black flex justify-center items-center font-montserrat">
+                            Pacote diário
+                        </div>
+                        <p class="text-center">
+                            3MT/3 rodadas
+                        </p>
+                        <div class="bg-8 min-h-[30px] font-black flex justify-center items-center font-montserrat">
+                            Pacote semanal
+                        </div>
+                        <p class="text-center">
+                            15MT/21 voltas (adicionar 3 jogadas por dia para clientes)
+                        </p>
+                        <div class="bg-9 min-h-[30px] font-black flex justify-center items-center font-montserrat">
+                            Compar pacotes de rodadas
+                        </div>
+                        <p class="text-center">
+                            2MT/ 1 rodadas; 4MT/ 2 rodadas; 10MT/ 5 rodadas
+                        </p>
+                        <hr class="h-[0.5px] w-full bg-white" />
+                        <div class="text-justify">
+                            <p>
+                                O serviço terá um máximo de 10 jogos por turno, cada desafio que completar será pontuado e somado, se não passar em nenhum desafio, parará nesse desafio.
+                            </p>
+                            <p>
+                                As regras do painel de avaliação:
+                            </p>
+                        </div>
+                        <div class="bg-[#ffffff1a] min-h-[42px] font-bold flex justify-center items-center">
+                            Os desafios específicos são os seguintes
+                        </div>
+                        <div class="max-w-[199px] w-full mx-auto">
+                            <p>• Desafio 1 _ 2 pontos</p>
+                            <p>• Desafio 2 _ 5 pontos</p>
+                            <p>• Desafio 3 _ 7 pontos</p>
+                            <p>• Desafio 4 _ 9 pontos</p>
+                        </div>
+                        <div class="bg-8 min-h-[22px] flex items-center justify-center">
+                            <div class="max-w-[199px] w-full mx-auto">
+                                • Desafio 5 _ Premio
+                            </div>
+                        </div>
+                        <div class="max-w-[199px] w-full mx-auto">
+                            <p>• Desafio 6_ 12 pontos</p>
+                            <p>• Desafio 7_ 15 pontos</p>
+                            <p>• Desafio 8_ 17 pontos</p>
+                            <p>• Desafio 9_ 19 pontos</p>
+                        </div>
+                        <div class="bg-8 min-h-[22px] flex items-center justify-center">
+                            <div class="max-w-[199px] w-full mx-auto">
+                                • Challenge 10 _ Premio
+                            </div>
+                        </div>
+                        <p class="text-justify">
+                            Para os marcos de desafio 5 e 10, receberá um presente aleatório do sistema, 1 dos seguintes presentes:
+                        </p>
+                        <div class="mx-12 flex justify-between items-center">
+                            <img src="../assets/icons/number_5.svg" alt="number_5"
+                                 class="w-[40px] h-[40px] shadow-2 rounded-full" />
+                            <img src="../assets/icons/number_10.svg" alt="number_10"
+                                 class="w-[40px] h-[40px] shadow-3 rounded-full" />
+                        </div>
+                        <div class="gif-challenge grid grid-cols-2 mx-[0.59rem]">
+                            <div>
+                                <p class="font-bold">Gif Challenge 5</p>
+                                <div>
+                                    <p>• 15 pontos</p>
+                                    <p>• 50 MB</p>
+                                    <p>• 5 MT</p>
+                                </div>
+                            </div>
+                            <div class="w-fit ml-auto flex flex-col">
+                                <p class="font-bold">Gif Challenge 10</p>
+                                <div>
+                                    <p>• 30 pontos</p>
+                                    <p>• 100 MB</p>
+                                    <p>• 10 MT</p>
+                                </div>
+                            </div>
+                        </div>
+                        <p class="text-justify text-xs italic font-normal">
+                            Os presentes serão gerados aleatoriamente e adicionados diretamente à conta de jogo do subscritor.
+                        </p>
+                        <hr class="h-[0.5px] w-full bg-white" />
+                        <p class="text-justify">
+                            Os pontos acumulados nos milestones serão acumulados mensalmente para participar na corrida TOP para receber os prémios mensais do serviço, os Subscritores com TOP 1 pontos altos no mês, os pontos são calculados das 00:01 do primeiro dia do mês às 23:59 do último dia do mês.
+                        </p>
+                        <div class="bg-[#ffffff1a] min-h-[42px] font-bold flex justify-center items-center">
+                            Top 1
+                        </div>
+                        <div class="flex justify-center items-center">
+                            <img src="../assets/icons/cup.svg" alt="cup" class="w-[65px] h-[83px]" />
+                        </div>
+                        <div>
+                            <p class="text-[#FFE148] text-[2rem] font-black text-center leading-[44.8px]">20,000 MT</p>
+                            <p class="text-center">adicionado à carteira eMola.</p>
+                        </div>
+                        <hr class="h-[0.5px] w-full bg-white" />
+                        <div class="italic text-xs text-justify leading-[16.8px]">
+                            <p class="font-extrabold">*Nota</p>
+
+                            <p>
+                                - Em 3 meses consecutivos, os subscritores só podem receber prémios durante um máximo de 1 mês. Se o assinante ainda alcançar oTOP 1, este será atribuído ao assinante com a pontuação mais próxima.
+                            </p>
+
+                            <br />
+
+                            <p>
+                                - Prémios mensais De 01 a 05, o pessoal entrará em contacto com os clientes para confirmar e adicionar os prémios aos clientes. Se após 10 dias o cliente não for contactado, o prémio será cancelado.
+                            </p>
+                        </div>
+                        <div class="px-2"></div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- Bottom Navigation -->
+    @Html.Partial("_Navigation")
+</div>

+ 174 - 0
WebChallenge/WebChallenge/Views/Home/Guide1.cshtml

@@ -0,0 +1,174 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions
+@using WebChallenge.Texts;
+
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+}
+
+
+<div class="main-content logo-background glass-background h-dvh relative z-0">
+    <div class="h-full">
+        <div class="h-full flex flex-col">
+            <div class="overflow-auto flex-grow-1 relative z-10 h-full flex flex-col">
+                <div class="flex flex-col h-full">
+                    <div class="mt-3 mx-5 relative">
+                        <div class="image-light absolute w-full top-[2px]">
+                            <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                                 class="-translate-y-1/2 w-full">
+                        </div>
+                        <img src="../assets/images/his.png" alt="his frame"
+                             class="shadow-1 rounded-[2.5rem] max-h-[360px]" />
+                        <div class="image-light absolute bottom-0 w-full">
+                            <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                                 class="translate-y-1/2 w-full">
+                        </div>
+                        <div class="absolute top-0 h-full w-full rounded-[2.5rem] flex justify-center items-center px-6 text-white font-normal uppercase font-Alatsi text-[1.375rem]">
+                            GUIDE
+                        </div>
+                    </div>
+                    <div class="flex-grow overflow-auto mt-4 px-9 flex flex-col gap-3 text-white leading-[22.4px]">
+                        <p class="text-justify">
+                            Movitel challenges is a service where customers can participate in many different games and
+                            diverse in game content such as egg shooting, archery, soccer... In addition to experiencing
+                            many attractive games, the service also brings many opportunities to receive valuable prizes
+                            and utilities for players such as: SMS/Data/airtime and money added to Wallet.
+                        </p>
+                        <div class="flex justify-center">
+                            <img src="../assets/icons/arrow-down.svg" alt="arrow down" class="w-[17px]" />
+                        </div>
+                        <p class="text-justify">
+                            To join the game, you can register for Daily, Weekly packages or buy turns as follows:
+                        </p>
+                        <div class="bg-7 min-h-[30px] font-black flex justify-center items-center font-montserrat">
+                            Daily package
+                        </div>
+                        <p class="text-center">
+                            3MT/3 turns
+                        </p>
+                        <div class="bg-8 min-h-[30px] font-black flex justify-center items-center font-montserrat">
+                            Weekly package
+                        </div>
+                        <p class="text-center">
+                            15MT/21 turns (add 3 plays per day)
+                        </p>
+                        <div class="bg-9 min-h-[30px] font-black flex justify-center items-center font-montserrat">
+                            Buyturn package
+                        </div>
+                        <p class="text-center">
+                            2MT/ 1 turn; 4MT/ 2 turns; 10MT/ 5 turns
+                        </p>
+                        <hr class="h-[0.5px] w-full bg-white" />
+                        <div class="text-justify">
+                            <p>
+                                The service will have a maximum of 10 games per turn, each challenge you complete will
+                                be scored and added together, if you do not pass any challenge you will stop at that
+                                challenge.
+                            </p>
+                            <p>
+                                The rules for the scoreboard through
+                            </p>
+                        </div>
+                        <div class="bg-[#ffffff1a] min-h-[42px] font-bold flex justify-center items-center">
+                            Specific challenges are as follows
+                        </div>
+                        <div class="max-w-[199px] w-full mx-auto">
+                            <p>• Challenge 1 _ 2 point</p>
+                            <p>• Challenge 2 _ 5 point</p>
+                            <p>• Challenge 3 _ 7 point</p>
+                            <p>• Challenge 4 _ 9 point</p>
+                        </div>
+                        <div class="bg-8 min-h-[22px] flex items-center justify-center">
+                            <div class="max-w-[199px] w-full mx-auto">
+                                • Challenge 5 _ Gift
+                            </div>
+                        </div>
+                        <div class="max-w-[199px] w-full mx-auto">
+                            <p>• Challenge 6 _ 12 point</p>
+                            <p>• Challenge 7_ 15 point</p>
+                            <p>• Challenge 8_ 17 point</p>
+                            <p>• Challenge 9_ 19 point</p>
+                        </div>
+                        <div class="bg-8 min-h-[22px] flex items-center justify-center">
+                            <div class="max-w-[199px] w-full mx-auto">
+                                • Challenge 10 _ Gift
+                            </div>
+                        </div>
+                        <p class="text-justify">
+                            For challenge milestones 5 and 10 you will receive a random gift from the system, 1 of the
+                            following gifts:
+                        </p>
+                        <div class="mx-12 flex justify-between items-center">
+                            <img src="../assets/icons/number_5.svg" alt="number_5"
+                                 class="w-[40px] h-[40px] shadow-2 rounded-full" />
+                            <img src="../assets/icons/number_10.svg" alt="number_10"
+                                 class="w-[40px] h-[40px] shadow-3 rounded-full" />
+                        </div>
+                        <div class="gif-challenge grid grid-cols-2 mx-[0.59rem]">
+                            <div>
+                                <p class="font-bold">Gif Challenge 5</p>
+                                <div>
+                                    <p>• 15 point</p>
+                                    <p>• 50 MB</p>
+                                    <p>• 5 MT</p>
+                                </div>
+                            </div>
+                            <div class="w-fit ml-auto flex flex-col">
+                                <p class="font-bold">Gif Challenge 10</p>
+                                <div>
+                                    <p>• 30 point</p>
+                                    <p>• 100 MB</p>
+                                    <p>• 10 MT</p>
+                                </div>
+                            </div>
+                        </div>
+                        <p class="text-justify text-xs italic font-normal">
+                            Gifts will be generated randomly and added directly to the subscriber's game account.
+                        </p>
+                        <hr class="h-[0.5px] w-full bg-white" />
+                        <p class="text-justify">
+                            Points accumulated at milestones will be accumulated monthly to participate in the TOP race
+                            to receive monthly prizes of the service, Subscribers with TOP 1 points high in the month,
+                            points are calculated from 00:01 on the first day of the month to 23:59 on the last day of
+                            the month.
+                        </p>
+                        <div class="bg-[#ffffff1a] min-h-[42px] font-bold flex justify-center items-center">
+                            Top 1
+                        </div>
+                        <div class="flex justify-center items-center">
+                            <img src="../assets/icons/cup.svg" alt="cup" class="w-[65px] h-[83px]" />
+                        </div>
+                        <div>
+                            <p class="text-[#FFE148] text-[2rem] font-black text-center leading-[44.8px]">20,000 MT</p>
+                            <p class="text-center">added to eMola wallet.</p>
+                        </div>
+                        <hr class="h-[0.5px] w-full bg-white" />
+                        <div class="italic text-xs text-justify leading-[16.8px]">
+                            <p class="font-extrabold">*Note</p>
+
+                            <p>
+                                - In 3 consecutive months, subscribers can only receive rewards for a maximum of 1
+                                month. If the subscriber still reaches TOP 1, it will be given to the subscriber with
+                                the closest score.
+                            </p>
+
+                            <br />
+
+                            <p>
+                                - Monthly Prizes From 01 to 05, staff will contact customers to confirm and add rewards
+                                to customers. If after 10 days the customer cannot be contacted, the prize will be
+                                canceled.
+                            </p>
+                        </div>
+                        <div class="px-2"></div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    @Html.Partial("_Navigation")
+</div>

+ 93 - 0
WebChallenge/WebChallenge/Views/Home/History.cshtml

@@ -0,0 +1,93 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions
+@using WebChallenge.Controllers
+@model List<PlayHistory>
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+}
+
+
+
+<div class="main-content logo-background game h-dvh relative history">
+
+    <div class="h-full">
+        <div class="h-full flex flex-col">
+            <div class="overflow-auto flex-grow-1 relative z-10 h-full flex flex-col">
+                <div class="mt-4 mx-4 px-1 rounded-3xl">
+                    <div class="flex justify-between">
+                        <button id="exitBtn" onclick="showModal('exitModal')"
+                                class="w-10 h-10 rounded-full flex justify-center items-center bg-[#F20] border border-white">
+                            <img src="../assets/icons/exit.svg" alt="exit" />
+                        </button>
+                        <a href="/Home/Setting"
+                           class="w-10 h-10 rounded-full flex justify-center items-center bg-[#2EA929] border border-white">
+                            <img src="../assets/icons/setting.svg" alt="setting" />
+                        </a>
+                    </div>
+                </div>
+
+                <div class="flex flex-col flex-grow justify-center h-full-40">
+                    <div class="mt-48 mx-5 relative">
+                        <div class="image-light absolute w-full top-[2px]" style="top: -24px; z-index: 12;">
+                            <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                                 class="-translate-y-1/2 w-full">
+                        </div>
+                        <img src="../assets/images/his.png" alt="his frame"
+                             class="shadow-1 rounded-[2.5rem] -translate-y-1/2" style="position: absolute; z-index: 12;" />
+                        <div class="image-light absolute bottom-0 w-full" style="z-index: 11; bottom: -23px;">
+                            <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                                 class="translate-y-1/2 w-full">
+                        </div>
+                        <div class="absolute top-0 h-full w-full rounded-[2.5rem] flex justify-between items-center px-6 text-white font-bold" style="z-index: 12;">
+                            <span>@Lang.No</span>
+                            <span>@Lang.Time</span>
+                            <span>@Lang.Result</span>
+                            <span>@Lang.Coin</span>
+                            <span>@Lang.Prize</span>
+                        </div>
+                    </div>
+
+                    <div class="overflow-auto list-table-history relative z-10">
+                        <div class="mx-5 mt-4">
+                            <table class="w-full">
+                                <tbody>
+                                    @if (Model != null)
+                                    {
+                                        for (int i = 0; i < Model.Count; i++)
+                                        {
+                                            var his = Model[i];
+                                            var prize = (his.data.StartsWith("0") ? "" : his.data + ", ") + (his.mt.StartsWith("0") ? "" : his.mt);
+
+                                            <tr class="text-white font-roboto text-[14px] text-center">
+                                                <td class="px-4 text-center">@(i+1)</td>
+                                                <td class="px-4 text-center">
+                                                    <div class="date-history flex flex-col">
+                                                        <span class="font-normal leading-none">@his.date.Substring(11)</span>
+                                                        <span class="text-[10px] font-semibold leading-none mt-1 color-FFC489">@his.date.Substring(0, 10)</span>
+                                                    </div>
+                                                </td>
+                                                <td class="px-4 font-normal text-right">@his.step</td>
+                                                <td class="px-4 font-normal text-right">@his.point</td>
+                                                <td class="pr-8 font-bold text-right">
+                                                    @(prize == "" ? "0MT" : prize)
+                                                </td>
+                                            </tr>
+                                        }
+                                    }
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+
+    <!-- Bottom Navigation -->
+    @Html.Partial("_Navigation")
+
+</div>

+ 204 - 0
WebChallenge/WebChallenge/Views/Home/Index.cshtml

@@ -0,0 +1,204 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions
+@using WebChallenge.Controllers
+
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+}
+
+<div class="main-content logo-background glass-background h-dvh relative z-0">
+    <div class="h-full">
+        <div class="h-full flex flex-col">
+            <div class="overflow-auto flex-grow-1 relative z-10 h-full flex flex-col">
+                <div class="mt-4 mx-4 px-1 rounded-3xl">
+                    <div class="flex justify-between">
+                        <button id="exitBtn" onclick="showModal('exitModal')"
+                                class="w-10 h-10 rounded-full flex justify-center items-center bg-[#F20] border border-white">
+                            <img src="../assets/icons/exit.svg" alt="exit" />
+                        </button>
+                        <a href="/Home/Setting"
+                           class="w-10 h-10 rounded-full flex justify-center items-center bg-[#2EA929] border border-white">
+                            <img src="../assets/icons/setting.svg" alt="setting" />
+                        </a>
+                    </div>
+                </div>
+
+                <div class="flex flex-col flex-grow justify-center">
+                    <div class="flex flex-col items-center gap-[5px] justify-center -mt-1 h-full max-h-[175px]">
+                        <img src="../assets/icons/logo.svg" alt="movitel_challenges.png" class="max-w-[40px] max-h-[45px]" />
+                        <img src="../assets/images/movitel_challenges.png" alt="movitel_challenges.png"
+                             class="max-w-[14.125rem] max-h-[7.5625rem]" />
+                    </div>
+                    @if (userInfo.isactive == "0")
+                    {
+                        <div class="flex justify-between pt-[2px]">
+                            <div onclick="register('DAILY')"
+                                 class="text-white uppercase relative z-10 h-[55px] w-[147px] hover:cursor-pointer pulse-animation">
+                                <div class="absolute w-full h-full z-0">
+                                    <img src="../assets/images/image_1.png" alt="image 1" class="w-full"
+                                         style="height: calc(100% + 11px)">
+                                </div>
+                                <div class="relative z-10 h-full flex flex-col justify-end pl-2 pb-[3px]">
+                                    <p class="text-[2rem] italic font-black leading-none">@Lang.Daily</p>
+                                    <p class="text-[0.6875rem] italic font-black leading-none flex items-center gap-2">
+                                        @Lang.package <img src="../assets/icons/arrow-to-right.svg" alt="arrow" />
+                                    </p>
+                                </div>
+                            </div>
+                            <div onclick="register('WEEKLY')"
+                                 class="text-white uppercase relative z-10 h-[55px] w-[147px] hover:cursor-pointer pulse-animation">
+                                <div class="absolute w-full h-full z-0">
+                                    <img src="../assets/images/image_3.png" alt="image 1" class="w-full"
+                                         style="height: calc(100% + 11px)">
+                                </div>
+                                <div class="relative z-10 h-full flex flex-col justify-end pr-2 pb-[3px]">
+                                    <p class="text-[1.5625rem] italic font-black leading-none text-end">@Lang.Weekly</p>
+                                    <p class="text-[0.6875rem] italic font-black leading-none flex items-center justify-end gap-2">
+                                        <img src="../assets/icons/arrow-to-left.svg" alt="arrow" class="translate-y-[180deg]" />
+                                        @Lang.package
+                                    </p>
+                                </div>
+                            </div>
+                        </div>
+                    }
+
+                    <div class="mt-[2.31rem] flex flex-col gap-5 items-center">
+                        @if (userInfo.remain_turn > 0)
+                        {
+                            <a href="/Home/CheckPlay"
+                               class="play-button max-w-[17.375rem] w-full py-5 text-[#5A5A5A] text-[2.5rem] leading-[2.025rem] font-Alatsi text-center pulse-animation">
+                                @Lang.Play
+                            </a>
+                        }
+                        <a href="/Home/BuyTurn"
+                           class="max-w-[17.375rem] w-full py-1 px-[0.625rem] rounded-[1.25rem] border border-white bg-1 font-Alatsi text-white text-2xl text-center pulse-animation">
+                            @Lang.BuyTurn
+                        </a>
+                    </div>
+
+                    <div class="mb-[2.07rem]">
+                        <div class="flex justify-center items-center relative mt-10">
+                            <img src="../assets/icons/arrow_1.svg" alt="arrow 1"
+                                 class="absolute left-0 w-[81.7px] h-[129.2px] z-10" />
+                            <a href="/Home/Ranking" class="relative w-full h-full">
+                                <img src="../assets/images/Group-35.png" alt="arrow 2"
+                                     class="z-0 overflow-hidden absolute top-0 h-full w-full" />
+                                <p class="relative w-full text-center uppercase text-white font-Alatsi text-[2rem] font-normal py-[0.53rem] px-[0.625rem] z-10 pulse-animation">
+                                    @Lang.RankingCoin
+                                </p>
+                            </a>
+                            <img src="../assets/icons/arrow_2.svg" alt="arrow 2"
+                                 class="absolute right-0 w-[81.7px] h-[129.2px] overflow-hidden" />
+                        </div>
+
+                        <div class="mt-[1.38rem] px-16">
+                            <div class="flex items-center gap-3">
+                                <img src="../assets/icons/coin.svg" alt="icons" />
+                                <div class="flex justify-between flex-grow">
+                                    <p class="text-white text-2xl">@Lang.MyCoin</p>
+                                    <p class="text-[#FDB514] text-end font-black text-2xl">@userInfo.score</p>
+                                </div>
+                            </div>
+                            <hr class="my-3 h-[0.5px]" />
+                            <div class="flex items-center gap-3">
+                                <img src="../assets/icons/start-fill.svg" alt="icons" />
+                                <div class="flex justify-between flex-grow">
+                                    <p class="text-white text-2xl">@Lang.turns</p>
+                                    <p class="text-[#FDB514] text-end font-black text-2xl" id="remainTurn">@userInfo.remain_turn</p>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    @Html.Partial("_Navigation")
+</div>
+
+
+@section Scripts {
+    <script>
+
+        var getUrlParameter = function getUrlParameter(sParam) {
+            var sPageURL = window.location.search.substring(1),
+                sURLVariables = sPageURL.split('&'),
+                sParameterName,
+                i;
+
+            for (i = 0; i < sURLVariables.length; i++) {
+                sParameterName = sURLVariables[i].split('=');
+
+                if (sParameterName[0] === sParam) {
+                    return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
+                }
+            }
+            return false;
+        };
+
+        //function hideModal(modalName) {
+        //    $("#" + modalName).modal('hide');
+        //}
+        //function showModal(id) {
+        //    $("#" + id).modal('show');
+        //}
+
+
+        $(document).ready(function () {
+            var gameOver = getUrlParameter("gameover");
+            var stage = getUrlParameter("stage");
+            if (gameOver == '1' && stage != null && stage != '0') {
+                // show game over & score
+                $("#challengeOver").html(stage);
+                showModal('dialogGameOver');
+            }
+        });
+
+
+        function homepage() {
+            location.href = "/Home/Index";
+        }
+                //$(".play-now").click(function () {
+                //    // start play
+                //});
+
+                //$(".btn-register").click(function () {
+                //    //showModal('confirm-otp');
+                //});
+
+                //function checkPlay() {
+                //    let remainTurn = parseInt($("#remainTurn").html());
+                //    if (remainTurn <= 0) {
+                //        // show dialog
+                //        $("#dialog-failed-message").html('Lang.OutOfTurn');
+                //        showModal("failed-register");
+                //    } else {
+                //        // send check play
+                //        $.ajax({
+                //            url: "/Home/CheckPlay",
+                //            data: {
+                //            },
+                //            type: "POST",
+                //            success: function (data) {
+                //                if (data.error == "0") {
+                //                    // redirect to play
+                //                    location.href = data.href;
+                //                } else {
+                //                    // show dialog
+                //                    $("#dialog-info-message").html(data.content);
+                //                    showModal("dialog-info");
+                //                }
+                //            },
+                //            error: function (data) {
+                //                console.log(data);
+                //            }
+                //        });
+                //    }
+                //}
+
+    </script>
+}

+ 127 - 0
WebChallenge/WebChallenge/Views/Home/Login.cshtml

@@ -0,0 +1,127 @@
+@{
+    ViewData["Title"] = @Lang.Login;
+    //Layout = "../Shared/_LayoutLogin";
+}
+@using WebChallenge.Extensions;
+
+@{
+    string loginUser = Context.Session.GetComplexData<string>("loginUser");
+}
+
+<!-- Login Form -->
+<div class="w-full h-full flex flex-col justify-end pr-6 pb-3">
+    <div class="bg-opacity-70 w-full max-w-md login-content">
+        <h2 class="text-white font-normal mb-4 text-center font-Alatsi text-[36px]">@Lang.Login</h2>
+        <div class="flex flex-col items-center justify-center">
+            <!-- Phone Number -->
+            <div class="mb-4 w-full flex justify-center">
+                <input type="text" name="phone" placeholder="@Lang.PhoneNumber" id="phoneNumber" value="@loginUser"
+                       class="font-roboto w-full px-4 py-2 border-white bg-transparent color-DADADA placeholder-white text-[20px] font-normal">
+            </div>
+            <!-- OTP -->
+            <div class="mb-4 w-full flex justify-center">
+                <input type="password" name="password" id="password" placeholder="@Lang.Password"
+                       class="font-roboto w-full px-4 py-2  color-DADADA2 border-white bg-transparent text-[18px] font-normal">
+            </div>
+            <!-- Login Button -->
+            <button class="text-[24px] font-Alatsi w-full py-2 text-white font-normal btn-login" onclick="login()">
+                @Lang.Login
+            </button>
+        </div>
+        <!-- Resend OTP -->
+        @*<p class="text-white text-center mt-4 text-[16px] font-roboto font-normal" id="forgotPassword">
+                <a href="#" class="text-orange-500 font-bold hover:underline text-[16px] resend"
+                   onclick="forgotPassword()">
+                    Forgot password?
+                </a>
+            </p>*@
+        <p class="text-white text-center mt-4 text-[16px] font-roboto font-normal" id="resendOtp">
+            @Lang.NotReceiveOtp?
+            <button onclick="getPassword();" class="text-orange-500 font-bold hover:underline text-[16px] resend">
+                @Lang.Resend
+            </button>
+        </p>
+    </div>
+</div>
+
+
+
+@section Scripts {
+    <script>
+        var clicked = false;
+        function login() {
+            console.log("login");
+            if (clicked) {
+                return;
+            }
+            clicked = true;
+            let users = $("#phoneNumber").val().trim();
+            let password = $("#password").val().trim();
+            $.ajax({
+                url: "/Home/LoginAction",
+                data: {
+                    msisdn: users,
+                    users: users,
+                    pass: password,
+                    command: "LOGIN"
+                },
+                type: "POST",
+                success: function (data) {
+                    console.log(data);
+                    clicked = false;
+                    if (data.error == "0") {
+                        if (data.href != null) {
+                            location.href = data.href;
+                        }
+                    } else {
+                        //$("#login-error").show();
+                        //$("#login-error").html(data.content);
+                        // failed
+                        showDialog('dialogResult', "@Lang.Error", data.content, data.error);
+                    }
+                },
+                error: function (data) {
+                    clicked = false;
+                    console.log(data);
+                }
+            });
+        }
+
+        function getPassword() {
+            console.log("get password");
+            let users = $("#phoneNumber").val().trim();
+            //let password = $("#password").val().trim();
+            $.ajax({
+                url: "/Home/ResetPasswordAction",
+                data: {
+                    msisdn: users,
+                    users: users,
+                    command: "RESETPASS"
+                },
+                type: "POST",
+                success: function (data) {
+                    if (data.error == "0") {
+                        $("#password").val("");
+                        $("#password").attr("placeholder", "@Lang.PasswordSent");
+                    } else {
+                        showDialog('dialogResult', "@Lang.Error", data.content, data.error);
+                    }
+                },
+                error: function (data) {
+                    console.log(data);
+                }
+            });
+        }
+
+        // Lấy phần tử cần kiểm tra
+        const loginContent = document.querySelector('.login-content');
+
+        // Lắng nghe sự kiện click trên document
+        document.addEventListener('click', function (event) {
+            // Kiểm tra nếu click không nằm trong phần tử loginContent
+            if (!loginContent.contains(event.target)) {
+                window.location.href = '/Home/Start';
+            }
+        });
+    </script>
+}

+ 255 - 0
WebChallenge/WebChallenge/Views/Home/Playing.cshtml

@@ -0,0 +1,255 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions;
+@using WebChallenge.Controllers;
+@using System.Web;
+@model PlayingObj
+@{
+    UserInfo loginRes = Context.Session.GetComplexData<UserInfo>("userInfo");
+    GameInfo gameInfo = null;
+    string gameUrl = "";
+    if (Model.gameIndex < Model.listGame.Count)
+    {
+        gameInfo = Model.listGame[Model.gameIndex];
+        gameUrl = gameInfo.gameLink + "?playId=" + gameInfo.playId
+           + "&playKey=" + gameInfo.playKey
+           + "&playDetailId=" + gameInfo.playDetailId
+           + "&playDetailKey=" + gameInfo.playDetailKey
+           + "&token=" + HttpUtility.UrlEncode(loginRes.token);
+    }
+    string isdn = loginRes.msisdn.Substring(3);
+    var lang = LanguageController.getCurrentLang();
+
+    var giftInfo = Model.gift;
+    var shownGift = Model.shownGift;
+    bool isMileStone = Model.gameIndex == 5 || Model.gameIndex == 10;
+}
+
+<input type="hidden" value="@(giftInfo == null ? 1 : 0)" id="shownGift" />
+
+<div class="main-content logo-background glass-background hidden-navigation h-dvh relative z-0">
+    <div class="h-full">
+        <div class="h-full flex flex-col">
+            <div class="overflow-auto flex-grow-1 relative z-10 h-full flex flex-col">
+                <div class="mt-4 mx-4 px-1 rounded-3xl">
+                    <div class="flex justify-between">
+                        <button id="exitBtn" onclick="showModal('backModal')"
+                                class="w-10 h-10 rounded-full flex justify-center items-center bg-[#F20] border border-white">
+                            <img src="../assets/icons/exit.svg" alt="exit" />
+                        </button>
+                        @*<a href="setting.html"
+                               class="w-10 h-10 rounded-full flex justify-center items-center bg-[#2EA929] border border-white">
+                                <img src="../assets/icons/setting.svg" alt="setting" />
+                            </a>*@
+                    </div>
+                </div>
+                @if (gameInfo != null)
+                {
+                <div class="flex flex-col flex-grow justify-center max-h-[750px]">
+                    <div class="mt-6 flex justify-center">
+                        <img src="@gameInfo.gameIcon" alt="image puzzle" class="max-w-[300px]" />
+                    </div>
+
+                    <div class="mt-3 mx-4 text-center flex flex-col gap-3 text-white">
+                        <div>
+                            <p class="font-extrabold text-2xl leading-[normal]">@Lang.MiniGameInfo</p>
+                            @if (lang == LanguageController.GLOBAL)
+                                {
+                            <p class="mt-1 leading-[normal]">
+                                @gameInfo.gameTitleGlobal
+                            </p>
+                                }
+                                else
+                                {
+                            <p class="mt-1 leading-[normal]">
+                                @gameInfo.gameTitleLocal
+                            </p>
+                                }
+                        </div>
+
+                        <div>
+                            <div class="light-border"></div>
+
+                            <p class="font-bold mt-5 leading-[normal]">@Lang.GameRules:</p>
+                            @if (lang == LanguageController.GLOBAL)
+                                {
+                            <div>
+                                @Html.Raw(gameInfo.gameDescriptionGlobal)
+                            </div>
+                                }
+                                else
+                                {
+                            <div>
+                                @Html.Raw(gameInfo.gameDescriptionLocal)
+                            </div>
+                                }
+                            @*<ul class="list-disc ml-8 mt-1">
+                                    <li class="text-start leading-[normal]">
+                                        Each player must find hidden objects around the island in under 15 minutes.
+                                    </li>
+                                    <li class="text-start leading-[normal]">
+                                        No external tools or devices allowed.
+                                    </li>
+                                    <li class="text-start leading-[normal]">
+                                        The player with the most collected items wins a special prize.
+                                    </li>
+                                    <li class="text-start leading-[normal]">
+                                        Ties are decided by a bonus question about island trivia.
+                                    </li>
+                                </ul>*@
+
+                            <div class="light-border mt-5"></div>
+                        </div>
+                    </div>
+
+                    <div class="flex justify-center">
+                        <a href="@gameUrl"
+                           class="play-button max-w-[17.375rem] w-full py-5 mt-[0.94rem] text-[#5A5A5A] text-[2.5rem] leading-[2.025rem] font-Alatsi text-center pulse-animation">
+                            @Lang.PlayNow
+                        </a>
+                    </div>
+
+                    <div class="pb-[3.56rem]"></div>
+                </div>
+
+                }
+            </div>
+        </div>
+    </div>
+</div>
+
+<div id="backModal"
+     class="modal-popup fixed top-0 left-0 inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
+    <!-- Modal Content -->
+    <div class="px-4 w-full content-modal overflow-auto max-h-dvh">
+        <div class="popup-buy-error">
+            <p class="text-center">
+                @Lang.ConfirmExit
+            </p>
+            <div class="w-full flex gap-5 justify-between px-5">
+                <a href="/Home/Index"
+                   class="bg-4 h-[41px] w-full max-w-[136.5px] text-[#5A5A5A] font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                    @Lang.Exit
+                </a>
+                <a href="#" onclick="hideModal('backModal')"
+                   id="closeModal"
+                   class="bg-[#F06522] h-[41px] w-full max-w-[136.5px] text-white font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                    @Lang.Close
+                </a>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div id="dialogWinner" data-open="false"
+     class="modal-popup fixed top-0 left-0 inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
+    <!-- Modal Content -->
+    <div class="px-4 w-full content-modal overflow-auto max-h-dvh">
+        <div class="modal-container overflow-hidden relative"">
+            <div class="modal mx-4">
+                <div class="popup-linear text-white flex flex-col items-center gap-5 pt-[2.65625rem] pr-[0.875rem] pb-[2.71875rem] pl-[0.875rem]">
+
+                    @if (isMileStone)
+                    {
+                    <div class="image-light absolute top-[3px] w-full">
+                        <img src="../assets/images/glowing-golden-figma.png" alt="Laser Beam" class="-translate-y-1/2 w-full">
+                    </div>
+
+                    <div class="image-light absolute left-[3px] top-0" style="height: calc(100% - 10px)">
+                        <img src="../assets/images/glowing-golden-figma-left.png" alt="Laser Beam" class="-translate-x-1/2" style="height: calc(100% - 50px)">
+                    </div>
+
+                    <div class="image-light absolute right-[3px] top-0" style="height: calc(100% - 10px)">
+                        <img src="../assets/images/glowing-golden-figma-right.png" alt="Laser Beam" class="translate-x-1/2" style="height: calc(100% - 50px)">
+                    </div>
+                    }
+
+                    <div class="text-center">
+                        <p class="text-2xl font-bold uppercase leading-none">@Lang.Congratulations !</p>
+                        @if (!isMileStone)
+                        {
+                        <p class="text-[#FBFF00] text-xl font-black uppercase leading-none">
+                            @Lang.WinChallenge @Model.gameIndex
+                        </p>
+                        }
+                    </div>
+
+                    @if (isMileStone)
+                    {
+                    <img src="../assets/icons/cup.svg" alt="success" class="w-[73px] h-[94px]" />
+                    }
+
+                    <div class="flex flex-col items-center">
+                        <p class="max-w-[307px] text-center leading-[1.0125rem]">
+                            @Lang.WinReward.Replace("%index%", Model.gameIndex + "")
+                        </p>
+                        @if (giftInfo != null)
+                        {
+                            if (giftInfo.giftType == GiftType.MB)
+                            {
+                        <img src="../assets/images/data.png" alt="data" class="max-w-[157px] max-h-[49px] mt-[0.66rem]">
+                        <p class="text-xl font-black">@giftInfo.gift MB</p>
+                            }
+                            else if (giftInfo.giftType == GiftType.Money)
+                            {
+                        <img src="../assets/images/mt.png" alt="MT" class="max-w-[157px] max-h-[49px] mt-[0.66rem]">
+                        <p class="text-xl font-black">@giftInfo.gift MT</p>
+                            }
+                            else
+                            {
+                        <img src="../assets/icons/coin.svg" alt="Coin" class="max-w-[157px] max-h-[49px] mt-[0.66rem]">
+                        <p class="text-xl font-black">@giftInfo.gift @Lang.Coin</p>
+                            }
+                        }
+
+                    </div>
+
+                    @*<img src="../assets/icons/coin.svg" alt="success" class="w-[61.298px] h-[64px]" />*@
+
+                    @*<p>
+                            Total score: <span class="text-[#FBFF00] font-extrabold ml-5">2500</span>
+                        </p>*@
+                    @if (gameInfo != null)
+                    {
+                    <p class="text-center w-full max-w-[270px]">
+                        @Lang.NextGameOrClose
+                    </p>
+                    }
+
+                    <div class="w-full flex gap-5 justify-center px-5">
+                        @if (gameInfo != null)
+                        {
+                        <a href="#" onclick="hideModal('dialogWinner')"
+                           class="bg-4 h-[41px] w-full max-w-[136.5px] text-[#5A5A5A] font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                            @Lang.NextGame
+                        </a>
+                        }
+                        <a href="/Home/Index"
+                           class="bg-[#F06522] h-[41px] w-full max-w-[136.5px] text-white font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                            @Lang.Close
+                        </a>
+                    </div>
+                </div>
+            </div>
+            @if (isMileStone) {
+            <img src="../assets/images/confertti.png" alt="confertti" class="absolute -top-5 pointer-events-none object-contain" />
+            }
+        </div>
+    </div>
+</div>
+
+@section Scripts {
+    <script>
+
+        $(document).ready(function () {
+            var shownGift = $("#shownGift").val();
+            console.log("shownGift: " + shownGift);
+            if (shownGift == '0') {
+                showModal('dialogWinner');
+            }
+        });
+
+
+    </script>
+}

+ 107 - 0
WebChallenge/WebChallenge/Views/Home/Ranking.cshtml

@@ -0,0 +1,107 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions
+@using WebChallenge.Controllers
+@model List<TopUser>
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+}
+
+
+
+<div class="main-content logo-background game h-dvh relative winner-ranker">
+    <div class="h-full">
+        <div class="h-full flex flex-col justify-end">
+            <div class="flex flex-col flex-grow justify-center h-full max-h-[650px] overflow-auto">
+                <div class="mx-5 relative translate-y-1/2 z-10">
+                    <div class="image-light absolute w-full top-[2px]">
+                        <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                             class="-translate-y-1/2 w-full">
+                    </div>
+                    <img src="../assets/images/his.png" alt="his frame" class="shadow-1 rounded-[2.5rem]" />
+                    <div class="image-light absolute bottom-0 w-full">
+                        <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                             class="translate-y-1/2 w-full">
+                    </div>
+                    <div class="absolute top-0 h-full w-full rounded-[2.5rem] flex justify-between items-center px-6 text-white font-bold">
+                        <span>@Lang.Top</span>
+                        <span>@Lang.PhoneNumber</span>
+                        <span>@Lang.TotalCoin</span>
+                        <span>@Lang.Time</span>
+                    </div>
+                </div>
+                <!-- Content -->
+                <div class="w-full table-container list-table-winner h-full">
+                    <table class="w-full text-left border-collapse">
+                        <tbody>
+                            @if (Model != null && Model.Count > 0)
+                            {
+                                for (int i = 0; i < Model.Count; i++)
+                                {
+                                    var topPLayer = Model[i];
+                                    <tr class="text-white font-roboto text-[14px] text-center">
+                                        <td class="py-2 pl-10 font-normal"><span class="ranker-stt">@(topPLayer.seq)</span></td>
+                                        <td class="py-2 pl-6 font-normal">@(userInfo.msisdn == topPLayer.msisdn ? isdn: BaseController.HideMsisdn(topPLayer.msisdn))</td>
+                                        <td class="py-2 px-4 font-bold text-right">
+                                            @topPLayer.totalScore
+                                        </td>
+                                        <td class="py-2 pr-7 font-bold text-right">
+                                            <div class="date-history flex flex-col justify-center items-end">
+                                                <span class="font-normal">@topPLayer.timeUpdate.Substring(11)</span>
+                                                <span class="text-[10px] font-semibold color-FFC489">@topPLayer.timeUpdate.Substring(0, 10)</span>
+                                            </div>
+                                        </td>
+                                    </tr>
+                                }
+                            }
+                        </tbody>
+                    </table>
+                    <div class="text-center ranker-gr-bt mt-2">
+                        <!-- My Rank Section -->
+                        <div class="flex justify-between items-center bt-rank w-36 text-white text-[16px]">
+                            <span class="font-normal">@Lang.MyRank</span>
+                            <span class="font-black">@userInfo.ranking</span>
+                        </div>
+
+                        <!-- Notification -->
+                        <p class="mt-3 text-white font-bold text-[16px]">
+                            @Lang.RegisterToBeRanked
+                        </p>
+
+                        <!-- Buttons -->
+                        <div class="flex justify-around mt-5">
+                            <a href="/Home/Index" class=" text-white font-normal text-[20px] font-Alatsi close py-1">
+                                @Lang.Close
+                            </a>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- Bottom Navigation -->
+    <div class="navigation">
+        <div class="flex justify-between items-center h-full">
+            <a href="/Home/Index" class="item ">
+                <img src="../assets/icons/home.svg" alt="Home" />
+                <span class="text-xs mt-1">Home</span>
+            </a>
+            <a href="/Home/History" class="item">
+                <img src="../assets/icons/history.svg" alt="Result" />
+                <span class="text-xs mt-1">History</span>
+            </a>
+            <a href="/Home/Winner" class="item">
+                <img src="../assets/icons/start.svg" alt="Result" />
+                <span class="text-xs mt-1">Winner list</span>
+            </a>
+            <a href="/Home/Guide" class="item">
+                <img src="../assets/icons/guide.svg" alt="Result" />
+                <span class="text-xs mt-1">Guide</span>
+            </a>
+        </div>
+    </div>
+
+</div>

+ 99 - 0
WebChallenge/WebChallenge/Views/Home/Setting.cshtml

@@ -0,0 +1,99 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions;
+@using WebChallenge.Texts;
+@using WebChallenge.Controllers;
+
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+    string lang = LanguageController.getCurrentLang();
+}
+@model SubInfoRes
+
+<div class="main-content logo-background h-dvh relative z-0">
+
+    <div class="h-full">
+        <div class="h-full flex flex-col">
+            <div class="overflow-auto flex-grow-1 relative z-10 h-full">
+                <div id="mainContent" class="bg-6 mt-3 mx-4 pb-9 px-1 pt-[0.44rem] rounded-3xl">
+                    <div class="flex justify-between">
+                        <button onclick="closePopup()"
+                                class="w-10 h-10 rounded-full flex justify-center items-center bg-[#F20] border border-white">
+                            <img src="../assets/icons/close.svg" class="p-2" alt="exit" />
+                        </button>
+                        <p class="font-Alatsi text-[2.25rem] leading-none">@Lang.Setting</p>
+                        <div></div>
+                    </div>
+
+                    <div class="flex justify-center">
+                        <img src="../assets/images/icons8-user-100.png" alt="Avatar"
+                             class="mt-5 w-full max-w-[5.5rem] max-h-[5.5rem]" />
+                    </div>
+
+                    <div class="mt-3 text-center">
+                        @Lang.Hello, <span class="text-[#FF874D] font-bold">@userInfo.msisdn.Substring(BaseController.CountryCode.Length)</span>
+                    </div>
+
+                    <div class="mt-[0.44rem]">
+                        <p class="text-center leading-[2.025rem] text-[1.125rem] font-bold">@Lang.Language</p>
+                        <div class="flex gap-3 justify-center">
+                            <button class="@("setLang px-1 py-1" + (lang == "1" ? " active" : ""))" lang="en">
+                                <img src="../assets/icons/lang-1.svg" alt="lang 1" class="w-[40px] h-[20px]">
+                            </button>
+                            <button class="@("setLang px-1 py-1" + (lang == "0" ? " active" : ""))" lang="fr">
+                                <img src="../assets/icons/lang-2.svg" alt="lang 2" class="w-[40px] h-[20px]">
+                            </button>
+                        </div>
+                    </div>
+
+                    @if (Model.packetType != "0" && Model.packetType != null)
+                    {
+                        <div class="mt-2">
+                            <p class="text-lg font-bold text-center leading-[2.025rem]">@Lang.MyPackage</p>
+
+                            <div class="flex justify-center mt-1">
+                                <button class="text-lg leading-[2.025rem] text-[#030100] bg-[#76DF45] rounded-[2.5rem] h-[41px] max-w-[219px] w-full px-2">
+                                    @if (Model.packetType == "1")
+                                    {
+                                        @Lang.DailyPackage
+                                    }
+                                    else
+                                    {
+                                        @Lang.WeeklyPackge
+                                    }
+                                </button>
+                            </div>
+
+                            <div class="mt-2 text-center flex justify-center">
+                                <p class="text-[#434343] max-w-[156px]">
+                                    @Lang.CancelConfirm
+                                    <button class="text-[#F20] font-bold underline" onclick="showModal('dialogCancel')">@Lang.Cancel</button>
+                                </p>
+                            </div>
+                        </div>
+                    }
+                </div>
+            </div>
+        </div>
+    </div>
+
+
+    <!-- Bottom Navigation -->
+    @Html.Partial("_Navigation")
+</div>
+
+@section Scripts {
+    <script>
+        function closePopup() {
+            if (document.referrer && document.referrer !== window.location.href) {
+                // Trang trước khác trang hiện tại -> Có thể quay lại
+                window.history.back();
+            } else {
+                // Trang trước là chính trang hiện tại hoặc không có trang trước -> Chuyển hướng về trang index
+                window.location.href = '/Home/Index';
+            }
+        }
+    </script>
+}

+ 123 - 0
WebChallenge/WebChallenge/Views/Home/Signup.cshtml

@@ -0,0 +1,123 @@
+@{
+    ViewData["Title"] = @Lang.SignUp;
+    //Layout = "../Shared/_LayoutLogin";
+}
+
+<!-- Login Form -->
+
+<div class="main-content logo-background game h-dvh login index">
+    <!-- Content -->
+    <div class="w-full h-full flex flex-col justify-end items-start pr-6 pb-3">
+        <!-- Login Form -->
+        <div class="bg-opacity-70 w-full max-w-md login-content">
+            <h2 class="text-white font-normal mb-4 text-center font-Alatsi text-[36px]">@Lang.CreateAccount</h2>
+            <div class="flex flex-col items-center justify-center">
+                <!-- Phone Number -->
+                <div class="mb-4 w-full flex justify-center">
+                    <input type="text" name="phone" id="phoneNumber" placeholder="@Lang.PhoneNumber"
+                           class="font-roboto w-full px-4 py-2 border-white bg-transparent color-DADADA placeholder-white text-[20px] font-normal">
+                </div>
+                <!-- OTP -->
+                @*<div class="mb-4 w-full justify-center hidden form-control-otp">
+                        <input type="text" name="otp" id="otp" placeholder="@Lang.PasswordSent"
+                               class="font-roboto w-full px-4 py-2  color-DADADA2 border-white bg-transparent text-[18px] font-normal">
+                    </div>*@
+                <!-- Login Button -->
+                <button onclick="getPassword();" id="btn-signup"
+                        class="text-[24px] font-Alatsi w-full py-2 text-white font-normal btn-login">
+                    @Lang.SendOtp
+                </button>
+            </div>
+            <!-- Login -->
+            <p class="text-white text-center mt-4 text-[16px] font-roboto font-normal" id="login-text">
+                @Lang.AlreadyHaveAccount
+                <a href="/Home/Login" class="text-orange-500 font-bold hover:underline text-[16px] resend">@Lang.Login</a>
+            </p>
+            <!-- Resend OTP -->
+            @*<p class="text-white text-center mt-4 text-[16px] font-roboto font-normal hidden" id="resend-text">
+                    @Lang.NotReceiveOtp
+                    <a href="#" class="text-orange-500 font-bold hover:underline text-[16px] resend">@Lang.Resend</a>
+                </p>*@
+        </div>
+    </div>
+</div>
+
+
+
+@section Scripts {
+    <script>
+        var clicked = false;
+        function login() {
+            console.log("login");
+            if (clicked) {
+                return;
+            }
+            clicked = true;
+            let users = $("#phoneNumber").val().trim();
+            let password = $("#password").val().trim();
+            $.ajax({
+                url: "/Home/LoginAction",
+                data: {
+                    msisdn: users,
+                    users: users,
+                    pass: password,
+                    command: "LOGIN"
+                },
+                type: "POST",
+                success: function (data) {
+                    console.log(data);
+                    clicked = false;
+                    if (data.error == "0") {
+                        if (data.href != null) {
+                            location.href = data.href;
+                        }
+                    } else {
+                        //$("#login-error").show();
+                        //$("#login-error").html(data.content);
+                        // failed
+                        showDialog('dialogResult', "@Lang.Error", data.content, data.error);
+                    }
+                },
+                error: function (data) {
+                    clicked = false;
+                    console.log(data);
+                }
+            });
+        }
+
+        function getPassword() {
+            let users = $("#phoneNumber").val().trim();
+            //let password = $("#password").val().trim();
+            $.ajax({
+                url: "/Home/ResetPasswordAction",
+                data: {
+                    msisdn: users,
+                    users: users,
+                    command: "RESETPASS"
+                },
+                type: "POST",
+                success: function (data) {
+                    if (data.error == "0") {
+                        location.href = "/Home/Login"
+                    } else {
+                        showDialog('dialogResult', "@Lang.Error", data.content, data.error);
+                    }
+                },
+                error: function (data) {
+                    console.log(data);
+                }
+            });
+        }
+
+        // Lấy phần tử cần kiểm tra
+        const loginContent = document.querySelector('.login-content');
+
+        // Lắng nghe sự kiện click trên document
+        document.addEventListener('click', function (event) {
+            // Kiểm tra nếu click không nằm trong phần tử loginContent
+            if (!loginContent.contains(event.target)) {
+                window.location.href = '/Home/Start';
+            }
+        });
+    </script>
+}

+ 20 - 0
WebChallenge/WebChallenge/Views/Home/Start.cshtml

@@ -0,0 +1,20 @@
+@{
+    ViewData["Title"] = "Login";
+    //Layout = "../Shared/_LayoutLogin";
+}
+
+<div class="main-content logo-background game h-dvh relative index">
+    <!-- Signup Button -->
+    <div class="signup inline-block">
+        <p class="btn-signup font-Alatsi text-[28px] font-normal text-white">
+            <a href="/Home/Signup">@Lang.SignUp</a>/<a href="/Home/Login">@Lang.Login</a>
+        </p>
+    </div>
+</div>
+
+
+
+@section Scripts {
+    <script>
+    </script>
+}

+ 57 - 0
WebChallenge/WebChallenge/Views/Home/Winner.cshtml

@@ -0,0 +1,57 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions;
+@using WebChallenge.Texts;
+@using WebChallenge.Controllers;
+
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+}
+
+
+<div class="main-content logo-background game h-dvh relative">
+    <div class="h-full w-full flex items-end">
+        <div class="flex flex-col justify-center h-full winner pb-[1.75rem] w-full">
+            <!-- Header Section -->
+            <div class="text-center mt-16 font-roboto">
+                <span class="text-white text-lg font-normal text-[16px] leading-none">
+                    @Lang.Hello,
+                    <span class="text-[16px] color-FF874D font-normal leading-none">@userInfo.msisdn.Substring(BaseController.CountryCode.Length)</span>
+                </span>
+                <h1 class="text-white font-normal mt-3 text-[32px] font-Alatsi winner-text leading-none">@Lang.WinnerList</h1>
+            </div>
+
+            <!-- Prizes Section -->
+            <div class="flex flex-col items-center mt-6 gap-4 px-8 winner-content">
+                <!-- Daily Prize -->
+                <a href="/Home/WinnerDaily" class=" text-white py-1 font-normal w-5/6 text-[24px] font-Alatsi text-center winner-bt-daily pulse-animation">
+                    @Lang.DailyPrize
+                </a>
+                <div class="bg-orange-500 rounded-lg overflow-hidden w-full">
+                    <img src="../assets/images/sms-MT-data.png" alt="Daily Prize" class="w-full">
+                </div>
+
+                <!-- Monthly Prize -->
+                <a href="/Home/WinnerMonthly" class="text-white py-1 font-normal w-5/6 text-[24px] font-Alatsi mt-2 text-center winner-bt-monthly pulse-animation">
+                    @Lang.MonthlyPrize
+                </a>
+                <div class="relative overflow-hidden w-full h-32 flex items-center justify-between p-4">
+                    <!-- Text -->
+                    <div class="text-left">
+                        <p class="text-white font-black leading-none text-[37px] font-roboto">20.000</p>
+                        <p class="text-white font-normal text-[24px] font-roboto">MT</p>
+                    </div>
+                    <!-- Background -->
+                    <div class="absolute inset-0 z-[-1]">
+                        <img src="../assets/images/mmt-moza.png" alt="Background" class="object-cover w-full h-full">
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- Bottom Navigation -->
+    @Html.Partial("_Navigation")
+</div>

+ 89 - 0
WebChallenge/WebChallenge/Views/Home/WinnerDaily.cshtml

@@ -0,0 +1,89 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions
+@using WebChallenge.Controllers
+@model List<WinnerDaily>
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+}
+
+
+
+<div class="main-content logo-background game h-dvh relative winner-daily">
+    <div class="h-full flex flex-col justify-end">
+        <div class="flex flex-col flex-grow justify-center h-full max-h-[750px]">
+            <div class="mt-48 mx-5 relative">
+                <div class="image-light absolute w-full top-[2px]">
+                    <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                         class="-translate-y-1/2 w-full">
+                </div>
+                <img src="../assets/images/his.png" alt="his frame" class="shadow-1 rounded-[2.5rem]" />
+                <div class="image-light absolute bottom-0 w-full">
+                    <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                         class="translate-y-1/2 w-full">
+                </div>
+                <div class="absolute top-0 h-full w-full rounded-[2.5rem] flex justify-between items-center px-6 text-white font-bold">
+                    <span>@Lang.No</span>
+                    <span>@Lang.Time</span>
+                    <span>@Lang.PhoneNumber</span>
+                    <span>@Lang.Prize</span>
+                </div>
+            </div>
+            <!-- Content -->
+            <div class="mt-4 h-full overflow-auto relative z-10">
+                <table class="w-full text-left leading-tight list-table-winner ">
+                    <tbody>
+                        @if (Model != null)
+                        {
+                            for (int i = 0; i < Model.Count; i++)
+                            {
+                                var topPLayer = Model[i];
+                                <tr class="text-white font-roboto text-[14px] text-center">
+                                    <td class="py-2 pl-10 font-normal">@(i + 1)</td>
+                                    <td class="py-2 pl-8">
+                                        <div class="date-history flex flex-col justify-center items-start">
+                                            <span class="font-normal">@topPLayer.date.Substring(11)</span>
+                                            <span class="text-[10px] font-semibold color-FFC489">@topPLayer.date.Substring(0, 10)</span>
+                                        </div>
+                                    </td>
+                                    <td class="py-2 px-4 font-normal">@BaseController.HideMsisdn(topPLayer.msisdn)</td>
+                                    <td class="py-2 pr-8 font-bold text-right">@topPLayer.prize</td>
+                                </tr>
+                            }
+                        }
+                    </tbody>
+                </table>
+                <!-- Pagination -->
+                @*<div class="flex justify-center items-center pt-4 ">
+                        <ul class="flex space-x-2 text-[14px] font-normal font-roboto color-A1A1A1">
+                            <li>
+                                <button class="active">1</button>
+                            </li>
+                            <li>
+                                <button class="">2</button>
+                            </li>
+                            <li>
+                                <button class="">3</button>
+                            </li>
+                            <li>
+                                <button class="">4</button>
+                            </li>
+                            <li>
+                                <button class="">....</button>
+                            </li>
+                        </ul>
+                    </div>*@
+                <!-- Close Button -->
+                <div class="text-center pt-3">
+                    <a href="/Home/Winner" class="text-white font-normal text-[24px] bt-close">@Lang.Close</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- Bottom Navigation -->
+    @Html.Partial("_Navigation")
+
+</div>

+ 91 - 0
WebChallenge/WebChallenge/Views/Home/WinnerMonthly.cshtml

@@ -0,0 +1,91 @@
+@{
+    ViewData["Title"] = "Home Page";
+}
+@using WebChallenge.Extensions
+@using WebChallenge.Controllers
+@model List<WinnerMonthly>
+@{
+    UserInfo userInfo = Context.Session.GetComplexData<UserInfo>("userInfo");
+    string isdn = userInfo.msisdn.Substring(3);
+}
+
+
+
+<div class="main-content logo-background game h-dvh relative winner-monthly">
+    <div class="h-full">
+        <div class="h-full flex flex-col justify-end">
+            <div class="flex flex-col flex-grow justify-center h-full max-h-[750px]">
+                <div class="mt-48 mx-5 relative">
+                    <div class="image-light absolute w-full top-[2px]">
+                        <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                             class="-translate-y-1/2 w-full">
+                    </div>
+                    <img src="../assets/images/his.png" alt="his frame" class="shadow-1 rounded-[2.5rem]" />
+                    <div class="image-light absolute bottom-0 w-full">
+                        <img src="../assets/images/glowing-golden-figma-2.png" alt="Laser Beam"
+                             class="translate-y-1/2 w-full">
+                    </div>
+                    <div class="absolute top-0 h-full w-full rounded-[2.5rem] flex justify-between items-center px-6 text-white font-bold">
+                        <span>@Lang.No</span>
+                        <span>@Lang.Time</span>
+                        <span>@Lang.PhoneNumber</span>
+                        <span>@Lang.Prize</span>
+                    </div>
+                </div>
+                <!-- Content -->
+                <div class="mt-4 h-full overflow-auto relative z-10">
+                    <table class="w-full text-left leading-tight list-table-winner ">
+                        <tbody>
+                            @if (Model != null)
+                            {
+                                for (int i = 0; i < Model.Count; i++)
+                                {
+                                    var topPLayer = Model[i];
+                                    <tr class="text-white font-roboto text-[14px] text-center">
+                                        <td class="py-2 pl-8 font-normal">@(i + 1)</td>
+                                        <td class="py-2 pl-8">
+                                            <div class="date-history flex flex-col justify-center items-start">
+                                                <span class="font-normal">@topPLayer.date.Substring(11)</span>
+                                                <span class="text-[10px] font-semibold color-FFC489">@topPLayer.date.Substring(3, 7)</span>
+                                            </div>
+                                        </td>
+                                        <td class="py-2 px-4 font-normal">@BaseController.HideMsisdn(topPLayer.msisdn)</td>
+                                        <td class="py-2 pr-8 font-bold text-right">@topPLayer.money @Lang.Curency</td>
+                                    </tr>
+                                }
+                            }
+                        </tbody>
+                    </table>
+                    <!-- Pagination -->
+                    @*<div class="flex justify-center items-center pt-4 ">
+                            <ul class="flex space-x-2 text-[14px] font-normal font-roboto color-A1A1A1">
+                                <li>
+                                    <button class="active">1</button>
+                                </li>
+                                <li>
+                                    <button class="">2</button>
+                                </li>
+                                <li>
+                                    <button class="">3</button>
+                                </li>
+                                <li>
+                                    <button class="">4</button>
+                                </li>
+                                <li>
+                                    <button class="">....</button>
+                                </li>
+                            </ul>
+                        </div>*@
+                    <!-- Close Button -->
+                    <div class="text-center pt-3">
+                        <a href="/Home/Winner" class="text-white font-normal text-[24px] bt-close">@Lang.Close</a>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <!-- Bottom Navigation -->
+    @Html.Partial("_Navigation")
+
+</div>

+ 21 - 0
WebChallenge/WebChallenge/Views/Home/_Navigation.cshtml

@@ -0,0 +1,21 @@
+ <!-- Bottom Navigation -->
+<div class="navigation">
+    <div class="flex justify-between items-center h-full">
+        <a href="/Home/Index" class="item active">
+            <img src="../assets/icons/home.svg" alt="Home" />
+            <span class="text-xs mt-1">@Lang.Home</span>
+        </a>
+        <a href="/Home/History" class="item">
+            <img src="../assets/icons/history.svg" alt="Result" />
+            <span class="text-xs mt-1">@Lang.History</span>
+        </a>
+        <a href="/Home/Winner" class="item">
+            <img src="../assets/icons/start.svg" alt="Result" />
+            <span class="text-xs mt-1">@Lang.Winner</span>
+        </a>
+        <a href="/Home/Guide" class="item">
+            <img src="../assets/icons/guide.svg" alt="Result" />
+            <span class="text-xs mt-1">@Lang.Guide</span>
+        </a>
+    </div>
+</div>

+ 25 - 0
WebChallenge/WebChallenge/Views/Shared/Error.cshtml

@@ -0,0 +1,25 @@
+@model ErrorViewModel
+@{
+    ViewData["Title"] = "Error";
+}
+
+<h1 class="text-danger">Error.</h1>
+<h2 class="text-danger">An error occurred while processing your request.</h2>
+
+@if (Model.ShowRequestId)
+{
+    <p>
+        <strong>Request ID:</strong> <code>@Model.RequestId</code>
+    </p>
+}
+
+<h3>Development Mode</h3>
+<p>
+    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
+</p>
+<p>
+    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>
+    It can result in displaying sensitive information from exceptions to end users.
+    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
+    and restarting the app.
+</p>

+ 342 - 0
WebChallenge/WebChallenge/Views/Shared/_Layout.cshtml

@@ -0,0 +1,342 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+@using WebChallenge.Controllers;
+@using WebChallenge.Extensions;
+@using System.Globalization;
+@using Newtonsoft.Json;
+
+@{
+
+}
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="vi" lang="vi">
+
+<head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+    <title>Movitel Ganha Mais</title>
+
+    <!--CSS-->
+    <link rel="stylesheet" href="~/css/all.min.css" />
+    <link rel="stylesheet" href="~/css/custom.css" />
+
+    <!--JS-->
+    <script src="~/lib/jquery/jquery.min.js"></script>
+    <script src="~/js/input.js"></script>
+</head>
+
+
+<body>
+    @Html.AntiForgeryToken()
+
+    <div class="main-content logo-background game h-dvh login">
+        <!-- Content -->
+        <!-- Body content -->
+        @RenderBody()
+
+        <div id="dialogResult" data-open="false"
+             class="modal-popup fixed top-0 left-0 inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
+            <!-- Modal Content -->
+            <div class="px-4 w-full content-modal overflow-auto max-h-dvh">
+                <div class="modal-container">
+                    <div class="modal mx-4">
+                        <div class="popup-buy-error">
+                            <p class="text-2xl font-bold uppercase" id="dialogHeader">
+
+                            </p>
+
+                            <img src="~/assets/icons/error.svg" alt="error" id="dialogIcon" />
+
+                            <p class="text-center" id="dialogMessage">
+
+                            </p>
+
+                            <input type="hidden" id="reload" />
+                            <input type="hidden" id="exit" />
+
+                            <a href="#" onclick="closeDialog('dialogResult')" class="font-Alatsi text-2xl bg-[#F06522] rounded-[1.25rem] w-full max-w-[224px] px-[0.625rem] text-center">
+                                @Lang.Close
+                            </a>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div id="dialogGameOver" data-open="false"
+             class="modal-popup fixed top-0 left-0 inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
+            <!-- Modal Content -->
+            <div class="px-4 w-full content-modal overflow-auto max-h-dvh">
+                <div class="modal-container">
+                    <div class="modal mx-4">
+                        <div class="popup-linear text-white flex flex-col items-center gap-5 pt-[2.65625rem] pr-[0.875rem] pb-[2.71875rem] pl-[0.875rem]">
+                            <div class="text-center">
+                                <p class="text-2xl font-bold uppercase leading-none">@Lang.GameOver</p>
+                                <p class="text-[#FBFF00] text-xl font-black uppercase leading-none">
+                                    @Lang.Challenge <span id="challengeOver">1</span>
+                                </p>
+                            </div>
+
+                            <img src="../assets/icons/error.svg" alt="success" />
+
+                            @*<p>
+                                Total score: <span class="text-[#FBFF00] font-extrabold ml-5">200</span>
+                            </p>*@
+
+                            <p class="text-center w-full max-w-[250px]">
+                                @Lang.PlayAgainOrClose
+                            </p>
+
+                            <div class="w-full flex gap-5 justify-between px-5">
+                                <a href="/Home/CheckPlay"
+                                   class="bg-4 h-[41px] w-full max-w-[136.5px] text-[#5A5A5A] font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                                    @Lang.PlayNow
+                                </a>
+                                <a href="#" onclick="hideModal('dialogGameOver')"
+                                   class="bg-[#F06522] h-[41px] w-full max-w-[136.5px] text-white font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                                    @Lang.Close
+                                </a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div id="exitModal"
+             class="modal-popup fixed top-0 left-0 inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
+            <!-- Modal Content -->
+            <div class="px-4 w-full content-modal overflow-auto max-h-dvh">
+                <div class="popup-buy-error">
+                    <p class="text-center">
+                        @Lang.ConfirmExit
+                    </p>
+                    <div class="w-full flex gap-5 justify-between px-5">
+                        <a href="/Home/Logout"
+                           class="bg-4 h-[41px] w-full max-w-[136.5px] text-[#5A5A5A] font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                            @Lang.Exit
+                        </a>
+                        <a href="#" onclick="hideModal('exitModal')"
+                           id="closeModal"
+                           class="bg-[#F06522] h-[41px] w-full max-w-[136.5px] text-white font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                            @Lang.Close
+                        </a>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div id="dialogCancel"
+             class="modal-popup fixed top-0 left-0 inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
+            <!-- Modal Content -->
+            <div class="px-4 w-full content-modal overflow-auto max-h-dvh">
+                <div class="popup-buy-error">
+                    <p class="text-left">
+                        @Html.Raw(Lang.CancelDetailInfo)
+                    </p>
+                    <div class="w-full flex gap-5 justify-center px-5">                        
+                        <a href="#" onclick="hideModal('dialogCancel')"
+                           id="closeModal"
+                           class="bg-[#F06522] h-[41px] w-full max-w-[136.5px] text-white font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                            @Lang.Close
+                        </a>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div id="optionPayment" data-open="false"
+             class="modal-popup fixed top-0 left-0 inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
+            <!-- Modal Content -->
+            <div class="px-4 w-full content-modal overflow-auto max-h-dvh">
+                <div class="popup-buy-error">
+                    <p class="text-center uppercase">
+                        @Lang.SelectPaymentChannel
+                    </p>
+
+                    <div class="w-full">
+                        <input type="hidden" id="packagePeriod"/>
+                        <div>
+                            <input type="radio" id="basicAccount" name="payment" value="MAIN_AUTO" checked=checked />
+                            <label for="basicAccount">@Lang.PayBasic</label>
+                        </div>
+                        <div>
+                            <input type="radio" id="eMola" name="payment" value="WALLET_AUTO" />
+                            <label for="eMola">@Lang.PayEmola</label>
+                        </div>
+                        @*<div>
+                            <input type="radio" id="eMolaReNew" name="payment" value="3" />
+                            <label for="eMolaReNew">Pay via e-Mola auto renew</label>
+                        </div>*@
+
+                        <div class="w-full flex gap-5 justify-center px-5 mt-3">
+                            <button type="button" onclick="hideModal('optionPayment')" class="bg-4 h-[41px] w-full max-w-[136.5px] text-[#5A5A5A] font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                                @Lang.Cancel
+                            </button>
+                            <button type="button" onclick="selectPayment();" class="bg-[#F06522] h-[41px] w-full max-w-[136.5px] text-white font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                                @Lang.Submit
+                            </button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <div id="dialogOtp" data-open="false"
+             class="modal-popup fixed top-0 left-0 inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
+
+            <div class="px-4 w-full content-modal overflow-auto max-h-dvh">
+                <div class="popup-buy-error">
+                    <p class="text-center">
+                        @Lang.EnterOtp
+                    </p>
+
+                    <div class="enter-otp">
+                        <input class="input-otp font-roboto bg-transparent text-[18px] font-normal" id="otp1" maxlength="1" placeholder="" />
+                        <input class="input-otp font-roboto bg-transparent text-[18px] font-normal" id="otp2" maxlength="1" placeholder="" />
+                        <input class="input-otp font-roboto bg-transparent text-[18px] font-normal" id="otp3" maxlength="1" placeholder="" />
+                        <input class="input-otp font-roboto bg-transparent text-[18px] font-normal" id="otp4" maxlength="1" placeholder="" />
+                        <input class="input-otp font-roboto bg-transparent text-[18px] font-normal" id="otp5" maxlength="1" placeholder="" />
+                        <input class="input-otp font-roboto bg-transparent text-[18px] font-normal" id="otp6" maxlength="1" placeholder="" />
+                    </div>
+                    <p class="otp-error"></p>
+
+                    <div class="w-full flex gap-5 justify-between px-5 ">
+                        <button class="bg-4 h-[41px] w-full max-w-[136.5px] text-[#5A5A5A] font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center btn-confirm">
+                            @Lang.Confirm
+                        </button>
+                        <a href="#" onclick="hideModal('dialogOtp')"
+                           id="closeModal"
+                           class="bg-[#F06522] h-[41px] w-full max-w-[136.5px] text-white font-Alatsi text-2xl rounded-[1.25rem] flex justify-center items-center text-center">
+                            @Lang.Close
+                        </a>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+    </div>
+
+
+    @*<script src="~/js/spin.js"></script>*@
+
+
+    <script>
+
+        var flag = false;
+        var clicked = false;
+
+    </script>
+
+    <script>
+        $('#dialogOtp').on('show', function () {
+            console.log("open");
+            $("#otp1").focus();
+        });
+
+        $("#dialogOtp .btn-confirm").click(function () {
+            var otp = $("#otp1").val() + $("#otp2").val() + $("#otp3").val() + $("#otp4").val() + $("#otp5").val() + $("#otp6").val();
+            if (otp.length < 6) {
+                return;
+            }
+            $.ajax({
+                url: "/Home/ConfirmOtp",
+                data: {
+                    otp: otp
+                },
+                type: "POST",
+                success: function (data) {
+                    if (data.error == "0") {
+                        hideModal("dialogOtp");
+                        hideModal("optionPayment");
+                        // success
+                        showDialog('dialogResult', "@Lang.Success", data.content, data.error);
+                    } else {
+                        // show error
+                        $(".otp-error").html(data.content);
+                    }
+                },
+                error: function (data) {
+                    console.log(data);
+                }
+            });
+        });
+
+        function selectPayment() {
+            var option = $("input[name='payment']:checked").val();
+            var period = $("#packagePeriod").val();
+            requestOtp(period + "_" + option);
+        }
+
+        function requestOtp(subServiceCode) {
+            $.ajax({
+                url: "/Home/RequestOtp",
+                data: {
+                    subServiceCode: subServiceCode
+                },
+                type: "POST",
+                success: function (data) {
+                    console.log(data);
+                    if (data.error == "100") {
+                        // otp
+                        $(".input-otp").val('');                        
+                        hideModal("optionPayment");
+                        showModal("dialogOtp");
+                    } else if (data.error == "0") {
+                       // success
+                       hideModal("optionPayment");
+                       showDialog('dialogResult', "@Lang.Success", data.content, data.error);
+                    } else if (data.error == "109") {
+                       // waiting
+                       hideModal("optionPayment");
+                       showDialog('dialogResult', "@Lang.Result", data.content, data.error, 'warning');
+                    } else {
+                        // show dialog failed
+                       hideModal("optionPayment");
+                       showDialog('dialogResult', "@Lang.Error", data.content, data.error);
+                    }
+                },
+                error: function (data) {
+                    console.log(data);
+                }
+            });
+        }
+
+        $(".input-otp").on('keydown', function (e) {
+            if (e.which == 8 || e.which == 46) {
+                $(this).val('');
+                $(this).prev(".input-otp").focus();
+            } else {
+                var num = String.fromCharCode();
+                $(this).val(num);
+                //$(this).next(".input-otp").focus();
+            }
+        });
+
+        $(".input-otp").on('keyup', function (e) {
+            if (e.which == 8 || e.which == 46) {
+            } else {
+                $(this).next(".input-otp").focus();
+            }
+            //}
+        });
+
+        function buyMore(packg) {
+            requestOtp(packg);
+        }
+
+        function register(packg) {
+            $("#packagePeriod").val(packg);
+            showModal('optionPayment');
+            //requestOtp(packg);
+        }
+
+    </script>
+
+    @RenderSection("scripts", required: false)
+</body>
+
+</html>

+ 113 - 0
WebChallenge/WebChallenge/Views/Shared/_LayoutLogin.cshtml

@@ -0,0 +1,113 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+@using WebChallenge.Controllers;
+@using WebChallenge.Extensions;
+@using System.Globalization;
+@using Newtonsoft.Json;
+
+@{
+
+}
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="vi" lang="vi">
+
+<head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+    <title>Movitel Ganha Mais</title>
+
+    <!--CSS-->
+    <link rel="stylesheet" href="~/css/all.min.css" />
+    <link rel="stylesheet" href="~/css/custom.css" />
+
+    <!--JS-->
+    <script src="~/lib/jquery/jquery.min.js"></script>
+
+    @*<script src="~/js/all.min.js"></script>*@
+</head>
+
+
+<body>
+    @Html.AntiForgeryToken()
+
+    <div class="main-content logo-background game h-dvh login">
+        <!-- Content -->
+        
+            <!-- Body content -->
+            @RenderBody() 
+
+        <div id="dialogResult" data-open="false"
+             class="modal-popup fixed top-0 left-0 inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
+            <!-- Modal Content -->
+            <div class="px-4 w-full content-modal overflow-auto max-h-dvh">
+                <div class="modal-container">
+                    <div class="modal mx-4">
+                        <div class="popup-buy-error">
+                            <p class="text-2xl font-bold uppercase" id="dialogHeader">
+                                
+                            </p>
+
+                            <img src="~/assets/icons/error.svg" alt="error" id="dialogIcon" />
+
+                            <p class="text-center" id="dialogMessage">
+                                
+                            </p>
+
+                            <input type="hidden" id="reload" />
+                            <input type="hidden" id="exit" />
+
+                            <a href="#" onclick="closeDialog('dialogResult')" class="font-Alatsi text-2xl bg-[#F06522] rounded-[1.25rem] w-full max-w-[224px] px-[0.625rem] text-center">
+                                @Lang.Close
+                            </a>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+
+    </div>
+
+
+    @*<script src="~/js/spin.js"></script>*@
+
+
+    <script>
+
+        var flag = false;
+        var clicked = false;
+
+    </script>
+
+    <script>
+            // Lấy phần tử cần kiểm tra
+            //const loginContent = document.querySelector('.login-content');
+
+            //// Lắng nghe sự kiện click trên document
+            //document.addEventListener('click', function (event) {
+            //    // Kiểm tra nếu click không nằm trong phần tử loginContent
+            //    if (!loginContent.contains(event.target)) {
+            //        window.location.href = 'index.html';
+            //    }
+            //});
+
+            //function forgotPassword() {
+            //    const forgotPassword = document.getElementById('forgotPassword');
+            //    forgotPassword.classList.add('hidden');
+
+            //    const resendOtp = document.getElementById('resendOtp');
+            //    resendOtp.classList.remove('hidden');
+
+            //    const password = document.getElementById('password');
+
+            //    password.placeholder = 'Please check SMS to get OTP';
+            //}
+    </script>
+
+    @RenderSection("scripts", required: false)
+</body>
+
+</html>

+ 2 - 0
WebChallenge/WebChallenge/Views/Shared/_ValidationScriptsPartial.cshtml

@@ -0,0 +1,2 @@
+<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
+<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

+ 4 - 0
WebChallenge/WebChallenge/Views/_ViewImports.cshtml

@@ -0,0 +1,4 @@
+@using WebChallenge
+@using WebChallenge.Models
+@using WebChallenge.Texts
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

+ 74 - 0
WebChallenge/WebChallenge/Views/_ViewStart.cshtml

@@ -0,0 +1,74 @@
+@{
+    Layout = "_Layout";
+}
+
+
+<script src="~/lib/jquery/jquery.min.js"></script>
+<script>
+    function closeDialog(name) {
+        //$("#" + name).parent().removeClass('glass-background-2');
+        hideModal(name);
+        let reload = $("#reload").val();
+        console.log("reload: " + reload);
+        let exit = $("#exit").val();
+        if (reload == "1") {
+            location.reload();
+        }
+        if (exit == "1") {
+            if ($("#channel").val() == "1") {
+                location.href = 'Movitel://home';
+            } else {
+                location.href = '/Home/Login';
+            }
+        }
+    }
+
+    function showDialog(name, header, content, error, type) {
+        //$("#" + name).parent().addClass('glass-background-2');
+        console.log("showDialog: " + name + ", " + header + ", " + content + ", " + error);
+        $("#dialogHeader").html(header);
+        $("#dialogMessage").html(content);
+        if (type == 'error') {
+            // error
+            $("#dialogIcon").attr("src", "../assets/icons/error.svg");
+        } else if (type == 'success') {
+            // success
+            $("#dialogIcon").attr("src", "../assets/icons/success.svg");
+        } else if (type == 'warning') {
+            // warning
+            $("#dialogIcon").attr("src", "../assets/icons/warning.png");
+        } else {
+            if (error == "0") {
+                // success
+                $("#dialogIcon").attr("src", "../assets/icons/success.svg");
+            } else {
+                // error
+                $("#dialogIcon").attr("src", "../assets/icons/error.svg");
+            }
+        }
+        if (error == "-1") {
+            $("#exit").val("1");
+        } else {
+            $("#exit").val("0");
+        }
+        showModal(name);
+    }
+
+    function hideModal(name) {
+        $("#" + name).addClass("hidden");
+        $("#" + name).data("open", "false");
+    }
+
+    function showModal(name) {
+        $("#" + name).removeClass("hidden");
+        $("#" + name).data("open", "true");
+    }
+
+    function hideElement(name) {
+        $("#" + name).hide();
+    }
+    function showElement(name) {
+        $("#" + name).show();
+    }
+
+</script>

+ 46 - 0
WebChallenge/WebChallenge/WebChallenge.csproj

@@ -0,0 +1,46 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+    <CopyRefAssembliesToPublishDirectory>false</CopyRefAssembliesToPublishDirectory>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Compile Remove="wwwroot\games\**" />
+    <Content Remove="wwwroot\games\**" />
+    <EmbeddedResource Remove="wwwroot\games\**" />
+    <None Remove="wwwroot\games\**" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Content Remove="Views\Home\TopPlayer.cshtml" />
+    <Content Remove="Views\Shared\_LayoutLogin.cshtml" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="log4net" Version="2.0.17" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="5.0.17" />
+    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.0.0">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Compile Update="Texts\Lang.Designer.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Lang.resx</DependentUpon>
+    </Compile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Update="Texts\Lang.resx">
+      <Generator>PublicResXFileCodeGenerator</Generator>
+      <LastGenOutput>Lang.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+
+</Project>

+ 9 - 0
WebChallenge/WebChallenge/appsettings.Development.json

@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+  }
+}

+ 33 - 0
WebChallenge/WebChallenge/appsettings.json

@@ -0,0 +1,33 @@
+{
+  //"wsLogin": "http://171.244.50.177:8983/api/userApi/usersRegister/data",
+  //"usersCheckStatus": "http://171.244.50.177:8983/api/userApi/usersCheckStatus/data",
+  //"subCheckStatus": "http://171.244.50.177:8983/api/subApi/subCheckStatus/data",
+  //"playGameCheck": "http://171.244.50.177:8983/api/subApi/playGameCheck/data",
+  //"playGameUpdate": "http://171.244.50.177:8983/api/subApi/playGameUpdate/data",
+  //"playTop": "http://171.244.50.177:8983/api/subApi/playTop/data",
+  //"getHisPlay": "http://171.244.50.177:8983/api/subApi/getHisPlay/data",
+  //"getWinDaily": "http://171.244.50.177:8983/api/subApi/getWinDaily/data",
+  //"getWinMonthly": "http://171.244.50.177:8983/api/subApi/getWinMonthly/data",
+  //"mpsRequest": "http://171.244.50.177:8983/api/subApi/mpsRequest/data",
+
+  "wsLogin": "http://10.229.40.99:8989/api/userApi/usersRegister/data",
+  "usersCheckStatus": "http://10.229.40.99:8989/api/userApi/usersCheckStatus/data",
+  "subCheckStatus": "http://10.229.40.99:8989/api/subApi/subCheckStatus/data",
+  "playGameCheck": "http://10.229.40.99:8989/api/subApi/playGameCheck/data",
+  "playGameUpdate": "http://10.229.40.99:8989/api/subApi/playGameUpdate/data",
+  "playTop": "http://10.229.40.99:8989/api/subApi/playTop/data",
+  "getHisPlay": "http://10.229.40.99:8989/api/subApi/getHisPlay/data",
+  "getWinDaily": "http://10.229.40.99:8989/api/subApi/getWinDaily/data",
+  "getWinMonthly": "http://10.229.40.99:8989/api/subApi/getWinMonthly/data",
+  "mpsRequest": "http://10.229.40.99:8989/api/subApi/mpsRequest/data",
+  "countryCode": "258",
+
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+  },
+  "AllowedHosts": "*"
+}

+ 21 - 0
WebChallenge/WebChallenge/log4net.config

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<log4net>
+  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
+    <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
+    <file value="log/" />
+    <datePattern value="'full.'yyyy.MM.dd'.log'" />
+    <staticLogFileName value="false" />
+    <appendToFile value="true" />
+    <rollingStyle value="Composite" />
+    <maxSizeRollBackups value="10" />
+    <maximumFileSize value="5MB" />
+    <layout type="log4net.Layout.PatternLayout">
+      <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
+    </layout>
+  </appender> 
+  <root>
+    <level value="DEBUG" />
+    <appender-ref ref="RollingLogFileAppender" />
+  </root>
+</log4net>
+

+ 3 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/arrow-down.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="23" height="19" viewBox="0 0 23 19" fill="none">
+    <path d="M10.4393 18.0607C11.0251 18.6464 11.9749 18.6464 12.5607 18.0607L22.1066 8.51472C22.6924 7.92893 22.6924 6.97919 22.1066 6.3934C21.5208 5.80761 20.5711 5.80761 19.9853 6.3934L11.5 14.8787L3.01472 6.3934C2.42893 5.80761 1.47918 5.80761 0.893398 6.3934C0.307612 6.97918 0.307611 7.92893 0.893398 8.51472L10.4393 18.0607ZM10 -6.55671e-08L10 17L13 17L13 6.55671e-08L10 -6.55671e-08Z" fill="white"/>
+</svg>

+ 3 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/arrow-to-left.svg

@@ -0,0 +1,3 @@
+<svg width="51" height="12" viewBox="0 0 51 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 6L10 0.226497V11.7735L0 6ZM51 7H9V5H51V7Z" fill="white"/>
+</svg>

+ 3 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/arrow-to-right.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="51" height="12" viewBox="0 0 51 12" fill="none">
+    <path d="M51 6L41 0.226497V11.7735L51 6ZM0 7H42V5H0V7Z" fill="white"/>
+</svg>

+ 41 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/arrow_1.svg

@@ -0,0 +1,41 @@
+<svg width="105" height="130" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+    <defs>
+        <filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="119.49" id="filter0_d_2052_669" width="104.5" x="0" y="9.05">
+            <feFlood flood-opacity="0" result="BackgroundImageFix"/>
+            <feColorMatrix in="SourceAlpha" result="hardAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
+            <feOffset dy="3.8"/>
+            <feGaussianBlur stdDeviation="1.9"/>
+            <feComposite in2="hardAlpha" operator="out"/>
+            <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
+            <feBlend in2="BackgroundImageFix"/>
+            <feBlend in="SourceGraphic" in2="effect1_dropShadow_2052_669"/>
+        </filter>
+        <filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="94.81" id="filter1_d_2052_669" width="83.12" x="7.13" y="21.4">
+            <feFlood flood-opacity="0" result="BackgroundImageFix"/>
+            <feColorMatrix in="SourceAlpha" result="hardAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
+            <feOffset dy="3.8"/>
+            <feGaussianBlur stdDeviation="1.9"/>
+            <feComposite in2="hardAlpha" operator="out"/>
+            <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
+            <feBlend in2="BackgroundImageFix"/>
+            <feBlend in="SourceGraphic" in2="effect1_dropShadow_2052_669"/>
+        </filter>
+        <linearGradient id="paint0_linear_2052_669" x1="-0.33" x2="1" y1="0.5" y2="0.5">
+            <stop stop-color="#BA0600"/>
+            <stop offset="1" stop-color="#E4AF00"/>
+        </linearGradient>
+        <linearGradient id="paint1_linear_2052_669" x1="-0.33" x2="1" y1="0.5" y2="0.5">
+            <stop stop-color="#EE0C05"/>
+            <stop offset="1" stop-color="#FFC815"/>
+        </linearGradient>
+    </defs>
+    <g class="layer">
+        <title>Layer 1</title>
+        <g filter="url(#filter0_d_2052_669)" id="svg_1">
+            <path d="m96.7,65l-96.9,55.94l0,-111.89l96.9,55.95z" fill="url(#paint0_linear_2052_669)" id="svg_2"/>
+        </g>
+        <g filter="url(#filter1_d_2052_669)" id="svg_3">
+            <path d="m82.45,65l-75.52,43.6l0,-87.2l75.52,43.6z" fill="url(#paint1_linear_2052_669)" id="svg_4"/>
+        </g>
+    </g>
+</svg>

+ 38 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/arrow_2.svg

@@ -0,0 +1,38 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="130" fill="none">
+    <g filter="url(#filter0_d_2052_672)">
+        <path d="M4.29981 64.9999L101.2 120.945L101.2 9.05466L4.29981 64.9999Z" fill="url(#paint0_linear_2052_672)"/>
+    </g>
+    <g filter="url(#filter1_d_2052_672)">
+        <path d="M18.5498 64.9999L94.0748 108.604L94.0748 21.3955L18.5498 64.9999Z" fill="url(#paint1_linear_2052_672)"/>
+    </g>
+    <defs>
+        <filter id="filter0_d_2052_672" x="0.499805" y="9.05469" width="104.5" height="119.491" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+            <feFlood flood-opacity="0" result="BackgroundImageFix"/>
+            <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+            <feOffset dy="3.8"/>
+            <feGaussianBlur stdDeviation="1.9"/>
+            <feComposite in2="hardAlpha" operator="out"/>
+            <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
+            <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_2052_672"/>
+            <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_2052_672" result="shape"/>
+        </filter>
+        <filter id="filter1_d_2052_672" x="14.7498" y="21.3955" width="83.1249" height="94.8087" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+            <feFlood flood-opacity="0" result="BackgroundImageFix"/>
+            <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+            <feOffset dy="3.8"/>
+            <feGaussianBlur stdDeviation="1.9"/>
+            <feComposite in2="hardAlpha" operator="out"/>
+            <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
+            <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_2052_672"/>
+            <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_2052_672" result="shape"/>
+        </filter>
+        <linearGradient id="paint0_linear_2052_672" x1="133.5" y1="64.9999" x2="4.29982" y2="64.9999" gradientUnits="userSpaceOnUse">
+            <stop stop-color="#BA0600"/>
+            <stop offset="1" stop-color="#E4AF00"/>
+        </linearGradient>
+        <linearGradient id="paint1_linear_2052_672" x1="119.25" y1="64.9999" x2="18.5498" y2="64.9999" gradientUnits="userSpaceOnUse">
+            <stop stop-color="#EE0C05"/>
+            <stop offset="1" stop-color="#FFC815"/>
+        </linearGradient>
+    </defs>
+</svg>

+ 7 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/close.svg

@@ -0,0 +1,7 @@
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
+<svg fill="#FFFFFF" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" xml:space="preserve" stroke="#FFFFFF">
+
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
+
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
+
<g id="SVGRepo_iconCarrier"> <g> <g> <polygon points="512,59.076 452.922,0 256,196.922 59.076,0 0,59.076 196.922,256 0,452.922 59.076,512 256,315.076 452.922,512 512,452.922 315.076,256 "/> </g> </g> </g>
+
</svg>

+ 38 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/coin.svg

@@ -0,0 +1,38 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="36" height="38" viewBox="0 0 36 38" fill="none">
+    <g clip-path="url(#clip0_2041_490)">
+        <path d="M7.66699 3.26996L10.6076 1.67033C13.1597 0.281996 16.1881 -0.30388 19.4372 0.152752C28.5663 1.43576 35.9817 10.4633 35.9999 20.3168C36.0118 26.6633 32.9518 31.8043 28.3328 34.317L25.3923 35.9166L7.66699 3.26996Z" fill="url(#paint0_linear_2041_490)"/>
+        <path d="M16.4967 1.75211C7.36759 0.469105 -0.018179 7.41667 3.36107e-05 17.2699C0.0182462 27.1232 7.43386 36.1512 16.563 37.4342C25.6921 38.7172 33.0777 31.7694 33.0595 21.9161C33.0412 12.0629 25.6259 3.03511 16.4967 1.75211Z" fill="url(#paint1_linear_2041_490)"/>
+        <path d="M18.7181 35.6219C18.0993 35.6219 17.4662 35.5769 16.8365 35.4885C14.8656 35.2115 12.9466 34.5225 11.1328 33.4405C9.3581 32.3818 7.76 30.995 6.3833 29.3188C5.00024 27.6349 3.91341 25.748 3.15286 23.7102C2.36862 21.6089 1.96904 19.4407 1.96487 17.2664C1.95741 13.21 3.35145 9.57518 5.89068 7.03156C6.9909 5.92915 8.26688 5.07074 9.68286 4.48003C11.1388 3.87265 12.7062 3.56458 14.3418 3.56458C14.9599 3.56458 15.593 3.60956 16.2234 3.69799C18.1943 3.97491 20.1132 4.66392 21.927 5.74592C23.7018 6.80467 25.2999 8.19146 26.6766 9.86746C28.0596 11.5514 29.1464 13.4382 29.907 15.4761C30.6912 17.5773 31.0908 19.7453 31.0948 21.9198C31.1022 25.9766 29.708 29.6119 27.1683 32.156C26.0681 33.2582 24.7923 34.1166 23.3763 34.7071C21.9211 35.314 20.3541 35.6219 18.7194 35.6219H18.7181Z" fill="url(#paint2_linear_2041_490)"/>
+        <path d="M15.06 12.3709L14.529 13.9673C14.3223 14.3682 13.9161 14.6271 13.4654 14.6453L11.1581 14.7383C10.7719 14.7539 10.4619 14.9663 10.2132 15.1901C10.1406 15.2555 9.65918 15.7659 9.65918 15.7659C9.65918 15.7659 9.87949 16.3406 10.2339 16.779L12.2616 19.2869C12.4795 19.5566 12.5763 19.9044 12.5284 20.2478L12.0834 23.4466C11.9509 24.3987 12.8951 25.1393 13.7882 24.7843L16.1843 23.8313C16.5703 23.6779 17.007 23.7255 17.3508 23.9583L19.4977 25.4134C19.9427 25.7149 20.4347 25.9159 20.4347 25.9159C20.4347 25.9159 21.0682 25.2914 21.1557 25.1904C21.3747 24.937 21.4961 24.5927 21.443 24.2052L21.0741 21.5207C21.0195 21.1233 21.1584 20.7237 21.4478 20.4459L23.384 18.6192C24.0687 17.962 23.8126 16.77 22.909 16.4797L19.9045 15.5145C19.5679 15.4063 19.2926 15.161 19.1464 14.8388L17.8445 11.9689C17.4524 11.1046 16.2895 10.9942 15.6202 11.7096C15.5574 11.7767 15.06 12.3714 15.06 12.3714V12.3709Z" fill="url(#paint3_linear_2041_490)"/>
+        <path d="M14.9422 12.5584L13.8822 14.614C13.6755 15.0149 13.2693 15.2738 12.8186 15.292L10.5113 15.3851C9.48128 15.4266 8.93885 16.6242 9.58705 17.4258L11.6148 19.9336C11.8327 20.2033 11.9295 20.5511 11.8816 20.8945L11.4366 24.0934C11.3041 25.0455 12.2483 25.786 13.1414 25.431L15.5375 24.478C15.9235 24.3246 16.3602 24.3722 16.704 24.6051L18.8509 26.0601C19.749 26.6688 20.9438 25.9265 20.7962 24.8517L20.4273 22.1672C20.3727 21.7698 20.5116 21.3702 20.801 21.0924L22.7471 19.2238C23.4317 18.5666 23.1658 17.4163 22.2624 17.126L19.258 16.1608C18.9213 16.0526 18.646 15.8073 18.4998 15.4851L17.198 12.6152C16.7652 11.6612 15.4223 11.6274 14.9422 12.5586V12.5584Z" fill="url(#paint4_linear_2041_490)"/>
+        <path opacity="0.28" d="M9.30408 10.3138C6.98449 12.6334 5.83819 15.2475 4.75575 14.165C3.67331 13.0826 4.6761 10.3248 6.99568 8.00521C9.31527 5.68562 12.0731 4.68283 13.1555 5.76527C14.2379 6.84772 11.6237 7.99423 9.3043 10.3136L9.30408 10.3138Z" fill="white"/>
+        <path opacity="0.28" d="M4.17265 17.8554C4.74235 17.8554 5.20419 17.3936 5.20419 16.8239C5.20419 16.2542 4.74235 15.7924 4.17265 15.7924C3.60295 15.7924 3.14111 16.2542 3.14111 16.8239C3.14111 17.3936 3.60295 17.8554 4.17265 17.8554Z" fill="white"/>
+        <path opacity="0.36" d="M16.1996 13.2838C16.0238 14.2208 15.5977 15.1099 14.9771 15.834C14.8464 15.9865 14.698 16.1377 14.506 16.1978C14.314 16.2582 14.0696 16.1943 13.9877 16.0107C13.9077 15.831 13.975 15.6045 14.1029 15.4549C14.8499 14.5793 15.1055 13.9259 15.3199 13.2913C15.3763 13.1236 15.4957 12.9799 15.6286 12.8634C15.6352 12.8575 15.6422 12.852 15.6493 12.8463C15.9007 12.6508 16.2626 12.8739 16.216 13.189C16.2114 13.2208 16.2057 13.2527 16.1998 13.284L16.1996 13.2838Z" fill="white"/>
+        <path opacity="0.36" d="M13.0117 16.6743C12.717 16.7074 12.4605 16.5749 12.4385 16.3785C12.4166 16.1819 12.6373 15.996 12.932 15.9631C13.2267 15.93 13.4832 16.0625 13.5052 16.2589C13.5271 16.4555 13.3064 16.6413 13.0117 16.6743Z" fill="white"/>
+    </g>
+    <defs>
+        <linearGradient id="paint0_linear_2041_490" x1="16.7299" y1="19.6789" x2="31.603" y2="9.71438" gradientUnits="userSpaceOnUse">
+            <stop offset="0.73" stop-color="#E8A12E"/>
+            <stop offset="1" stop-color="#D4852A"/>
+        </linearGradient>
+        <linearGradient id="paint1_linear_2041_490" x1="5.64134" y1="26.8882" x2="28.211" y2="11.7671" gradientUnits="userSpaceOnUse">
+            <stop stop-color="#E8A12E"/>
+            <stop offset="1" stop-color="#F7CE2A"/>
+        </linearGradient>
+        <linearGradient id="paint2_linear_2041_490" x1="6.98629" y1="25.9872" x2="26.7683" y2="12.7339" gradientUnits="userSpaceOnUse">
+            <stop stop-color="#F7CE2A"/>
+            <stop offset="1" stop-color="#E8A12E"/>
+        </linearGradient>
+        <linearGradient id="paint3_linear_2041_490" x1="12.4587" y1="22.4563" x2="22.0084" y2="16.0584" gradientUnits="userSpaceOnUse">
+            <stop offset="0.73" stop-color="#E8A12E"/>
+            <stop offset="1" stop-color="#D4852A"/>
+        </linearGradient>
+        <linearGradient id="paint4_linear_2041_490" x1="11.7664" y1="23.0337" x2="21.3212" y2="16.6321" gradientUnits="userSpaceOnUse">
+            <stop stop-color="#FFE757"/>
+            <stop offset="1" stop-color="#F5C845"/>
+        </linearGradient>
+        <clipPath id="clip0_2041_490">
+            <rect width="36" height="37.5867" fill="white"/>
+        </clipPath>
+    </defs>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 6 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/cup.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 24 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/error.svg


+ 3 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/exit.svg

@@ -0,0 +1,3 @@
+<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M6.66667 14.6667H17.3333V17.3334H6.66667V21.3334L0 16L6.66667 10.6667V14.6667ZM5.33236 24H8.94447C10.8248 25.6596 13.2948 26.6667 16 26.6667C21.8911 26.6667 26.6667 21.8911 26.6667 16C26.6667 10.109 21.8911 5.33335 16 5.33335C13.2948 5.33335 10.8248 6.34038 8.94447 8.00002H5.33236C7.76491 4.7615 11.6378 2.66669 16 2.66669C23.3637 2.66669 29.3333 8.63622 29.3333 16C29.3333 23.3638 23.3637 29.3334 16 29.3334C11.6378 29.3334 7.76491 27.2386 5.33236 24Z" fill="white"/>
+</svg>

+ 3 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/guide.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="29" height="28" viewBox="0 0 29 28" fill="none">
+    <path d="M15.6667 24.5V26.8333H13.3333V24.5H4C3.35568 24.5 2.83334 23.9777 2.83334 23.3333V4.66667C2.83334 4.02234 3.35568 3.5 4 3.5H11C12.3938 3.5 13.645 4.11104 14.5 5.07988C15.3551 4.11104 16.6062 3.5 18 3.5H25C25.6444 3.5 26.1667 4.02234 26.1667 4.66667V23.3333C26.1667 23.9777 25.6444 24.5 25 24.5H15.6667ZM23.8333 22.1667V5.83333H18C16.7113 5.83333 15.6667 6.878 15.6667 8.16667V22.1667H23.8333ZM13.3333 22.1667V8.16667C13.3333 6.878 12.2887 5.83333 11 5.83333H5.16667V22.1667H13.3333Z" fill="white"/>
+</svg>

+ 3 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/history.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="29" height="28" viewBox="0 0 29 28" fill="none">
+    <path d="M14.8333 2.33333C21.2766 2.33333 26.5 7.55667 26.5 14C26.5 20.4433 21.2766 25.6667 14.8333 25.6667C8.39 25.6667 3.16666 20.4433 3.16666 14H5.49999C5.49999 19.1547 9.67867 23.3333 14.8333 23.3333C19.988 23.3333 24.1667 19.1547 24.1667 14C24.1667 8.84534 19.988 4.66666 14.8333 4.66666C11.6253 4.66666 8.79521 6.28522 7.11526 8.75028L10.1667 8.75V11.0833H3.16666V4.08333H5.49999L5.49987 6.99904C7.62839 4.16587 11.0168 2.33333 14.8333 2.33333ZM16 8.16666L15.9998 13.5158L19.783 17.2998L18.1331 18.9497L13.6664 14.4818L13.6667 8.16666H16Z" fill="white"/>
+</svg>

+ 3 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/home.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="25" height="23" viewBox="0 0 25 23" fill="none">
+    <path d="M13.1781 1.13399C12.7724 0.844233 12.2275 0.844233 11.8218 1.13399L0.73848 9.05065L2.09471 10.9493L12.4999 3.51706L22.9051 10.9493L24.2614 9.05065L13.1781 1.13399ZM21.3447 12.8007L13.1781 6.96732C12.7724 6.67757 12.2275 6.67757 11.8218 6.96732L3.65515 12.8007C3.34856 13.0197 3.16659 13.3732 3.16659 13.75V21.3333C3.16659 21.9777 3.68892 22.5 4.33326 22.5H20.6665C21.3109 22.5 21.8332 21.9777 21.8332 21.3333V13.75C21.8332 13.3732 21.6513 13.0197 21.3447 12.8007ZM5.49993 20.1667V14.3504L12.4999 9.35039L19.4999 14.3504V20.1667H5.49993Z" fill="white"/>
+</svg>

+ 3 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/icon_1.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="132" height="46" viewBox="0 0 132 46" fill="none">
+  <path d="M0 0H101.02L132 46H0V0Z" fill="#F06522"/>
+</svg>

+ 21 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/icon_2.svg

@@ -0,0 +1,21 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="144" height="54" viewBox="0 0 144 54" fill="none">
+    <g filter="url(#filter0_d_107_440)">
+        <path d="M0 14C0 9.58172 3.58172 6 8 6H108.5C111.018 6 113.389 7.18555 114.9 9.2L137.4 39.2C141.355 44.4739 137.592 52 131 52H8C3.58172 52 0 48.4183 0 44V14Z" fill="url(#paint0_linear_107_440)"/>
+    </g>
+    <defs>
+        <filter id="filter0_d_107_440" x="-4" y="0" width="147.015" height="54" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+            <feFlood flood-opacity="0" result="BackgroundImageFix"/>
+            <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+            <feOffset dy="-2"/>
+            <feGaussianBlur stdDeviation="2"/>
+            <feComposite in2="hardAlpha" operator="out"/>
+            <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
+            <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_107_440"/>
+            <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_107_440" result="shape"/>
+        </filter>
+        <linearGradient id="paint0_linear_107_440" x1="0" y1="29" x2="147" y2="29" gradientUnits="userSpaceOnUse">
+            <stop stop-color="#F06522"/>
+            <stop offset="1" stop-color="#EE0000"/>
+        </linearGradient>
+    </defs>
+</svg>

+ 22 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/icon_3.svg

@@ -0,0 +1,22 @@
+<svg width="151" height="57" viewBox="0 0 151 57" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M147 0H45.9796L15 46H147V0Z" fill="#44B140"/>
+<g filter="url(#filter0_d_2016_739)">
+<path d="M147 17C147 12.5817 143.418 9 139 9H38.5C35.9819 9 33.6108 10.1856 32.1 12.2L9.6 42.2C5.64458 47.4739 9.40764 55 16 55H139C143.418 55 147 51.4183 147 47V17Z" fill="url(#paint0_linear_2016_739)"/>
+</g>
+<defs>
+<filter id="filter0_d_2016_739" x="3.98547" y="3" width="147.015" height="54" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="-2"/>
+<feGaussianBlur stdDeviation="2"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_2016_739"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_2016_739" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_2016_739" x1="0" y1="32" x2="147" y2="32" gradientUnits="userSpaceOnUse">
+<stop stop-color="#38B100"/>
+<stop offset="1" stop-color="#C9D800"/>
+</linearGradient>
+</defs>
+</svg>

+ 3 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/icon_4.svg

@@ -0,0 +1,3 @@
+<svg width="132" height="46" viewBox="0 0 132 46" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M132 0H30.9796L1.60933e-06 46H132V0Z" fill="#44B140"/>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 6 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/lang-1.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 6 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/lang-2.svg


+ 66 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_1.svg

@@ -0,0 +1,66 @@
+<svg width="46" height="51" viewBox="0 0 46 51" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g filter="url(#filter0_dd_27_184)">
+<g clip-path="url(#clip0_27_184)">
+<rect x="5.5" y="5.5" width="35" height="35" rx="17.5" fill="url(#paint0_linear_27_184)"/>
+<rect x="5.5" y="5.5" width="35" height="35" rx="17.5" stroke="url(#paint1_linear_27_184)"/>
+<mask id="path-4-outside-1_27_184" maskUnits="userSpaceOnUse" x="20.5" y="11.5" width="5" height="22" fill="black">
+<rect fill="white" x="20.5" y="11.5" width="5" height="22"/>
+<path d="M21.1372 32.5V14.57L24.8497 12.8375V32.5H21.1372Z"/>
+</mask>
+<path d="M21.1372 32.5V14.57L24.8497 12.8375V32.5H21.1372Z" fill="white"/>
+<path d="M21.1372 32.5H20.6372V33H21.1372V32.5ZM21.1372 14.57L20.9258 14.1169L20.6372 14.2516V14.57H21.1372ZM24.8497 12.8375H25.3497V12.0524L24.6383 12.3844L24.8497 12.8375ZM24.8497 32.5V33H25.3497V32.5H24.8497ZM21.6372 32.5V14.57H20.6372V32.5H21.6372ZM21.3486 15.0231L25.0611 13.2906L24.6383 12.3844L20.9258 14.1169L21.3486 15.0231ZM24.3497 12.8375V32.5H25.3497V12.8375H24.3497ZM24.8497 32H21.1372V33H24.8497V32Z" fill="url(#paint2_linear_27_184)" mask="url(#path-4-outside-1_27_184)"/>
+<g opacity="0.2">
+<rect x="8.56043" y="4.46191" width="13.099" height="44.9569" transform="rotate(-54.7289 8.56043 4.46191)" fill="url(#paint3_linear_27_184)" style="mix-blend-mode:overlay"/>
+</g>
+<g opacity="0.1">
+<rect x="0.736427" y="9.41162" width="6.62836" height="49.1133" transform="rotate(-54.7289 0.736427 9.41162)" fill="url(#paint4_linear_27_184)" style="mix-blend-mode:overlay"/>
+</g>
+</g>
+<rect x="4.5" y="4.5" width="37" height="37" rx="18.5" stroke="url(#paint5_linear_27_184)" shape-rendering="crispEdges"/>
+</g>
+<defs>
+<filter id="filter0_dd_27_184" x="0" y="0" width="46" height="51" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="5"/>
+<feGaussianBlur stdDeviation="2"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.66 0"/>
+<feBlend mode="multiply" in2="BackgroundImageFix" result="effect1_dropShadow_27_184"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="-2"/>
+<feGaussianBlur stdDeviation="1"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.88 0"/>
+<feBlend mode="color-dodge" in2="effect1_dropShadow_27_184" result="effect2_dropShadow_27_184"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_27_184" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_27_184" x1="23" y1="5" x2="23" y2="41" gradientUnits="userSpaceOnUse">
+<stop stop-color="#93A249"/>
+<stop offset="1" stop-color="#444E16"/>
+</linearGradient>
+<linearGradient id="paint1_linear_27_184" x1="5" y1="10.5" x2="43.5" y2="29.5" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#81FF7D"/>
+</linearGradient>
+<linearGradient id="paint2_linear_27_184" x1="23" y1="5.5" x2="23" y2="40.5" gradientUnits="userSpaceOnUse">
+<stop stop-color="#717171"/>
+<stop offset="1" stop-color="#252525"/>
+</linearGradient>
+<linearGradient id="paint3_linear_27_184" x1="15.1099" y1="4.46191" x2="15.1099" y2="49.4188" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#FBFF00"/>
+</linearGradient>
+<linearGradient id="paint4_linear_27_184" x1="4.05061" y1="9.41162" x2="4.05061" y2="58.5249" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#FBFF00"/>
+</linearGradient>
+<linearGradient id="paint5_linear_27_184" x1="23" y1="5" x2="23" y2="41" gradientUnits="userSpaceOnUse">
+<stop stop-color="#9FFF96"/>
+<stop offset="1" stop-color="#005321"/>
+</linearGradient>
+<clipPath id="clip0_27_184">
+<rect x="5" y="5" width="36" height="36" rx="18" fill="white"/>
+</clipPath>
+</defs>
+</svg>

BIN
WebChallenge/WebChallenge/wwwroot/assets/icons/level_1.zip


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 10 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_10.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 10 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_2.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 10 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_3.svg


+ 66 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_4.svg

@@ -0,0 +1,66 @@
+<svg width="46" height="51" viewBox="0 0 46 51" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g filter="url(#filter0_dd_27_201)">
+<g clip-path="url(#clip0_27_201)">
+<rect x="5.5" y="5.5" width="35" height="35" rx="17.5" fill="url(#paint0_linear_27_201)"/>
+<rect x="5.5" y="5.5" width="35" height="35" rx="17.5" stroke="url(#paint1_linear_27_201)"/>
+<mask id="path-4-outside-1_27_201" maskUnits="userSpaceOnUse" x="13.5" y="12.5" width="17" height="21" fill="black">
+<rect fill="white" x="13.5" y="12.5" width="17" height="21"/>
+<path d="M14.5017 28.7325L21.5692 13.3325H27.3717V26.3675H29.6817V29.035H27.3717V32.5H23.7692V29.035H14.6942L14.5017 28.7325ZM19.3967 26.3675H23.9342L24.058 15.2987L20.9642 22.9575L19.3967 26.3675Z"/>
+</mask>
+<path d="M14.5017 28.7325L21.5692 13.3325H27.3717V26.3675H29.6817V29.035H27.3717V32.5H23.7692V29.035H14.6942L14.5017 28.7325ZM19.3967 26.3675H23.9342L24.058 15.2987L20.9642 22.9575L19.3967 26.3675Z" fill="white"/>
+<path d="M14.5017 28.7325L14.0473 28.5239L13.9338 28.7713L14.0799 29.0009L14.5017 28.7325ZM21.5692 13.3325V12.8325H21.2486L21.1148 13.1239L21.5692 13.3325ZM27.3717 13.3325H27.8717V12.8325H27.3717V13.3325ZM27.3717 26.3675H26.8717V26.8675H27.3717V26.3675ZM29.6817 26.3675H30.1817V25.8675H29.6817V26.3675ZM29.6817 29.035V29.535H30.1817V29.035H29.6817ZM27.3717 29.035V28.535H26.8717V29.035H27.3717ZM27.3717 32.5V33H27.8717V32.5H27.3717ZM23.7692 32.5H23.2692V33H23.7692V32.5ZM23.7692 29.035H24.2692V28.535H23.7692V29.035ZM14.6942 29.035L14.2724 29.3034L14.4198 29.535H14.6942V29.035ZM19.3967 26.3675L18.9424 26.1587L18.6166 26.8675H19.3967V26.3675ZM23.9342 26.3675V26.8675H24.4287L24.4342 26.3731L23.9342 26.3675ZM24.058 15.2987L24.558 15.3043L23.5944 15.1115L24.058 15.2987ZM20.9642 22.9575L21.4185 23.1663L21.4234 23.1557L21.4278 23.1448L20.9642 22.9575ZM14.9562 28.9411L22.0237 13.541L21.1148 13.1239L14.0473 28.5239L14.9562 28.9411ZM21.5692 13.8325H27.3717V12.8325H21.5692V13.8325ZM26.8717 13.3325V26.3675H27.8717V13.3325H26.8717ZM27.3717 26.8675H29.6817V25.8675H27.3717V26.8675ZM29.1817 26.3675V29.035H30.1817V26.3675H29.1817ZM29.6817 28.535H27.3717V29.535H29.6817V28.535ZM26.8717 29.035V32.5H27.8717V29.035H26.8717ZM27.3717 32H23.7692V33H27.3717V32ZM24.2692 32.5V29.035H23.2692V32.5H24.2692ZM23.7692 28.535H14.6942V29.535H23.7692V28.535ZM15.1161 28.7666L14.9236 28.4641L14.0799 29.0009L14.2724 29.3034L15.1161 28.7666ZM19.3967 26.8675H23.9342V25.8675H19.3967V26.8675ZM24.4342 26.3731L24.558 15.3043L23.558 15.2932L23.4343 26.3619L24.4342 26.3731ZM23.5944 15.1115L20.5006 22.7702L21.4278 23.1448L24.5216 15.486L23.5944 15.1115ZM20.5099 22.7487L18.9424 26.1587L19.851 26.5763L21.4185 23.1663L20.5099 22.7487Z" fill="url(#paint2_linear_27_201)" mask="url(#path-4-outside-1_27_201)"/>
+<g opacity="0.2">
+<rect x="8.56043" y="4.46191" width="13.099" height="44.9569" transform="rotate(-54.7289 8.56043 4.46191)" fill="url(#paint3_linear_27_201)" style="mix-blend-mode:overlay"/>
+</g>
+<g opacity="0.1">
+<rect x="0.736428" y="9.41162" width="6.62836" height="49.1133" transform="rotate(-54.7289 0.736428 9.41162)" fill="url(#paint4_linear_27_201)" style="mix-blend-mode:overlay"/>
+</g>
+</g>
+<rect x="4.5" y="4.5" width="37" height="37" rx="18.5" stroke="url(#paint5_linear_27_201)" shape-rendering="crispEdges"/>
+</g>
+<defs>
+<filter id="filter0_dd_27_201" x="0" y="0" width="46" height="51" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="5"/>
+<feGaussianBlur stdDeviation="2"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.66 0"/>
+<feBlend mode="multiply" in2="BackgroundImageFix" result="effect1_dropShadow_27_201"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="-2"/>
+<feGaussianBlur stdDeviation="1"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.88 0"/>
+<feBlend mode="color-dodge" in2="effect1_dropShadow_27_201" result="effect2_dropShadow_27_201"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_27_201" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_27_201" x1="23" y1="5" x2="23" y2="41" gradientUnits="userSpaceOnUse">
+<stop stop-color="#93A249"/>
+<stop offset="1" stop-color="#444E16"/>
+</linearGradient>
+<linearGradient id="paint1_linear_27_201" x1="5" y1="10.5" x2="43.5" y2="29.5" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#81FF7D"/>
+</linearGradient>
+<linearGradient id="paint2_linear_27_201" x1="22" y1="5.5" x2="22" y2="40.5" gradientUnits="userSpaceOnUse">
+<stop stop-color="#717171"/>
+<stop offset="1" stop-color="#252525"/>
+</linearGradient>
+<linearGradient id="paint3_linear_27_201" x1="15.1099" y1="4.46191" x2="15.1099" y2="49.4188" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#FBFF00"/>
+</linearGradient>
+<linearGradient id="paint4_linear_27_201" x1="4.05061" y1="9.41162" x2="4.05061" y2="58.5249" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#FBFF00"/>
+</linearGradient>
+<linearGradient id="paint5_linear_27_201" x1="23" y1="5" x2="23" y2="41" gradientUnits="userSpaceOnUse">
+<stop stop-color="#9FFF96"/>
+<stop offset="1" stop-color="#005321"/>
+</linearGradient>
+<clipPath id="clip0_27_201">
+<rect x="5" y="5" width="36" height="36" rx="18" fill="white"/>
+</clipPath>
+</defs>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 10 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_5.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 10 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_6.svg


+ 66 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_7.svg

@@ -0,0 +1,66 @@
+<svg width="46" height="51" viewBox="0 0 46 51" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g filter="url(#filter0_dd_27_213)">
+<g clip-path="url(#clip0_27_213)">
+<rect x="5.5" y="5.5" width="35" height="35" rx="17.5" fill="url(#paint0_linear_27_213)"/>
+<rect x="5.5" y="5.5" width="35" height="35" rx="17.5" stroke="url(#paint1_linear_27_213)"/>
+<mask id="path-4-outside-1_27_213" maskUnits="userSpaceOnUse" x="15.5" y="12.5" width="15" height="21" fill="black">
+<rect fill="white" x="15.5" y="12.5" width="15" height="21"/>
+<path d="M19.434 32.5L24.9478 16.5775H16.9865V13.3325H29.554L23.3665 32.5H19.434Z"/>
+</mask>
+<path d="M19.434 32.5L24.9478 16.5775H16.9865V13.3325H29.554L23.3665 32.5H19.434Z" fill="white"/>
+<path d="M19.434 32.5L18.9615 32.3364L18.7318 33H19.434V32.5ZM24.9478 16.5775L25.4202 16.7411L25.65 16.0775H24.9478V16.5775ZM16.9865 16.5775H16.4865V17.0775H16.9865V16.5775ZM16.9865 13.3325V12.8325H16.4865V13.3325H16.9865ZM29.554 13.3325L30.0298 13.4861L30.2408 12.8325H29.554V13.3325ZM23.3665 32.5V33H23.7305L23.8423 32.6536L23.3665 32.5ZM19.9065 32.6636L25.4202 16.7411L24.4753 16.4139L18.9615 32.3364L19.9065 32.6636ZM24.9478 16.0775H16.9865V17.0775H24.9478V16.0775ZM17.4865 16.5775V13.3325H16.4865V16.5775H17.4865ZM16.9865 13.8325H29.554V12.8325H16.9865V13.8325ZM29.0782 13.1789L22.8907 32.3464L23.8423 32.6536L30.0298 13.4861L29.0782 13.1789ZM23.3665 32H19.434V33H23.3665V32Z" fill="url(#paint2_linear_27_213)" mask="url(#path-4-outside-1_27_213)"/>
+<g opacity="0.2">
+<rect x="8.56043" y="4.46191" width="13.099" height="44.9569" transform="rotate(-54.7289 8.56043 4.46191)" fill="url(#paint3_linear_27_213)" style="mix-blend-mode:overlay"/>
+</g>
+<g opacity="0.1">
+<rect x="0.736427" y="9.41162" width="6.62836" height="49.1133" transform="rotate(-54.7289 0.736427 9.41162)" fill="url(#paint4_linear_27_213)" style="mix-blend-mode:overlay"/>
+</g>
+</g>
+<rect x="4.5" y="4.5" width="37" height="37" rx="18.5" stroke="url(#paint5_linear_27_213)" shape-rendering="crispEdges"/>
+</g>
+<defs>
+<filter id="filter0_dd_27_213" x="0" y="0" width="46" height="51" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="5"/>
+<feGaussianBlur stdDeviation="2"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.66 0"/>
+<feBlend mode="multiply" in2="BackgroundImageFix" result="effect1_dropShadow_27_213"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="-2"/>
+<feGaussianBlur stdDeviation="1"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.88 0"/>
+<feBlend mode="color-dodge" in2="effect1_dropShadow_27_213" result="effect2_dropShadow_27_213"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_27_213" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_27_213" x1="23" y1="5" x2="23" y2="41" gradientUnits="userSpaceOnUse">
+<stop stop-color="#93A249"/>
+<stop offset="1" stop-color="#444E16"/>
+</linearGradient>
+<linearGradient id="paint1_linear_27_213" x1="5" y1="10.5" x2="43.5" y2="29.5" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#81FF7D"/>
+</linearGradient>
+<linearGradient id="paint2_linear_27_213" x1="23" y1="5.5" x2="23" y2="40.5" gradientUnits="userSpaceOnUse">
+<stop stop-color="#717171"/>
+<stop offset="1" stop-color="#252525"/>
+</linearGradient>
+<linearGradient id="paint3_linear_27_213" x1="15.1099" y1="4.46191" x2="15.1099" y2="49.4188" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#FBFF00"/>
+</linearGradient>
+<linearGradient id="paint4_linear_27_213" x1="4.05061" y1="9.41162" x2="4.05061" y2="58.5249" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="1" stop-color="#FBFF00"/>
+</linearGradient>
+<linearGradient id="paint5_linear_27_213" x1="23" y1="5" x2="23" y2="41" gradientUnits="userSpaceOnUse">
+<stop stop-color="#9FFF96"/>
+<stop offset="1" stop-color="#005321"/>
+</linearGradient>
+<clipPath id="clip0_27_213">
+<rect x="5" y="5" width="36" height="36" rx="18" fill="white"/>
+</clipPath>
+</defs>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 10 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_8.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 10 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/level_9.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 11 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/logo.svg


+ 5 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/logout.svg

@@ -0,0 +1,5 @@
+<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="0.5" y="0.5" width="41" height="41" rx="20.5" fill="#FF2200"/>
+<rect x="0.5" y="0.5" width="41" height="41" rx="20.5" stroke="white"/>
+<path d="M11.6667 19.6666H22.3333V22.3333H11.6667V26.3333L5 21L11.6667 15.6666V19.6666ZM10.3324 29H13.9445C15.8248 30.6596 18.2948 31.6666 21 31.6666C26.8911 31.6666 31.6667 26.891 31.6667 21C31.6667 15.1089 26.8911 10.3333 21 10.3333C18.2948 10.3333 15.8248 11.3403 13.9445 13H10.3324C12.7649 9.76144 16.6378 7.66663 21 7.66663C28.3637 7.66663 34.3333 13.6362 34.3333 21C34.3333 28.3637 28.3637 34.3333 21 34.3333C16.6378 34.3333 12.7649 32.2385 10.3324 29Z" fill="white"/>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 9 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/number_10.svg


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 9 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/number_5.svg


+ 5 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/setting.svg

@@ -0,0 +1,5 @@
+<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="0.5" y="0.5" width="41" height="41" rx="20.5" fill="#2EA929"/>
+<rect x="0.5" y="0.5" width="41" height="41" rx="20.5" stroke="white"/>
+<path d="M16.5818 10.3334L20.0573 6.85794C20.578 6.33723 21.4223 6.33723 21.9429 6.85794L25.4184 10.3334H30.3335C31.0699 10.3334 31.6668 10.9304 31.6668 11.6667V16.5818L35.1423 20.0573C35.6629 20.578 35.6629 21.4222 35.1423 21.9429L31.6668 25.4184V30.3334C31.6668 31.0698 31.0699 31.6668 30.3335 31.6668H25.4184L21.9429 35.1422C21.4223 35.6629 20.578 35.6629 20.0573 35.1422L16.5818 31.6668H11.6668C10.9304 31.6668 10.3334 31.0698 10.3334 30.3334V25.4184L6.85797 21.9429C6.33726 21.4222 6.33726 20.578 6.85797 20.0573L10.3334 16.5818V11.6667C10.3334 10.9304 10.9304 10.3334 11.6668 10.3334H16.5818ZM13.0001 13.0001V17.6864L9.68639 21.0001L13.0001 24.3138V29.0001H17.6864L21.0001 32.3138L24.3139 29.0001H29.0001V24.3138L32.3139 21.0001L29.0001 17.6864V13.0001H24.3139L21.0001 9.68636L17.6864 13.0001H13.0001ZM21.0001 26.3334C18.0546 26.3334 15.6668 23.9456 15.6668 21.0001C15.6668 18.0546 18.0546 15.6667 21.0001 15.6667C23.9456 15.6667 26.3335 18.0546 26.3335 21.0001C26.3335 23.9456 23.9456 26.3334 21.0001 26.3334ZM21.0001 23.6668C22.4729 23.6668 23.6668 22.4729 23.6668 21.0001C23.6668 19.5273 22.4729 18.3334 21.0001 18.3334C19.5273 18.3334 18.3335 19.5273 18.3335 21.0001C18.3335 22.4729 19.5273 23.6668 21.0001 23.6668Z" fill="white"/>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 6 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/start-fill.svg


+ 10 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/start.svg

@@ -0,0 +1,10 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="29" height="28" viewBox="0 0 29 28" fill="none">
+    <g clip-path="url(#clip0_31_822)">
+        <path d="M14.1674 21.3033L5.93833 25.9096L7.77622 16.6599L0.85253 10.2571L10.2174 9.14673L14.1674 0.583328L18.1172 9.14673L27.4821 10.2571L20.5585 16.6599L22.3963 25.9096L14.1674 21.3033ZM14.1674 18.6293L19.1218 21.4026L18.0153 15.8336L22.1839 11.9786L16.5455 11.3101L14.1674 6.15418L11.7892 11.3101L6.15073 11.9786L10.3194 15.8336L9.21279 21.4026L14.1674 18.6293Z" fill="white"/>
+    </g>
+    <defs>
+        <clipPath id="clip0_31_822">
+            <rect width="28" height="28" fill="white" transform="translate(0.166656)"/>
+        </clipPath>
+    </defs>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 38 - 0
WebChallenge/WebChallenge/wwwroot/assets/icons/success.svg


BIN
WebChallenge/WebChallenge/wwwroot/assets/icons/warning.png


BIN
WebChallenge/WebChallenge/wwwroot/assets/images/Frame_25.png


BIN
WebChallenge/WebChallenge/wwwroot/assets/images/Group-35.png


BIN
WebChallenge/WebChallenge/wwwroot/assets/images/Group_31.png


BIN
WebChallenge/WebChallenge/wwwroot/assets/images/avt.png


BIN
WebChallenge/WebChallenge/wwwroot/assets/images/bg_image.png


BIN
WebChallenge/WebChallenge/wwwroot/assets/images/bg_image_2.png


BIN
WebChallenge/WebChallenge/wwwroot/assets/images/bg_image_no_text.png


BIN
WebChallenge/WebChallenge/wwwroot/assets/images/bg_image_no_text_2.jpg


BIN
WebChallenge/WebChallenge/wwwroot/assets/images/bg_image_old.png


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.