一、在http://www.aspnetboilerplate.com/Templates 網站下載ABP模版javascript
二、解壓後打開解決方案,解決方案目錄:css
三、在AbpTest.Web.Host項目的appsettings.json中配置數據庫鏈接字符串html
新建名爲AbpTestDb的空白數據庫,在NuGet包管理控制檯 執行 Update-Database 命令,初始化數據庫java
四、運行應用程序將看到Swagger生成的API接口頁面jquery
AspNet Core2 瀏覽器緩存使用
Core2中使用Microsoft.AspNetCore.Mvc下的ResponseCacheAttribute特性來控制Http Get請求的緩存web
原理是設置http請求 響應頭的Cache-control來告訴瀏覽器如何進行客戶端緩存
一、在Startup的ConfigureServices方法裏面設置一個CacheProfiles,Duration屬性定義瀏覽器緩存的秒數,CacheProfiles一個通用的緩存配置項
services.AddMvc(option => { /*客戶端緩存*/ option.CacheProfiles.Add("default", new Microsoft.AspNetCore.Mvc.CacheProfile { Duration = 600 /*10分鐘*/ }); });
二、在須要緩存的Action上面添加ResponseCacheAttribute特性,CacheProfileName 的值使用服務配置的名稱,該Action將使用配置項進行緩存
[ResponseCache(CacheProfileName = "default")]
也能夠在Action 上賦予 Duration 值,指定瀏覽器緩存的時間 shell
查看ResponseCacheAttribute中的代碼數據庫
public unsafe IFilterMetadata CreateInstance(IServiceProvider serviceProvider) { //IL_0000: Unknown result type (might be due to invalid IL) //IL_0008: Unknown result type (might be due to invalid IL) //IL_000e: Unknown result type (might be due to invalid IL) //IL_0025: Unknown result type (might be due to invalid IL) //IL_0032: Expected Ref, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL) if (serviceProvider == (IServiceProvider)0) { throw new ArgumentNullException("serviceProvider"); } IOptions<MvcOptions> requiredService = serviceProvider.GetRequiredService<IOptions<MvcOptions>>(); CacheProfile cacheProfile = null; if (this.CacheProfileName != null) { ((IDictionary)(?)requiredService.Value.CacheProfiles).TryGetValue((!0)this.CacheProfileName, ref *(!1*)(&cacheProfile)); if (cacheProfile == null) { throw new InvalidOperationException(Resources.FormatCacheProfileNotFound(this.CacheProfileName)); } } this._duration = (this._duration ?? ((cacheProfile != null) ? cacheProfile.Duration : null)); this._noStore = (this._noStore ?? ((cacheProfile != null) ? cacheProfile.NoStore : null)); this._location = (this._location ?? ((cacheProfile != null) ? cacheProfile.Location : null)); this.VaryByHeader = (this.VaryByHeader ?? ((cacheProfile != null) ? cacheProfile.VaryByHeader : null)); this.VaryByQueryKeys = (this.VaryByQueryKeys ?? ((cacheProfile != null) ? cacheProfile.VaryByQueryKeys : null)); return new ResponseCacheFilter(new CacheProfile { Duration = this._duration, Location = this._location, NoStore = this._noStore, VaryByHeader = this.VaryByHeader, VaryByQueryKeys = this.VaryByQueryKeys }); }
能夠得知Action上設置-----優先級高於--CacheProfiles裏面的配置json
緩存最終經過ResponseCacheFilter過濾器來實現,ResponseCacheFilter 的代碼:c#
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.ResponseCaching; using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; namespace Microsoft.AspNetCore.Mvc.Internal { /// <summary> /// An <see cref="T:Microsoft.AspNetCore.Mvc.Filters.IActionFilter" /> which sets the appropriate headers related to response caching. /// </summary> public class ResponseCacheFilter : IResponseCacheFilter, IActionFilter, IFilterMetadata { private readonly CacheProfile _cacheProfile; private int? _cacheDuration; private ResponseCacheLocation? _cacheLocation; private bool? _cacheNoStore; private string _cacheVaryByHeader; private string[] _cacheVaryByQueryKeys; /// <summary> /// Gets or sets the duration in seconds for which the response is cached. /// This is a required parameter. /// This sets "max-age" in "Cache-control" header. /// </summary> public int Duration { get { return (this._cacheDuration ?? this._cacheProfile.Duration) ?? 0; } set { this._cacheDuration = value; } } /// <summary> /// Gets or sets the location where the data from a particular URL must be cached. /// </summary> public ResponseCacheLocation Location { get { return (this._cacheLocation ?? this._cacheProfile.Location) ?? ResponseCacheLocation.Any; } set { this._cacheLocation = value; } } /// <summary> /// Gets or sets the value which determines whether the data should be stored or not. /// When set to <see langword="true" />, it sets "Cache-control" header to "no-store". /// Ignores the "Location" parameter for values other than "None". /// Ignores the "duration" parameter. /// </summary> public bool NoStore { get { return (this._cacheNoStore ?? this._cacheProfile.NoStore) ?? false; } set { this._cacheNoStore = value; } } /// <summary> /// Gets or sets the value for the Vary response header. /// </summary> public string VaryByHeader { get { return this._cacheVaryByHeader ?? this._cacheProfile.VaryByHeader; } set { this._cacheVaryByHeader = value; } } /// <summary> /// Gets or sets the query keys to vary by. /// </summary> /// <remarks> /// <see cref="P:Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter.VaryByQueryKeys" /> requires the response cache middleware. /// </remarks> public string[] VaryByQueryKeys { get { return this._cacheVaryByQueryKeys ?? this._cacheProfile.VaryByQueryKeys; } set { this._cacheVaryByQueryKeys = value; } } /// <summary> /// Creates a new instance of <see cref="T:Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter" /> /// </summary> /// <param name="cacheProfile">The profile which contains the settings for /// <see cref="T:Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter" />.</param> public ResponseCacheFilter(CacheProfile cacheProfile) { this._cacheProfile = cacheProfile; } /// <inheritdoc /> public void OnActionExecuting(ActionExecutingContext context) { //IL_0008: Unknown result type (might be due to invalid IL) //IL_0051: Unknown result type (might be due to invalid IL) //IL_00d4: Unknown result type (might be due to invalid IL) //IL_0185: Unknown result type (might be due to invalid IL) if (context == null) { throw new ArgumentNullException("context"); } if (!this.IsOverridden(context)) { if (!this.NoStore && !this._cacheProfile.Duration.get_HasValue() && !this._cacheDuration.get_HasValue()) { throw new InvalidOperationException(Resources.FormatResponseCache_SpecifyDuration("NoStore", "Duration")); } IHeaderDictionary headers = context.HttpContext.Response.Headers; ((IDictionary)(?)headers).Remove((!0)"Vary"); ((IDictionary)(?)headers).Remove((!0)"Cache-Control"); ((IDictionary)(?)headers).Remove((!0)"Pragma"); if (!string.IsNullOrEmpty(this.VaryByHeader)) { headers["Vary"] = this.VaryByHeader; } if (this.VaryByQueryKeys != null) { IResponseCachingFeature responseCachingFeature = context.HttpContext.Features.Get<IResponseCachingFeature>(); if (responseCachingFeature == null) { throw new InvalidOperationException(Resources.FormatVaryByQueryKeys_Requires_ResponseCachingMiddleware("VaryByQueryKeys")); } responseCachingFeature.VaryByQueryKeys = this.VaryByQueryKeys; } if (this.NoStore) { headers["Cache-Control"] = "no-store"; if (this.Location == ResponseCacheLocation.None) { headers.AppendCommaSeparatedValues("Cache-Control", "no-cache"); headers["Pragma"] = "no-cache"; } } else { string text = null; switch (this.Location) { case ResponseCacheLocation.Any: text = "public"; break; case ResponseCacheLocation.Client: text = "private"; break; case ResponseCacheLocation.None: text = "no-cache"; headers["Pragma"] = "no-cache"; break; } text = string.Format((IFormatProvider)CultureInfo.get_InvariantCulture(), "{0}{1}max-age={2}", (object)text, (object)((text != null) ? "," : null), (object)this.Duration); if (text != null) { headers["Cache-Control"] = text; } } } } /// <inheritdoc /> public void OnActionExecuted(ActionExecutedContext context) { } internal bool IsOverridden(ActionExecutingContext context) { //IL_0008: Unknown result type (might be due to invalid IL) if (context == null) { throw new ArgumentNullException("context"); } return Enumerable.Last<IResponseCacheFilter>(Enumerable.OfType<IResponseCacheFilter>((IEnumerable)context.Filters)) != this; } } }
c#基礎,單線程,跨線程訪問和線程帶參數
1 using System; 2 using System.Collections.Generic; 3 using System.Threading; 4 using System.Windows.Forms; 5 6 namespace 線程和跨線程 7 { 8 public partial class Form1 : Form 9 { 10 public Form1() 11 { 12 InitializeComponent(); 13 } 14 /// <summary> 15 /// 單線程直接假死了 16 /// </summary> 17 /// <param name="sender"></param> 18 /// <param name="e"></param> 19 private void btnAlone_Click(object sender, EventArgs e) 20 { 21 for (int i = 0; i < 100000; i++) 22 { 23 //經過[調試]-[窗口]-[輸出]顯示打印值 24 Console.WriteLine(i); 25 } 26 } 27 28 29 /// <summary> 30 /// 新線程運行,窗體不假死 31 /// </summary> 32 /// <param name="sender"></param> 33 /// <param name="e"></param> 34 private void btnNew_Click(object sender, EventArgs e) 35 { 36 Thread th = new Thread(ShowCalculator) 37 { 38 IsBackground = true 39 }; 40 th.Start(); 41 42 } 43 /// <summary> 44 /// 循環計算方法,供新線程使用 45 /// </summary> 46 private void ShowCalculator() 47 { 48 for (int i = 0; i < 100000; i++) 49 {//經過[調試]-[窗口]-[輸出]顯示打印值 50 Console.WriteLine(i); 51 } 52 } 53 /// <summary> 54 /// 帶參數的 55 /// </summary> 56 /// <param name="sender"></param> 57 /// <param name="e"></param> 58 private void btnParameters_Click(object sender, EventArgs e) 59 { 60 List<int> list = new List<int>() { 1, 2, 3, 4, 5 }; 61 ParameterizedThreadStart parThreadStart = new ParameterizedThreadStart(ShowParameters); 62 Thread th = new Thread(parThreadStart) { IsBackground = true }; 63 th.Start(list); 64 } 65 private void ShowParameters(object obj) 66 { 67 //線程中的參數只能是Object 68 List<int> result = obj as List<int>; 69 foreach (var item in result) 70 { 71 MessageBox.Show(item.ToString()); 72 } 73 } 74 /// <summary> 75 /// 跨線程訪問 76 /// </summary> 77 /// <param name="sender"></param> 78 /// <param name="e"></param> 79 private void button1_Click(object sender, EventArgs e) 80 { 81 Thread th = new Thread(ShowMulti) { IsBackground = true }; 82 th.Start(); 83 } 84 /// <summary> 85 /// 解決跨線程訪問報異常,不使用 86 /// </summary> 87 private void ShowMulti() 88 { 89 int first = 0; 90 for (int i = 0; i < 10; i++) 91 { 92 first = i; 93 } 94 //是否要對lbl控件進行跨線程 95 if (this.lblShow.InvokeRequired) 96 { 97 //對委託中的數據類型驗證 98 this.lblShow.Invoke(new Action<Label, string>(ShowLableValue), this.lblShow, first.ToString()); 99 } 100 else 101 { 102 this.lblShow.Text = first.ToString(); 103 } 104 } 105 /// <summary> 106 /// 把值寫到控件中 107 /// </summary> 108 /// <param name="lbl"></param> 109 /// <param name="value"></param> 110 private void ShowLableValue(Label lbl, string value) 111 { 112 lbl.Text = value; 113 } 114 115 private void Form1_Load(object sender, EventArgs e) 116 { 117 //關閉跨進程檢查 118 //Label.CheckForIllegalCrossThreadCalls = false; 119 //改用委託方法實現 120 } 121 } 122 }
wpf 禁用啓用webbroswer右鍵菜單
//禁用腳本錯誤等相似的窗口信息 this.webBrowser1.ScriptErrorsSuppressed = true; //禁用右鍵菜單 this.webBrowser1.IsWebBrowserContextMenuEnabled = false; //禁用鍵盤快捷鍵 this.webBrowser1.WebBrowserShortcutsEnabled = false; //打開IE打印機會話框 this.webBrowser1.ShowPrintDialog(); //打開IE的打印預覽會話框 this.webBrowser1.ShowPrintPreviewDialog(); //打開IE的保存 會話框 this.webBrowser1.ShowSaveAsDialog();
EF Core 2.0使用MsSql/MySql實現DB First和Code First
參考地址
ASP.NET Core MVC 和 EF Core - 教程系列
環境
開始搭建
一、在 Visual Studio 2017 中建立新項目
- 「文件」>「新建」>「項目」
- 從左側菜單中選擇「已安裝」>「模板」>「Visual C#」>「.NET Core」。
- 選擇「ASP.NET Core Web 應用程序」。
- 輸入「EFGetStarted.AspNetCore.NewDb」做爲名稱,而後單擊「肯定」。
- 在「新建 ASP.NET Core Web 應用程序」對話框中:
- 確保在下拉列表中選擇「.NET Core」和「ASP.NET Core 2.0」選項
- 選擇「Web 應用程序(模型視圖控制器)」項目模板
- 確保將「身份驗證」設置爲「無身份驗證」
- 單擊「肯定」
二、安裝 Entity Framework Core
- 工具」>「NuGet 包管理器」>「包管理器控制檯」
1.一、安裝數據庫提供程序
MsSql
運行:Install-Package Microsoft.EntityFrameworkCore.SqlServer
MySql
運行:柚子:Install-Package Pomelo.EntityFrameworkCore.MySql
或者
官方:Install-Package MySql.Data.EntityFrameworkCore -Version 8.0.11
1.二、安裝程序包管理器控制檯
運行:Install-Package Microsoft.EntityFrameworkCore.Tools
1.三、安裝設計包
運行:Install-Package Microsoft.EntityFrameworkCore.Design
數據據庫提供程序設計包 (EF Core 2.0 再也不須要)
MsSql
運行:Install-Package Microsoft.EntityFrameworkCore.SqlServer.Design
MySql
運行:Install-Package Pomelo.EntityFrameworkCore.MySql.Design
DB First——從現有數據庫建立模型
MySql
運行:Scaffold-DbContext -Connection "Server=localhost;User Id=root;Password=123456;Database=vanfj" -Provider "Pomelo.EntityFrameworkCore.MySql" -OutputDir "Models"
MsSql
運行:Scaffold-DbContext -Connection "Server=localhost;User Id=root;Password=123456;Database=vanfj" -Provider "Microsoft.EntityFrameworkCore.SqlServer" -OutputDir "Models"
使用說明:將Connection中的鏈接字符串替換爲本身的數據庫鏈接,將OutputDir中的Models替換爲本身要生成的文件目錄名
Code First——從模型生成到數據庫
一、建立模型
1.一、建立上下文
public class SchoolContext : DbContext { public SchoolContext(DbContextOptions<SchoolContext> options) : base(options) { } public DbSet<Course> Courses { get; set; } public DbSet<Enrollment> Enrollments { get; set; } public DbSet<Student> Students { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Course>().ToTable("Course"); modelBuilder.Entity<Enrollment>().ToTable("Enrollment"); modelBuilder.Entity<Student>().ToTable("Student"); } } public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } public enum Grade { A, B, C, D, F } public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public Grade? Grade { get; set; } public Course Course { get; set; } public Student Student { get; set; } } { A, B, C, D, F } public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public Grade? Grade { get; set; } public Course Course { get; set; } public Student Student { get; set; } } public class Course { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } public ICollection<Enrollment> Enrollments { get; set; } }
1.二、Startup文件注入上下文
EF Core在版本 2.0 中,引入了一種在依賴關係注入中註冊自定義 DbContext 類型的新方法,即以透明形式引入可重用 DbContext 實例的池。
要使用 DbContext 池,請在服務註冊期間使用 AddDbContextPool 而不是 AddDbContext
public void ConfigureServices(IServiceCollection services) { services.AddDbContextPool<SchoolContext>(options => options.UseMySql(Configuration.GetConnectionString("DefaultConnection"))); services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore); }
1.三、appsettings.json文件添加鏈接字符串
{ "ConnectionStrings": { "DefaultConnection": "Server=localhost;User Id=root;Password=123456;Database=vanfj" }, "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" } } }
二、執行NuGet命令,建立數據庫
2.一、爲遷移搭建基架
運行:Add-Migration InitialCreate
2.二、將新遷移應用到數據庫
運行:Update-Database
EF Core 2.0 NuGet命令
Get-Help about_EntityFrameworkCore 獲取EF Core命令幫助
添加一個遷移數據庫 遷移的名稱 目錄(及其子命名空間)路徑是相對於項目目錄。 默認值爲"Migrations"。
Add-Migration -Name <String> -OutputDir <String>
Add-Migration InitialCreate 第一次執行初始化用這個
刪除上次的遷移數據庫 不檢查以查看遷移是否已應用到數據庫。
Remove-Migration -Force
目標遷移。 若是爲"0",將恢復全部遷移。 默認到最後一個遷移。
Update-Database
Update-Database LastGoodMigration 還原遷移
刪除數據庫 顯示的數據庫會被丟棄,但沒有刪除它
Drop-Database -WhatIf
Get-DbContext 獲取有關 DbContext 類型的信息
從數據庫更新DbContext和實體的類型
Scaffold-DbContext
-Connection <String> 數據庫的鏈接字符串。
-Provider <String> 要使用的提供程序。 (例如 Microsoft.EntityFrameworkCore.SqlServer)
-OutputDir <String > 要將文件放入的目錄。 路徑是相對於項目目錄。
--Context <String > 若要生成的 dbcontext 名稱。
-Schemas <String[]> 要生成實體類型的表架構。
-Tables <String[]> 要生成實體類型的表。
-DataAnnotations 使用屬性來配置該模型 (若是可能)。 若是省略,則使用僅 fluent API。
-UseDatabaseNames 使用直接從數據庫表和列名稱。
-Force 覆蓋現有文件。
從遷移中生成的 SQL 腳本
Script-Migration
-From <String> 開始遷移。 默認值爲 0 (初始數據庫)
-To <String> 結束的遷移。 默認到最後一個遷移
-Idempotent 生成能夠在任何遷移的數據庫使用的腳本
-Output <String> 要將結果寫入的文件
ASP.NET Core部署到Windows IIS
網上已經有許多ASP.NET Core關於Widows IIS部署的文章,在部署到服務器時遇到了一些問題,在這裏我就再也不對原理進行闡釋(複製)了,只寫下一些關鍵環節,想看原理的同窗請參考官網,此文章做爲留用。
步驟:
一、ASP.NET Core程序內配置
二、Windows Server配置
1、ASP.NET Core應用程序配置
web.config 配置(官方教程)
重點修改 processPath 和 arguments 兩個參數
processPath 修改成 dotnet
arguments 修改成 當前項目名稱的dll
配置示例:
Startup 啓用 IISIntegration 組件
FTP發佈到IIS
在這裏我使用的是VS FTP直接發佈到IIS,也可使用文件系統先發布到本地,二者任選一種均可以
2、Windows Server配置
安裝環境
一、 Microsoft Visual C ++ 2015 Redistributable
目前這裏這裏連接的版本是DotNetCore.2.0.7-WindowsHosting,也能夠在.NET全部下載自行選擇對應的版本
提示:版本很重要,版本很重要,版本很重要
IIS配置
應用程序池設置爲無託管代碼
最後來測試是否成功
QRCode.js:使用 JavaScript 生成二維碼
什麼是 QRCode.js?
QRCode.js 是一個用於生成二維碼的 JavaScript 庫。主要是經過獲取 DOM 的標籤,再經過 HTML5 Canvas 繪製而成,不依賴任何庫。
基本用法
載入 JavaScript 文件
<script type="text/javascript" src="http://static.runoob.com/assets/qrcode/qrcode.min.js"></script>
DOM結構
<div id="qrcode"></div>
JavaScropt調用
//簡單形式 new QRCode(document.getElementById("qrcode"), "http://www.runoob.com"); // 設置要生成二維碼的連接 // 設置參數方式 var qrcode = new QRCode("test", { text: "http://www.runoob.com", width: 128, height: 128, colorDark : "#000000", colorLight : "#ffffff", correctLevel : QRCode.CorrectLevel.H }); // 使用 API qrcode.clear(); qrcode.makeCode('new content');
參數說明
new QRCode(element, option)
名稱 | 默認值 | 說明 |
---|---|---|
element | - | 顯示二維碼的元素或該元素的 ID |
option | 參數配置 |
option 參數說明
名稱 | 默認值 | 說明 |
---|---|---|
width | 256 | 圖像寬度 |
height | 256 | 圖像高度 |
colorDark | "#000000" | 前景色 |
colorLight | "#ffffff" | 背景色 |
correctLevel | QRCode.CorrectLevel.L | 容錯級別,可設置爲: QRCode.CorrectLevel.L QRCode.CorrectLevel.M QRCode.CorrectLevel.Q QRCode.CorrectLevel.H |
API 接口
名稱 | 說明 |
---|---|
makeCode(text) | 設置二維碼內容 |
clear() | 清除二維碼。(僅在不支持 Canvas 的瀏覽器下有效) |
瀏覽器支持
支持該庫的瀏覽器有:IE6~10, Chrome, Firefox, Safari, Opera, Mobile Safari, Android, Windows Mobile, 等。
實例代碼
HTML 代碼
<input id="text" type="text" value="http://www.runoob.com" /><br /> <div id="qrcode"></div>
CSS 代碼
#qrcode { width:160px; height:160px; margin-top:15px; }
JavaScript 代碼
var qrcode = new QRCode("qrcode"); function makeCode () { var elText = document.getElementById("text"); if (!elText.value) { alert("Input a text"); elText.focus(); return; } qrcode.makeCode(elText.value); } makeCode(); $("#text"). on("blur", function () { makeCode(); }). on("keydown", function (e) { if (e.keyCode == 13) { makeCode(); } });
HTML完整代碼
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko"> <head> <title>Javascript 二維碼生成庫:QRCode</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" /> <script type="text/javascript" src="http://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script> <script type="text/javascript" src="http://static.runoob.com/assets/qrcode/qrcode.min.js"></script> </head> <body> <input id="text" type="text" value="http://www.runoob.com" style="width:80%" /><br /> <div id="qrcode" style="width:100px; height:100px; margin-top:15px;"></div> <script type="text/javascript"> var qrcode = new QRCode(document.getElementById("qrcode"), { width : 100, height : 100 }); function makeCode () { var elText = document.getElementById("text"); if (!elText.value) { alert("Input a text"); elText.focus(); return; } qrcode.makeCode(elText.value); } makeCode(); $("#text"). on("blur", function () { makeCode(); }). on("keydown", function (e) { if (e.keyCode == 13) { makeCode(); } }); </script> </body> </html>