瀏覽代碼

no message

甘艺伟 2 周之前
當前提交
082d4d53ac
共有 100 個文件被更改,包括 11665 次插入0 次删除
  1. 24 0
      README.md
  2. 1202 0
      adminindex - 副本.js
  3. 1279 0
      adminindex.js
  4. 5 0
      a后端协议脚本.bat
  5. 18 0
      a后端接口脚本.bat
  6. 二進制
      excel/audio_音乐.xls
  7. 二進制
      excel/guide_引导.xls
  8. 二進制
      excel/help_帮助表.xls
  9. 二進制
      excel/item_道具.xls
  10. 二進制
      excel/kaiqi_功能开启.xls
  11. 二進制
      excel/languageClient_前端多语言.xls
  12. 二進制
      excel/languageSever_后端多语言.xls
  13. 二進制
      excel/language_多语言.xls
  14. 二進制
      excel/math_全局表.xls
  15. 二進制
      excel/name_角色名 .xlsx
  16. 二進制
      excel/package_打包.xls
  17. 二進制
      excel/pingbici_屏蔽词.xls
  18. 二進制
      excel/shop_商店.xls
  19. 1327 0
      index.js
  20. 1 0
      node_modules/.bin/acorn
  21. 1 0
      node_modules/.bin/apidoc
  22. 1 0
      node_modules/.bin/browserslist
  23. 1 0
      node_modules/.bin/crc32
  24. 1 0
      node_modules/.bin/envinfo
  25. 1 0
      node_modules/.bin/esbuild
  26. 1 0
      node_modules/.bin/flat
  27. 1 0
      node_modules/.bin/handlebars
  28. 1 0
      node_modules/.bin/import-local-fixture
  29. 1 0
      node_modules/.bin/json5
  30. 1 0
      node_modules/.bin/markdown-it
  31. 1 0
      node_modules/.bin/node-which
  32. 1 0
      node_modules/.bin/nodemon
  33. 1 0
      node_modules/.bin/nodetouch
  34. 1 0
      node_modules/.bin/nopt
  35. 1 0
      node_modules/.bin/resolve
  36. 1 0
      node_modules/.bin/semver
  37. 1 0
      node_modules/.bin/sshpk-conv
  38. 1 0
      node_modules/.bin/sshpk-sign
  39. 1 0
      node_modules/.bin/sshpk-verify
  40. 1 0
      node_modules/.bin/terser
  41. 1 0
      node_modules/.bin/uglifyjs
  42. 1 0
      node_modules/.bin/update-browserslist-db
  43. 1 0
      node_modules/.bin/uuid
  44. 1 0
      node_modules/.bin/webpack
  45. 1 0
      node_modules/.bin/webpack-cli
  46. 1 0
      node_modules/.bin/xlsx
  47. 2984 0
      node_modules/.package-lock.json
  48. 26 0
      node_modules/@colors/colors/LICENSE
  49. 219 0
      node_modules/@colors/colors/README.md
  50. 83 0
      node_modules/@colors/colors/examples/normal-usage.js
  51. 80 0
      node_modules/@colors/colors/examples/safe-string.js
  52. 184 0
      node_modules/@colors/colors/index.d.ts
  53. 211 0
      node_modules/@colors/colors/lib/colors.js
  54. 46 0
      node_modules/@colors/colors/lib/custom/trap.js
  55. 110 0
      node_modules/@colors/colors/lib/custom/zalgo.js
  56. 110 0
      node_modules/@colors/colors/lib/extendStringPrototype.js
  57. 13 0
      node_modules/@colors/colors/lib/index.js
  58. 10 0
      node_modules/@colors/colors/lib/maps/america.js
  59. 12 0
      node_modules/@colors/colors/lib/maps/rainbow.js
  60. 11 0
      node_modules/@colors/colors/lib/maps/random.js
  61. 5 0
      node_modules/@colors/colors/lib/maps/zebra.js
  62. 95 0
      node_modules/@colors/colors/lib/styles.js
  63. 35 0
      node_modules/@colors/colors/lib/system/has-flag.js
  64. 151 0
      node_modules/@colors/colors/lib/system/supports-colors.js
  65. 45 0
      node_modules/@colors/colors/package.json
  66. 64 0
      node_modules/@colors/colors/safe.d.ts
  67. 10 0
      node_modules/@colors/colors/safe.js
  68. 12 0
      node_modules/@colors/colors/themes/generic-logging.js
  69. 26 0
      node_modules/@dabh/diagnostics/CHANGELOG.md
  70. 20 0
      node_modules/@dabh/diagnostics/LICENSE
  71. 473 0
      node_modules/@dabh/diagnostics/README.md
  72. 11 0
      node_modules/@dabh/diagnostics/adapters/hash.js
  73. 18 0
      node_modules/@dabh/diagnostics/adapters/index.js
  74. 11 0
      node_modules/@dabh/diagnostics/adapters/localstorage.js
  75. 11 0
      node_modules/@dabh/diagnostics/adapters/process.env.js
  76. 35 0
      node_modules/@dabh/diagnostics/browser/development.js
  77. 8 0
      node_modules/@dabh/diagnostics/browser/index.js
  78. 6 0
      node_modules/@dabh/diagnostics/browser/override.js
  79. 24 0
      node_modules/@dabh/diagnostics/browser/production.js
  80. 212 0
      node_modules/@dabh/diagnostics/diagnostics.js
  81. 19 0
      node_modules/@dabh/diagnostics/logger/console.js
  82. 20 0
      node_modules/@dabh/diagnostics/modifiers/namespace-ansi.js
  83. 32 0
      node_modules/@dabh/diagnostics/modifiers/namespace.js
  84. 36 0
      node_modules/@dabh/diagnostics/node/development.js
  85. 8 0
      node_modules/@dabh/diagnostics/node/index.js
  86. 21 0
      node_modules/@dabh/diagnostics/node/override.js
  87. 24 0
      node_modules/@dabh/diagnostics/node/production.js
  88. 64 0
      node_modules/@dabh/diagnostics/package.json
  89. 21 0
      node_modules/@discoveryjs/json-ext/LICENSE
  90. 256 0
      node_modules/@discoveryjs/json-ext/README.md
  91. 791 0
      node_modules/@discoveryjs/json-ext/dist/json-ext.js
  92. 0 0
      node_modules/@discoveryjs/json-ext/dist/json-ext.min.js
  93. 1 0
      node_modules/@discoveryjs/json-ext/dist/version.js
  94. 31 0
      node_modules/@discoveryjs/json-ext/index.d.ts
  95. 56 0
      node_modules/@discoveryjs/json-ext/package.json
  96. 6 0
      node_modules/@discoveryjs/json-ext/src/index.js
  97. 384 0
      node_modules/@discoveryjs/json-ext/src/parse-chunked.js
  98. 231 0
      node_modules/@discoveryjs/json-ext/src/stringify-info.js
  99. 3 0
      node_modules/@discoveryjs/json-ext/src/stringify-stream-browser.js
  100. 408 0
      node_modules/@discoveryjs/json-ext/src/stringify-stream.js

+ 24 - 0
README.md

@@ -0,0 +1,24 @@
+# excel导出json并提供给typescript使用,带类型提示
+# by @yuanxiao
+# 基于@lanmianbao 的ts版配置文件读取模式制作
+# environment  node v10.6.0
+# 特别适用于前后端都用typescript开发的项目,前后端同时维护一份表,并舍弃各端不需要的数据
+# 表格配置需求:
+    第一行:描述
+    第二行:字段类型(string;number;boolean;自定义Object)
+    第三行:前端使用的数据索引
+    第四行:后端使用的数据索引
+    第五行&&之后:数据内容
+
+    表单开头带 【!】 的表示这是一个备注表,不会被解析
+    数据索引一栏 (前端第3行,后端第4行)
+        a:带 【*】 的表示以此字段为key,带 【**】 的表示以此字段为key,且是一个列表
+        b:索引中带【.】的代表切割符,表示需要以多字段取值,例如  rank.id  需要以 rank 和 id 取值
+# 使用方法:
+    >node index.js
+    >输入需要导出前端表(c)或后端表(s)
+
+# 备注:
+    typescript项目需要以来@type/node包才能使用require
+# 解析配置表-环境安装
+    >

+ 1202 - 0
adminindex - 副本.js

@@ -0,0 +1,1202 @@
+const path = require('./path.json');
+const readline = require('readline');
+var archiver = require('archiver');
+const fs = require('fs');
+const xl = require('xlsx');
+let excelDir = './excel'; // excel配置表目录
+let outDir = './out'; // 导出目录
+let outJsonFolder = 'excel'; // 导出的json目录
+//前端需要在load界面加载的表
+let loadJson = ["audioInfo","languageLang","languageText","mathInfo","packageInfo","userInfo"]
+
+//后端配置
+let serverPath = "./common/"
+let apiurl = "../zhetian_backend_kaifa/public/api/assets/main.bundle.js"
+
+// 前后端解析索引的行
+let hang = 3; // 前端3 后端4
+// 表格列表 example: ["iconopen","mainTask"]
+let excelFiles = [];
+// 表名 +分表名
+let excelFen = [];
+// 表格与表单的数据类型 example:{iconopen:{id:string}}
+let excelAndSheets = {};
+var s_xls = require('./s_xls');
+
+// 检测传入的参数
+var args = process.argv.splice(2)
+var jiexiTarget = args[0] || "" // s:后端 c:前端
+// console.log("检测传入的参数:", jiexiTarget)
+
+function exeExcelConfig_c() {
+	let str = '';
+
+	// 添加类型定义
+	excelFiles.forEach((excelName) => {
+		str += `// type for ${excelName}.excel\n`;
+		for (const sheetName in excelAndSheets[excelName]) {
+			str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
+
+			//遍历索引存入类型定义
+			let keyObjList = excelAndSheets[excelName][sheetName];
+			for (const key in keyObjList) {
+				str += `${key.split(',')[0]}:${keyObjList[key].value},`;
+			}
+			// 去掉最后一个逗号 ","
+			if (str.charAt(str.length - 1) == ',') {
+				str = str.substring(0, str.length - 1);
+			}
+			str += '}';
+			str += '\n';
+		}
+	});
+	str += '\n';
+
+	//导出
+	str += `export class XlsConfig {\n`;
+	excelFen.forEach((element) => {
+		str += `    xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
+	});
+	// str += `    constructor(callback: Function) {\n`
+
+	// let str111 = [];
+	// excelFen.forEach((element) => {
+	// 	str111.push('"' + element + '"');
+	// });
+
+	// str += `    }\n`
+
+	str += `
+    constructor(bundleName:string, callback: Function) {
+        cc.assetManager.loadBundle(bundleName, (err, bundle) => {
+            bundle.loadDir("", (err2, assets: cc.JsonAsset[]) => {
+                assets.forEach(element => {
+                    this["xls" + this.firstUpCase(element.name)] = element.json
+                });
+                callback(this)
+            })
+        })
+    }
+    // 首字母大写
+    private firstUpCase(str: string) {
+        return str[0].toUpperCase() + str.substring(1)
+    }
+}`;
+
+	if (hang == 3) {
+		outDir = path.configPath;
+	} else {
+		outDir = serverPath;
+	}
+	// 写入文件
+	let outPath = `${outDir}xlsConfig.ts`;
+	fs.writeFile(outPath, str, function (err) {
+		if (err) {
+			console.log('xlsConfig写入失败:', err);
+		}
+	});
+
+	let pro = '';
+	if (hang == 4) {
+		pro += 'import { CTX } from "../src/util/master";\n';
+	}
+
+	pro += `export default class ConfProxy<T> {
+    static getKey(args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += element
+            out += "_"
+        });
+        return out
+    }
+    static setKey(target: any, args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += target[element]
+            out += "_"
+        });
+        return out
+    }
+    pool: { [key: string]: T } = {}
+    constructor(conf: T[], ...args: string[]) {
+        conf.forEach(element => {
+            this.pool[ConfProxy.setKey(element, args)] = element
+        });
+    }
+    
+    getItem(...args: string[]): T | null {
+        return this.pool[ConfProxy.getKey(args)]
+    }`;
+
+	if (hang == 4) {
+		pro += `
+        
+    getItemCtx(ctx:CTX,...args: string[]): T {
+        let back = this.pool[ConfProxy.getKey(args)]
+        if(back == null){
+            console.error("配置错误"+args,this.pool)
+            ctx.throw("配置错误"+args)
+        }
+        return back
+    }
+        `;
+	}
+
+	pro += `
+
+}
+export class ConfListProxy<T> {
+    pool: { [key: string]: T[] } = {}
+    constructor(conf: T[], ...args: string[]) {
+        conf.forEach(element => {
+            let key = ConfProxy.setKey(element, args)
+            if (this.pool[key] == null) {
+                this.pool[key] = []
+            }
+            this.pool[key].push(element)
+        });
+    }
+    getItemList(...args: string[]): T[] | null {
+        return this.pool[ConfProxy.getKey(args)]
+    }
+}`;
+
+	pro += '\n';
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}confProxy.ts`;
+	} else {
+		proPath = serverPath + `confProxy.ts`;
+	}
+
+	fs.writeFile(proPath, pro, function (err) {
+		if (err) {
+			console.log('ConfProxy写入失败:', err);
+		}
+	});
+}
+
+function exeExcelConfig() {
+	let str = '';
+
+	// 引入ts文件
+	excelFen.forEach((element) => {
+		str += `const  ${element}  = require( "./excel/${element}.json")\n`;
+	});
+	str += '\n';
+
+	// 添加类型定义
+	excelFiles.forEach((excelName) => {
+		str += `// type for ${excelName}.excel\n`;
+		for (const sheetName in excelAndSheets[excelName]) {
+			str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
+
+			//遍历索引存入类型定义
+			let keyObjList = excelAndSheets[excelName][sheetName];
+			for (const key in keyObjList) {
+				str += `${key.split(',')[0]}:${keyObjList[key].value},`;
+			}
+			// 去掉最后一个逗号 ","
+			if (str.charAt(str.length - 1) == ',') {
+				str = str.substring(0, str.length - 1);
+			}
+			str += '}';
+			str += '\n';
+		}
+	});
+	str += '\n';
+
+	//导出
+	str += `export class XlsConfig {\n`;
+	excelFen.forEach((element) => {
+		str += `    xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
+	});
+	str += `    constructor() {\n`;
+	excelFen.forEach((element) => {
+		str += `        this.xls${toUpperCaseByStr(element)} = <xls${toUpperCaseByStr(element)}[]>${element}\n`;
+	});
+
+	str += `    }\n`;
+	str += '}\n';
+
+	if (hang == 3) {
+		outDir = path.configPath;
+	} else {
+		outDir = serverPath
+	}
+	// 写入文件
+	let outPath = `${outDir}xlsConfig.ts`;
+	fs.writeFile(outPath, str, function (err) {
+		if (err) {
+			console.log('xlsConfig写入失败:', err);
+		}
+	});
+
+	let pro = '';
+	if (hang == 4) {
+		pro += 'import { CTX } from "../src/util/master";\n';
+	}
+
+	pro += `export default class ConfProxy<T> {
+    static getKey(args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += element
+            out += "_"
+        });
+        return out
+    }
+    static setKey(target: any, args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += target[element]
+            out += "_"
+        });
+        return out
+    }
+    pool: { [key: string]: T } = {}
+    constructor(conf: T[], ...args: string[]) {
+        conf.forEach(element => {
+            this.pool[ConfProxy.setKey(element, args)] = element
+        });
+    }
+    
+    getItem(...args: string[]): T | null {
+        return this.pool[ConfProxy.getKey(args)]
+    }`;
+
+	if (hang == 4) {
+		pro += `
+        
+    getItemCtx(ctx:CTX,...args: string[]): T {
+        let back = this.pool[ConfProxy.getKey(args)]
+        if(back == null){
+            console.error("配置错误"+args,this.pool)
+            ctx.throw("配置错误"+args)
+        }
+        return back
+    }
+        `;
+	}
+
+	pro += `
+
+}
+export class ConfListProxy<T> {
+    pool: { [key: string]: T[] } = {}
+    constructor(conf: T[], ...args: string[]) {
+        conf.forEach(element => {
+            let key = ConfProxy.setKey(element, args)
+            if (this.pool[key] == null) {
+                this.pool[key] = []
+            }
+            this.pool[key].push(element)
+        });
+    }
+    getItemList(...args: string[]): T[] | null {
+        return this.pool[ConfProxy.getKey(args)]
+	}`;
+
+	if (hang == 4) {
+		pro += `
+        
+	getItemListCtx(ctx:CTX,...args: string[]): T[] {
+        let back = this.pool[ConfProxy.getKey(args)]
+        if(back == null){
+            console.error("list配置错误"+args,this.pool)
+            ctx.throw("list配置错误"+args)
+        }
+        return back
+    }
+        `;
+	}
+
+	pro += `
+}
+`
+
+
+	pro += '\n';
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}confProxy.ts`;
+	} else {
+		proPath = serverPath + `confProxy.ts`;
+	}
+
+	fs.writeFile(proPath, pro, function (err) {
+		if (err) {
+			console.log('ConfProxy写入失败:', err);
+		}
+	});
+}
+
+// 字符串开头变为大写
+function toUpperCaseByStr(txt) {
+	return txt.slice(0, 1).toUpperCase() + txt.slice(1);
+}
+
+// 分析配置表
+function doExcel(excel) {
+	let excelName = excel.split('_')[0];
+	if(s_xls.XlsBack[excelName] == null ){
+		return
+	}
+	let fileDir = `${excelDir}/${excel}`;
+	let workbook = xl.readFile(fileDir);
+	// 获取 Excel 中所有表名
+	const sheetNames = workbook.SheetNames; // 返回 ['sheet1', 'sheet2']
+	let _sheetNames = [];
+	for (const element of sheetNames) {
+		if(s_xls.XlsBack[excelName][element] == null){
+			continue
+		}
+		_sheetNames.push(element);
+	}
+	if (_sheetNames.length == 0) {
+		return;
+	}
+	console.log('...start excel ' + excel);
+	// 加到【excelAndSheets】中
+	let obj = {};
+	excelAndSheets[excelName] = {};
+	_sheetNames.forEach((sheetName) => {
+		let sheet = workbook.Sheets[sheetName];
+		excelAndSheets[excelName][sheetName] = {};
+		doSheet(obj, excelName, sheetName, sheet);
+	});
+
+	let outDir1 = ""
+	let outDir2 = ""
+	if (hang == 3) {
+		outDir1 = `${path.jsonPath}`;
+		if (!fs.existsSync(outDir1)) {
+			fs.mkdirSync(outDir1)
+		}
+		outDir2 = `${path.loadJsonPath}`;
+		if (!fs.existsSync(outDir2)) {
+			fs.mkdirSync(outDir2)
+		}
+	} else {
+		outDir1 = serverPath + `${outJsonFolder}`;
+		if (!fs.existsSync(outDir1)) {
+			fs.mkdirSync(outDir1)
+		}
+	}
+	for (const key in obj) {
+		let jsonStr = `${geshihua(obj[key])}`;
+		if (hang == 3 && key == "languageText") {
+			//程序翻译文本暂时不需要通过excel转,避免冲突
+			continue
+		}
+		if (outDir2 != "" && loadJson.indexOf(key) >= 0) {
+			fs.writeFile(`${outDir2}/${key}.json`, jsonStr, function (err) {
+				if (err) {
+					console.log(err);
+				}
+			});
+		} else {
+			fs.writeFile(`${outDir1}/${key}.json`, jsonStr, function (err) {
+				if (err) {
+					console.log(err);
+				}
+			});
+		}
+	}
+}
+
+function geshihua(data) {
+	let count = 1;
+	let _data = '[\n';
+	for (const val of data) {
+		if (count == 1) {
+			_data += '  ' + JSON.stringify(val);
+		} else {
+			_data += `,\n`;
+			_data += '  ' + JSON.stringify(val);
+		}
+		count++;
+	}
+	_data += '\n]';
+	return _data;
+}
+
+//分析表单  obj数据,表名,表单名,表单数据内容
+function doSheet(obj, excelName, sheetName, sheet) {
+	let newKey = excelName + toUpperCaseByStr(sheetName);
+	excelFen.push(newKey);
+	if (obj[newKey] == null) {
+		obj[newKey] = [];
+	}
+
+	// 索引列表  example:{A:"",B:"id",C:"hp",D:"attack"}
+	let keyList = {};
+	// 类型列表 example:{A:"number",B:"string",C:"boolean",D:"{}[]"}
+	let typeList = {};
+	//备注
+	let psList = {};
+
+	let _tempObj = {};
+	for (const key in sheet) {
+		// 单元格定位id example: A25
+		const sheetKey = sheet[key];
+		// A25->25
+		let _hang = key.replace(/[^0-9]+/gi, '');
+		// A25->A
+		let _lie = key.replace(/[^A-Z]+/gi, '');
+		if (_lie == 'A') {
+			if (Object.keys(_tempObj).length > 0) {
+				//这边检测是否有放空配置的。如果有 , 补上默认类型
+				let _tempObj_1 = {};
+				for (const key in keyList) {
+					if (_tempObj[keyList[key]] == null) {
+						if (typeList[key] == 'number') {
+							_tempObj_1[keyList[key]] = 0;
+						} else if (typeList[key] == 'string') {
+							_tempObj_1[keyList[key]] = '';
+						} else if (typeList[key] == 'boolean') {
+							_tempObj_1[keyList[key]] = false;
+						} else if (typeList[key].indexOf('[]') != -1) {
+							_tempObj_1[keyList[key]] = null;
+						} else if (typeList[key].substring(0, 0 + 1) == '{') {
+							_tempObj_1[keyList[key]] = null;
+						} else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
+							_tempObj_1[keyList[key]] = null;
+						} else {
+							console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
+						}
+					} else {
+						_tempObj_1[keyList[key]] = _tempObj[keyList[key]];
+					}
+				}
+
+				obj[newKey].push(_tempObj_1);
+				_tempObj = {};
+			}
+		}
+		if (sheet['A' + _hang] == null) {
+			// 第一列没有配置参数,就跳过
+			continue;
+		}
+		if (_hang == 1) {
+			psList[_lie] = sheetKey.v;
+		}
+		// 储存类型
+		if (_hang == 2) {
+			typeList[_lie] = sheetKey.v;
+		}
+		// 储存索引
+		if (_hang == hang && sheetKey.v && typeList[_lie]) {
+			// 正则抽取真正的值(去掉所有的*)
+			let realVal = sheetKey.v.replace(/[\*]/g, '');
+			// 判断下作为key的字段
+			let isKey = 0; // 0:不是key,1:单key,2:列表key
+			if (sheetKey.v.slice(0, 2) == '**') {
+				isKey = 2;
+			} else if (sheetKey.v.slice(0, 1) == '*') {
+				isKey = 1;
+			}
+			keyList[_lie] = realVal.split(',')[0].trim();
+			// id:string
+			excelAndSheets[excelName][sheetName][keyList[_lie]] = {
+				ps: psList[_lie],
+				isKey: isKey,
+				value: typeList[_lie],
+				keys: realVal
+			};
+		}
+		// 储存数据
+		if (_hang >= 5 && keyList[_lie] != null && typeList[_lie] != null) {
+			// 根据类型转化数据内容,在做储存处理
+			let _val;
+			if (typeList[_lie] == 'number') {
+				if (typeof sheetKey.v != 'number') {
+					_val = Number(sheetKey.v);
+					if (isNaN(_val)) {
+						console.log(
+							'\x1b[33m%s\x1b[0m',
+							'警告,出现NaN数据类型,表名:' +
+							excelName +
+							' 表单:' +
+							sheetName +
+							' 索引:' +
+							keyList[_lie] +
+							' 表格ID:' +
+							key
+						);
+					}
+					_val = 0;
+				} else {
+					_val = sheetKey.v;
+				}
+			} else if (typeList[_lie] == 'boolean') {
+				if (sheetKey.v == 'true' || sheetKey.v == 'TRUE' || sheetKey.v == true) {
+					_val = true;
+				} else {
+					_val = false;
+				}
+			} else if (typeList[_lie][0] == '{' || typeList[_lie].slice(-1) == ']') {
+				try {
+					_val = JSON.parse(sheetKey.v);
+				} catch (error) {
+					console.log(
+						'\x1b[33m%s\x1b[0m',
+						'警告:json格式错误,表名:' + excelName + ' 表单:' + sheetName + ' 索引:' + keyList[_lie] + ' 表格ID:' + key
+					);
+				}
+			} else if (typeList[_lie] == 'string') {
+				if (typeof sheetKey.v == 'number') {
+					_val = Math.floor(sheetKey.v).toString();
+				} else {
+					_val = sheetKey.v;
+				}
+			} else {
+				_val = sheetKey.v;
+			}
+
+			_tempObj[keyList[_lie].trim()] = _val;
+		}
+	}
+
+	//这边检测是否有放空配置的。如果有 , 补上默认类型
+	let _tempObj_1 = {};
+	for (const key in keyList) {
+		if (_tempObj[keyList[key]] == null) {
+			if (typeList[key] == 'number') {
+				_tempObj_1[keyList[key]] = 0;
+			} else if (typeList[key] == 'string') {
+				_tempObj_1[keyList[key]] = '';
+			} else if (typeList[key] == 'boolean') {
+				_tempObj_1[keyList[key]] = false;
+			} else if (typeList[key].indexOf('[]') != -1) {
+				_tempObj_1[keyList[key]] = null;
+			} else if (typeList[key].substring(0, 0 + 1) == '{') {
+				_tempObj_1[keyList[key]] = null;
+			} else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
+				_tempObj_1[keyList[key]] = null;
+			} else {
+				console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
+			}
+		} else {
+			_tempObj_1[keyList[key]] = _tempObj[keyList[key]];
+		}
+	}
+
+	// 储存最后一个
+	obj[newKey].push(_tempObj_1);
+}
+
+// //--------------------start-------------------  控制台人机交互
+function readSyncByRl(tips) {
+	tips = tips || '> ';
+
+	return new Promise((resolve) => {
+		const rl = readline.createInterface({
+			input: process.stdin,
+			output: process.stdout
+		});
+
+		rl.question(tips, (answer) => {
+			rl.close();
+			resolve(answer.trim());
+		});
+	});
+}
+
+/**
+ * 后端创建xls对应gameCfg完成脚本
+ */
+function createGameCfg_s() {
+	let strs = '';
+	strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
+
+	let strHead = `XlsConfig`;
+	let count = 2;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
+			count++;
+			if (count % 9 == 0) {
+				strHead += `\n`;
+			}
+		}
+	}
+	strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
+	strs += `export default class Gamecfg {\n`;
+	strs += `    static init() {\n`;
+	strs += `       let xls = new XlsConfig()\n`;
+
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				let cs = ``;
+				for (let index = 1; index < val.length; index++) {
+					cs += `,"${val[index]}"`;
+				}
+				if (val[0] == 'ConfProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(key2)} = new ${val[0]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(key2)}List = new ${val[0]}(xls.xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				let cs1 = ``;
+				for (let index = 2; index < val.length; index++) {
+					cs1 += `,"${val[index]}"`;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(val[0])} = new ${val[1]}(xls.xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)}List = new ${val[1]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+			}
+		}
+	}
+
+
+	strs += `	}\n`;
+
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+
+				if (val[0] == 'ConfProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(key2)} : ${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)} >\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(key2)}List : ${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(val[0])} : ${val[1]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(
+						val[0]
+					)}List : ${val[1]}<xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `}\n`;
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}gameCfg.ts`;
+	} else {
+		proPath = serverPath + `gameCfg.ts`;
+	}
+
+	fs.writeFile(proPath, strs, function (err) {
+		if (err) {
+			console.log('gameCfg写入失败:', err);
+		}
+	});
+}
+
+/**
+ * 前端创建xls对应gameCfg完成脚本
+ */
+function createGameCfg_c() {
+	let strs = '';
+	strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
+
+	let strHead = `XlsConfig`;
+	let count = 2;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				console.log('=======过滤========', key1, key2);
+				continue;
+			}
+			strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
+			count++;
+			if (count % 9 == 0) {
+				strHead += `\n`;
+			}
+		}
+	}
+	strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
+	strs += `export default class Gamecfg {\n`;
+
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				if (val[0] == 'ConfProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(key2)}:${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(key2)}List:${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(val[0])}:${val[1]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				//别名
+				if (val[1] == 'ConfListProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(val[0])}List:${val[1]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `\n`;
+	strs += `    static initLoading(loadSuccess: Function) {\n`;
+	strs += `       try {\n`;
+	strs += `           new XlsConfig("loadJson",(xls: XlsConfig) => {\n`;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			let jsonName = key1+toUpperCaseByStr(key2)
+			if (loadJson.indexOf(jsonName) < 0) {
+				continue
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				let cs = ``;
+				for (let index = 1; index < val.length; index++) {
+					cs += `,"${val[index]}"`;
+				}
+				if (val[0] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)} = new ${val[0]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)}List = new ${val[0]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				let cs1 = ``;
+				for (let index = 2; index < val.length; index++) {
+					cs1 += `,"${val[index]}"`;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)} = new ${val[1]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)}List = new ${val[1]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `
+				loadSuccess(true)
+			})
+		} catch (error) {
+			loadSuccess(false)
+		}
+	}`;
+	strs += `\n`;
+	strs += `    static init(loadSuccess: Function) {\n`;
+	strs += `       try {\n`;
+	strs += `           new XlsConfig("pzwj",(xls: XlsConfig) => {\n`;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			let jsonName = key1+toUpperCaseByStr(key2)
+			if (loadJson.indexOf(jsonName) >= 0) {
+				continue
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				let cs = ``;
+				for (let index = 1; index < val.length; index++) {
+					cs += `,"${val[index]}"`;
+				}
+				if (val[0] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)} = new ${val[0]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)}List = new ${val[0]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				let cs1 = ``;
+				for (let index = 2; index < val.length; index++) {
+					cs1 += `,"${val[index]}"`;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)} = new ${val[1]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)}List = new ${val[1]}(xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `
+                loadSuccess(true)
+            })
+        } catch (error) {
+            loadSuccess(false)
+        }
+    }
+}`;
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}gameCfg.ts`;
+	} else {
+		proPath = serverPath + `gameCfg.ts`;
+	}
+
+	fs.writeFile(proPath, strs, function (err) {
+		if (err) {
+			console.log('gameCfg写入失败:', err);
+		}
+	});
+}
+
+function createXyc() {
+	const body = fs.readFileSync(apiurl,"utf-8");
+	let arr = body.split('/a/apidoc"}]},')
+
+	arr[1] = '[' + arr[1]
+	let arr1 = arr[1].split('}];const');
+	let str2 = arr1[0].replace(/!1/g, '0') + '}]';
+	let apidoc = `//所有接口定义\n`
+	apidoc += `export let apidoc:{[key:string]:string} = {\n`
+
+	try {
+		let strc = '';
+		var jsons = eval('(' + str2 + ')');
+
+		for (const json of jsons) {
+			let jsontitle = json.url.split('/');
+			let title = toUpperCaseByStr(jsontitle[1]) + toUpperCaseByStr(jsontitle[2]);
+			let jsonUrl = json.url.slice(1);
+
+			strc += `//${json.name}\n`;
+			strc += `export class ${title}\n`;
+			strc += `{\n`;
+			strc += `    static url:string = "${jsonUrl}"\n`;
+			strc += `}\n`;
+			strc += `export interface ${title}Pram{\n`;
+
+			apidoc += `    "/${jsonUrl}":"${json.name}",\n`
+
+			let _Parameter = [];
+			let hasUuid = 0;
+			let hasToken = 0;
+			if(json.parameter != null){
+				for (const Parameter of json.parameter.fields.Parameter) {
+					let description = Parameter.description;
+					let arr11 = description.split('<p>');
+					let arr12 = arr11[1].split('</p>');
+	
+					let _type = Parameter.type;
+					_Parameter.push({
+						type: _type,
+						field: Parameter.field,
+						description: arr12[0]
+					});
+					if (Parameter.field == 'uuid') {
+						hasUuid = 1;
+					}
+					if (Parameter.field == 'token') {
+						hasToken = 1;
+					}
+				}
+			}
+			for (const _rameter of _Parameter) {
+				if (hasUuid == 1 && hasToken == 1) {
+					if (_rameter.field == 'uuid' || _rameter.field == 'token') {
+						continue;
+					}
+				}
+				strc += `	${_rameter.field}:${_rameter.type} //${_rameter.description}\n`;
+			}
+			strc += `}\n\n`;
+		}
+
+		apidoc += `}`
+
+		if (hang == 3) {
+			outDir = path.configPath;
+		} else {
+			outDir = serverPath
+		}
+
+		strc += `
+//前端返回的特殊事件
+export interface keyValue{
+[key:string]:number
+}
+export interface keyValues{
+    [key:string]:number[]
+}
+export type ZixuanSelectCs = [string,string,number];
+export type Wxmspinzhi = [number,number]
+export type Wxmskeys = [number,string,string];
+export type Wxmslm = [number,string];
+`
+		let proPath = `${outDir}Xyc.ts`;
+		fs.writeFileSync(proPath, strc, function (err) {
+			if (err) {
+				console.log('Xyc写入失败:', err);
+			}
+		});
+
+		let proPath1 = `${outDir}apidoc.ts`;
+		fs.writeFileSync(proPath1, apidoc, function (err) {
+			if (err) {
+				console.log('Xyc写入失败:', err);
+			}
+		});
+
+
+
+	} catch (error) {
+		console.log('===', error);
+	}
+
+}
+
+//拷贝  s_to_proto
+function copy_s_to_proto() {
+	fs.copyFile(serverPath+'Xys.ts', './s_to_proto/Xys.ts', (err) => {
+		console.log('=', err);
+	});
+	fs.copyFile(serverPath+'Xyc.ts', './s_to_proto/Xyc.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile(serverPath+'gameMethod.ts', './s_to_proto/gameMethod.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile(serverPath+'fight.ts', './s_to_proto/fight.ts', (err) => {
+		console.log('=', err);
+	});
+}
+
+//拷贝  proto
+function copy_proto_to_c() {
+	outDir = path.configPath;
+	fs.copyFile('./s_to_proto/Xys.ts', outDir + 'Xys.ts', (err) => {
+		console.log('=', err);
+	});
+	fs.copyFile('./s_to_proto/Xyc.ts', outDir + 'Xyc.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile('./s_to_proto/gameMethod.ts', outDir + 'gameMethod.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile('./s_to_proto/fight.ts', outDir + 'fight.ts', (err) => {
+		console.log('=', err);
+	});
+}
+
+function createZip() {
+	const output = fs.createWriteStream(path.excelPath + outJsonFolder + '/excel.zip');
+	const archive = archiver('zip', {
+		zlib: {
+			level: 9 // 设置压缩等级
+		}
+	});
+	archive.pipe(output);
+
+
+	let files = fs.readdirSync(path.jsonPath)
+
+	for (const file of files) {
+		if (file.indexOf('json.meta') != -1) {
+			continue
+		}
+		archive.append(fs.createReadStream(path.jsonPath + file), { 'name': file });
+	}
+
+	archive.finalize(); // 完成压缩
+	archive.on('end', () => {
+		// 压缩结束时触发
+		console.log('压缩完成');
+	});
+}
+
+/**
+ * 延迟多少毫秒
+ */
+function sleep(ms) {
+	if (ms < 1) {
+		return;
+	}
+	return new Promise((reslove, reject) => {
+		setTimeout(() => {
+			reslove(1);
+		}, ms);
+	});
+}
+
+// 开始解析配置表
+function doExe(res) {
+	// console.log(res);
+	if (res != 'c' && res != 's' && res != 'C' && res != 'S') {
+		console.log('非法输入');
+		return;
+	}
+	if (res == 'c' || res == 'C') {
+		hang = 3;
+	} else {
+		hang = 4;
+	}
+
+	if (hang == 3) {
+		outDir = path.configPath;
+	} else {
+		outDir = serverPath;
+	}
+
+	console.log('\x1b[37m'); // 控制台文字切为白色
+
+
+
+	if (hang == 4) {
+
+		fs.rmdir(serverPath + outJsonFolder, { recursive: true }, (err, data) => {
+			if (err) {
+				console.log('删除json文件失败' + err);
+			}
+			console.log('删除json文件成功');
+			// 解析表格
+			fs.readdirSync(excelDir).forEach((excelName) => {
+				if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
+					excelFiles.push(excelName.split('_')[0]);
+					doExcel(excelName);
+				}
+			});
+			
+		});
+	}
+
+
+
+	if (hang == 3) {
+
+		fs.unlink(path.excelPath + outJsonFolder + '/excel.zip', (err, data) => {
+			if (err) {
+				console.log('删除zip文件失败' + err);
+			}
+			console.log('删除zip文件成功');
+
+			// 解析表格
+			fs.readdirSync(excelDir).forEach((excelName) => {
+				if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
+					excelFiles.push(excelName.split('_')[0]);
+					doExcel(excelName);
+				}
+			});
+
+			// 生成配置表读取文件(ts)
+			exeExcelConfig_c();
+			console.log('*******创建配置文件完成*******');
+
+			// createXyc();
+			// console.log('*******创建xyc完成*******');
+
+			createGameCfg_c();
+			console.log('*******创建xls对应gameCfg完成*******');
+
+			copy_proto_to_c();
+			console.log('*******拷贝完成*******');
+
+			console.log("----全部完成----")
+		});
+
+
+	}
+	sleep(4000);
+
+	// if (hang == 3) {
+	//
+	// }
+}
+
+
+
+
+
+if (jiexiTarget == "s" || jiexiTarget == "c") {
+	doExe(jiexiTarget)
+} else {
+	readSyncByRl('exe client->c or server->s:').then((res) => {
+		doExe(res)
+	});
+}
+
+// //---------------------end--------------------  控制台人机交互

+ 1279 - 0
adminindex.js

@@ -0,0 +1,1279 @@
+const path = require('./path.json');
+const readline = require('readline');
+
+const fs = require('fs');
+const xl = require('xlsx');
+let excelDir = './excel'; // excel配置表目录
+let outDir = './out'; // 导出目录
+let outJsonFolder = 'excel'; // 导出的json目录
+//前端需要在load界面加载的表
+let loadJson = ["audioInfo", "languageLang", "languageClientText", "mathInfo", "packageInfo"]
+
+const cluster = require('cluster');
+
+//后端配置
+let serverPath = "./common/"
+let apiurl = "../zhetian_backend_kaifa/public/api/assets/main.bundle.js"
+
+// 前后端解析索引的行
+let hang = 3; // 前端3 后端4
+// 表格列表 example: ["iconopen","mainTask"]
+let excelFiles = [];
+// 表名 +分表名
+let excelFen = [];
+// 表格与表单的数据类型 example:{iconopen:{id:string}}
+let excelAndSheets = {};
+var s_xls = require('./s_xls');
+const { exit } = require('process');
+
+// 检测传入的参数
+var args = process.argv.splice(2)
+var jiexiTarget = args[0] || "" // s:后端 c:前端
+
+function exeExcelConfig_c() {
+	let str = '';
+	str += `import GameController from "../GameController"\nimport { gameMethod } from "./gameMethod"\n`
+	// 添加类型定义
+	excelFiles.forEach((excelName) => {
+		str += `// type for ${excelName}.excel\n`;
+		for (const sheetName in excelAndSheets[excelName]) {
+			str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
+
+			//遍历索引存入类型定义
+			let keyObjList = excelAndSheets[excelName][sheetName];
+			for (const key in keyObjList) {
+				str += `${key.split(',')[0]}:${keyObjList[key].value},`;
+			}
+			// 去掉最后一个逗号 ","
+			if (str.charAt(str.length - 1) == ',') {
+				str = str.substring(0, str.length - 1);
+			}
+			str += '}';
+			str += '\n';
+		}
+	});
+	str += '\n';
+
+	//导出
+	str += `export class XlsConfig {\n`;
+	excelFen.forEach((element) => {
+		str += `    xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
+	});
+	// str += `    constructor(callback: Function) {\n`
+
+	// let str111 = [];
+	// excelFen.forEach((element) => {
+	// 	str111.push('"' + element + '"');
+	// });
+
+	// str += `    }\n`
+
+	str += `
+    constructor(bundleName:string, callback: Function) {
+        cc.assetManager.loadBundle(bundleName, (err, bundle) => {
+			if (err) {
+                GameController.clear()
+                cc.game.restart()
+                return
+            }
+            if (gameMethod.isEmpty(bundle) && cc.sys.platform == cc.sys.WECHAT_GAME) {
+                //小游戏平台,缓存过期,自动清理缓存,重启游戏
+				console.error("加载配置表的bundle失败,清理缓存重新加载")
+                cc.assetManager.cacheManager.clearCache()
+                GameController.clear()
+                cc.game.restart()
+                return
+            }
+            bundle.loadDir("", (err2, assets: cc.JsonAsset[]) => {
+				if (err2) {
+					GameController.clear()
+                    cc.game.restart()
+				    return
+				}
+                assets.forEach(element => {
+                    this["xls" + this.firstUpCase(element.name)] = element.json
+                });
+                callback(this)
+            })
+        })
+    }
+    // 首字母大写
+    private firstUpCase(str: string) {
+        return str[0].toUpperCase() + str.substring(1)
+    }
+}`;
+
+	if (hang == 3) {
+		outDir = path.configPath;
+	} else {
+		outDir = serverPath;
+	}
+	// 写入文件
+	let outPath = `${outDir}xlsConfig.ts`;
+	fs.writeFile(outPath, str, function (err) {
+		if (err) {
+			console.log('xlsConfig写入失败:', err);
+		}
+	});
+
+	let pro = '';
+	if (hang == 4) {
+		pro += 'import { CTX } from "../src/util/master";\n';
+	}
+
+	pro += `export default class ConfProxy<T> {
+    static getKey(args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += element
+            out += "_"
+        });
+        return out
+    }
+    static setKey(target: any, args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += target[element]
+            out += "_"
+        });
+        return out
+    }
+    pool: { [key: string]: T } = {}
+	name:string = ""
+    constructor(xlsname:string,conf: T[], ...args: string[]) {
+		this.name = xlsname
+        conf.forEach(element => {
+            this.pool[ConfProxy.setKey(element, args)] = element
+        });
+    }
+    
+    getItem(...args: string[]): T | null {
+        return this.pool[ConfProxy.getKey(args)]
+    }`;
+
+	if (hang == 4) {
+		pro += `
+        
+    getItemCtx(ctx:CTX,...args: string[]): T {
+        let back = this.pool[ConfProxy.getKey(args)]
+        if(back == null){
+            console.error("配置错误"+args,this.name)
+            ctx.throw("配置错误"+args)
+        }
+        return back
+    }
+        `;
+	}
+
+	pro += `
+
+}
+export class ConfListProxy<T> {
+    pool: { [key: string]: T[] } = {}
+	name:string = ""
+    constructor(xlsname:string,conf: T[], ...args: string[]) {
+		this.name = xlsname
+        conf.forEach(element => {
+            let key = ConfProxy.setKey(element, args)
+            if (this.pool[key] == null) {
+                this.pool[key] = []
+            }
+            this.pool[key].push(element)
+        });
+    }
+    getItemList(...args: string[]): T[] | null {
+        return this.pool[ConfProxy.getKey(args)]
+    }
+}`;
+
+	pro += '\n';
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}confProxy.ts`;
+	} else {
+		proPath = serverPath + `confProxy.ts`;
+	}
+
+	fs.writeFile(proPath, pro, function (err) {
+		if (err) {
+			console.log('ConfProxy写入失败:', err);
+		}
+	});
+}
+
+function exeExcelConfig() {
+	let str = '';
+
+	// 引入ts文件
+	excelFen.forEach((element) => {
+		str += `const  ${element}  = require( "./excel/${element}.json")\n`;
+	});
+	str += '\n';
+
+	// 添加类型定义
+	excelFiles.forEach((excelName) => {
+		str += `// type for ${excelName}.excel\n`;
+		for (const sheetName in excelAndSheets[excelName]) {
+			str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
+
+			//遍历索引存入类型定义
+			let keyObjList = excelAndSheets[excelName][sheetName];
+			for (const key in keyObjList) {
+				str += `${key.split(',')[0]}:${keyObjList[key].value},`;
+			}
+			// 去掉最后一个逗号 ","
+			if (str.charAt(str.length - 1) == ',') {
+				str = str.substring(0, str.length - 1);
+			}
+			str += '}';
+			str += '\n';
+		}
+	});
+	str += '\n';
+
+	//导出
+	str += `export class XlsConfig {\n`;
+	excelFen.forEach((element) => {
+		str += `    xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
+	});
+	str += `    constructor() {\n`;
+	excelFen.forEach((element) => {
+		str += `        this.xls${toUpperCaseByStr(element)} = <xls${toUpperCaseByStr(element)}[]>${element}\n`;
+	});
+
+	str += `    }\n`;
+	str += '}\n';
+
+	if (hang == 3) {
+		outDir = path.configPath;
+	} else {
+		outDir = serverPath
+	}
+	// 写入文件
+	let outPath = `${outDir}xlsConfig.ts`;
+	fs.writeFile(outPath, str, function (err) {
+		if (err) {
+			console.log('xlsConfig写入失败:', err);
+		}
+	});
+
+	let pro = '';
+	if (hang == 4) {
+		pro += 'import { CTX } from "../src/util/master";\n';
+	}
+
+	pro += `export default class ConfProxy<T> {
+    static getKey(args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += element
+            out += "_"
+        });
+        return out
+    }
+    static setKey(target: any, args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += target[element]
+            out += "_"
+        });
+        return out
+    }
+    pool: { [key: string]: T } = {}
+	name:string = ""
+    constructor(xlsname:string,conf: T[], ...args: string[]) {
+		this.name = xlsname
+        conf.forEach(element => {
+            this.pool[ConfProxy.setKey(element, args)] = element
+        });
+    }
+    
+    getItem(...args: string[]): T | null {
+        return this.pool[ConfProxy.getKey(args)]
+    }`;
+
+	if (hang == 4) {
+		pro += `
+        
+    getItemCtx(ctx:CTX,...args: string[]): T {
+        let back = this.pool[ConfProxy.getKey(args)]
+        if(back == null){
+            console.error("配置错误"+args,this.name)
+            ctx.throw("配置错误"+args)
+        }
+        return back
+    }
+        `;
+	}
+
+	pro += `
+
+}
+export class ConfListProxy<T> {
+    pool: { [key: string]: T[] } = {}
+	name:string = ""
+    constructor(xlsname:string,conf: T[], ...args: string[]) {
+		this.name = xlsname
+        conf.forEach(element => {
+            let key = ConfProxy.setKey(element, args)
+            if (this.pool[key] == null) {
+                this.pool[key] = []
+            }
+            this.pool[key].push(element)
+        });
+    }
+    getItemList(...args: string[]): T[] | null {
+        return this.pool[ConfProxy.getKey(args)]
+	}`;
+
+	if (hang == 4) {
+		pro += `
+        
+	getItemListCtx(ctx:CTX,...args: string[]): T[] {
+        let back = this.pool[ConfProxy.getKey(args)]
+        if(back == null){
+            console.error("list配置错误"+args,this.name)
+            ctx.throw("list配置错误"+args)
+        }
+        return back
+    }
+        `;
+	}
+
+	pro += `
+}
+`
+
+
+	pro += '\n';
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}confProxy.ts`;
+	} else {
+		proPath = serverPath + `confProxy.ts`;
+	}
+
+	fs.writeFile(proPath, pro, function (err) {
+		if (err) {
+			console.log('ConfProxy写入失败:', err);
+		}
+	});
+}
+
+// 字符串开头变为大写
+function toUpperCaseByStr(txt) {
+	return txt.slice(0, 1).toUpperCase() + txt.slice(1);
+}
+
+// 分析配置表
+function doExcel(excel) {
+	let excelName = excel.split('_')[0];
+	if (s_xls.XlsBack[excelName] == null) {
+		return
+	}
+
+	let fileDir = `${excelDir}/${excel}`;
+	let workbook = xl.readFile(fileDir);
+	// 获取 Excel 中所有表名
+	const sheetNames = workbook.SheetNames; // 返回 ['sheet1', 'sheet2']
+	let _sheetNames = [];
+	for (const element of sheetNames) {
+		if (s_xls.XlsBack[excelName][element] == null) {
+			continue
+		}
+		_sheetNames.push(element);
+	}
+	if (_sheetNames.length == 0) {
+		return;
+	}
+	console.time("...start excel " + excel)
+	// 加到【excelAndSheets】中
+	let obj = {};
+	excelAndSheets[excelName] = {};
+	_sheetNames.forEach((sheetName) => {
+		let sheet = workbook.Sheets[sheetName];
+		excelAndSheets[excelName][sheetName] = {};
+		doSheet(obj, excelName, sheetName, sheet);
+	});
+
+	let outDir1 = ""
+	let outDir2 = ""
+	if (hang == 3) {
+		outDir1 = `${path.jsonPath}`;
+		if (!fs.existsSync(outDir1)) {
+			fs.mkdirSync(outDir1)
+		}
+		outDir2 = `${path.loadJsonPath}`;
+		if (!fs.existsSync(outDir2)) {
+			fs.mkdirSync(outDir2)
+		}
+	} else {
+		outDir1 = serverPath + `${outJsonFolder}`;
+		if (!fs.existsSync(outDir1)) {
+			fs.mkdirSync(outDir1)
+		}
+	}
+	for (const key in obj) {
+		let jsonStr = `${geshihua(obj[key])}`;
+		if (outDir2 != "" && loadJson.indexOf(key) >= 0) {
+			fs.writeFileSync(`${outDir2}/${key}.json`, jsonStr, function (err) {
+				if (err) {
+					console.log(err);
+				}
+			});
+		} else {
+			fs.writeFileSync(`${outDir1}/${key}.json`, jsonStr, function (err) {
+				if (err) {
+					console.log(err);
+				}
+			});
+		}
+	}
+	console.timeEnd("...start excel " + excel)
+}
+
+function geshihua(data) {
+	let count = 1;
+	let _data = '[\n';
+	for (const val of data) {
+		if (count == 1) {
+			_data += '  ' + JSON.stringify(val);
+		} else {
+			_data += `,\n`;
+			_data += '  ' + JSON.stringify(val);
+		}
+		count++;
+	}
+	_data += '\n]';
+	return _data;
+}
+
+//分析表单  obj数据,表名,表单名,表单数据内容
+function doSheet(obj, excelName, sheetName, sheet) {
+	let newKey = excelName + toUpperCaseByStr(sheetName);
+	excelFen.push(newKey);
+	if (obj[newKey] == null) {
+		obj[newKey] = [];
+	}
+
+	// 索引列表  example:{A:"",B:"id",C:"hp",D:"attack"}
+	let keyList = {};
+	// 类型列表 example:{A:"number",B:"string",C:"boolean",D:"{}[]"}
+	let typeList = {};
+	//备注
+	let psList = {};
+
+	let _tempObj = {};
+	for (const key in sheet) {
+		// 单元格定位id example: A25
+		const sheetKey = sheet[key];
+		// A25->25
+		let _hang = key.replace(/[^0-9]+/gi, '');
+		// A25->A
+		let _lie = key.replace(/[^A-Z]+/gi, '');
+		if (_lie == 'A') {
+			if (Object.keys(_tempObj).length > 0) {
+				//这边检测是否有放空配置的。如果有 , 补上默认类型
+				let _tempObj_1 = {};
+				for (const key in keyList) {
+					if (_tempObj[keyList[key]] == null) {
+						if (typeList[key] == 'number') {
+							_tempObj_1[keyList[key]] = 0;
+						} else if (typeList[key] == 'string') {
+							_tempObj_1[keyList[key]] = '';
+						} else if (typeList[key] == 'boolean') {
+							_tempObj_1[keyList[key]] = false;
+						} else if (typeList[key].indexOf('[]') != -1) {
+							_tempObj_1[keyList[key]] = null;
+						} else if (typeList[key].substring(0, 0 + 1) == '{') {
+							_tempObj_1[keyList[key]] = null;
+						} else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
+							_tempObj_1[keyList[key]] = null;
+						} else {
+							console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
+						}
+					} else {
+						_tempObj_1[keyList[key]] = _tempObj[keyList[key]];
+					}
+				}
+
+				obj[newKey].push(_tempObj_1);
+				_tempObj = {};
+			}
+		}
+		if (sheet['A' + _hang] == null) {
+			// 第一列没有配置参数,就跳过
+			continue;
+		}
+		if (_hang == 1) {
+			psList[_lie] = sheetKey.v;
+		}
+		// 储存类型
+		if (_hang == 2) {
+			typeList[_lie] = sheetKey.v;
+		}
+		// 储存索引
+		if (_hang == hang && sheetKey.v && typeList[_lie]) {
+			// 正则抽取真正的值(去掉所有的*)
+			let realVal = sheetKey.v.replace(/[\*]/g, '');
+			// 判断下作为key的字段
+			let isKey = 0; // 0:不是key,1:单key,2:列表key
+			if (sheetKey.v.slice(0, 2) == '**') {
+				isKey = 2;
+			} else if (sheetKey.v.slice(0, 1) == '*') {
+				isKey = 1;
+			}
+			keyList[_lie] = realVal.split(',')[0].trim();
+			// id:string
+			excelAndSheets[excelName][sheetName][keyList[_lie]] = {
+				ps: psList[_lie],
+				isKey: isKey,
+				value: typeList[_lie],
+				keys: realVal
+			};
+		}
+		// 储存数据
+		if (_hang >= 5 && keyList[_lie] != null && typeList[_lie] != null) {
+			// 根据类型转化数据内容,在做储存处理
+			let _val;
+			if (typeList[_lie] == 'number') {
+				if (typeof sheetKey.v != 'number') {
+					_val = Number(sheetKey.v);
+					if (isNaN(_val)) {
+						console.log(
+							'\x1b[33m%s\x1b[0m',
+							'警告,出现NaN数据类型,表名:' +
+							excelName +
+							' 表单:' +
+							sheetName +
+							' 索引:' +
+							keyList[_lie] +
+							' 表格ID:' +
+							key
+						);
+					}
+					_val = 0;
+				} else {
+					_val = sheetKey.v;
+				}
+			} else if (typeList[_lie] == 'boolean') {
+				if (sheetKey.v == 'true' || sheetKey.v == 'TRUE' || sheetKey.v == true) {
+					_val = true;
+				} else {
+					_val = false;
+				}
+			} else if (typeList[_lie][0] == '{' || typeList[_lie].slice(-1) == ']') {
+				try {
+					_val = JSON.parse(sheetKey.v);
+				} catch (error) {
+					console.log(
+						'\x1b[33m%s\x1b[0m',
+						'警告:json格式错误,表名:' + excelName + ' 表单:' + sheetName + ' 索引:' + keyList[_lie] + ' 表格ID:' + key
+					);
+				}
+			} else if (typeList[_lie] == 'string') {
+				if (typeof sheetKey.v == 'number') {
+					_val = Math.floor(sheetKey.v).toString();
+				} else {
+					_val = sheetKey.v;
+				}
+			} else {
+				_val = sheetKey.v;
+			}
+
+			_tempObj[keyList[_lie].trim()] = _val;
+		}
+	}
+
+	//这边检测是否有放空配置的。如果有 , 补上默认类型
+	let _tempObj_1 = {};
+	for (const key in keyList) {
+		if (_tempObj[keyList[key]] == null) {
+			if (typeList[key] == 'number') {
+				_tempObj_1[keyList[key]] = 0;
+			} else if (typeList[key] == 'string') {
+				_tempObj_1[keyList[key]] = '';
+			} else if (typeList[key] == 'boolean') {
+				_tempObj_1[keyList[key]] = false;
+			} else if (typeList[key].indexOf('[]') != -1) {
+				_tempObj_1[keyList[key]] = null;
+			} else if (typeList[key].substring(0, 0 + 1) == '{') {
+				_tempObj_1[keyList[key]] = null;
+			} else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
+				_tempObj_1[keyList[key]] = null;
+			} else {
+				console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
+			}
+		} else {
+			_tempObj_1[keyList[key]] = _tempObj[keyList[key]];
+		}
+	}
+
+	// 储存最后一个
+	obj[newKey].push(_tempObj_1);
+}
+
+// //--------------------start-------------------  控制台人机交互
+function readSyncByRl(tips) {
+	tips = tips || '> ';
+
+	return new Promise((resolve) => {
+		const rl = readline.createInterface({
+			input: process.stdin,
+			output: process.stdout
+		});
+
+		rl.question(tips, (answer) => {
+			rl.close();
+			resolve(answer.trim());
+		});
+	});
+}
+
+/**
+ * 后端创建xls对应gameCfg完成脚本
+ */
+function createGameCfg_s() {
+	let strs = '';
+	strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
+
+	let strHead = `XlsConfig`;
+	let count = 2;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
+			count++;
+			if (count % 9 == 0) {
+				strHead += `\n`;
+			}
+		}
+	}
+	strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
+	strs += `export default class Gamecfg {\n`;
+	strs += `    static init() {\n`;
+	strs += `       let xls = new XlsConfig()\n`;
+
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				let cs = ``;
+				for (let index = 1; index < val.length; index++) {
+					cs += `,"${val[index]}"`;
+				}
+				if (val[0] == 'ConfProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(key2)} = new ${val[0]}("${key1}${toUpperCaseByStr(key2)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(key2)}List = new ${val[0]}("${key1}${toUpperCaseByStr(key2)}List",xls.xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				let cs1 = ``;
+				for (let index = 2; index < val.length; index++) {
+					cs1 += `,"${val[index]}"`;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(val[0])} = new ${val[1]}("${key1}${toUpperCaseByStr(val[0])}",xls.xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)}List = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+			}
+		}
+	}
+
+
+	strs += `	}\n`;
+
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+
+				if (val[0] == 'ConfProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(key2)} : ${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)} >\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(key2)}List : ${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(val[0])} : ${val[1]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(
+						val[0]
+					)}List : ${val[1]}<xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `}\n`;
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}gameCfg.ts`;
+	} else {
+		proPath = serverPath + `gameCfg.ts`;
+	}
+
+	fs.writeFile(proPath, strs, function (err) {
+		if (err) {
+			console.log('gameCfg写入失败:', err);
+		}
+	});
+}
+
+/**
+ * 前端创建xls对应gameCfg完成脚本
+ */
+function createGameCfg_c() {
+	let strs = '';
+	strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
+
+	let strHead = `XlsConfig`;
+	let count = 2;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
+			count++;
+			if (count % 9 == 0) {
+				strHead += `\n`;
+			}
+		}
+	}
+	strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
+	strs += `export default class Gamecfg {\n`;
+
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				if (val[0] == 'ConfProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(key2)}:${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(key2)}List:${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(val[0])}:${val[1]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				//别名
+				if (val[1] == 'ConfListProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(val[0])}List:${val[1]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `\n`;
+	strs += `    static initLoading(loadSuccess: Function) {\n`;
+	strs += `       try {\n`;
+	strs += `           new XlsConfig("loadJson",(xls: XlsConfig) => {\n`;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			let jsonName = key1 + toUpperCaseByStr(key2)
+			if (loadJson.indexOf(jsonName) < 0) {
+				continue
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				let cs = ``;
+				for (let index = 1; index < val.length; index++) {
+					cs += `,"${val[index]}"`;
+				}
+				if (val[0] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)} = new ${val[0]}("${key1}${toUpperCaseByStr(
+						key2
+					)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)}List = new ${val[0]}("${key1}${toUpperCaseByStr(
+						key2
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				let cs1 = ``;
+				for (let index = 2; index < val.length; index++) {
+					cs1 += `,"${val[index]}"`;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)} = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)}List = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `
+				loadSuccess(true)
+			})
+		} catch (error) {
+			loadSuccess(false)
+		}
+	}`;
+	strs += `\n`;
+	strs += `    static init(loadSuccess: Function) {\n`;
+	strs += `       try {\n`;
+	strs += `           new XlsConfig("pzwj",(xls: XlsConfig) => {\n`;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			let jsonName = key1 + toUpperCaseByStr(key2)
+			if (loadJson.indexOf(jsonName) >= 0) {
+				continue
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				let cs = ``;
+				for (let index = 1; index < val.length; index++) {
+					cs += `,"${val[index]}"`;
+				}
+				if (val[0] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)} = new ${val[0]}("${key1}${toUpperCaseByStr(
+						key2
+					)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)}List = new ${val[0]}("${key1}${toUpperCaseByStr(
+						key2
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				let cs1 = ``;
+				for (let index = 2; index < val.length; index++) {
+					cs1 += `,"${val[index]}"`;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)} = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)}List = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `
+                loadSuccess(true)
+            })
+        } catch (error) {
+            loadSuccess(false)
+        }
+    }
+}`;
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}gameCfg.ts`;
+	} else {
+		proPath = serverPath + `gameCfg.ts`;
+	}
+
+	fs.writeFile(proPath, strs, function (err) {
+		if (err) {
+			console.log('gameCfg写入失败:', err);
+		}
+	});
+}
+
+function createXyc() {
+	const body = fs.readFileSync(apiurl, "utf-8");
+	let arr = body.split('/a/apidoc"}]},')
+
+	arr[1] = '[' + arr[1]
+	let arr1 = arr[1].split('}];const');
+	let str2 = arr1[0].replace(/!1/g, '0') + '}]';
+	let apidoc = `//所有接口定义\n`
+	apidoc += `export let apidoc:{[key:string]:string} = {\n`
+
+	try {
+		let strc = '';
+		var jsons = eval('(' + str2 + ')');
+
+		for (const json of jsons) {
+			let jsontitle = json.url.split('/');
+			let title = toUpperCaseByStr(jsontitle[1]) + toUpperCaseByStr(jsontitle[2]);
+			let jsonUrl = json.url.slice(1);
+
+			strc += `//${json.name}\n`;
+			strc += `export class ${title}\n`;
+			strc += `{\n`;
+			strc += `    static url:string = "${jsonUrl}"\n`;
+			strc += `}\n`;
+			strc += `export interface ${title}Pram{\n`;
+
+			apidoc += `    "/${jsonUrl}":"${json.name}",\n`
+
+			let _Parameter = [];
+			let hasUuid = 0;
+			let hasToken = 0;
+			if (json.parameter != null) {
+				for (const Parameter of json.parameter.fields.Parameter) {
+					let description = Parameter.description;
+					let arr11 = description.split('<p>');
+					let arr12 = arr11[1].split('</p>');
+
+					let _type = Parameter.type;
+					_Parameter.push({
+						type: _type,
+						field: Parameter.field,
+						description: arr12[0]
+					});
+					if (Parameter.field == 'uuid') {
+						hasUuid = 1;
+					}
+					if (Parameter.field == 'token') {
+						hasToken = 1;
+					}
+				}
+			}
+			for (const _rameter of _Parameter) {
+				if (hasUuid == 1 && hasToken == 1) {
+					if (_rameter.field == 'uuid' || _rameter.field == 'token') {
+						continue;
+					}
+				}
+				strc += `	${_rameter.field}:${_rameter.type} //${_rameter.description}\n`;
+			}
+			strc += `}\n\n`;
+		}
+
+		apidoc += `}`
+
+		if (hang == 3) {
+			outDir = path.configPath;
+		} else {
+			outDir = serverPath
+		}
+
+		strc += `
+//前端返回的特殊事件
+export interface keyValue{
+[key:string]:number
+}
+export interface keyValues{
+    [key:string]:number[]
+}
+export interface keyValueString{
+    [key:string]:string
+}
+export type ZixuanSelectCs = [string,string,number];
+export type Wxmspinzhi = [number,number]
+export type Wxmskeys = [number,string,string];
+export type Wxmslm = [number,string];
+`
+		let proPath = `${outDir}Xyc.ts`;
+		fs.writeFileSync(proPath, strc, function (err) {
+			if (err) {
+				console.log('Xyc写入失败:', err);
+			}
+		});
+
+		let proPath1 = `${outDir}apidoc.ts`;
+		fs.writeFileSync(proPath1, apidoc, function (err) {
+			if (err) {
+				console.log('Xyc写入失败:', err);
+			}
+		});
+
+
+
+	} catch (error) {
+		console.log('===', error);
+	}
+
+}
+
+//拷贝  s_to_proto
+function copy_s_to_proto() {
+	fs.copyFile(serverPath + 'Xys.ts', './s_to_proto/Xys.ts', (err) => {
+		console.log('=', err);
+	});
+	fs.copyFile(serverPath + 'Xyc.ts', './s_to_proto/Xyc.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile(serverPath + 'gameMethod.ts', './s_to_proto/gameMethod.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile(serverPath + 'fight.ts', './s_to_proto/fight.ts', (err) => {
+		console.log('=', err);
+	});
+}
+
+//拷贝  proto
+function copy_proto_to_c() {
+	outDir = path.configPath;
+	fs.copyFile('./s_to_proto/Xys.ts', outDir + 'Xys.ts', (err) => {
+		console.log('=', err);
+	});
+	fs.copyFile('./s_to_proto/Xyc.ts', outDir + 'Xyc.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile('./s_to_proto/gameMethod.ts', outDir + 'gameMethod.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile('./s_to_proto/fight.ts', outDir + 'fight.ts', (err) => {
+		console.log('=', err);
+	});
+}
+
+/**
+ * 延迟多少毫秒
+ */
+function sleep(ms) {
+	if (ms < 1) {
+		return;
+	}
+	return new Promise((reslove, reject) => {
+		setTimeout(() => {
+			reslove(1);
+		}, ms);
+	});
+}
+
+// 开始解析配置表
+function doExe(res) {
+	// console.log(res);
+	if (res != 'c' && res != 's' && res != 'C' && res != 'S') {
+		console.log('非法输入');
+		return;
+	}
+	if (res == 'c' || res == 'C') {
+		hang = 3;
+	} else {
+		hang = 4;
+	}
+
+	if (hang == 3) {
+		outDir = path.configPath;
+	} else {
+		outDir = serverPath;
+	}
+
+	console.log('\x1b[37m'); // 控制台文字切为白色
+
+
+
+	if (hang == 4) {
+
+		fs.rm(serverPath + outJsonFolder, { recursive: true }, (err, data) => {
+			if (err) {
+				console.log('删除json文件失败' + err);
+			}
+			console.log('删除json文件成功');
+
+			let sendNum = 0
+			let overNum = 0
+			// 解析表格
+			fs.readdirSync(excelDir).forEach((excelName) => {
+				if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
+					excelFiles.push(excelName.split('_')[0]);
+
+					const worker = cluster.fork(excelName);
+					sendNum += 1
+					worker.send({ "hang": 4, "excelName": excelName })
+					worker.on('message', function (mes) {
+						let mesarr = JSON.parse(mes)
+						for (const ar of mesarr.excelFen) {
+							excelFen.push(ar)
+						}
+						for (const key in mesarr.excelAndSheets) {
+							excelAndSheets[key] = mesarr.excelAndSheets[key]
+						}
+						overNum += 1
+						console.log(`配置表解析 发送${sendNum}个,完成${overNum}个`)
+					})
+
+				}
+			});
+			const intervalId = setInterval(() => {
+				if (sendNum <= overNum) {
+					console.log("----全部完成----")
+					clearInterval(intervalId);
+				}
+			}, 1000);
+		
+		});
+	}
+
+
+
+	if (hang == 3) {
+
+		fs.unlink(path.excelPath + outJsonFolder + '/excel.zip', (err, data) => {
+			if (err) {
+				console.log('删除zip文件失败' + err);
+			}
+			console.log('删除zip文件成功');
+			let sendNum = 0
+			let overNum = 0
+			let xls = {}
+			// 解析表格
+			fs.readdirSync(excelDir).forEach((excelName) => {
+				if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
+					excelFiles.push(excelName.split('_')[0]);
+					// doExcel(excelName);
+					xls[excelName] = 1
+					const worker = cluster.fork(excelName);
+					sendNum += 1
+					worker.send({ "hang": 3, "excelName": excelName })
+					worker.on('message', function (mes) {
+						let mesarr = JSON.parse(mes)
+						for (const ar of mesarr.excelFen) {
+							excelFen.push(ar)
+						}
+						for (const key in mesarr.excelAndSheets) {
+							excelAndSheets[key] = mesarr.excelAndSheets[key]
+						}
+						overNum += 1
+						delete xls[excelName]
+						console.log(`配置表解析 发送${sendNum}个,完成${overNum}个`)
+						worker.destroy();
+					})
+
+				}
+			});
+
+			const intervalId = setInterval(() => {
+				if (sendNum <= overNum) {
+					// 生成配置表读取文件(ts)
+					exeExcelConfig_c();
+					console.log('*******创建配置文件完成*******');
+
+					// createXyc();
+					// console.log('*******创建xyc完成*******');
+
+					createGameCfg_c();
+					console.log('*******创建xls对应gameCfg完成*******');
+
+					copy_proto_to_c();
+					console.log('*******拷贝完成*******');
+
+					console.log("----全部完成----")
+					clearInterval(intervalId);
+				}
+			}, 1000);
+
+
+		});
+
+
+	}
+	sleep(4000);
+
+	// if (hang == 3) {
+	//
+	// }
+}
+
+if (!cluster.isMaster) {
+	process.on("message", function (message) {
+		hang = message.hang
+		doExcel(message.excelName)
+		process.send(JSON.stringify({ "excelFen": excelFen, "excelAndSheets": excelAndSheets }))
+		process.exit()
+	});
+	return
+}
+
+if (jiexiTarget == "s" || jiexiTarget == "c") {
+	doExe(jiexiTarget)
+} else {
+	readSyncByRl('exe client->c or server->s:').then((res) => {
+		doExe(res)
+	});
+}
+
+// //---------------------end--------------------  控制台人机交互

+ 5 - 0
a后端协议脚本.bat

@@ -0,0 +1,5 @@
+@echo off 
+if not "%OS%"=="Windows_NT" exit
+
+@echo s|node index.js --export
+

+ 18 - 0
a后端接口脚本.bat

@@ -0,0 +1,18 @@
+@echo off 
+if not "%OS%"=="Windows_NT" exit
+
+start cmd /c "cd ..\zhetian_backend_kaifa && apidoc -i src/   -c  src/apidoc.json   -o public/api/  " 
+
+
+
+
+
+
+
+
+
+
+
+
+
+

二進制
excel/audio_音乐.xls


二進制
excel/guide_引导.xls


二進制
excel/help_帮助表.xls


二進制
excel/item_道具.xls


二進制
excel/kaiqi_功能开启.xls


二進制
excel/languageClient_前端多语言.xls


二進制
excel/languageSever_后端多语言.xls


二進制
excel/language_多语言.xls


二進制
excel/math_全局表.xls


二進制
excel/name_角色名 .xlsx


二進制
excel/package_打包.xls


二進制
excel/pingbici_屏蔽词.xls


二進制
excel/shop_商店.xls


+ 1327 - 0
index.js

@@ -0,0 +1,1327 @@
+const path = require('./path.json');
+const readline = require('readline');
+var archiver = require('archiver');
+const fs = require('fs');
+const xl = require('xlsx');
+let excelDir = './excel'; // excel配置表目录
+let outDir = './out'; // 导出目录
+let outJsonFolder = 'excel'; // 导出的json目录
+//前端需要在load界面加载的表
+let loadJson = ["audioInfo", "languageLang", "languageClientText", "mathInfo", "packageInfo"]
+
+const cluster = require('cluster');
+
+//后端配置
+let serverPath = "../zhetian_backend_kaifa/common/"
+let apiurl = "../zhetian_backend_kaifa/public/api/assets/main.bundle.js"
+
+// 前后端解析索引的行
+let hang = 3; // 前端3 后端4
+// 表格列表 example: ["iconopen","mainTask"]
+let excelFiles = [];
+// 表名 +分表名
+let excelFen = [];
+// 表格与表单的数据类型 example:{iconopen:{id:string}}
+let excelAndSheets = {};
+var s_xls = require('./s_xls');
+const { exit } = require('process');
+
+// 检测传入的参数
+var args = process.argv.splice(2)
+var jiexiTarget = args[0] || "" // s:后端 c:前端
+
+function exeExcelConfig_c() {
+	let str = '';
+	str += `import GameController from "../GameController"\nimport { gameMethod } from "./gameMethod"\n`
+	// 添加类型定义
+	excelFiles.forEach((excelName) => {
+		str += `// type for ${excelName}.excel\n`;
+		for (const sheetName in excelAndSheets[excelName]) {
+			str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
+
+			//遍历索引存入类型定义
+			let keyObjList = excelAndSheets[excelName][sheetName];
+			for (const key in keyObjList) {
+				str += `${key.split(',')[0]}:${keyObjList[key].value},`;
+			}
+			// 去掉最后一个逗号 ","
+			if (str.charAt(str.length - 1) == ',') {
+				str = str.substring(0, str.length - 1);
+			}
+			str += '}';
+			str += '\n';
+		}
+	});
+	str += '\n';
+
+	//导出
+	str += `export class XlsConfig {\n`;
+	excelFen.forEach((element) => {
+		str += `    xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
+	});
+	// str += `    constructor(callback: Function) {\n`
+
+	// let str111 = [];
+	// excelFen.forEach((element) => {
+	// 	str111.push('"' + element + '"');
+	// });
+
+	// str += `    }\n`
+
+	str += `
+    constructor(bundleName:string, callback: Function, progressCallback?: Function) {
+        cc.assetManager.loadBundle(bundleName, (err, bundle) => {
+			if (err) {
+                GameController.clear()
+                cc.game.restart()
+                if (progressCallback) {
+                    progressCallback(0, 0.99);
+                }
+                return
+            }
+            if (gameMethod.isEmpty(bundle) && cc.sys.platform == cc.sys.WECHAT_GAME) {
+                //小游戏平台,缓存过期,自动清理缓存,重启游戏
+				console.error("加载配置表的bundle失败,清理缓存重新加载")
+                cc.assetManager.cacheManager.clearCache()
+                GameController.clear()
+                cc.game.restart()
+                if (progressCallback) {
+                    progressCallback(0, 0.99);
+                }
+                return
+            }
+            bundle.loadDir("",(finish: number, total: number, item: any)=>{
+                if (progressCallback) {
+                    progressCallback(finish, total);
+                }
+            }, (err2, assets: cc.JsonAsset[]) => {
+				if (err2) {
+					GameController.clear()
+                    cc.game.restart()
+                    if (progressCallback) {
+                        progressCallback(0, 0.99);
+                    }
+				    return
+				}
+                let current = 0;
+                assets.forEach(element => {
+                    this["xls" + this.firstUpCase(element.name)] = element.json;
+                    current++;
+                });
+                callback(this)
+            })
+        })
+    }
+    // 首字母大写
+    private firstUpCase(str: string) {
+        return str[0].toUpperCase() + str.substring(1)
+    }
+}`;
+
+	if (hang == 3) {
+		outDir = path.configPath;
+	} else {
+		outDir = serverPath;
+	}
+	// 写入文件
+	let outPath = `${outDir}xlsConfig.ts`;
+	fs.writeFile(outPath, str, function (err) {
+		if (err) {
+			console.log('xlsConfig写入失败:', err);
+		}
+	});
+
+	let pro = '';
+	if (hang == 4) {
+		pro += 'import { CTX } from "../src/util/master";\n';
+	}
+
+	pro += `export default class ConfProxy<T> {
+    static getKey(args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += element
+            out += "_"
+        });
+        return out
+    }
+    static setKey(target: any, args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += target[element]
+            out += "_"
+        });
+        return out
+    }
+    pool: { [key: string]: T } = {}
+	name:string = ""
+    constructor(xlsname:string,conf: T[], ...args: string[]) {
+		this.name = xlsname
+        conf.forEach(element => {
+            this.pool[ConfProxy.setKey(element, args)] = element
+        });
+    }
+    
+    getItem(...args: string[]): T | null {
+		return this.pool[ConfProxy.getKey(args)]
+    }`;
+
+	if (hang == 4) {
+		pro += `
+        
+    getItemCtx(ctx:CTX,...args: string[]): T {
+        let back = this.pool[ConfProxy.getKey(args)]
+        if(back == null){
+            console.error("配置错误"+args,this.name)
+            ctx.throw("配置错误"+args)
+        }
+        return back
+    }
+        `;
+	}
+
+	pro += `
+
+}
+export class ConfListProxy<T> {
+    pool: { [key: string]: T[] } = {}
+	name:string = ""
+    constructor(xlsname:string,conf: T[], ...args: string[]) {
+		this.name = xlsname
+        conf.forEach(element => {
+            let key = ConfProxy.setKey(element, args)
+            if (this.pool[key] == null) {
+                this.pool[key] = []
+            }
+            this.pool[key].push(element)
+        });
+    }
+    getItemList(...args: string[]): T[] | null {
+        return this.pool[ConfProxy.getKey(args)]
+    }
+}`;
+
+	pro += '\n';
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}confProxy.ts`;
+	} else {
+		proPath = serverPath + `confProxy.ts`;
+	}
+
+	fs.writeFile(proPath, pro, function (err) {
+		if (err) {
+			console.log('ConfProxy写入失败:', err);
+		}
+	});
+}
+
+function exeExcelConfig() {
+	let str = '';
+
+	// 引入ts文件
+	excelFen.forEach((element) => {
+		str += `const  ${element}  = require( "./excel/${element}.json")\n`;
+	});
+	str += '\n';
+
+	// 添加类型定义
+	excelFiles.forEach((excelName) => {
+		str += `// type for ${excelName}.excel\n`;
+		for (const sheetName in excelAndSheets[excelName]) {
+			str += `export type xls${toUpperCaseByStr(excelName)}${toUpperCaseByStr(sheetName)} = {`;
+
+			//遍历索引存入类型定义
+			let keyObjList = excelAndSheets[excelName][sheetName];
+			for (const key in keyObjList) {
+				str += `${key.split(',')[0]}:${keyObjList[key].value},`;
+			}
+			// 去掉最后一个逗号 ","
+			if (str.charAt(str.length - 1) == ',') {
+				str = str.substring(0, str.length - 1);
+			}
+			str += '}';
+			str += '\n';
+		}
+	});
+	str += '\n';
+
+	//导出
+	str += `export class XlsConfig {\n`;
+	excelFen.forEach((element) => {
+		str += `    xls${toUpperCaseByStr(element)}: xls${toUpperCaseByStr(element)}[]\n`;
+	});
+	str += `    constructor() {\n`;
+	excelFen.forEach((element) => {
+		str += `        this.xls${toUpperCaseByStr(element)} = <xls${toUpperCaseByStr(element)}[]>${element}\n`;
+	});
+
+	str += `    }\n`;
+	str += '}\n';
+
+	if (hang == 3) {
+		outDir = path.configPath;
+	} else {
+		outDir = serverPath
+	}
+	// 写入文件
+	let outPath = `${outDir}xlsConfig.ts`;
+	fs.writeFile(outPath, str, function (err) {
+		if (err) {
+			console.log('xlsConfig写入失败:', err);
+		}
+	});
+
+	let pro = '';
+	if (hang == 4) {
+		pro += 'import { CTX } from "../src/util/master";\n';
+	}
+
+	pro += `export default class ConfProxy<T> {
+    static getKey(args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += element
+            out += "_"
+        });
+        return out
+    }
+    static setKey(target: any, args: string[]): string {
+        let out = ""
+        args.forEach(element => {
+            out += target[element]
+            out += "_"
+        });
+        return out
+    }
+    pool: { [key: string]: T } = {}
+	name:string = ""
+    constructor(xlsname:string,conf: T[], ...args: string[]) {
+		this.name = xlsname
+        conf.forEach(element => {
+            this.pool[ConfProxy.setKey(element, args)] = this.deepFreeze(element)
+        });
+    }
+    
+    getItem(...args: string[]): T | null {
+		return this.pool[ConfProxy.getKey(args)]
+    }`;
+
+	if (hang == 4) {
+		pro += `
+        
+    getItemCtx(ctx:CTX,...args: string[]): T {
+        let back = this.pool[ConfProxy.getKey(args)]
+        if(back == null){
+            console.error("配置错误"+args,this.name)
+            ctx.throw("配置错误"+args)
+        }
+        return back
+    }
+
+
+    deepFreeze<T>(obj: T): T {
+        Object.freeze(obj);
+        Object.getOwnPropertyNames(obj).forEach(prop => {
+          const value = (obj as Record<string, any>)[prop];
+          if (value !== null 
+                && (typeof value === "object" || typeof value === "function") 
+                && !Object.isFrozen(value)) {
+            this.deepFreeze(value);
+          }
+        });
+        return obj as T;
+    }
+
+
+        `;
+	}
+
+	pro += `
+
+}
+export class ConfListProxy<T> {
+    pool: { [key: string]: T[] } = {}
+	name:string = ""
+    constructor(xlsname:string,conf: T[], ...args: string[]) {
+		this.name = xlsname
+        conf.forEach(element => {
+            let key = ConfProxy.setKey(element, args)
+            if (this.pool[key] == null) {
+                this.pool[key] = []
+            }
+            this.pool[key].push(element)
+        });
+    }
+    getItemList(...args: string[]): T[] | null {
+        return this.pool[ConfProxy.getKey(args)]
+	}`;
+
+	if (hang == 4) {
+		pro += `
+        
+	getItemListCtx(ctx:CTX,...args: string[]): T[] {
+        let back = this.pool[ConfProxy.getKey(args)]
+        if(back == null){
+            console.error("list配置错误"+args,this.name)
+            ctx.throw("list配置错误"+args)
+        }
+        return back
+    }
+        `;
+	}
+
+	pro += `
+}
+`
+
+
+	pro += '\n';
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}confProxy.ts`;
+	} else {
+		proPath = serverPath + `confProxy.ts`;
+	}
+
+	fs.writeFile(proPath, pro, function (err) {
+		if (err) {
+			console.log('ConfProxy写入失败:', err);
+		}
+	});
+}
+
+// 字符串开头变为大写
+function toUpperCaseByStr(txt) {
+	return txt.slice(0, 1).toUpperCase() + txt.slice(1);
+}
+
+// 分析配置表
+function doExcel(excel) {
+	let excelName = excel.split('_')[0];
+	if (s_xls.XlsBack[excelName] == null) {
+		return
+	}
+
+	let fileDir = `${excelDir}/${excel}`;
+	let workbook = xl.readFile(fileDir);
+	// 获取 Excel 中所有表名
+	const sheetNames = workbook.SheetNames; // 返回 ['sheet1', 'sheet2']
+	let _sheetNames = [];
+	for (const element of sheetNames) {
+		if (s_xls.XlsBack[excelName][element] == null) {
+			continue
+		}
+		_sheetNames.push(element);
+	}
+	if (_sheetNames.length == 0) {
+		return;
+	}
+	console.time("...start excel " + excel)
+	// 加到【excelAndSheets】中
+	let obj = {};
+	excelAndSheets[excelName] = {};
+	_sheetNames.forEach((sheetName) => {
+		let sheet = workbook.Sheets[sheetName];
+		excelAndSheets[excelName][sheetName] = {};
+		doSheet(obj, excelName, sheetName, sheet);
+	});
+
+	let outDir1 = ""
+	let outDir2 = ""
+	if (hang == 3) {
+		outDir1 = `${path.jsonPath}`;
+		if (!fs.existsSync(outDir1)) {
+			fs.mkdirSync(outDir1)
+		}
+		outDir2 = `${path.loadJsonPath}`;
+		if (!fs.existsSync(outDir2)) {
+			fs.mkdirSync(outDir2)
+		}
+	} else {
+		outDir1 = serverPath + `${outJsonFolder}`;
+		if (!fs.existsSync(outDir1)) {
+			fs.mkdirSync(outDir1)
+		}
+	}
+	for (const key in obj) {
+		let jsonStr = `${geshihua(obj[key])}`;
+		if (outDir2 != "" && loadJson.indexOf(key) >= 0) {
+			fs.writeFileSync(`${outDir2}/${key}.json`, jsonStr, function (err) {
+				if (err) {
+					console.log(err);
+				}
+			});
+		} else {
+			fs.writeFileSync(`${outDir1}/${key}.json`, jsonStr, function (err) {
+				if (err) {
+					console.log(err);
+				}
+			});
+		}
+	}
+	console.timeEnd("...start excel " + excel)
+}
+
+function geshihua(data) {
+	let count = 1;
+	let _data = '[\n';
+	for (const val of data) {
+		if (count == 1) {
+			_data += '  ' + JSON.stringify(val);
+		} else {
+			_data += `,\n`;
+			_data += '  ' + JSON.stringify(val);
+		}
+		count++;
+	}
+	_data += '\n]';
+	return _data;
+}
+
+//分析表单  obj数据,表名,表单名,表单数据内容
+function doSheet(obj, excelName, sheetName, sheet) {
+	let newKey = excelName + toUpperCaseByStr(sheetName);
+	excelFen.push(newKey);
+	if (obj[newKey] == null) {
+		obj[newKey] = [];
+	}
+
+	// 索引列表  example:{A:"",B:"id",C:"hp",D:"attack"}
+	let keyList = {};
+	// 类型列表 example:{A:"number",B:"string",C:"boolean",D:"{}[]"}
+	let typeList = {};
+	//备注
+	let psList = {};
+
+	let _tempObj = {};
+	for (const key in sheet) {
+		// 单元格定位id example: A25
+		const sheetKey = sheet[key];
+		// A25->25
+		let _hang = key.replace(/[^0-9]+/gi, '');
+		// A25->A
+		let _lie = key.replace(/[^A-Z]+/gi, '');
+		if (_lie == 'A') {
+			if (Object.keys(_tempObj).length > 0) {
+				//这边检测是否有放空配置的。如果有 , 补上默认类型
+				let _tempObj_1 = {};
+				for (const key in keyList) {
+					if (_tempObj[keyList[key]] == null) {
+						if (typeList[key] == 'number') {
+							_tempObj_1[keyList[key]] = 0;
+						} else if (typeList[key] == 'string') {
+							_tempObj_1[keyList[key]] = '';
+						} else if (typeList[key] == 'boolean') {
+							_tempObj_1[keyList[key]] = false;
+						} else if (typeList[key].indexOf('[]') != -1) {
+							_tempObj_1[keyList[key]] = null;
+						} else if (typeList[key].substring(0, 0 + 1) == '{') {
+							_tempObj_1[keyList[key]] = null;
+						} else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
+							_tempObj_1[keyList[key]] = null;
+						} else {
+							console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
+						}
+					} else {
+						_tempObj_1[keyList[key]] = _tempObj[keyList[key]];
+					}
+				}
+
+				obj[newKey].push(_tempObj_1);
+				_tempObj = {};
+			}
+		}
+		if (sheet['A' + _hang] == null) {
+			// 第一列没有配置参数,就跳过
+			continue;
+		}
+		if (_hang == 1) {
+			psList[_lie] = sheetKey.v;
+		}
+		// 储存类型
+		if (_hang == 2) {
+			typeList[_lie] = sheetKey.v;
+		}
+		// 储存索引
+		if (_hang == hang && sheetKey.v && typeList[_lie]) {
+			// 正则抽取真正的值(去掉所有的*)
+			let realVal = sheetKey.v.replace(/[\*]/g, '');
+			// 判断下作为key的字段
+			let isKey = 0; // 0:不是key,1:单key,2:列表key
+			if (sheetKey.v.slice(0, 2) == '**') {
+				isKey = 2;
+			} else if (sheetKey.v.slice(0, 1) == '*') {
+				isKey = 1;
+			}
+			keyList[_lie] = realVal.split(',')[0].trim();
+			// id:string
+			excelAndSheets[excelName][sheetName][keyList[_lie]] = {
+				ps: psList[_lie],
+				isKey: isKey,
+				value: typeList[_lie],
+				keys: realVal
+			};
+		}
+		// 储存数据
+		if (_hang >= 5 && keyList[_lie] != null && typeList[_lie] != null) {
+			// 根据类型转化数据内容,在做储存处理
+			let _val;
+			if (typeList[_lie] == 'number') {
+				if (typeof sheetKey.v != 'number') {
+					_val = Number(sheetKey.v);
+					if (isNaN(_val)) {
+						console.log(
+							'\x1b[33m%s\x1b[0m',
+							'警告,出现NaN数据类型,表名:' +
+							excelName +
+							' 表单:' +
+							sheetName +
+							' 索引:' +
+							keyList[_lie] +
+							' 表格ID:' +
+							key
+						);
+					}
+					_val = 0;
+				} else {
+					_val = sheetKey.v;
+				}
+			} else if (typeList[_lie] == 'boolean') {
+				if (sheetKey.v == 'true' || sheetKey.v == 'TRUE' || sheetKey.v == true) {
+					_val = true;
+				} else {
+					_val = false;
+				}
+			} else if (typeList[_lie][0] == '{' || typeList[_lie].slice(-1) == ']') {
+				try {
+					_val = JSON.parse(sheetKey.v);
+				} catch (error) {
+					console.log(
+						'\x1b[33m%s\x1b[0m',
+						'警告:json格式错误,表名:' + excelName + ' 表单:' + sheetName + ' 索引:' + keyList[_lie] + ' 表格ID:' + key
+					);
+				}
+			} else if (typeList[_lie] == 'string') {
+				if (typeof sheetKey.v == 'number') {
+					_val = Math.floor(sheetKey.v).toString();
+				} else {
+					_val = sheetKey.v;
+				}
+			} else {
+				_val = sheetKey.v;
+			}
+
+			_tempObj[keyList[_lie].trim()] = _val;
+		}
+	}
+
+	//这边检测是否有放空配置的。如果有 , 补上默认类型
+	let _tempObj_1 = {};
+	for (const key in keyList) {
+		if (_tempObj[keyList[key]] == null) {
+			if (typeList[key] == 'number') {
+				_tempObj_1[keyList[key]] = 0;
+			} else if (typeList[key] == 'string') {
+				_tempObj_1[keyList[key]] = '';
+			} else if (typeList[key] == 'boolean') {
+				_tempObj_1[keyList[key]] = false;
+			} else if (typeList[key].indexOf('[]') != -1) {
+				_tempObj_1[keyList[key]] = null;
+			} else if (typeList[key].substring(0, 0 + 1) == '{') {
+				_tempObj_1[keyList[key]] = null;
+			} else if (typeList[key][0] == "[" && typeList[key][typeList[key].length - 1] == "]") { // 元组
+				_tempObj_1[keyList[key]] = null;
+			} else {
+				console.error('配置表有未知定义', excelName, sheetName, keyList[key], typeList[key]);
+			}
+		} else {
+			_tempObj_1[keyList[key]] = _tempObj[keyList[key]];
+		}
+	}
+
+	// 储存最后一个
+	obj[newKey].push(_tempObj_1);
+}
+
+// //--------------------start-------------------  控制台人机交互
+function readSyncByRl(tips) {
+	tips = tips || '> ';
+
+	return new Promise((resolve) => {
+		const rl = readline.createInterface({
+			input: process.stdin,
+			output: process.stdout
+		});
+
+		rl.question(tips, (answer) => {
+			rl.close();
+			resolve(answer.trim());
+		});
+	});
+}
+
+/**
+ * 后端创建xls对应gameCfg完成脚本
+ */
+function createGameCfg_s() {
+	let strs = '';
+	strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
+
+	let strHead = `XlsConfig`;
+	let count = 2;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
+			count++;
+			if (count % 9 == 0) {
+				strHead += `\n`;
+			}
+		}
+	}
+	strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
+	strs += `export default class Gamecfg {\n`;
+	strs += `    static init() {\n`;
+	strs += `       let xls = new XlsConfig()\n`;
+
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				let cs = ``;
+				for (let index = 1; index < val.length; index++) {
+					cs += `,"${val[index]}"`;
+				}
+				if (val[0] == 'ConfProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(key2)} = new ${val[0]}("${key1}${toUpperCaseByStr(key2)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(key2)}List = new ${val[0]}("${key1}${toUpperCaseByStr(key2)}List",xls.xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				let cs1 = ``;
+				for (let index = 2; index < val.length; index++) {
+					cs1 += `,"${val[index]}"`;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(val[0])} = new ${val[1]}("${key1}${toUpperCaseByStr(val[0])}",xls.xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `       Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)}List = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+			}
+		}
+	}
+
+
+	strs += `	}\n`;
+
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+
+				if (val[0] == 'ConfProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(key2)} : ${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)} >\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(key2)}List : ${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(val[0])} : ${val[1]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `	static ${key1}${toUpperCaseByStr(
+						val[0]
+					)}List : ${val[1]}<xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `}\n`;
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}gameCfg.ts`;
+	} else {
+		proPath = serverPath + `gameCfg.ts`;
+	}
+
+	fs.writeFile(proPath, strs, function (err) {
+		if (err) {
+			console.log('gameCfg写入失败:', err);
+		}
+	});
+}
+
+/**
+ * 前端创建xls对应gameCfg完成脚本
+ */
+function createGameCfg_c() {
+	let strs = '';
+	strs += `import ConfProxy, { ConfListProxy } from "./confProxy"\n`;
+
+	let strHead = `XlsConfig`;
+	let count = 2;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			strHead += `, xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)}`;
+			count++;
+			if (count % 9 == 0) {
+				strHead += `\n`;
+			}
+		}
+	}
+	strs += `import { ${strHead} } from "./xlsConfig"\n\n`;
+	strs += `export default class Gamecfg {\n`;
+
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				if (val[0] == 'ConfProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(key2)}:${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(key2)}List:${val[0]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(val[0])}:${val[1]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+				//别名
+				if (val[1] == 'ConfListProxy') {
+					strs += `    static ${key1}${toUpperCaseByStr(val[0])}List:${val[1]}<xls${toUpperCaseByStr(
+						key1
+					)}${toUpperCaseByStr(key2)}>\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `\n`;
+	strs += `    static initLoading(loadSuccess: Function) {\n`;
+	strs += `       try {\n`;
+	strs += `           new XlsConfig("loadJson",(xls: XlsConfig) => {\n`;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			let jsonName = key1 + toUpperCaseByStr(key2)
+			if (loadJson.indexOf(jsonName) < 0) {
+				continue
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				let cs = ``;
+				for (let index = 1; index < val.length; index++) {
+					cs += `,"${val[index]}"`;
+				}
+				if (val[0] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)} = new ${val[0]}("${key1}${toUpperCaseByStr(
+						key2
+					)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)}List = new ${val[0]}("${key1}${toUpperCaseByStr(
+						key2
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				let cs1 = ``;
+				for (let index = 2; index < val.length; index++) {
+					cs1 += `,"${val[index]}"`;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)} = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)}List = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `
+				loadSuccess(true)
+			})
+		} catch (error) {
+			loadSuccess(false)
+		}
+	}`;
+	strs += `\n`;
+	strs += `    static init(loadSuccess: Function, progressCallback: Function) {\n`;
+	strs += `       try {\n`;
+	strs += `           new XlsConfig("pzwj",(xls: XlsConfig) => {\n`;
+	for (const key1 in s_xls.XlsBack) {
+		for (const key2 in s_xls.XlsBack[key1]) {
+			if (s_xls.XlsBack[key1][key2].length <= 0) {
+				continue;
+			}
+			let jsonName = key1 + toUpperCaseByStr(key2)
+			if (loadJson.indexOf(jsonName) >= 0) {
+				continue
+			}
+			for (const val of s_xls.XlsBack[key1][key2]) {
+				let cs = ``;
+				for (let index = 1; index < val.length; index++) {
+					cs += `,"${val[index]}"`;
+				}
+				if (val[0] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)} = new ${val[0]}("${key1}${toUpperCaseByStr(
+						key2
+					)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				if (val[0] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						key2
+					)}List = new ${val[0]}("${key1}${toUpperCaseByStr(
+						key2
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs})\n`;
+					continue;
+				}
+				let cs1 = ``;
+				for (let index = 2; index < val.length; index++) {
+					cs1 += `,"${val[index]}"`;
+				}
+				//别名
+				if (val[1] == 'ConfProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)} = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+				if (val[1] == 'ConfListProxy') {
+					strs += `               Gamecfg.${key1}${toUpperCaseByStr(
+						val[0]
+					)}List = new ${val[1]}("${key1}${toUpperCaseByStr(
+						val[0]
+					)}List",xls.xls${toUpperCaseByStr(key1)}${toUpperCaseByStr(key2)} ${cs1})\n`;
+					continue;
+				}
+			}
+		}
+	}
+	strs += `
+                loadSuccess(true)
+            }, progressCallback)
+        } catch (error) {
+            loadSuccess(false)
+        }
+    }
+}`;
+
+	// 写入文件
+	let proPath = '';
+	if (hang == 3) {
+		proPath = `${path.configPath}gameCfg.ts`;
+	} else {
+		proPath = serverPath + `gameCfg.ts`;
+	}
+
+	fs.writeFile(proPath, strs, function (err) {
+		if (err) {
+			console.log('gameCfg写入失败:', err);
+		}
+	});
+}
+
+function createXyc() {
+	const body = fs.readFileSync(apiurl, "utf-8");
+	let arr = body.split('/a/apidoc"}]},')
+
+	arr[1] = '[' + arr[1]
+	let arr1 = arr[1].split('}];const');
+	let str2 = arr1[0].replace(/!1/g, '0') + '}]';
+	let apidoc = `//所有接口定义\n`
+	apidoc += `export let apidoc:{[key:string]: {name:string,parms: {[key:string]: {type: string, desc: string}}}} = {\n`
+
+	try {
+		let strc = '';
+		var jsons = eval('(' + str2 + ')');
+
+		for (const json of jsons) {
+			let jsontitle = json.url.split('/');
+			let title = toUpperCaseByStr(jsontitle[1]) + toUpperCaseByStr(jsontitle[2]);
+			let jsonUrl = json.url.slice(1);
+
+			strc += `//${json.name}\n`;
+			strc += `export class ${title}\n`;
+			strc += `{\n`;
+			strc += `    static url:string = "${jsonUrl}"\n`;
+			strc += `}\n`;
+			strc += `export interface ${title}Pram{\n`;
+
+			apidoc += `    "/${jsonUrl}":{name:"${json.name}",parms:{`
+
+			let _Parameter = [];
+			let hasUuid = 0;
+			let hasToken = 0;
+			if (json.parameter != null) {
+				for (const Parameter of json.parameter.fields.Parameter) {
+					let description = Parameter.description;
+					let arr11 = description.split('<p>');
+					let arr12 = arr11[1].split('</p>');
+
+					let _type = Parameter.type;
+					_Parameter.push({
+						type: _type,
+						field: Parameter.field,
+						description: arr12[0]
+					});
+					if (Parameter.field == 'uuid') {
+						hasUuid = 1;
+					}
+					if (Parameter.field == 'token') {
+						hasToken = 1;
+					}
+				}
+			}
+			
+			for (const _rameter of _Parameter) {
+				if (hasUuid == 1 && hasToken == 1) {
+					if (_rameter.field == 'uuid' || _rameter.field == 'token') {
+						continue;
+					}
+				}
+				strc += `	${_rameter.field}:${_rameter.type} //${_rameter.description}\n`;
+				apidoc += `"${_rameter.field}": {type: "${_rameter.type}", desc: "${_rameter.description}"},`
+			}
+			strc += `}\n\n`;
+			apidoc += `}},\n\n`;
+		}
+
+		apidoc += `}`
+
+		if (hang == 3) {
+			outDir = path.configPath;
+		} else {
+			outDir = serverPath
+		}
+
+		strc += `
+//前端返回的特殊事件
+export interface keyValue{
+[key:string]:number
+}
+export interface keyValues{
+    [key:string]:number[]
+}
+export interface keyValueString{
+    [key:string]:string
+}
+export type ZixuanSelectCs = [string,string,number];
+export type Wxmspinzhi = [number,number]
+export type Wxmskeys = [number,string,string];
+export type Wxmslm = [number,string];
+`
+		let proPath = `${outDir}Xyc.ts`;
+		fs.writeFileSync(proPath, strc, function (err) {
+			if (err) {
+				console.log('Xyc写入失败:', err);
+			}
+		});
+
+		let proPath1 = `${outDir}apidoc.ts`;
+		fs.writeFileSync(proPath1, apidoc, function (err) {
+			if (err) {
+				console.log('Xyc写入失败:', err);
+			}
+		});
+
+
+
+	} catch (error) {
+		console.log('===', error);
+	}
+
+}
+
+//拷贝  s_to_proto
+function copy_s_to_proto() {
+	fs.copyFile(serverPath + 'Xys.ts', './s_to_proto/Xys.ts', (err) => {
+		console.log('=', err);
+	});
+	fs.copyFile(serverPath + 'Xyc.ts', './s_to_proto/Xyc.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile(serverPath + 'gameMethod.ts', './s_to_proto/gameMethod.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile(serverPath + 'fight.ts', './s_to_proto/fight.ts', (err) => {
+		console.log('=', err);
+	});
+}
+
+//拷贝  proto
+function copy_proto_to_c() {
+	outDir = path.configPath;
+	fs.copyFile('./s_to_proto/Xys.ts', outDir + 'Xys.ts', (err) => {
+		console.log('=', err);
+	});
+	fs.copyFile('./s_to_proto/Xyc.ts', outDir + 'Xyc.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile('./s_to_proto/gameMethod.ts', outDir + 'gameMethod.ts', (err) => {
+		console.log('=', err);
+	});
+
+	fs.copyFile('./s_to_proto/fight.ts', outDir + 'fight.ts', (err) => {
+		console.log('=', err);
+	});
+}
+
+
+/**
+ * 延迟多少毫秒
+ */
+function sleep(ms) {
+	if (ms < 1) {
+		return;
+	}
+	return new Promise((reslove, reject) => {
+		setTimeout(() => {
+			reslove(1);
+		}, ms);
+	});
+}
+
+// 开始解析配置表
+function doExe(res) {
+	// console.log(res);
+	if (res != 'c' && res != 's' && res != 'C' && res != 'S') {
+		console.log('非法输入');
+		return;
+	}
+	if (res == 'c' || res == 'C') {
+		hang = 3;
+	} else {
+		hang = 4;
+	}
+
+	if (hang == 3) {
+		outDir = path.configPath;
+	} else {
+		outDir = serverPath;
+	}
+
+	console.log('\x1b[37m'); // 控制台文字切为白色
+
+
+
+	if (hang == 4) {
+
+		fs.rm(serverPath + outJsonFolder, { recursive: true }, (err, data) => {
+			if (err) {
+				console.log('删除json文件失败' + err);
+			}
+			console.log('删除json文件成功');
+
+			let sendNum = 0
+			let overNum = 0
+			// 解析表格
+			fs.readdirSync(excelDir).forEach((excelName) => {
+				if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
+					excelFiles.push(excelName.split('_')[0]);
+
+					const worker = cluster.fork(excelName);
+					sendNum += 1
+					worker.send({ "hang": 4, "excelName": excelName })
+					worker.on('message', function (mes) {
+						let mesarr = JSON.parse(mes)
+						for (const ar of mesarr.excelFen) {
+							excelFen.push(ar)
+						}
+						for (const key in mesarr.excelAndSheets) {
+							excelAndSheets[key] = mesarr.excelAndSheets[key]
+						}
+						overNum += 1
+						console.log(`配置表解析 发送${sendNum}个,完成${overNum}个`)
+					})
+
+				}
+			});
+
+			const intervalId = setInterval(() => {
+				if (sendNum <= overNum) {
+					createXyc();
+					console.log('*******创建xyc完成*******');
+
+					createGameCfg_s();
+					console.log('*******创建xls对应gameCfg完成*******');
+
+					copy_s_to_proto();
+					console.log('*******拷贝完成*******');
+					exeExcelConfig();
+					console.log('*******创建配置文件完成*******');
+
+					console.log("----全部完成----")
+					clearInterval(intervalId);
+				}
+			}, 1000);
+		});
+	}
+
+
+
+	if (hang == 3) {
+
+		fs.unlink(path.excelPath + outJsonFolder + '/excel.zip', (err, data) => {
+			if (err) {
+				console.log('删除zip文件失败' + err);
+			}
+			console.log('删除zip文件成功');
+			let sendNum = 0
+			let overNum = 0
+			let xls = {}
+			// 解析表格
+			fs.readdirSync(excelDir).forEach((excelName) => {
+				if ((excelName.substr(-4) == '.xls' || excelName.substr(-5) == '.xlsx') && excelName.substr(0, 1) != '~') {
+					excelFiles.push(excelName.split('_')[0]);
+					// doExcel(excelName);
+					xls[excelName] = 1
+					const worker = cluster.fork(excelName);
+					sendNum += 1
+					worker.send({ "hang": 3, "excelName": excelName })
+					worker.on('message', function (mes) {
+						let mesarr = JSON.parse(mes)
+						for (const ar of mesarr.excelFen) {
+							excelFen.push(ar)
+						}
+						for (const key in mesarr.excelAndSheets) {
+							excelAndSheets[key] = mesarr.excelAndSheets[key]
+						}
+						overNum += 1
+						delete xls[excelName]
+						console.log(`配置表解析 发送${sendNum}个,完成${overNum}个`)
+						worker.destroy();
+					})
+
+				}
+			});
+
+			const intervalId = setInterval(() => {
+				if (sendNum <= overNum) {
+					// 生成配置表读取文件(ts)
+					exeExcelConfig_c();
+					console.log('*******创建配置文件完成*******');
+
+					// createXyc();
+					// console.log('*******创建xyc完成*******');
+
+					createGameCfg_c();
+					console.log('*******创建xls对应gameCfg完成*******');
+
+					copy_proto_to_c();
+					console.log('*******拷贝完成*******');
+
+					console.log("----全部完成----")
+					clearInterval(intervalId);
+				}
+			}, 1000);
+
+
+		});
+
+
+	}
+	sleep(4000);
+
+	// if (hang == 3) {
+	//
+	// }
+}
+
+if (!cluster.isMaster) {
+	process.on("message", function (message) {
+		hang = message.hang
+		doExcel(message.excelName)
+		process.send(JSON.stringify({ "excelFen": excelFen, "excelAndSheets": excelAndSheets }))
+		if(hang == 4){
+			process.exit()
+		}
+	});
+	return
+}
+
+if (jiexiTarget == "s" || jiexiTarget == "c") {
+	doExe(jiexiTarget)
+} else {
+	readSyncByRl('exe client->c or server->s:').then((res) => {
+		doExe(res)
+	});
+}
+
+// //---------------------end--------------------  控制台人机交互

+ 1 - 0
node_modules/.bin/acorn

@@ -0,0 +1 @@
+../acorn/bin/acorn

+ 1 - 0
node_modules/.bin/apidoc

@@ -0,0 +1 @@
+../apidoc/bin/apidoc

+ 1 - 0
node_modules/.bin/browserslist

@@ -0,0 +1 @@
+../browserslist/cli.js

+ 1 - 0
node_modules/.bin/crc32

@@ -0,0 +1 @@
+../crc-32/bin/crc32.njs

+ 1 - 0
node_modules/.bin/envinfo

@@ -0,0 +1 @@
+../envinfo/dist/cli.js

+ 1 - 0
node_modules/.bin/esbuild

@@ -0,0 +1 @@
+../esbuild/bin/esbuild

+ 1 - 0
node_modules/.bin/flat

@@ -0,0 +1 @@
+../flat/cli.js

+ 1 - 0
node_modules/.bin/handlebars

@@ -0,0 +1 @@
+../handlebars/bin/handlebars

+ 1 - 0
node_modules/.bin/import-local-fixture

@@ -0,0 +1 @@
+../import-local/fixtures/cli.js

+ 1 - 0
node_modules/.bin/json5

@@ -0,0 +1 @@
+../json5/lib/cli.js

+ 1 - 0
node_modules/.bin/markdown-it

@@ -0,0 +1 @@
+../markdown-it/bin/markdown-it.js

+ 1 - 0
node_modules/.bin/node-which

@@ -0,0 +1 @@
+../which/bin/node-which

+ 1 - 0
node_modules/.bin/nodemon

@@ -0,0 +1 @@
+../nodemon/bin/nodemon.js

+ 1 - 0
node_modules/.bin/nodetouch

@@ -0,0 +1 @@
+../touch/bin/nodetouch.js

+ 1 - 0
node_modules/.bin/nopt

@@ -0,0 +1 @@
+../nopt/bin/nopt.js

+ 1 - 0
node_modules/.bin/resolve

@@ -0,0 +1 @@
+../resolve/bin/resolve

+ 1 - 0
node_modules/.bin/semver

@@ -0,0 +1 @@
+../semver/bin/semver.js

+ 1 - 0
node_modules/.bin/sshpk-conv

@@ -0,0 +1 @@
+../sshpk/bin/sshpk-conv

+ 1 - 0
node_modules/.bin/sshpk-sign

@@ -0,0 +1 @@
+../sshpk/bin/sshpk-sign

+ 1 - 0
node_modules/.bin/sshpk-verify

@@ -0,0 +1 @@
+../sshpk/bin/sshpk-verify

+ 1 - 0
node_modules/.bin/terser

@@ -0,0 +1 @@
+../terser/bin/terser

+ 1 - 0
node_modules/.bin/uglifyjs

@@ -0,0 +1 @@
+../uglify-js/bin/uglifyjs

+ 1 - 0
node_modules/.bin/update-browserslist-db

@@ -0,0 +1 @@
+../update-browserslist-db/cli.js

+ 1 - 0
node_modules/.bin/uuid

@@ -0,0 +1 @@
+../uuid/bin/uuid

+ 1 - 0
node_modules/.bin/webpack

@@ -0,0 +1 @@
+../webpack/bin/webpack.js

+ 1 - 0
node_modules/.bin/webpack-cli

@@ -0,0 +1 @@
+../webpack-cli/bin/cli.js

+ 1 - 0
node_modules/.bin/xlsx

@@ -0,0 +1 @@
+../xlsx/bin/xlsx.njs

+ 2984 - 0
node_modules/.package-lock.json

@@ -0,0 +1,2984 @@
+{
+  "name": "excel2json4ts",
+  "version": "1.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "node_modules/@colors/colors": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
+      "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
+      "engines": {
+        "node": ">=0.1.90"
+      }
+    },
+    "node_modules/@dabh/diagnostics": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
+      "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
+      "dependencies": {
+        "colorspace": "1.1.x",
+        "enabled": "2.0.x",
+        "kuler": "^2.0.0"
+      }
+    },
+    "node_modules/@discoveryjs/json-ext": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+      "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.16.17",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz",
+      "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+      "dependencies": {
+        "@jridgewell/set-array": "^1.2.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/source-map": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+      "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.0",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.4.15",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "node_modules/@types/eslint": {
+      "version": "8.56.5",
+      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz",
+      "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==",
+      "dependencies": {
+        "@types/estree": "*",
+        "@types/json-schema": "*"
+      }
+    },
+    "node_modules/@types/eslint-scope": {
+      "version": "3.7.7",
+      "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+      "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+      "dependencies": {
+        "@types/eslint": "*",
+        "@types/estree": "*"
+      }
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
+    },
+    "node_modules/@types/json-schema": {
+      "version": "7.0.15",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+      "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
+    },
+    "node_modules/@types/node": {
+      "version": "14.0.23",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz",
+      "integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw=="
+    },
+    "node_modules/@types/triple-beam": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
+      "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="
+    },
+    "node_modules/@webassemblyjs/ast": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
+      "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+      "dependencies": {
+        "@webassemblyjs/helper-numbers": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
+      "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw=="
+    },
+    "node_modules/@webassemblyjs/helper-api-error": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
+      "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q=="
+    },
+    "node_modules/@webassemblyjs/helper-buffer": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
+      "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA=="
+    },
+    "node_modules/@webassemblyjs/helper-numbers": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
+      "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
+      "dependencies": {
+        "@webassemblyjs/floating-point-hex-parser": "1.11.6",
+        "@webassemblyjs/helper-api-error": "1.11.6",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
+      "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA=="
+    },
+    "node_modules/@webassemblyjs/helper-wasm-section": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
+      "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+        "@webassemblyjs/wasm-gen": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/ieee754": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
+      "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+      "dependencies": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "node_modules/@webassemblyjs/leb128": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
+      "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+      "dependencies": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@webassemblyjs/utf8": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
+      "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA=="
+    },
+    "node_modules/@webassemblyjs/wasm-edit": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
+      "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+        "@webassemblyjs/helper-wasm-section": "1.11.6",
+        "@webassemblyjs/wasm-gen": "1.11.6",
+        "@webassemblyjs/wasm-opt": "1.11.6",
+        "@webassemblyjs/wasm-parser": "1.11.6",
+        "@webassemblyjs/wast-printer": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-gen": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
+      "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+        "@webassemblyjs/ieee754": "1.11.6",
+        "@webassemblyjs/leb128": "1.11.6",
+        "@webassemblyjs/utf8": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-opt": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
+      "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-buffer": "1.11.6",
+        "@webassemblyjs/wasm-gen": "1.11.6",
+        "@webassemblyjs/wasm-parser": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-parser": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
+      "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@webassemblyjs/helper-api-error": "1.11.6",
+        "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+        "@webassemblyjs/ieee754": "1.11.6",
+        "@webassemblyjs/leb128": "1.11.6",
+        "@webassemblyjs/utf8": "1.11.6"
+      }
+    },
+    "node_modules/@webassemblyjs/wast-printer": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
+      "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+      "dependencies": {
+        "@webassemblyjs/ast": "1.11.6",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@webpack-cli/configtest": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz",
+      "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==",
+      "peerDependencies": {
+        "webpack": "4.x.x || 5.x.x",
+        "webpack-cli": "4.x.x"
+      }
+    },
+    "node_modules/@webpack-cli/info": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz",
+      "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==",
+      "dependencies": {
+        "envinfo": "^7.7.3"
+      },
+      "peerDependencies": {
+        "webpack-cli": "4.x.x"
+      }
+    },
+    "node_modules/@webpack-cli/serve": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz",
+      "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==",
+      "peerDependencies": {
+        "webpack-cli": "4.x.x"
+      },
+      "peerDependenciesMeta": {
+        "webpack-dev-server": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="
+    },
+    "node_modules/@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
+    },
+    "node_modules/abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+    },
+    "node_modules/acorn": {
+      "version": "8.11.3",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
+      "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/acorn-import-assertions": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+      "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
+      "peerDependencies": {
+        "acorn": "^8"
+      }
+    },
+    "node_modules/adler-32": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
+      "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/ajv-keywords": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+      "peerDependencies": {
+        "ajv": "^6.9.1"
+      }
+    },
+    "node_modules/anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/apidoc": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/apidoc/-/apidoc-1.2.0.tgz",
+      "integrity": "sha512-Qagoj7QnqNHbDUDNpU21eLP4hJSAXn6knHtEjRYWTlSEmpYDGSQijejyFXaWGByhfryW8B1gL+6B57UB/F1lxw==",
+      "os": [
+        "darwin",
+        "freebsd",
+        "linux",
+        "openbsd",
+        "win32"
+      ],
+      "dependencies": {
+        "bootstrap": "3.4.1",
+        "commander": "^10.0.0",
+        "diff-match-patch": "^1.0.5",
+        "esbuild-loader": "^2.16.0",
+        "expose-loader": "^4.0.0",
+        "fs-extra": "^11.0.0",
+        "glob": "^7.2.0",
+        "handlebars": "^4.7.7",
+        "iconv-lite": "^0.6.3",
+        "jquery": "^3.6.0",
+        "klaw-sync": "^6.0.0",
+        "lodash": "^4.17.21",
+        "markdown-it": "^12.2.0",
+        "nodemon": "^3.0.1",
+        "prismjs": "^1.25.0",
+        "semver": "^7.5.0",
+        "style-loader": "^3.3.1",
+        "webpack": "^5.64.2",
+        "webpack-cli": "^4.9.1",
+        "winston": "^3.3.3"
+      },
+      "bin": {
+        "apidoc": "bin/apidoc"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      }
+    },
+    "node_modules/archiver": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz",
+      "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==",
+      "dependencies": {
+        "archiver-utils": "^2.1.0",
+        "async": "^3.2.3",
+        "buffer-crc32": "^0.2.1",
+        "readable-stream": "^3.6.0",
+        "readdir-glob": "^1.0.0",
+        "tar-stream": "^2.2.0",
+        "zip-stream": "^4.1.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/archiver-utils": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
+      "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
+      "dependencies": {
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.2.0",
+        "lazystream": "^1.0.0",
+        "lodash.defaults": "^4.2.0",
+        "lodash.difference": "^4.5.0",
+        "lodash.flatten": "^4.4.0",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.union": "^4.6.0",
+        "normalize-path": "^3.0.0",
+        "readable-stream": "^2.0.0"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/archiver-utils/node_modules/readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/archiver-utils/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "node_modules/archiver-utils/node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+    },
+    "node_modules/asn1": {
+      "version": "0.2.6",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+      "dependencies": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "node_modules/assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/async": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+      "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "node_modules/aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/aws4": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+      "dependencies": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "node_modules/big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/bl": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+      "dependencies": {
+        "buffer": "^5.5.0",
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.4.0"
+      }
+    },
+    "node_modules/bootstrap": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz",
+      "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "dependencies": {
+        "fill-range": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.23.0",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+      "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "caniuse-lite": "^1.0.30001587",
+        "electron-to-chromium": "^1.4.668",
+        "node-releases": "^2.0.14",
+        "update-browserslist-db": "^1.0.13"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/buffer-crc32": {
+      "version": "0.2.13",
+      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/buffer-from": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001594",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz",
+      "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ]
+    },
+    "node_modules/caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
+    },
+    "node_modules/cfb": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
+      "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
+      "dependencies": {
+        "adler-32": "~1.3.0",
+        "crc-32": "~1.2.0"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/chokidar": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/chrome-trace-event": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+      "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+      "engines": {
+        "node": ">=6.0"
+      }
+    },
+    "node_modules/clone-deep": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+      "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+      "dependencies": {
+        "is-plain-object": "^2.0.4",
+        "kind-of": "^6.0.2",
+        "shallow-clone": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/codepage": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
+      "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/color": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
+      "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+      "dependencies": {
+        "color-convert": "^1.9.3",
+        "color-string": "^1.6.0"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+    },
+    "node_modules/color-string": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+      "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+      "dependencies": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
+    "node_modules/colorette": {
+      "version": "2.0.20",
+      "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+      "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="
+    },
+    "node_modules/colorspace": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
+      "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
+      "dependencies": {
+        "color": "^3.1.3",
+        "text-hex": "1.0.x"
+      }
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/commander": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+      "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+      "engines": {
+        "node": ">=14"
+      }
+    },
+    "node_modules/compress-commons": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz",
+      "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==",
+      "dependencies": {
+        "buffer-crc32": "^0.2.13",
+        "crc32-stream": "^4.0.2",
+        "normalize-path": "^3.0.0",
+        "readable-stream": "^3.6.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+    },
+    "node_modules/core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
+    },
+    "node_modules/crc-32": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
+      "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
+      "bin": {
+        "crc32": "bin/crc32.njs"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/crc32-stream": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz",
+      "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==",
+      "dependencies": {
+        "crc-32": "^1.2.0",
+        "readable-stream": "^3.4.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/cross-spawn": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+      "dependencies": {
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/diff-match-patch": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+      "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+    },
+    "node_modules/ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+      "dependencies": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.4.692",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.692.tgz",
+      "integrity": "sha512-d5rZRka9n2Y3MkWRN74IoAsxR0HK3yaAt7T50e3iT9VZmCCQDT3geXUO5ZRMhDToa1pkCeQXuNo+0g+NfDOVPA=="
+    },
+    "node_modules/emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/enabled": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
+      "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
+    },
+    "node_modules/end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
+    "node_modules/enhanced-resolve": {
+      "version": "5.15.1",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz",
+      "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==",
+      "dependencies": {
+        "graceful-fs": "^4.2.4",
+        "tapable": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/entities": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+      "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/envinfo": {
+      "version": "7.11.1",
+      "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz",
+      "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==",
+      "bin": {
+        "envinfo": "dist/cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/es-module-lexer": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
+      "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w=="
+    },
+    "node_modules/esbuild": {
+      "version": "0.16.17",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz",
+      "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==",
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/android-arm": "0.16.17",
+        "@esbuild/android-arm64": "0.16.17",
+        "@esbuild/android-x64": "0.16.17",
+        "@esbuild/darwin-arm64": "0.16.17",
+        "@esbuild/darwin-x64": "0.16.17",
+        "@esbuild/freebsd-arm64": "0.16.17",
+        "@esbuild/freebsd-x64": "0.16.17",
+        "@esbuild/linux-arm": "0.16.17",
+        "@esbuild/linux-arm64": "0.16.17",
+        "@esbuild/linux-ia32": "0.16.17",
+        "@esbuild/linux-loong64": "0.16.17",
+        "@esbuild/linux-mips64el": "0.16.17",
+        "@esbuild/linux-ppc64": "0.16.17",
+        "@esbuild/linux-riscv64": "0.16.17",
+        "@esbuild/linux-s390x": "0.16.17",
+        "@esbuild/linux-x64": "0.16.17",
+        "@esbuild/netbsd-x64": "0.16.17",
+        "@esbuild/openbsd-x64": "0.16.17",
+        "@esbuild/sunos-x64": "0.16.17",
+        "@esbuild/win32-arm64": "0.16.17",
+        "@esbuild/win32-ia32": "0.16.17",
+        "@esbuild/win32-x64": "0.16.17"
+      }
+    },
+    "node_modules/esbuild-loader": {
+      "version": "2.21.0",
+      "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.21.0.tgz",
+      "integrity": "sha512-k7ijTkCT43YBSZ6+fBCW1Gin7s46RrJ0VQaM8qA7lq7W+OLsGgtLyFV8470FzYi/4TeDexniTBTPTwZUnXXR5g==",
+      "dependencies": {
+        "esbuild": "^0.16.17",
+        "joycon": "^3.0.1",
+        "json5": "^2.2.0",
+        "loader-utils": "^2.0.0",
+        "tapable": "^2.2.0",
+        "webpack-sources": "^1.4.3"
+      },
+      "funding": {
+        "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1"
+      },
+      "peerDependencies": {
+        "webpack": "^4.40.0 || ^5.0.0"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+      "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/eslint-scope": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/esrecurse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+      "dependencies": {
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/esrecurse/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/events": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+      "engines": {
+        "node": ">=0.8.x"
+      }
+    },
+    "node_modules/expose-loader": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/expose-loader/-/expose-loader-4.1.0.tgz",
+      "integrity": "sha512-oLAesnzerwDGGADzBMnu0LPqqnlVz6e2V9lTa+/4X6VeW9W93x/nJpw05WBrcIdbqXm/EdnEQpiVDFFiQXuNfg==",
+      "engines": {
+        "node": ">= 14.15.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.0.0"
+      }
+    },
+    "node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "node_modules/extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+      "engines": [
+        "node >=0.6.0"
+      ]
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+    },
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+    },
+    "node_modules/fastest-levenshtein": {
+      "version": "1.0.16",
+      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+      "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+      "engines": {
+        "node": ">= 4.9.1"
+      }
+    },
+    "node_modules/fecha": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
+      "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
+    },
+    "node_modules/fill-range": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/flat": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+      "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+      "bin": {
+        "flat": "cli.js"
+      }
+    },
+    "node_modules/fn.name": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
+      "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
+    },
+    "node_modules/forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 0.12"
+      }
+    },
+    "node_modules/frac": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
+      "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/fs-constants": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+    },
+    "node_modules/fs-extra": {
+      "version": "11.2.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
+      "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
+      "dependencies": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=14.14"
+      }
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/glob-to-regexp": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
+    },
+    "node_modules/graceful-fs": {
+      "version": "4.2.10",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+    },
+    "node_modules/handlebars": {
+      "version": "4.7.8",
+      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+      "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
+      "dependencies": {
+        "minimist": "^1.2.5",
+        "neo-async": "^2.6.2",
+        "source-map": "^0.6.1",
+        "wordwrap": "^1.0.0"
+      },
+      "bin": {
+        "handlebars": "bin/handlebars"
+      },
+      "engines": {
+        "node": ">=0.4.7"
+      },
+      "optionalDependencies": {
+        "uglify-js": "^3.1.4"
+      }
+    },
+    "node_modules/har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+      "deprecated": "this library is no longer supported",
+      "dependencies": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/hasown": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
+      "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
+      "dependencies": {
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.8",
+        "npm": ">=1.3.7"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/ignore-by-default": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+      "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="
+    },
+    "node_modules/import-local": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+      "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+      "dependencies": {
+        "pkg-dir": "^4.2.0",
+        "resolve-cwd": "^3.0.0"
+      },
+      "bin": {
+        "import-local-fixture": "fixtures/cli.js"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "node_modules/interpret": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
+      "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/is-arrayish": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.13.1",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
+      "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
+      "dependencies": {
+        "hasown": "^2.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
+    },
+    "node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+    },
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+    },
+    "node_modules/isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
+    },
+    "node_modules/jest-worker": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+      "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+      "dependencies": {
+        "@types/node": "*",
+        "merge-stream": "^2.0.0",
+        "supports-color": "^8.0.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      }
+    },
+    "node_modules/jest-worker/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/jest-worker/node_modules/supports-color": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
+      }
+    },
+    "node_modules/joycon": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
+      "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/jquery": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
+      "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
+    },
+    "node_modules/jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
+    },
+    "node_modules/json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
+    },
+    "node_modules/json-schema": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+    },
+    "node_modules/json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
+    },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "dependencies": {
+        "universalify": "^2.0.0"
+      },
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/jsprim": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+      "dependencies": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.4.0",
+        "verror": "1.10.0"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/klaw-sync": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
+      "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
+      "dependencies": {
+        "graceful-fs": "^4.1.11"
+      }
+    },
+    "node_modules/kuler": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
+      "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
+    },
+    "node_modules/lazystream": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
+      "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
+      "dependencies": {
+        "readable-stream": "^2.0.5"
+      },
+      "engines": {
+        "node": ">= 0.6.3"
+      }
+    },
+    "node_modules/lazystream/node_modules/readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/lazystream/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "node_modules/lazystream/node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/linkify-it": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+      "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+      "dependencies": {
+        "uc.micro": "^1.0.1"
+      }
+    },
+    "node_modules/loader-runner": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+      "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+      "engines": {
+        "node": ">=6.11.5"
+      }
+    },
+    "node_modules/loader-utils": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+      "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+      "dependencies": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^2.1.2"
+      },
+      "engines": {
+        "node": ">=8.9.0"
+      }
+    },
+    "node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
+    "node_modules/lodash.defaults": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+      "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
+    },
+    "node_modules/lodash.difference": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
+      "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA=="
+    },
+    "node_modules/lodash.flatten": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
+      "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g=="
+    },
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "node_modules/lodash.union": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
+      "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw=="
+    },
+    "node_modules/logform": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz",
+      "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==",
+      "dependencies": {
+        "@colors/colors": "1.6.0",
+        "@types/triple-beam": "^1.3.2",
+        "fecha": "^4.2.0",
+        "ms": "^2.1.1",
+        "safe-stable-stringify": "^2.3.1",
+        "triple-beam": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/markdown-it": {
+      "version": "12.3.2",
+      "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+      "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+      "dependencies": {
+        "argparse": "^2.0.1",
+        "entities": "~2.1.0",
+        "linkify-it": "^3.0.1",
+        "mdurl": "^1.0.1",
+        "uc.micro": "^1.0.5"
+      },
+      "bin": {
+        "markdown-it": "bin/markdown-it.js"
+      }
+    },
+    "node_modules/mdurl": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+      "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g=="
+    },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "node_modules/neo-async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
+    },
+    "node_modules/node-releases": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+      "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
+    },
+    "node_modules/nodemon": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz",
+      "integrity": "sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==",
+      "dependencies": {
+        "chokidar": "^3.5.2",
+        "debug": "^4",
+        "ignore-by-default": "^1.0.1",
+        "minimatch": "^3.1.2",
+        "pstree.remy": "^1.1.8",
+        "semver": "^7.5.3",
+        "simple-update-notifier": "^2.0.0",
+        "supports-color": "^5.5.0",
+        "touch": "^3.1.0",
+        "undefsafe": "^2.0.5"
+      },
+      "bin": {
+        "nodemon": "bin/nodemon.js"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/nodemon"
+      }
+    },
+    "node_modules/nopt": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+      "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
+      "dependencies": {
+        "abbrev": "1"
+      },
+      "bin": {
+        "nopt": "bin/nopt.js"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/one-time": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
+      "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
+      "dependencies": {
+        "fn.name": "1.x.x"
+      }
+    },
+    "node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/path-exists": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/path-key": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/path-parse": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+    },
+    "node_modules/performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
+    },
+    "node_modules/picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/pkg-dir": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+      "dependencies": {
+        "find-up": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/prismjs": {
+      "version": "1.29.0",
+      "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
+      "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+    },
+    "node_modules/psl": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+      "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
+    },
+    "node_modules/pstree.remy": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+      "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="
+    },
+    "node_modules/punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/readable-stream": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/readdir-glob": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.2.tgz",
+      "integrity": "sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA==",
+      "dependencies": {
+        "minimatch": "^5.1.0"
+      }
+    },
+    "node_modules/readdir-glob/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/readdir-glob/node_modules/minimatch": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
+      "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/rechoir": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
+      "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
+      "dependencies": {
+        "resolve": "^1.9.0"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
+      "dependencies": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/resolve": {
+      "version": "1.22.8",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+      "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+      "dependencies": {
+        "is-core-module": "^2.13.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/resolve-cwd": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+      "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+      "dependencies": {
+        "resolve-from": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/resolve-from": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/safe-stable-stringify": {
+      "version": "2.4.3",
+      "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
+      "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
+    "node_modules/schema-utils": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+      "dependencies": {
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/semver": {
+      "version": "7.6.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+      "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/serialize-javascript": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+      "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+      "dependencies": {
+        "randombytes": "^2.1.0"
+      }
+    },
+    "node_modules/shallow-clone": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+      "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+      "dependencies": {
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shebang-command": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+      "dependencies": {
+        "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shebang-regex": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+      "dependencies": {
+        "is-arrayish": "^0.3.1"
+      }
+    },
+    "node_modules/simple-update-notifier": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
+      "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
+      "dependencies": {
+        "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/source-list-map": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw=="
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.21",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/ssf": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
+      "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
+      "dependencies": {
+        "frac": "~1.1.2"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/sshpk": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+      "dependencies": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      },
+      "bin": {
+        "sshpk-conv": "bin/sshpk-conv",
+        "sshpk-sign": "bin/sshpk-sign",
+        "sshpk-verify": "bin/sshpk-verify"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/stack-trace": {
+      "version": "0.0.10",
+      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
+    "node_modules/style-loader": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz",
+      "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==",
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.0.0"
+      }
+    },
+    "node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/tapable": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+      "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/tar-stream": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+      "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+      "dependencies": {
+        "bl": "^4.0.3",
+        "end-of-stream": "^1.4.1",
+        "fs-constants": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^3.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/terser": {
+      "version": "5.28.1",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz",
+      "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==",
+      "dependencies": {
+        "@jridgewell/source-map": "^0.3.3",
+        "acorn": "^8.8.2",
+        "commander": "^2.20.0",
+        "source-map-support": "~0.5.20"
+      },
+      "bin": {
+        "terser": "bin/terser"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/terser-webpack-plugin": {
+      "version": "5.3.10",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
+      "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
+      "dependencies": {
+        "@jridgewell/trace-mapping": "^0.3.20",
+        "jest-worker": "^27.4.5",
+        "schema-utils": "^3.1.1",
+        "serialize-javascript": "^6.0.1",
+        "terser": "^5.26.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.1.0"
+      },
+      "peerDependenciesMeta": {
+        "@swc/core": {
+          "optional": true
+        },
+        "esbuild": {
+          "optional": true
+        },
+        "uglify-js": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/terser/node_modules/commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+    },
+    "node_modules/text-hex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
+      "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/touch": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+      "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+      "dependencies": {
+        "nopt": "~1.0.10"
+      },
+      "bin": {
+        "nodetouch": "bin/nodetouch.js"
+      }
+    },
+    "node_modules/tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "dependencies": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/triple-beam": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
+      "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
+      "engines": {
+        "node": ">= 14.0.0"
+      }
+    },
+    "node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
+    },
+    "node_modules/uc.micro": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+      "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
+    },
+    "node_modules/uglify-js": {
+      "version": "3.17.4",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
+      "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
+      "optional": true,
+      "bin": {
+        "uglifyjs": "bin/uglifyjs"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/undefsafe": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+      "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA=="
+    },
+    "node_modules/universalify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/update-browserslist-db": {
+      "version": "1.0.13",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+      "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      },
+      "bin": {
+        "update-browserslist-db": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
+    "node_modules/uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+    },
+    "node_modules/uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "node_modules/watchpack": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
+      "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+      "dependencies": {
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.1.2"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/webpack": {
+      "version": "5.90.3",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz",
+      "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==",
+      "dependencies": {
+        "@types/eslint-scope": "^3.7.3",
+        "@types/estree": "^1.0.5",
+        "@webassemblyjs/ast": "^1.11.5",
+        "@webassemblyjs/wasm-edit": "^1.11.5",
+        "@webassemblyjs/wasm-parser": "^1.11.5",
+        "acorn": "^8.7.1",
+        "acorn-import-assertions": "^1.9.0",
+        "browserslist": "^4.21.10",
+        "chrome-trace-event": "^1.0.2",
+        "enhanced-resolve": "^5.15.0",
+        "es-module-lexer": "^1.2.1",
+        "eslint-scope": "5.1.1",
+        "events": "^3.2.0",
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.2.9",
+        "json-parse-even-better-errors": "^2.3.1",
+        "loader-runner": "^4.2.0",
+        "mime-types": "^2.1.27",
+        "neo-async": "^2.6.2",
+        "schema-utils": "^3.2.0",
+        "tapable": "^2.1.1",
+        "terser-webpack-plugin": "^5.3.10",
+        "watchpack": "^2.4.0",
+        "webpack-sources": "^3.2.3"
+      },
+      "bin": {
+        "webpack": "bin/webpack.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependenciesMeta": {
+        "webpack-cli": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-cli": {
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz",
+      "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==",
+      "dependencies": {
+        "@discoveryjs/json-ext": "^0.5.0",
+        "@webpack-cli/configtest": "^1.2.0",
+        "@webpack-cli/info": "^1.5.0",
+        "@webpack-cli/serve": "^1.7.0",
+        "colorette": "^2.0.14",
+        "commander": "^7.0.0",
+        "cross-spawn": "^7.0.3",
+        "fastest-levenshtein": "^1.0.12",
+        "import-local": "^3.0.2",
+        "interpret": "^2.2.0",
+        "rechoir": "^0.7.0",
+        "webpack-merge": "^5.7.3"
+      },
+      "bin": {
+        "webpack-cli": "bin/cli.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "4.x.x || 5.x.x"
+      },
+      "peerDependenciesMeta": {
+        "@webpack-cli/generators": {
+          "optional": true
+        },
+        "@webpack-cli/migrate": {
+          "optional": true
+        },
+        "webpack-bundle-analyzer": {
+          "optional": true
+        },
+        "webpack-dev-server": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-cli/node_modules/commander": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+      "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/webpack-merge": {
+      "version": "5.10.0",
+      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
+      "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
+      "dependencies": {
+        "clone-deep": "^4.0.1",
+        "flat": "^5.0.2",
+        "wildcard": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/webpack-sources": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+      "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+      "dependencies": {
+        "source-list-map": "^2.0.0",
+        "source-map": "~0.6.1"
+      }
+    },
+    "node_modules/webpack/node_modules/webpack-sources": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+      "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/which": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/wildcard": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
+      "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ=="
+    },
+    "node_modules/winston": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/winston/-/winston-3.12.0.tgz",
+      "integrity": "sha512-OwbxKaOlESDi01mC9rkM0dQqQt2I8DAUMRLZ/HpbwvDXm85IryEHgoogy5fziQy38PntgZsLlhAYHz//UPHZ5w==",
+      "dependencies": {
+        "@colors/colors": "^1.6.0",
+        "@dabh/diagnostics": "^2.0.2",
+        "async": "^3.2.3",
+        "is-stream": "^2.0.0",
+        "logform": "^2.4.0",
+        "one-time": "^1.0.0",
+        "readable-stream": "^3.4.0",
+        "safe-stable-stringify": "^2.3.1",
+        "stack-trace": "0.0.x",
+        "triple-beam": "^1.3.0",
+        "winston-transport": "^4.7.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/winston-transport": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz",
+      "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==",
+      "dependencies": {
+        "logform": "^2.3.2",
+        "readable-stream": "^3.6.0",
+        "triple-beam": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/wmf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
+      "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/word": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
+      "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="
+    },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+    },
+    "node_modules/xlsx": {
+      "version": "0.18.5",
+      "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
+      "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
+      "dependencies": {
+        "adler-32": "~1.3.0",
+        "cfb": "~1.2.1",
+        "codepage": "~1.15.0",
+        "crc-32": "~1.2.1",
+        "ssf": "~0.11.2",
+        "wmf": "~1.0.1",
+        "word": "~0.3.0"
+      },
+      "bin": {
+        "xlsx": "bin/xlsx.njs"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+    },
+    "node_modules/zip-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz",
+      "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==",
+      "dependencies": {
+        "archiver-utils": "^2.1.0",
+        "compress-commons": "^4.1.0",
+        "readable-stream": "^3.6.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    }
+  }
+}

+ 26 - 0
node_modules/@colors/colors/LICENSE

@@ -0,0 +1,26 @@
+MIT License
+
+Original Library
+  - Copyright (c) Marak Squires
+
+Additional Functionality
+ - Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+ - Copyright (c) DABH (https://github.com/DABH)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 219 - 0
node_modules/@colors/colors/README.md

@@ -0,0 +1,219 @@
+# @colors/colors ("colors.js")
+[![Build Status](https://github.com/DABH/colors.js/actions/workflows/ci.yml/badge.svg)](https://github.com/DABH/colors.js/actions/workflows/ci.yml)
+[![version](https://img.shields.io/npm/v/@colors/colors.svg)](https://www.npmjs.org/package/@colors/colors)
+
+Please check out the [roadmap](ROADMAP.md) for upcoming features and releases.  Please open Issues to provide feedback.
+
+## get color and style in your node.js console
+
+![Demo](https://raw.githubusercontent.com/DABH/colors.js/master/screenshots/colors.png)
+
+## Installation
+
+    npm install @colors/colors
+
+## colors and styles!
+
+### text colors
+
+  - black
+  - red
+  - green
+  - yellow
+  - blue
+  - magenta
+  - cyan
+  - white
+  - gray
+  - grey
+
+### bright text colors
+
+  - brightRed
+  - brightGreen
+  - brightYellow
+  - brightBlue
+  - brightMagenta
+  - brightCyan
+  - brightWhite
+
+### background colors
+
+  - bgBlack
+  - bgRed
+  - bgGreen
+  - bgYellow
+  - bgBlue
+  - bgMagenta
+  - bgCyan
+  - bgWhite
+  - bgGray
+  - bgGrey
+
+### bright background colors
+
+  - bgBrightRed
+  - bgBrightGreen
+  - bgBrightYellow
+  - bgBrightBlue
+  - bgBrightMagenta
+  - bgBrightCyan
+  - bgBrightWhite
+
+### styles
+
+  - reset
+  - bold
+  - dim
+  - italic
+  - underline
+  - inverse
+  - hidden
+  - strikethrough
+
+### extras
+
+  - rainbow
+  - zebra
+  - america
+  - trap
+  - random
+
+
+## Usage
+
+By popular demand, `@colors/colors` now ships with two types of usages!
+
+The super nifty way
+
+```js
+var colors = require('@colors/colors');
+
+console.log('hello'.green); // outputs green text
+console.log('i like cake and pies'.underline.red); // outputs red underlined text
+console.log('inverse the color'.inverse); // inverses the color
+console.log('OMG Rainbows!'.rainbow); // rainbow
+console.log('Run the trap'.trap); // Drops the bass
+
+```
+
+or a slightly less nifty way which doesn't extend `String.prototype`
+
+```js
+var colors = require('@colors/colors/safe');
+
+console.log(colors.green('hello')); // outputs green text
+console.log(colors.red.underline('i like cake and pies')); // outputs red underlined text
+console.log(colors.inverse('inverse the color')); // inverses the color
+console.log(colors.rainbow('OMG Rainbows!')); // rainbow
+console.log(colors.trap('Run the trap')); // Drops the bass
+
+```
+
+I prefer the first way. Some people seem to be afraid of extending `String.prototype` and prefer the second way. 
+
+If you are writing good code you will never have an issue with the first approach. If you really don't want to touch `String.prototype`, the second usage will not touch `String` native object.
+
+## Enabling/Disabling Colors
+
+The package will auto-detect whether your terminal can use colors and enable/disable accordingly. When colors are disabled, the color functions do nothing. You can override this with a command-line flag:
+
+```bash
+node myapp.js --no-color
+node myapp.js --color=false
+
+node myapp.js --color
+node myapp.js --color=true
+node myapp.js --color=always
+
+FORCE_COLOR=1 node myapp.js
+```
+
+Or in code:
+
+```javascript
+var colors = require('@colors/colors');
+colors.enable();
+colors.disable();
+```
+
+## Console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data)
+
+```js
+var name = 'Beowulf';
+console.log(colors.green('Hello %s'), name);
+// outputs -> 'Hello Beowulf'
+```
+
+## Custom themes
+
+### Using standard API
+
+```js
+
+var colors = require('@colors/colors');
+
+colors.setTheme({
+  silly: 'rainbow',
+  input: 'grey',
+  verbose: 'cyan',
+  prompt: 'grey',
+  info: 'green',
+  data: 'grey',
+  help: 'cyan',
+  warn: 'yellow',
+  debug: 'blue',
+  error: 'red'
+});
+
+// outputs red text
+console.log("this is an error".error);
+
+// outputs yellow text
+console.log("this is a warning".warn);
+```
+
+### Using string safe API
+
+```js
+var colors = require('@colors/colors/safe');
+
+// set single property
+var error = colors.red;
+error('this is red');
+
+// set theme
+colors.setTheme({
+  silly: 'rainbow',
+  input: 'grey',
+  verbose: 'cyan',
+  prompt: 'grey',
+  info: 'green',
+  data: 'grey',
+  help: 'cyan',
+  warn: 'yellow',
+  debug: 'blue',
+  error: 'red'
+});
+
+// outputs red text
+console.log(colors.error("this is an error"));
+
+// outputs yellow text
+console.log(colors.warn("this is a warning"));
+
+```
+
+### Combining Colors
+
+```javascript
+var colors = require('@colors/colors');
+
+colors.setTheme({
+  custom: ['red', 'underline']
+});
+
+console.log('test'.custom);
+```
+
+*Protip: There is a secret undocumented style in `colors`. If you find the style you can summon him.*

+ 83 - 0
node_modules/@colors/colors/examples/normal-usage.js

@@ -0,0 +1,83 @@
+var colors = require('../lib/index');
+
+console.log('First some yellow text'.yellow);
+
+console.log('Underline that text'.yellow.underline);
+
+console.log('Make it bold and red'.red.bold);
+
+console.log(('Double Raindows All Day Long').rainbow);
+
+console.log('Drop the bass'.trap);
+
+console.log('DROP THE RAINBOW BASS'.trap.rainbow);
+
+// styles not widely supported
+console.log('Chains are also cool.'.bold.italic.underline.red);
+
+// styles not widely supported
+console.log('So '.green + 'are'.underline + ' ' + 'inverse'.inverse
+  + ' styles! '.yellow.bold);
+console.log('Zebras are so fun!'.zebra);
+
+//
+// Remark: .strikethrough may not work with Mac OS Terminal App
+//
+console.log('This is ' + 'not'.strikethrough + ' fun.');
+
+console.log('Background color attack!'.black.bgWhite);
+console.log('Use random styles on everything!'.random);
+console.log('America, Heck Yeah!'.america);
+
+// eslint-disable-next-line max-len
+console.log('Blindingly '.brightCyan + 'bright? '.brightRed + 'Why '.brightYellow + 'not?!'.brightGreen);
+
+console.log('Setting themes is useful');
+
+//
+// Custom themes
+//
+console.log('Generic logging theme as JSON'.green.bold.underline);
+// Load theme with JSON literal
+colors.setTheme({
+  silly: 'rainbow',
+  input: 'grey',
+  verbose: 'cyan',
+  prompt: 'grey',
+  info: 'green',
+  data: 'grey',
+  help: 'cyan',
+  warn: 'yellow',
+  debug: 'blue',
+  error: 'red',
+});
+
+// outputs red text
+console.log('this is an error'.error);
+
+// outputs yellow text
+console.log('this is a warning'.warn);
+
+// outputs grey text
+console.log('this is an input'.input);
+
+console.log('Generic logging theme as file'.green.bold.underline);
+
+// Load a theme from file
+try {
+  colors.setTheme(require(__dirname + '/../themes/generic-logging.js'));
+} catch (err) {
+  console.log(err);
+}
+
+// outputs red text
+console.log('this is an error'.error);
+
+// outputs yellow text
+console.log('this is a warning'.warn);
+
+// outputs grey text
+console.log('this is an input'.input);
+
+// console.log("Don't summon".zalgo)
+

+ 80 - 0
node_modules/@colors/colors/examples/safe-string.js

@@ -0,0 +1,80 @@
+var colors = require('../safe');
+
+console.log(colors.yellow('First some yellow text'));
+
+console.log(colors.yellow.underline('Underline that text'));
+
+console.log(colors.red.bold('Make it bold and red'));
+
+console.log(colors.rainbow('Double Raindows All Day Long'));
+
+console.log(colors.trap('Drop the bass'));
+
+console.log(colors.rainbow(colors.trap('DROP THE RAINBOW BASS')));
+
+// styles not widely supported
+console.log(colors.bold.italic.underline.red('Chains are also cool.'));
+
+// styles not widely supported
+console.log(colors.green('So ') + colors.underline('are') + ' '
+  + colors.inverse('inverse') + colors.yellow.bold(' styles! '));
+
+console.log(colors.zebra('Zebras are so fun!'));
+
+console.log('This is ' + colors.strikethrough('not') + ' fun.');
+
+
+console.log(colors.black.bgWhite('Background color attack!'));
+console.log(colors.random('Use random styles on everything!'));
+console.log(colors.america('America, Heck Yeah!'));
+
+// eslint-disable-next-line max-len
+console.log(colors.brightCyan('Blindingly ') + colors.brightRed('bright? ') + colors.brightYellow('Why ') + colors.brightGreen('not?!'));
+
+console.log('Setting themes is useful');
+
+//
+// Custom themes
+//
+// console.log('Generic logging theme as JSON'.green.bold.underline);
+// Load theme with JSON literal
+colors.setTheme({
+  silly: 'rainbow',
+  input: 'blue',
+  verbose: 'cyan',
+  prompt: 'grey',
+  info: 'green',
+  data: 'grey',
+  help: 'cyan',
+  warn: 'yellow',
+  debug: 'blue',
+  error: 'red',
+});
+
+// outputs red text
+console.log(colors.error('this is an error'));
+
+// outputs yellow text
+console.log(colors.warn('this is a warning'));
+
+// outputs blue text
+console.log(colors.input('this is an input'));
+
+
+// console.log('Generic logging theme as file'.green.bold.underline);
+
+// Load a theme from file
+colors.setTheme(require(__dirname + '/../themes/generic-logging.js'));
+
+// outputs red text
+console.log(colors.error('this is an error'));
+
+// outputs yellow text
+console.log(colors.warn('this is a warning'));
+
+// outputs grey text
+console.log(colors.input('this is an input'));
+
+// console.log(colors.zalgo("Don't summon him"))
+
+

+ 184 - 0
node_modules/@colors/colors/index.d.ts

@@ -0,0 +1,184 @@
+// Type definitions for @colors/colors 1.4+
+// Project: https://github.com/Marak/colors.js
+// Definitions by: Bart van der Schoor <https://github.com/Bartvds>, Staffan Eketorp <https://github.com/staeke>
+// Definitions: https://github.com/DABH/colors.js
+
+export interface Color {
+    (text: string): string;
+
+    strip: Color;
+    stripColors: Color;
+
+    black: Color;
+    red: Color;
+    green: Color;
+    yellow: Color;
+    blue: Color;
+    magenta: Color;
+    cyan: Color;
+    white: Color;
+    gray: Color;
+    grey: Color;
+
+    brightRed: Color;
+    brightGreen: Color;
+    brightYellow: Color;
+    brightBlue: Color;
+    brightMagenta: Color;
+    brightCyan: Color;
+    brightWhite: Color;
+
+    bgBlack: Color;
+    bgRed: Color;
+    bgGreen: Color;
+    bgYellow: Color;
+    bgBlue: Color;
+    bgMagenta: Color;
+    bgCyan: Color;
+    bgWhite: Color;
+
+    bgBrightRed: Color;
+    bgBrightGreen: Color;
+    bgBrightYellow: Color;
+    bgBrightBlue: Color;
+    bgBrightMagenta: Color;
+    bgBrightCyan: Color;
+    bgBrightWhite: Color;
+
+    reset: Color;
+    bold: Color;
+    dim: Color;
+    italic: Color;
+    underline: Color;
+    inverse: Color;
+    hidden: Color;
+    strikethrough: Color;
+
+    rainbow: Color;
+    zebra: Color;
+    america: Color;
+    trap: Color;
+    random: Color;
+    zalgo: Color;
+}
+
+export function enable(): void;
+export function disable(): void;
+export function setTheme(theme: any): void;
+
+export let enabled: boolean;
+
+export const strip: Color;
+export const stripColors: Color;
+
+export const black: Color;
+export const red: Color;
+export const green: Color;
+export const yellow: Color;
+export const blue: Color;
+export const magenta: Color;
+export const cyan: Color;
+export const white: Color;
+export const gray: Color;
+export const grey: Color;
+
+export const brightRed: Color;
+export const brightGreen: Color;
+export const brightYellow: Color;
+export const brightBlue: Color;
+export const brightMagenta: Color;
+export const brightCyan: Color;
+export const brightWhite: Color;
+
+export const bgBlack: Color;
+export const bgRed: Color;
+export const bgGreen: Color;
+export const bgYellow: Color;
+export const bgBlue: Color;
+export const bgMagenta: Color;
+export const bgCyan: Color;
+export const bgWhite: Color;
+
+export const bgBrightRed: Color;
+export const bgBrightGreen: Color;
+export const bgBrightYellow: Color;
+export const bgBrightBlue: Color;
+export const bgBrightMagenta: Color;
+export const bgBrightCyan: Color;
+export const bgBrightWhite: Color;
+
+export const reset: Color;
+export const bold: Color;
+export const dim: Color;
+export const italic: Color;
+export const underline: Color;
+export const inverse: Color;
+export const hidden: Color;
+export const strikethrough: Color;
+
+export const rainbow: Color;
+export const zebra: Color;
+export const america: Color;
+export const trap: Color;
+export const random: Color;
+export const zalgo: Color;
+
+declare global {
+    interface String {
+        strip: string;
+        stripColors: string;
+
+        black: string;
+        red: string;
+        green: string;
+        yellow: string;
+        blue: string;
+        magenta: string;
+        cyan: string;
+        white: string;
+        gray: string;
+        grey: string;
+
+        brightRed: string;
+        brightGreen: string;
+        brightYellow: string;
+        brightBlue: string;
+        brightMagenta: string;
+        brightCyan: string;
+        brightWhite: string;
+
+        bgBlack: string;
+        bgRed: string;
+        bgGreen: string;
+        bgYellow: string;
+        bgBlue: string;
+        bgMagenta: string;
+        bgCyan: string;
+        bgWhite: string;
+
+        bgBrightRed: string;
+        bgBrightGreen: string;
+        bgBrightYellow: string;
+        bgBrightBlue: string;
+        bgBrightMagenta: string;
+        bgBrightCyan: string;
+        bgBrightWhite: string;
+
+        reset: string;
+        // @ts-ignore
+        bold: string;
+        dim: string;
+        italic: string;
+        underline: string;
+        inverse: string;
+        hidden: string;
+        strikethrough: string;
+
+        rainbow: string;
+        zebra: string;
+        america: string;
+        trap: string;
+        random: string;
+        zalgo: string;
+    }
+}

+ 211 - 0
node_modules/@colors/colors/lib/colors.js

@@ -0,0 +1,211 @@
+/*
+
+The MIT License (MIT)
+
+Original Library
+  - Copyright (c) Marak Squires
+
+Additional functionality
+ - Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+var colors = {};
+module['exports'] = colors;
+
+colors.themes = {};
+
+var util = require('util');
+var ansiStyles = colors.styles = require('./styles');
+var defineProps = Object.defineProperties;
+var newLineRegex = new RegExp(/[\r\n]+/g);
+
+colors.supportsColor = require('./system/supports-colors').supportsColor;
+
+if (typeof colors.enabled === 'undefined') {
+  colors.enabled = colors.supportsColor() !== false;
+}
+
+colors.enable = function() {
+  colors.enabled = true;
+};
+
+colors.disable = function() {
+  colors.enabled = false;
+};
+
+colors.stripColors = colors.strip = function(str) {
+  return ('' + str).replace(/\x1B\[\d+m/g, '');
+};
+
+// eslint-disable-next-line no-unused-vars
+var stylize = colors.stylize = function stylize(str, style) {
+  if (!colors.enabled) {
+    return str+'';
+  }
+
+  var styleMap = ansiStyles[style];
+
+  // Stylize should work for non-ANSI styles, too
+  if (!styleMap && style in colors) {
+    // Style maps like trap operate as functions on strings;
+    // they don't have properties like open or close.
+    return colors[style](str);
+  }
+
+  return styleMap.open + str + styleMap.close;
+};
+
+var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
+var escapeStringRegexp = function(str) {
+  if (typeof str !== 'string') {
+    throw new TypeError('Expected a string');
+  }
+  return str.replace(matchOperatorsRe, '\\$&');
+};
+
+function build(_styles) {
+  var builder = function builder() {
+    return applyStyle.apply(builder, arguments);
+  };
+  builder._styles = _styles;
+  // __proto__ is used because we must return a function, but there is
+  // no way to create a function with a different prototype.
+  builder.__proto__ = proto;
+  return builder;
+}
+
+var styles = (function() {
+  var ret = {};
+  ansiStyles.grey = ansiStyles.gray;
+  Object.keys(ansiStyles).forEach(function(key) {
+    ansiStyles[key].closeRe =
+      new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
+    ret[key] = {
+      get: function() {
+        return build(this._styles.concat(key));
+      },
+    };
+  });
+  return ret;
+})();
+
+var proto = defineProps(function colors() {}, styles);
+
+function applyStyle() {
+  var args = Array.prototype.slice.call(arguments);
+
+  var str = args.map(function(arg) {
+    // Use weak equality check so we can colorize null/undefined in safe mode
+    if (arg != null && arg.constructor === String) {
+      return arg;
+    } else {
+      return util.inspect(arg);
+    }
+  }).join(' ');
+
+  if (!colors.enabled || !str) {
+    return str;
+  }
+
+  var newLinesPresent = str.indexOf('\n') != -1;
+
+  var nestedStyles = this._styles;
+
+  var i = nestedStyles.length;
+  while (i--) {
+    var code = ansiStyles[nestedStyles[i]];
+    str = code.open + str.replace(code.closeRe, code.open) + code.close;
+    if (newLinesPresent) {
+      str = str.replace(newLineRegex, function(match) {
+        return code.close + match + code.open;
+      });
+    }
+  }
+
+  return str;
+}
+
+colors.setTheme = function(theme) {
+  if (typeof theme === 'string') {
+    console.log('colors.setTheme now only accepts an object, not a string.  ' +
+      'If you are trying to set a theme from a file, it is now your (the ' +
+      'caller\'s) responsibility to require the file.  The old syntax ' +
+      'looked like colors.setTheme(__dirname + ' +
+      '\'/../themes/generic-logging.js\'); The new syntax looks like '+
+      'colors.setTheme(require(__dirname + ' +
+      '\'/../themes/generic-logging.js\'));');
+    return;
+  }
+  for (var style in theme) {
+    (function(style) {
+      colors[style] = function(str) {
+        if (typeof theme[style] === 'object') {
+          var out = str;
+          for (var i in theme[style]) {
+            out = colors[theme[style][i]](out);
+          }
+          return out;
+        }
+        return colors[theme[style]](str);
+      };
+    })(style);
+  }
+};
+
+function init() {
+  var ret = {};
+  Object.keys(styles).forEach(function(name) {
+    ret[name] = {
+      get: function() {
+        return build([name]);
+      },
+    };
+  });
+  return ret;
+}
+
+var sequencer = function sequencer(map, str) {
+  var exploded = str.split('');
+  exploded = exploded.map(map);
+  return exploded.join('');
+};
+
+// custom formatter methods
+colors.trap = require('./custom/trap');
+colors.zalgo = require('./custom/zalgo');
+
+// maps
+colors.maps = {};
+colors.maps.america = require('./maps/america')(colors);
+colors.maps.zebra = require('./maps/zebra')(colors);
+colors.maps.rainbow = require('./maps/rainbow')(colors);
+colors.maps.random = require('./maps/random')(colors);
+
+for (var map in colors.maps) {
+  (function(map) {
+    colors[map] = function(str) {
+      return sequencer(colors.maps[map], str);
+    };
+  })(map);
+}
+
+defineProps(colors, init());

+ 46 - 0
node_modules/@colors/colors/lib/custom/trap.js

@@ -0,0 +1,46 @@
+module['exports'] = function runTheTrap(text, options) {
+  var result = '';
+  text = text || 'Run the trap, drop the bass';
+  text = text.split('');
+  var trap = {
+    a: ['\u0040', '\u0104', '\u023a', '\u0245', '\u0394', '\u039b', '\u0414'],
+    b: ['\u00df', '\u0181', '\u0243', '\u026e', '\u03b2', '\u0e3f'],
+    c: ['\u00a9', '\u023b', '\u03fe'],
+    d: ['\u00d0', '\u018a', '\u0500', '\u0501', '\u0502', '\u0503'],
+    e: ['\u00cb', '\u0115', '\u018e', '\u0258', '\u03a3', '\u03be', '\u04bc',
+      '\u0a6c'],
+    f: ['\u04fa'],
+    g: ['\u0262'],
+    h: ['\u0126', '\u0195', '\u04a2', '\u04ba', '\u04c7', '\u050a'],
+    i: ['\u0f0f'],
+    j: ['\u0134'],
+    k: ['\u0138', '\u04a0', '\u04c3', '\u051e'],
+    l: ['\u0139'],
+    m: ['\u028d', '\u04cd', '\u04ce', '\u0520', '\u0521', '\u0d69'],
+    n: ['\u00d1', '\u014b', '\u019d', '\u0376', '\u03a0', '\u048a'],
+    o: ['\u00d8', '\u00f5', '\u00f8', '\u01fe', '\u0298', '\u047a', '\u05dd',
+      '\u06dd', '\u0e4f'],
+    p: ['\u01f7', '\u048e'],
+    q: ['\u09cd'],
+    r: ['\u00ae', '\u01a6', '\u0210', '\u024c', '\u0280', '\u042f'],
+    s: ['\u00a7', '\u03de', '\u03df', '\u03e8'],
+    t: ['\u0141', '\u0166', '\u0373'],
+    u: ['\u01b1', '\u054d'],
+    v: ['\u05d8'],
+    w: ['\u0428', '\u0460', '\u047c', '\u0d70'],
+    x: ['\u04b2', '\u04fe', '\u04fc', '\u04fd'],
+    y: ['\u00a5', '\u04b0', '\u04cb'],
+    z: ['\u01b5', '\u0240'],
+  };
+  text.forEach(function(c) {
+    c = c.toLowerCase();
+    var chars = trap[c] || [' '];
+    var rand = Math.floor(Math.random() * chars.length);
+    if (typeof trap[c] !== 'undefined') {
+      result += trap[c][rand];
+    } else {
+      result += c;
+    }
+  });
+  return result;
+};

+ 110 - 0
node_modules/@colors/colors/lib/custom/zalgo.js

@@ -0,0 +1,110 @@
+// please no
+module['exports'] = function zalgo(text, options) {
+  text = text || '   he is here   ';
+  var soul = {
+    'up': [
+      '̍', '̎', '̄', '̅',
+      '̿', '̑', '̆', '̐',
+      '͒', '͗', '͑', '̇',
+      '̈', '̊', '͂', '̓',
+      '̈', '͊', '͋', '͌',
+      '̃', '̂', '̌', '͐',
+      '̀', '́', '̋', '̏',
+      '̒', '̓', '̔', '̽',
+      '̉', 'ͣ', 'ͤ', 'ͥ',
+      'ͦ', 'ͧ', 'ͨ', 'ͩ',
+      'ͪ', 'ͫ', 'ͬ', 'ͭ',
+      'ͮ', 'ͯ', '̾', '͛',
+      '͆', '̚',
+    ],
+    'down': [
+      '̖', '̗', '̘', '̙',
+      '̜', '̝', '̞', '̟',
+      '̠', '̤', '̥', '̦',
+      '̩', '̪', '̫', '̬',
+      '̭', '̮', '̯', '̰',
+      '̱', '̲', '̳', '̹',
+      '̺', '̻', '̼', 'ͅ',
+      '͇', '͈', '͉', '͍',
+      '͎', '͓', '͔', '͕',
+      '͖', '͙', '͚', '̣',
+    ],
+    'mid': [
+      '̕', '̛', '̀', '́',
+      '͘', '̡', '̢', '̧',
+      '̨', '̴', '̵', '̶',
+      '͜', '͝', '͞',
+      '͟', '͠', '͢', '̸',
+      '̷', '͡', ' ҉',
+    ],
+  };
+  var all = [].concat(soul.up, soul.down, soul.mid);
+
+  function randomNumber(range) {
+    var r = Math.floor(Math.random() * range);
+    return r;
+  }
+
+  function isChar(character) {
+    var bool = false;
+    all.filter(function(i) {
+      bool = (i === character);
+    });
+    return bool;
+  }
+
+
+  function heComes(text, options) {
+    var result = '';
+    var counts;
+    var l;
+    options = options || {};
+    options['up'] =
+      typeof options['up'] !== 'undefined' ? options['up'] : true;
+    options['mid'] =
+      typeof options['mid'] !== 'undefined' ? options['mid'] : true;
+    options['down'] =
+      typeof options['down'] !== 'undefined' ? options['down'] : true;
+    options['size'] =
+      typeof options['size'] !== 'undefined' ? options['size'] : 'maxi';
+    text = text.split('');
+    for (l in text) {
+      if (isChar(l)) {
+        continue;
+      }
+      result = result + text[l];
+      counts = {'up': 0, 'down': 0, 'mid': 0};
+      switch (options.size) {
+        case 'mini':
+          counts.up = randomNumber(8);
+          counts.mid = randomNumber(2);
+          counts.down = randomNumber(8);
+          break;
+        case 'maxi':
+          counts.up = randomNumber(16) + 3;
+          counts.mid = randomNumber(4) + 1;
+          counts.down = randomNumber(64) + 3;
+          break;
+        default:
+          counts.up = randomNumber(8) + 1;
+          counts.mid = randomNumber(6) / 2;
+          counts.down = randomNumber(8) + 1;
+          break;
+      }
+
+      var arr = ['up', 'mid', 'down'];
+      for (var d in arr) {
+        var index = arr[d];
+        for (var i = 0; i <= counts[index]; i++) {
+          if (options[index]) {
+            result = result + soul[index][randomNumber(soul[index].length)];
+          }
+        }
+      }
+    }
+    return result;
+  }
+  // don't summon him
+  return heComes(text, options);
+};
+

+ 110 - 0
node_modules/@colors/colors/lib/extendStringPrototype.js

@@ -0,0 +1,110 @@
+var colors = require('./colors');
+
+module['exports'] = function() {
+  //
+  // Extends prototype of native string object to allow for "foo".red syntax
+  //
+  var addProperty = function(color, func) {
+    String.prototype.__defineGetter__(color, func);
+  };
+
+  addProperty('strip', function() {
+    return colors.strip(this);
+  });
+
+  addProperty('stripColors', function() {
+    return colors.strip(this);
+  });
+
+  addProperty('trap', function() {
+    return colors.trap(this);
+  });
+
+  addProperty('zalgo', function() {
+    return colors.zalgo(this);
+  });
+
+  addProperty('zebra', function() {
+    return colors.zebra(this);
+  });
+
+  addProperty('rainbow', function() {
+    return colors.rainbow(this);
+  });
+
+  addProperty('random', function() {
+    return colors.random(this);
+  });
+
+  addProperty('america', function() {
+    return colors.america(this);
+  });
+
+  //
+  // Iterate through all default styles and colors
+  //
+  var x = Object.keys(colors.styles);
+  x.forEach(function(style) {
+    addProperty(style, function() {
+      return colors.stylize(this, style);
+    });
+  });
+
+  function applyTheme(theme) {
+    //
+    // Remark: This is a list of methods that exist
+    // on String that you should not overwrite.
+    //
+    var stringPrototypeBlacklist = [
+      '__defineGetter__', '__defineSetter__', '__lookupGetter__',
+      '__lookupSetter__', 'charAt', 'constructor', 'hasOwnProperty',
+      'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString',
+      'valueOf', 'charCodeAt', 'indexOf', 'lastIndexOf', 'length',
+      'localeCompare', 'match', 'repeat', 'replace', 'search', 'slice',
+      'split', 'substring', 'toLocaleLowerCase', 'toLocaleUpperCase',
+      'toLowerCase', 'toUpperCase', 'trim', 'trimLeft', 'trimRight',
+    ];
+
+    Object.keys(theme).forEach(function(prop) {
+      if (stringPrototypeBlacklist.indexOf(prop) !== -1) {
+        console.log('warn: '.red + ('String.prototype' + prop).magenta +
+          ' is probably something you don\'t want to override.  ' +
+          'Ignoring style name');
+      } else {
+        if (typeof(theme[prop]) === 'string') {
+          colors[prop] = colors[theme[prop]];
+          addProperty(prop, function() {
+            return colors[prop](this);
+          });
+        } else {
+          var themePropApplicator = function(str) {
+            var ret = str || this;
+            for (var t = 0; t < theme[prop].length; t++) {
+              ret = colors[theme[prop][t]](ret);
+            }
+            return ret;
+          };
+          addProperty(prop, themePropApplicator);
+          colors[prop] = function(str) {
+            return themePropApplicator(str);
+          };
+        }
+      }
+    });
+  }
+
+  colors.setTheme = function(theme) {
+    if (typeof theme === 'string') {
+      console.log('colors.setTheme now only accepts an object, not a string. ' +
+        'If you are trying to set a theme from a file, it is now your (the ' +
+        'caller\'s) responsibility to require the file.  The old syntax ' +
+        'looked like colors.setTheme(__dirname + ' +
+        '\'/../themes/generic-logging.js\'); The new syntax looks like '+
+        'colors.setTheme(require(__dirname + ' +
+        '\'/../themes/generic-logging.js\'));');
+      return;
+    } else {
+      applyTheme(theme);
+    }
+  };
+};

+ 13 - 0
node_modules/@colors/colors/lib/index.js

@@ -0,0 +1,13 @@
+var colors = require('./colors');
+module['exports'] = colors;
+
+// Remark: By default, colors will add style properties to String.prototype.
+//
+// If you don't wish to extend String.prototype, you can do this instead and
+// native String will not be touched:
+//
+//   var colors = require('@colors/colors/safe');
+//   colors.red("foo")
+//
+//
+require('./extendStringPrototype')();

+ 10 - 0
node_modules/@colors/colors/lib/maps/america.js

@@ -0,0 +1,10 @@
+module['exports'] = function(colors) {
+  return function(letter, i, exploded) {
+    if (letter === ' ') return letter;
+    switch (i%3) {
+      case 0: return colors.red(letter);
+      case 1: return colors.white(letter);
+      case 2: return colors.blue(letter);
+    }
+  };
+};

+ 12 - 0
node_modules/@colors/colors/lib/maps/rainbow.js

@@ -0,0 +1,12 @@
+module['exports'] = function(colors) {
+  // RoY G BiV
+  var rainbowColors = ['red', 'yellow', 'green', 'blue', 'magenta'];
+  return function(letter, i, exploded) {
+    if (letter === ' ') {
+      return letter;
+    } else {
+      return colors[rainbowColors[i++ % rainbowColors.length]](letter);
+    }
+  };
+};
+

+ 11 - 0
node_modules/@colors/colors/lib/maps/random.js

@@ -0,0 +1,11 @@
+module['exports'] = function(colors) {
+  var available = ['underline', 'inverse', 'grey', 'yellow', 'red', 'green',
+    'blue', 'white', 'cyan', 'magenta', 'brightYellow', 'brightRed',
+    'brightGreen', 'brightBlue', 'brightWhite', 'brightCyan', 'brightMagenta'];
+  return function(letter, i, exploded) {
+    return letter === ' ' ? letter :
+      colors[
+          available[Math.round(Math.random() * (available.length - 2))]
+      ](letter);
+  };
+};

+ 5 - 0
node_modules/@colors/colors/lib/maps/zebra.js

@@ -0,0 +1,5 @@
+module['exports'] = function(colors) {
+  return function(letter, i, exploded) {
+    return i % 2 === 0 ? letter : colors.inverse(letter);
+  };
+};

+ 95 - 0
node_modules/@colors/colors/lib/styles.js

@@ -0,0 +1,95 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+var styles = {};
+module['exports'] = styles;
+
+var codes = {
+  reset: [0, 0],
+
+  bold: [1, 22],
+  dim: [2, 22],
+  italic: [3, 23],
+  underline: [4, 24],
+  inverse: [7, 27],
+  hidden: [8, 28],
+  strikethrough: [9, 29],
+
+  black: [30, 39],
+  red: [31, 39],
+  green: [32, 39],
+  yellow: [33, 39],
+  blue: [34, 39],
+  magenta: [35, 39],
+  cyan: [36, 39],
+  white: [37, 39],
+  gray: [90, 39],
+  grey: [90, 39],
+
+  brightRed: [91, 39],
+  brightGreen: [92, 39],
+  brightYellow: [93, 39],
+  brightBlue: [94, 39],
+  brightMagenta: [95, 39],
+  brightCyan: [96, 39],
+  brightWhite: [97, 39],
+
+  bgBlack: [40, 49],
+  bgRed: [41, 49],
+  bgGreen: [42, 49],
+  bgYellow: [43, 49],
+  bgBlue: [44, 49],
+  bgMagenta: [45, 49],
+  bgCyan: [46, 49],
+  bgWhite: [47, 49],
+  bgGray: [100, 49],
+  bgGrey: [100, 49],
+
+  bgBrightRed: [101, 49],
+  bgBrightGreen: [102, 49],
+  bgBrightYellow: [103, 49],
+  bgBrightBlue: [104, 49],
+  bgBrightMagenta: [105, 49],
+  bgBrightCyan: [106, 49],
+  bgBrightWhite: [107, 49],
+
+  // legacy styles for colors pre v1.0.0
+  blackBG: [40, 49],
+  redBG: [41, 49],
+  greenBG: [42, 49],
+  yellowBG: [43, 49],
+  blueBG: [44, 49],
+  magentaBG: [45, 49],
+  cyanBG: [46, 49],
+  whiteBG: [47, 49],
+
+};
+
+Object.keys(codes).forEach(function(key) {
+  var val = codes[key];
+  var style = styles[key] = [];
+  style.open = '\u001b[' + val[0] + 'm';
+  style.close = '\u001b[' + val[1] + 'm';
+});

+ 35 - 0
node_modules/@colors/colors/lib/system/has-flag.js

@@ -0,0 +1,35 @@
+/*
+MIT License
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+'use strict';
+
+module.exports = function(flag, argv) {
+  argv = argv || process.argv || [];
+
+  var terminatorPos = argv.indexOf('--');
+  var prefix = /^-{1,2}/.test(flag) ? '' : '--';
+  var pos = argv.indexOf(prefix + flag);
+
+  return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
+};

+ 151 - 0
node_modules/@colors/colors/lib/system/supports-colors.js

@@ -0,0 +1,151 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+'use strict';
+
+var os = require('os');
+var hasFlag = require('./has-flag.js');
+
+var env = process.env;
+
+var forceColor = void 0;
+if (hasFlag('no-color') || hasFlag('no-colors') || hasFlag('color=false')) {
+  forceColor = false;
+} else if (hasFlag('color') || hasFlag('colors') || hasFlag('color=true')
+           || hasFlag('color=always')) {
+  forceColor = true;
+}
+if ('FORCE_COLOR' in env) {
+  forceColor = env.FORCE_COLOR.length === 0
+    || parseInt(env.FORCE_COLOR, 10) !== 0;
+}
+
+function translateLevel(level) {
+  if (level === 0) {
+    return false;
+  }
+
+  return {
+    level: level,
+    hasBasic: true,
+    has256: level >= 2,
+    has16m: level >= 3,
+  };
+}
+
+function supportsColor(stream) {
+  if (forceColor === false) {
+    return 0;
+  }
+
+  if (hasFlag('color=16m') || hasFlag('color=full')
+      || hasFlag('color=truecolor')) {
+    return 3;
+  }
+
+  if (hasFlag('color=256')) {
+    return 2;
+  }
+
+  if (stream && !stream.isTTY && forceColor !== true) {
+    return 0;
+  }
+
+  var min = forceColor ? 1 : 0;
+
+  if (process.platform === 'win32') {
+    // Node.js 7.5.0 is the first version of Node.js to include a patch to
+    // libuv that enables 256 color output on Windows. Anything earlier and it
+    // won't work. However, here we target Node.js 8 at minimum as it is an LTS
+    // release, and Node.js 7 is not. Windows 10 build 10586 is the first
+    // Windows release that supports 256 colors. Windows 10 build 14931 is the
+    // first release that supports 16m/TrueColor.
+    var osRelease = os.release().split('.');
+    if (Number(process.versions.node.split('.')[0]) >= 8
+        && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
+      return Number(osRelease[2]) >= 14931 ? 3 : 2;
+    }
+
+    return 1;
+  }
+
+  if ('CI' in env) {
+    if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(function(sign) {
+      return sign in env;
+    }) || env.CI_NAME === 'codeship') {
+      return 1;
+    }
+
+    return min;
+  }
+
+  if ('TEAMCITY_VERSION' in env) {
+    return (/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0
+    );
+  }
+
+  if ('TERM_PROGRAM' in env) {
+    var version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
+
+    switch (env.TERM_PROGRAM) {
+      case 'iTerm.app':
+        return version >= 3 ? 3 : 2;
+      case 'Hyper':
+        return 3;
+      case 'Apple_Terminal':
+        return 2;
+      // No default
+    }
+  }
+
+  if (/-256(color)?$/i.test(env.TERM)) {
+    return 2;
+  }
+
+  if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
+    return 1;
+  }
+
+  if ('COLORTERM' in env) {
+    return 1;
+  }
+
+  if (env.TERM === 'dumb') {
+    return min;
+  }
+
+  return min;
+}
+
+function getSupportLevel(stream) {
+  var level = supportsColor(stream);
+  return translateLevel(level);
+}
+
+module.exports = {
+  supportsColor: getSupportLevel,
+  stdout: getSupportLevel(process.stdout),
+  stderr: getSupportLevel(process.stderr),
+};

+ 45 - 0
node_modules/@colors/colors/package.json

@@ -0,0 +1,45 @@
+{
+    "name": "@colors/colors",
+    "description": "get colors in your node.js console",
+    "version": "1.6.0",
+    "author": "DABH",
+    "contributors": [
+        {
+            "name": "DABH",
+            "url": "https://github.com/DABH"
+        }
+    ],
+    "homepage": "https://github.com/DABH/colors.js",
+    "bugs": "https://github.com/DABH/colors.js/issues",
+    "keywords": [
+        "ansi",
+        "terminal",
+        "colors"
+    ],
+    "repository": {
+        "type": "git",
+        "url": "http://github.com/DABH/colors.js.git"
+    },
+    "license": "MIT",
+    "scripts": {
+        "lint": "eslint . --fix",
+        "test": "export FORCE_COLOR=1 && node tests/basic-test.js && node tests/safe-test.js"
+    },
+    "engines": {
+        "node": ">=0.1.90"
+    },
+    "main": "lib/index.js",
+    "files": [
+        "examples",
+        "lib",
+        "LICENSE",
+        "safe.js",
+        "themes",
+        "index.d.ts",
+        "safe.d.ts"
+    ],
+    "devDependencies": {
+        "eslint": "^8.9.0",
+        "eslint-config-google": "^0.14.0"
+    }
+}

+ 64 - 0
node_modules/@colors/colors/safe.d.ts

@@ -0,0 +1,64 @@
+// Type definitions for Colors.js 1.2
+// Project: https://github.com/Marak/colors.js
+// Definitions by: Bart van der Schoor <https://github.com/Bartvds>, Staffan Eketorp <https://github.com/staeke>
+// Definitions: https://github.com/Marak/colors.js
+
+export const enabled: boolean;
+export function enable(): void;
+export function disable(): void;
+export function setTheme(theme: any): void;
+
+export function strip(str: string): string;
+export function stripColors(str: string): string;
+
+export function black(str: string): string;
+export function red(str: string): string;
+export function green(str: string): string;
+export function yellow(str: string): string;
+export function blue(str: string): string;
+export function magenta(str: string): string;
+export function cyan(str: string): string;
+export function white(str: string): string;
+export function gray(str: string): string;
+export function grey(str: string): string;
+
+export function brightRed(str: string): string;
+export function brightGreen(str: string): string;
+export function brightYellow(str: string): string;
+export function brightBlue(str: string): string;
+export function brightMagenta(str: string): string;
+export function brightCyan(str: string): string;
+export function brightWhite(str: string): string;
+
+export function bgBlack(str: string): string;
+export function bgRed(str: string): string;
+export function bgGreen(str: string): string;
+export function bgYellow(str: string): string;
+export function bgBlue(str: string): string;
+export function bgMagenta(str: string): string;
+export function bgCyan(str: string): string;
+export function bgWhite(str: string): string;
+
+export function bgBrightRed(str: string): string;
+export function bgBrightGreen(str: string): string;
+export function bgBrightYellow(str: string): string;
+export function bgBrightBlue(str: string): string;
+export function bgBrightMagenta(str: string): string;
+export function bgBrightCyan(str: string): string;
+export function bgBrightWhite(str: string): string;
+
+export function reset(str: string): string;
+export function bold(str: string): string;
+export function dim(str: string): string;
+export function italic(str: string): string;
+export function underline(str: string): string;
+export function inverse(str: string): string;
+export function hidden(str: string): string;
+export function strikethrough(str: string): string;
+
+export function rainbow(str: string): string;
+export function zebra(str: string): string;
+export function america(str: string): string;
+export function trap(str: string): string;
+export function random(str: string): string;
+export function zalgo(str: string): string;

+ 10 - 0
node_modules/@colors/colors/safe.js

@@ -0,0 +1,10 @@
+//
+// Remark: Requiring this file will use the "safe" colors API,
+// which will not touch String.prototype.
+//
+//   var colors = require('colors/safe');
+//   colors.red("foo")
+//
+//
+var colors = require('./lib/colors');
+module['exports'] = colors;

+ 12 - 0
node_modules/@colors/colors/themes/generic-logging.js

@@ -0,0 +1,12 @@
+module['exports'] = {
+  silly: 'rainbow',
+  input: 'grey',
+  verbose: 'cyan',
+  prompt: 'grey',
+  info: 'green',
+  data: 'grey',
+  help: 'cyan',
+  warn: 'yellow',
+  debug: 'blue',
+  error: 'red',
+};

+ 26 - 0
node_modules/@dabh/diagnostics/CHANGELOG.md

@@ -0,0 +1,26 @@
+# CHANGELOG
+
+### 2.0.2
+
+- Bump to kuler 2.0, which removes colornames as dependency, which we
+  never used. So smaller install size, less dependencies for all. 
+
+### 2.0.1
+
+- Use `storag-engine@3.0` which will automatically detect the correct
+  AsyncStorage implementation.
+- The upgrade also fixes a bug where it the `debug` and `diagnostics` values
+  to be JSON encoded instead of regular plain text.
+
+### 2.0.0
+
+- Documentation improvements.
+- Fixed a issue where async adapters were incorrectly detected.
+- Correctly inherit colors after applying colors the browser's console.
+
+### 2.0.0-alpha
+
+- Complete rewrite of all internals, now comes with separate builds for `browser`
+  `node` and `react-native` as well as dedicated builds for `production` and
+  `development` environments. Various utility methods and properties have
+  been added to the returned logger to make your lives even easier.

+ 20 - 0
node_modules/@dabh/diagnostics/LICENSE

@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Arnout Kazemier, Martijn Swaagman, the Contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 473 - 0
node_modules/@dabh/diagnostics/README.md

@@ -0,0 +1,473 @@
+# `diagnostics`
+
+Diagnostics in the evolution of debug pattern that is used in the Node.js core,  
+this extremely small but powerful technique can best be compared as feature
+flags for loggers. The created debug logger is disabled by default but can be
+enabled without changing a line of code, using flags.
+
+- Allows debugging in multiple JavaScript environments such as Node.js, browsers
+  and React-Native.
+- Separated development and production builds to minimize impact on your
+  application when bundled.
+- Allows for customization of logger, messages, and much more.
+
+![Output Example](example.png)
+
+## Installation
+
+The module is released in the public npm registry and can be installed by
+running:
+
+```
+npm install --save @dabh/diagnostics
+```
+
+## Usage
+
+- [Introduction](#introduction)
+- [Advanced usage](#advanced-usage)
+  - [Production and development builds](#production-and-development-builds)
+    - [WebPack](#webpack)
+    - [Node.js](#nodejs)
+- [API](#api)
+  - [.enabled](#enabled)
+  - [.namespace](#namespace)
+  - [.dev/prod](#devprod)
+  - [set](#set)
+  - [modify](#modify)
+  - [use](#use)
+- [Modifiers](#modifiers)
+  - [namespace](#namespace-1)
+- [Adapters](#adapters)
+  - [process.env](#process-env)
+  - [hash](#hash)
+  - [localStorage](#localstorage)
+  - [AsyncStorage](#asyncstorage)
+- [Loggers](#loggers)
+
+### Introduction
+
+To create a new logger simply `require` the `@dabh/diagnostics` module and call
+the returned function. It accepts 2 arguments:
+
+1. `namespace` **Required** This is the namespace of your logger so we know if we need to
+   enable your logger when a debug flag is used. Generally you use the name of
+   your library or application as first root namespace. For example if you're
+   building a parser in a library (example) you would set namespace
+   `example:parser`.
+2. `options` An object with additional configuration for the logger.
+   following keys are recognized:
+   - `force` Force the logger to be enabled.
+   - `colors` Colors are enabled by default for the logs, but you can set this
+     option to `false` to disable it.
+
+```js
+const debug = require('@dabh/diagnostics')('foo:bar:baz');
+const debug = require('@dabh/diagnostics')('foo:bar:baz', { options });
+
+debug('this is a log message %s', 'that will only show up when enabled');
+debug('that is pretty neat', { log: 'more', data: 1337 });
+```
+
+Unlike `console.log` statements that add and remove during your development
+lifecycle you create meaningful log statements that will give you insight in
+the library or application that you're developing.
+
+The created debugger uses different "adapters" to extract the debug flag
+out of the JavaScript environment. To learn more about enabling the debug flag
+in your specific environment click on one of the enabled adapters below.
+
+- **browser**: [localStorage](#localstorage), [hash](#hash)
+- **node.js**: [environment variables](#processenv)
+- **react-native**: [AsyncStorage](#asyncstorage)
+
+Please note that the returned logger is fully configured out of the box, you
+do not need to set any of the adapters/modifiers your self, they are there
+for when you want more advanced control over the process. But if you want to
+learn more about that, read the next section.
+
+### Advanced usage
+
+There are 2 specific usage patterns for `diagnostic`, library developers who
+implement it as part of their modules and applications developers who either
+use it in their application or are searching for ways to consume the messages.
+
+With the simple log interface as discussed in the [introduction](#introduction)
+section we make it easy for developers to add it as part of their libraries
+and applications, and with powerful [API](#api) we allow infinite customization
+by allowing custom adapters, loggers and modifiers to ensure that this library
+maintains relevant. These methods not only allow introduction of new loggers,
+but allow you think outside the box. For example you can maintain a history
+of past log messages, and output those when an uncaught exception happens in
+your application so you have additional context
+
+```js
+const diagnostics = require('@dabh/diagnostics');
+
+let index = 0;
+const limit = 200;
+const history = new Array(limit);
+
+//
+// Force all `diagnostic` loggers to be enabled.
+//
+diagnostics.force = process.env.NODE_ENV === 'prod';
+diagnostics.set(function customLogger(meta, message) {
+  history[index]= { meta, message, now: Date.now() };
+  if (index++ === limit) index = 0;
+
+  //
+  // We're running a development build, so output.
+  //
+  if (meta.dev) console.log.apply(console, message);
+});
+
+process.on('uncaughtException', async function (err) {
+  await saveErrorToDisk(err, history);
+  process.exit(1);
+});
+```
+
+The small snippet above will maintain a 200 limited FIFO (First In First Out)
+queue of all debug messages that can be referenced when your application crashes
+
+#### Production and development builds
+
+When you `require` the `@dabh/diagnostics` module you will be given a logger that is
+optimized for `development` so it can provide the best developer experience
+possible.
+
+The development logger enables all the [adapters](#adapters) for your
+JavaScript environment, adds a logger that outputs the messages to `console.log`
+and registers our message modifiers so log messages will be prefixed with the
+supplied namespace so you know where the log messages originates from.
+
+The development logger does not have any adapter, modifier and logger enabled
+by default. This ensures that your log messages never accidentally show up in
+production. However this does not mean that it's not possible to get debug
+messages in production. You can `force` the debugger to be enabled, and
+supply a [custom logger](#loggers).
+
+```js
+const diagnostics = require('@dabh/diagnostics');
+const debug = debug('foo:bar', { force: true });
+
+//
+// Or enable _every_ diagnostic instance:
+//
+diagnostics.force = true;
+```
+
+##### WebPack
+
+WebPack has the concept of [mode](https://webpack.js.org/concepts/mode/#usage)'s
+which creates different
+
+```js
+module.exports = {
+  mode: 'development' // 'production'
+}
+```
+
+When you are building your app using the WebPack CLI you can use the `--mode`
+flag:
+
+```
+webpack --mode=production app.js -o /dist/bundle.js
+```
+
+##### Node.js
+
+When you are running your app using `Node.js` you should the `NODE_ENV`
+environment variable to `production` to ensure that you libraries that you
+import are optimized for production.
+
+```
+NODE_ENV=production node app.js
+```
+
+### API
+
+The returned logger exposes some addition properties that can be used used in
+your application or library:
+
+#### .enabled
+
+The returned logger will have a `.enabled` property assigned to it. This boolean
+can be used to check if the logger was enabled:
+
+```js
+const debug = require('@dabh/diagnostics')('foo:bar');
+
+if (debug.enabled) {
+  //
+  // Do something special
+  //
+}
+```
+
+This property is exposed as:
+
+- Property on the logger.
+- Property on the meta/options object.
+
+#### .namespace
+
+This is the namespace that you originally provided to the function.
+
+```js
+const debug = require('@dabh/diagnostics')('foo:bar');
+
+console.log(debug.namespace); // foo:bar
+```
+
+This property is exposed as:
+
+- Property on the logger.
+- Property on the meta/options object.
+
+#### .dev/prod
+
+There are different builds available of `diagnostics`, when you create a
+production build of your application using `NODE_ENV=production` you will be
+given an optimized, smaller build of `diagnostics` to reduce your bundle size.
+The `dev` and `prod` booleans on the returned logger indicate if you have a
+production or development version of the logger.
+
+```js
+const debug = require('@dabh/diagnostics')('foo:bar');
+
+if (debug.prod) {
+  // do stuff
+}
+```
+
+This property is exposed as:
+
+- Property on the logger.
+- Property on the meta/options object.
+
+#### set
+
+Sets a new logger as default for  **all** `diagnostic` instances. The passed
+argument should be a function that write the log messages to where ever you
+want. It receives 2 arguments:
+
+1. `meta` An object with all the options that was provided to the original
+   logger that wants to write the log message as well as properties of the
+   debugger such as `prod`, `dev`, `namespace`, `enabled`. See [API](#api) for
+   all exposed properties.
+2. `args` An array of the log messages that needs to be written.
+
+```js
+const debug = require('@dabh/diagnostics')('foo:more:namespaces');
+
+debug.use(function logger(meta, args) {
+  console.log(meta);
+  console.debug(...args);
+});
+```
+
+This method is exposed as:
+
+- Method on the logger.
+- Method on the meta/options object.
+- Method on `diagnostics` module.
+
+#### modify
+
+The modify method allows you add a new message modifier to **all** `diagnostic`
+instances. The passed argument should be a function that returns the passed
+message after modification. The function receives 2 arguments:
+
+1. `message`, Array, the log message.
+2. `options`, Object, the options that were passed into the logger when it was
+   initially created.
+
+```js
+const debug = require('@dabh/diagnostics')('example:modifiers');
+
+debug.modify(function (message, options) {
+  return messages;
+});
+```
+
+This method is exposed as:
+
+- Method on the logger.
+- Method on the meta/options object.
+- Method on `diagnostics` module.
+
+See [modifiers](#modifiers) for more information.
+
+#### use
+
+Adds a new `adapter` to **all** `diagnostic` instances. The passed argument
+should be a function returns a boolean that indicates if the passed in
+`namespace` is allowed to write log messages.
+
+```js
+const diagnostics = require('@dabh/diagnostics');
+const debug = diagnostics('foo:bar');
+
+debug.use(function (namespace) {
+  return namespace === 'foo:bar';
+});
+```
+
+This method is exposed as:
+
+- Method on the logger.
+- Method on the meta/options object.
+- Method on `diagnostics` module.
+
+See [adapters](#adapters) for more information.
+
+### Modifiers
+
+To be as flexible as possible when it comes to transforming messages we've
+come up with the concept of `modifiers` which can enhance the debug messages.
+This allows you to introduce functionality or details that you find important
+for debug messages, and doesn't require us to add additional bloat to the
+`diagnostic` core.
+
+For example, you want the messages to be prefixed with the date-time of when
+the log message occured:
+
+```js
+const diagnostics = require('@dabh/diagnostics');
+
+diagnostics.modify(function datetime(args, options) {
+  args.unshift(new Date());
+  return args;
+});
+```
+
+Now all messages will be prefixed with date that is outputted by `new Date()`.
+The following modifiers are shipped with `diagnostics` and are enabled in
+**development** mode only:
+
+- [namespace](#namespace)
+
+#### namespace
+
+This modifier is enabled for all debug instances and prefixes the messages
+with the name of namespace under which it is logged. The namespace is colored
+using the `colorspace` module which groups similar namespaces under the same
+colorspace. You can have multiple namespaces for the debuggers where each
+namespace should be separated by a `:`
+
+```
+foo
+foo:bar
+foo:bar:baz
+```
+
+For console based output the `namespace-ansi` is used.
+
+### Adapters
+
+Adapters allows `diagnostics` to pull the `DEBUG` and `DIAGNOSTICS` environment
+variables from different sources. Not every JavaScript environment has a
+`process.env` that we can leverage. Adapters allows us to have different
+adapters for different environments. It means you can write your own custom
+adapter if needed as well.
+
+The `adapter` function should be passed a function as argument, this function
+will receive the `namespace` of a logger as argument and it should return a
+boolean that indicates if that logger should be enabled or not.
+
+```js
+const debug = require('@dabh/diagnostics')('example:namespace');
+
+debug.adapter(require('@dabh/diagnostics/adapters/localstorage'));
+```
+
+The modifiers are only enabled for `development`. The following adapters are
+available are available:
+
+#### process.env
+
+This adapter is enabled for `node.js`.
+
+Uses the `DEBUG` or `DIAGNOSTICS` (both are recognized) environment variables to
+pass in debug flag:
+
+**UNIX/Linux/Mac**
+```
+DEBUG=foo* node index.js
+```
+
+Using environment variables on Windows is a bit different, and also depends on
+toolchain you are using:
+
+**Windows**
+```
+set DEBUG=foo* & node index.js
+```
+
+**Powershell**
+```
+$env:DEBUG='foo*';node index.js
+```
+
+#### hash
+
+This adapter is enabled for `browsers`.
+
+This adapter uses the `window.location.hash` of as source for the environment
+variables. It assumes that hash is formatted using the same syntax as query
+strings:
+
+```js
+http://example.com/foo/bar#debug=foo*
+```
+
+It triggers on both the `debug=` and `diagnostics=` names.
+
+#### localStorage
+
+This adapter is enabled for `browsers`.
+
+This adapter uses the `localStorage` of the browser to store the debug flags.
+You can set the debug flag your self in your application code, but you can
+also open browser WebInspector and enable it through the console.
+
+```js
+localStorage.setItem('debug', 'foo*');
+```
+
+It triggers on both the `debug` and `diagnostics` storage items. (Please note
+that these keys should be entered in lowercase)
+
+#### AsyncStorage
+
+This adapter is enabled for `react-native`.
+
+This adapter uses the `AsyncStorage` API that is exposed by the `react-native`
+library to store and read the `debug` or `diagnostics` storage items.
+
+```js
+import { AsyncStorage } from 'react-native';
+
+AsyncStorage.setItem('debug', 'foo*');
+```
+
+Unlike other adapters, this is the only adapter that is `async` so that means
+that we're not able to instantly determine if a created logger should be
+enabled or disabled. So when a logger is created in `react-native` we initially
+assume it's disabled, any message that send during period will be queued
+internally.
+
+Once we've received the data from the `AsyncStorage` API we will determine
+if the logger should be enabled, flush the queued messages if needed and set
+all `enabled` properties accordingly on the returned logger.
+
+### Loggers
+
+By default it will log all messages to `console.log` in when the logger is
+enabled using the debug flag that is set using one of the adapters.
+
+## License
+
+[MIT](LICENSE)

+ 11 - 0
node_modules/@dabh/diagnostics/adapters/hash.js

@@ -0,0 +1,11 @@
+var adapter = require('./');
+
+/**
+ * Extracts the values from process.env.
+ *
+ * @type {Function}
+ * @public
+ */
+module.exports = adapter(function hash() {
+  return /(debug|diagnostics)=([^&]+)/i.exec(window.location.hash)[2];
+});

+ 18 - 0
node_modules/@dabh/diagnostics/adapters/index.js

@@ -0,0 +1,18 @@
+var enabled = require('enabled');
+
+/**
+ * Creates a new Adapter.
+ *
+ * @param {Function} fn Function that returns the value.
+ * @returns {Function} The adapter logic.
+ * @public
+ */
+module.exports = function create(fn) {
+  return function adapter(namespace) {
+    try {
+      return enabled(namespace, fn());
+    } catch (e) { /* Any failure means that we found nothing */ }
+
+    return false;
+  };
+}

+ 11 - 0
node_modules/@dabh/diagnostics/adapters/localstorage.js

@@ -0,0 +1,11 @@
+var adapter = require('./');
+
+/**
+ * Extracts the values from process.env.
+ *
+ * @type {Function}
+ * @public
+ */
+module.exports = adapter(function storage() {
+  return localStorage.getItem('debug') || localStorage.getItem('diagnostics');
+});

+ 11 - 0
node_modules/@dabh/diagnostics/adapters/process.env.js

@@ -0,0 +1,11 @@
+var adapter = require('./');
+
+/**
+ * Extracts the values from process.env.
+ *
+ * @type {Function}
+ * @public
+ */
+module.exports = adapter(function processenv() {
+  return process.env.DEBUG || process.env.DIAGNOSTICS;
+});

+ 35 - 0
node_modules/@dabh/diagnostics/browser/development.js

@@ -0,0 +1,35 @@
+var create = require('../diagnostics');
+
+/**
+ * Create a new diagnostics logger.
+ *
+ * @param {String} namespace The namespace it should enable.
+ * @param {Object} options Additional options.
+ * @returns {Function} The logger.
+ * @public
+ */
+var diagnostics = create(function dev(namespace, options) {
+  options = options || {};
+  options.namespace = namespace;
+  options.prod = false;
+  options.dev = true;
+
+  if (!dev.enabled(namespace) && !(options.force || dev.force)) {
+    return dev.nope(options);
+  }
+
+  return dev.yep(options);
+});
+
+//
+// Configure the logger for the given environment.
+//
+diagnostics.modify(require('../modifiers/namespace'));
+diagnostics.use(require('../adapters/localstorage'));
+diagnostics.use(require('../adapters/hash'));
+diagnostics.set(require('../logger/console'));
+
+//
+// Expose the diagnostics logger.
+//
+module.exports = diagnostics;

+ 8 - 0
node_modules/@dabh/diagnostics/browser/index.js

@@ -0,0 +1,8 @@
+//
+// Select the correct build version depending on the environment.
+//
+if (process.env.NODE_ENV === 'production') {
+  module.exports = require('./production.js');
+} else {
+  module.exports = require('./development.js');
+}

+ 6 - 0
node_modules/@dabh/diagnostics/browser/override.js

@@ -0,0 +1,6 @@
+var diagnostics = require('./');
+
+//
+// No way to override `debug` with `diagnostics` in the browser.
+//
+module.exports = diagnostics;

+ 24 - 0
node_modules/@dabh/diagnostics/browser/production.js

@@ -0,0 +1,24 @@
+var create = require('../diagnostics');
+
+/**
+ * Create a new diagnostics logger.
+ *
+ * @param {String} namespace The namespace it should enable.
+ * @param {Object} options Additional options.
+ * @returns {Function} The logger.
+ * @public
+ */
+var diagnostics = create(function prod(namespace, options) {
+  options = options || {};
+  options.namespace = namespace;
+  options.prod = true;
+  options.dev = false;
+
+  if (!(options.force || prod.force)) return prod.nope(options);
+  return prod.yep(options);
+});
+
+//
+// Expose the diagnostics logger.
+//
+module.exports = diagnostics;

+ 212 - 0
node_modules/@dabh/diagnostics/diagnostics.js

@@ -0,0 +1,212 @@
+/**
+ * Contains all configured adapters for the given environment.
+ *
+ * @type {Array}
+ * @public
+ */
+var adapters = [];
+
+/**
+ * Contains all modifier functions.
+ *
+ * @typs {Array}
+ * @public
+ */
+var modifiers = [];
+
+/**
+ * Our default logger.
+ *
+ * @public
+ */
+var logger = function devnull() {};
+
+/**
+ * Register a new adapter that will used to find environments.
+ *
+ * @param {Function} adapter A function that will return the possible env.
+ * @returns {Boolean} Indication of a successful add.
+ * @public
+ */
+function use(adapter) {
+  if (~adapters.indexOf(adapter)) return false;
+
+  adapters.push(adapter);
+  return true;
+}
+
+/**
+ * Assign a new log method.
+ *
+ * @param {Function} custom The log method.
+ * @public
+ */
+function set(custom) {
+  logger = custom;
+}
+
+/**
+ * Check if the namespace is allowed by any of our adapters.
+ *
+ * @param {String} namespace The namespace that needs to be enabled
+ * @returns {Boolean|Promise} Indication if the namespace is enabled by our adapters.
+ * @public
+ */
+function enabled(namespace) {
+  var async = [];
+
+  for (var i = 0; i < adapters.length; i++) {
+    if (adapters[i].async) {
+      async.push(adapters[i]);
+      continue;
+    }
+
+    if (adapters[i](namespace)) return true;
+  }
+
+  if (!async.length) return false;
+
+  //
+  // Now that we know that we Async functions, we know we run in an ES6
+  // environment and can use all the API's that they offer, in this case
+  // we want to return a Promise so that we can `await` in React-Native
+  // for an async adapter.
+  //
+  return new Promise(function pinky(resolve) {
+    Promise.all(
+      async.map(function prebind(fn) {
+        return fn(namespace);
+      })
+    ).then(function resolved(values) {
+      resolve(values.some(Boolean));
+    });
+  });
+}
+
+/**
+ * Add a new message modifier to the debugger.
+ *
+ * @param {Function} fn Modification function.
+ * @returns {Boolean} Indication of a successful add.
+ * @public
+ */
+function modify(fn) {
+  if (~modifiers.indexOf(fn)) return false;
+
+  modifiers.push(fn);
+  return true;
+}
+
+/**
+ * Write data to the supplied logger.
+ *
+ * @param {Object} meta Meta information about the log.
+ * @param {Array} args Arguments for console.log.
+ * @public
+ */
+function write() {
+  logger.apply(logger, arguments);
+}
+
+/**
+ * Process the message with the modifiers.
+ *
+ * @param {Mixed} message The message to be transformed by modifers.
+ * @returns {String} Transformed message.
+ * @public
+ */
+function process(message) {
+  for (var i = 0; i < modifiers.length; i++) {
+    message = modifiers[i].apply(modifiers[i], arguments);
+  }
+
+  return message;
+}
+
+/**
+ * Introduce options to the logger function.
+ *
+ * @param {Function} fn Calback function.
+ * @param {Object} options Properties to introduce on fn.
+ * @returns {Function} The passed function
+ * @public
+ */
+function introduce(fn, options) {
+  var has = Object.prototype.hasOwnProperty;
+
+  for (var key in options) {
+    if (has.call(options, key)) {
+      fn[key] = options[key];
+    }
+  }
+
+  return fn;
+}
+
+/**
+ * Nope, we're not allowed to write messages.
+ *
+ * @returns {Boolean} false
+ * @public
+ */
+function nope(options) {
+  options.enabled = false;
+  options.modify = modify;
+  options.set = set;
+  options.use = use;
+
+  return introduce(function diagnopes() {
+    return false;
+  }, options);
+}
+
+/**
+ * Yep, we're allowed to write debug messages.
+ *
+ * @param {Object} options The options for the process.
+ * @returns {Function} The function that does the logging.
+ * @public
+ */
+function yep(options) {
+  /**
+   * The function that receives the actual debug information.
+   *
+   * @returns {Boolean} indication that we're logging.
+   * @public
+   */
+  function diagnostics() {
+    var args = Array.prototype.slice.call(arguments, 0);
+
+    write.call(write, options, process(args, options));
+    return true;
+  }
+
+  options.enabled = true;
+  options.modify = modify;
+  options.set = set;
+  options.use = use;
+
+  return introduce(diagnostics, options);
+}
+
+/**
+ * Simple helper function to introduce various of helper methods to our given
+ * diagnostics function.
+ *
+ * @param {Function} diagnostics The diagnostics function.
+ * @returns {Function} diagnostics
+ * @public
+ */
+module.exports = function create(diagnostics) {
+  diagnostics.introduce = introduce;
+  diagnostics.enabled = enabled;
+  diagnostics.process = process;
+  diagnostics.modify = modify;
+  diagnostics.write = write;
+  diagnostics.nope = nope;
+  diagnostics.yep = yep;
+  diagnostics.set = set;
+  diagnostics.use = use;
+
+  return diagnostics;
+}

+ 19 - 0
node_modules/@dabh/diagnostics/logger/console.js

@@ -0,0 +1,19 @@
+/**
+ * An idiot proof logger to be used as default. We've wrapped it in a try/catch
+ * statement to ensure the environments without the `console` API do not crash
+ * as well as an additional fix for ancient browsers like IE8 where the
+ * `console.log` API doesn't have an `apply`, so we need to use the Function's
+ * apply functionality to apply the arguments.
+ *
+ * @param {Object} meta Options of the logger.
+ * @param {Array} messages The actuall message that needs to be logged.
+ * @public
+ */
+module.exports = function (meta, messages) {
+  //
+  // So yea. IE8 doesn't have an apply so we need a work around to puke the
+  // arguments in place.
+  //
+  try { Function.prototype.apply.call(console.log, console, messages); }
+  catch (e) {}
+}

+ 20 - 0
node_modules/@dabh/diagnostics/modifiers/namespace-ansi.js

@@ -0,0 +1,20 @@
+var colorspace = require('colorspace');
+var kuler = require('kuler');
+
+/**
+ * Prefix the messages with a colored namespace.
+ *
+ * @param {Array} args The messages array that is getting written.
+ * @param {Object} options Options for diagnostics.
+ * @returns {Array} Altered messages array.
+ * @public
+ */
+module.exports = function ansiModifier(args, options) {
+  var namespace = options.namespace;
+  var ansi = options.colors !== false
+  ? kuler(namespace +':', colorspace(namespace))
+  : namespace +':';
+
+  args[0] = ansi +' '+ args[0];
+  return args;
+};

+ 32 - 0
node_modules/@dabh/diagnostics/modifiers/namespace.js

@@ -0,0 +1,32 @@
+var colorspace = require('colorspace');
+
+/**
+ * Prefix the messages with a colored namespace.
+ *
+ * @param {Array} messages The messages array that is getting written.
+ * @param {Object} options Options for diagnostics.
+ * @returns {Array} Altered messages array.
+ * @public
+ */
+module.exports = function colorNamespace(args, options) {
+  var namespace = options.namespace;
+
+  if (options.colors === false) {
+    args[0] = namespace +': '+ args[0];
+    return args;
+  }
+
+  var color = colorspace(namespace);
+
+  //
+  // The console API supports a special %c formatter in browsers. This is used
+  // to style console messages with any CSS styling, in our case we want to
+  // use colorize the namespace for clarity. As these are formatters, and
+  // we need to inject our CSS string as second messages argument so it
+  // gets picked up correctly.
+  //
+  args[0] = '%c'+ namespace +':%c '+ args[0];
+  args.splice(1, 0, 'color:'+ color, 'color:inherit');
+
+  return args;
+};

+ 36 - 0
node_modules/@dabh/diagnostics/node/development.js

@@ -0,0 +1,36 @@
+var create = require('../diagnostics');
+var tty = require('tty').isatty(1);
+
+/**
+ * Create a new diagnostics logger.
+ *
+ * @param {String} namespace The namespace it should enable.
+ * @param {Object} options Additional options.
+ * @returns {Function} The logger.
+ * @public
+ */
+var diagnostics = create(function dev(namespace, options) {
+  options = options || {};
+  options.colors = 'colors' in options ? options.colors : tty;
+  options.namespace = namespace;
+  options.prod = false;
+  options.dev = true;
+
+  if (!dev.enabled(namespace) && !(options.force || dev.force)) {
+    return dev.nope(options);
+  }
+  
+  return dev.yep(options);
+});
+
+//
+// Configure the logger for the given environment.
+//
+diagnostics.modify(require('../modifiers/namespace-ansi'));
+diagnostics.use(require('../adapters/process.env'));
+diagnostics.set(require('../logger/console'));
+
+//
+// Expose the diagnostics logger.
+//
+module.exports = diagnostics;

+ 8 - 0
node_modules/@dabh/diagnostics/node/index.js

@@ -0,0 +1,8 @@
+//
+// Select the correct build version depending on the environment.
+//
+if (process.env.NODE_ENV === 'production') {
+  module.exports = require('./production.js');
+} else {
+  module.exports = require('./development.js');
+}

+ 21 - 0
node_modules/@dabh/diagnostics/node/override.js

@@ -0,0 +1,21 @@
+const diagnostics = require('./');
+
+//
+// Override the existing `debug` call so it will use `diagnostics` instead
+// of the `debug` module.
+//
+try {
+  var key = require.resolve('debug');
+
+  require.cache[key] = {
+    exports: diagnostics,
+    filename: key,
+    loaded: true,
+    id: key
+  };
+} catch (e) { /* We don't really care if it fails */ }
+
+//
+// Export the default import as exports again.
+//
+module.exports = diagnostics;

+ 24 - 0
node_modules/@dabh/diagnostics/node/production.js

@@ -0,0 +1,24 @@
+var create = require('../diagnostics');
+
+/**
+ * Create a new diagnostics logger.
+ *
+ * @param {String} namespace The namespace it should enable.
+ * @param {Object} options Additional options.
+ * @returns {Function} The logger.
+ * @public
+ */
+var diagnostics = create(function prod(namespace, options) {
+  options = options || {};
+  options.namespace = namespace;
+  options.prod = true;
+  options.dev = false;
+
+  if (!(options.force || prod.force)) return prod.nope(options);
+  return prod.yep(options);
+});
+
+//
+// Expose the diagnostics logger.
+//
+module.exports = diagnostics;

+ 64 - 0
node_modules/@dabh/diagnostics/package.json

@@ -0,0 +1,64 @@
+{
+  "name": "@dabh/diagnostics",
+  "version": "2.0.3",
+  "description": "Tools for debugging your node.js modules and event loop",
+  "main": "./node",
+  "browser": "./browser",
+  "scripts": {
+    "test:basic": "mocha --require test/mock.js test/*.test.js",
+    "test:node": "mocha --require test/mock test/node.js",
+    "test:browser": "mocha --require test/mock test/browser.js",
+    "test:runner": "npm run test:basic && npm run test:node && npm run test:browser",
+    "webpack:node:prod": "webpack --mode=production node/index.js -o /dev/null --json | webpack-bundle-size-analyzer",
+    "webpack:node:dev": "webpack --mode=development node/index.js -o /dev/null --json | webpack-bundle-size-analyzer",
+    "webpack:browser:prod": "webpack --mode=production browser/index.js -o /dev/null --json | webpack-bundle-size-analyzer",
+    "webpack:browser:dev": "webpack --mode=development browser/index.js -o /dev/null --json | webpack-bundle-size-analyzer",
+    "test": "nyc --reporter=text --reporter=lcov npm run test:runner"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/3rd-Eden/diagnostics.git"
+  },
+  "keywords": [
+    "debug",
+    "debugger",
+    "debugging",
+    "diagnostic",
+    "diagnostics",
+    "event",
+    "loop",
+    "metrics",
+    "stats"
+  ],
+  "author": "Arnout Kazemier",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/3rd-Eden/diagnostics/issues"
+  },
+  "homepage": "https://github.com/3rd-Eden/diagnostics",
+  "devDependencies": {
+    "assume": "2.3.x",
+    "asyncstorageapi": "^1.0.2",
+    "mocha": "9.2.x",
+    "nyc": "^15.1.0",
+    "objstorage": "^1.0.0",
+    "pre-commit": "1.2.x",
+    "require-poisoning": "^2.0.0",
+    "webpack": "4.x",
+    "webpack-bundle-size-analyzer": "^3.0.0",
+    "webpack-cli": "3.x"
+  },
+  "dependencies": {
+    "colorspace": "1.1.x",
+    "enabled": "2.0.x",
+    "kuler": "^2.0.0"
+  },
+  "contributors": [
+    "Martijn Swaagman (https://github.com/swaagie)",
+    "Jarrett Cruger (https://github.com/jcrugzz)",
+    "Sevastos (https://github.com/sevastos)"
+  ],
+  "directories": {
+    "test": "test"
+  }
+}

+ 21 - 0
node_modules/@discoveryjs/json-ext/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Roman Dvornov <rdvornov@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 256 - 0
node_modules/@discoveryjs/json-ext/README.md

@@ -0,0 +1,256 @@
+# json-ext
+
+[![NPM version](https://img.shields.io/npm/v/@discoveryjs/json-ext.svg)](https://www.npmjs.com/package/@discoveryjs/json-ext)
+[![Build Status](https://github.com/discoveryjs/json-ext/actions/workflows/ci.yml/badge.svg)](https://github.com/discoveryjs/json-ext/actions/workflows/ci.yml)
+[![Coverage Status](https://coveralls.io/repos/github/discoveryjs/json-ext/badge.svg?branch=master)](https://coveralls.io/github/discoveryjs/json-ext?)
+[![NPM Downloads](https://img.shields.io/npm/dm/@discoveryjs/json-ext.svg)](https://www.npmjs.com/package/@discoveryjs/json-ext)
+
+A set of utilities that extend the use of JSON. Designed to be fast and memory efficient
+
+Features:
+
+- [x] `parseChunked()` – Parse JSON that comes by chunks (e.g. FS readable stream or fetch response stream)
+- [x] `stringifyStream()` – Stringify stream (Node.js)
+- [x] `stringifyInfo()` – Get estimated size and other facts of JSON.stringify() without converting a value to string
+- [ ] **TBD** Support for circular references
+- [ ] **TBD** Binary representation [branch](https://github.com/discoveryjs/json-ext/tree/binary)
+- [ ] **TBD** WHATWG [Streams](https://streams.spec.whatwg.org/) support
+
+## Install
+
+```bash
+npm install @discoveryjs/json-ext
+```
+
+## API
+
+- [parseChunked(chunkEmitter)](#parsechunkedchunkemitter)
+- [stringifyStream(value[, replacer[, space]])](#stringifystreamvalue-replacer-space)
+- [stringifyInfo(value[, replacer[, space[, options]]])](#stringifyinfovalue-replacer-space-options)
+    - [Options](#options)
+        - [async](#async)
+        - [continueOnCircular](#continueoncircular)
+- [version](#version)
+
+### parseChunked(chunkEmitter)
+
+Works the same as [`JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) but takes `chunkEmitter` instead of string and returns [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
+
+> NOTE: `reviver` parameter is not supported yet, but will be added in next releases.
+> NOTE: WHATWG streams aren't supported yet
+
+When to use:
+- It's required to avoid freezing the main thread during big JSON parsing, since this process can be distributed in time
+- Huge JSON needs to be parsed (e.g. >500MB on Node.js)
+- Needed to reduce memory pressure. `JSON.parse()` needs to receive the entire JSON before parsing it. With `parseChunked()` you may parse JSON as first bytes of it comes. This approach helps to avoid storing a huge string in the memory at a single time point and following GC.
+
+[Benchmark](https://github.com/discoveryjs/json-ext/tree/master/benchmarks#parse-chunked)
+
+Usage:
+
+```js
+const { parseChunked } = require('@discoveryjs/json-ext');
+
+// as a regular Promise
+parseChunked(chunkEmitter)
+    .then(data => {
+        /* data is parsed JSON */
+    });
+
+// using await (keep in mind that not every runtime has a support for top level await)
+const data = await parseChunked(chunkEmitter);
+```
+
+Parameter `chunkEmitter` can be:
+- [`ReadableStream`](https://nodejs.org/dist/latest-v14.x/docs/api/stream.html#stream_readable_streams) (Node.js only)
+```js
+const fs = require('fs');
+const { parseChunked } = require('@discoveryjs/json-ext');
+
+parseChunked(fs.createReadStream('path/to/file.json'))
+```
+- Generator, async generator or function that returns iterable (chunks). Chunk might be a `string`, `Uint8Array` or `Buffer` (Node.js only):
+```js
+const { parseChunked } = require('@discoveryjs/json-ext');
+const encoder = new TextEncoder();
+
+// generator
+parseChunked(function*() {
+    yield '{ "hello":';
+    yield Buffer.from(' "wor');    // Node.js only
+    yield encoder.encode('ld" }'); // returns Uint8Array(5) [ 108, 100, 34, 32, 125 ]
+});
+
+// async generator
+parseChunked(async function*() {
+    for await (const chunk of someAsyncSource) {
+        yield chunk;
+    }
+});
+
+// function that returns iterable
+parseChunked(() => ['{ "hello":', ' "world"}'])
+```
+
+Using with [fetch()](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API):
+
+```js
+async function loadData(url) {
+    const response = await fetch(url);
+    const reader = response.body.getReader();
+
+    return parseChunked(async function*() {
+        while (true) {
+            const { done, value } = await reader.read();
+
+            if (done) {
+                break;
+            }
+
+            yield value;
+        }
+    });
+}
+
+loadData('https://example.com/data.json')
+    .then(data => {
+        /* data is parsed JSON */
+    })
+```
+
+### stringifyStream(value[, replacer[, space]])
+
+Works the same as [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify), but returns an instance of [`ReadableStream`](https://nodejs.org/dist/latest-v14.x/docs/api/stream.html#stream_readable_streams) instead of string.
+
+> NOTE: WHATWG Streams aren't supported yet, so function available for Node.js only for now
+
+Departs from JSON.stringify():
+- Outputs `null` when `JSON.stringify()` returns `undefined` (since streams may not emit `undefined`)
+- A promise is resolving and the resulting value is stringifying as a regular one
+- A stream in non-object mode is piping to output as is
+- A stream in object mode is piping to output as an array of objects
+
+When to use:
+- Huge JSON needs to be generated (e.g. >500MB on Node.js)
+- Needed to reduce memory pressure. `JSON.stringify()` needs to generate the entire JSON before send or write it to somewhere. With `stringifyStream()` you may send a result to somewhere as first bytes of the result appears. This approach helps to avoid storing a huge string in the memory at a single time point.
+- The object being serialized contains Promises or Streams (see Usage for examples)
+
+[Benchmark](https://github.com/discoveryjs/json-ext/tree/master/benchmarks#stream-stringifying)
+
+Usage:
+
+```js
+const { stringifyStream } = require('@discoveryjs/json-ext');
+
+// handle events
+stringifyStream(data)
+    .on('data', chunk => console.log(chunk))
+    .on('error', error => consold.error(error))
+    .on('finish', () => console.log('DONE!'));
+
+// pipe into a stream
+stringifyStream(data)
+    .pipe(writableStream);
+```
+
+Using Promise or ReadableStream in serializing object:
+
+```js
+const fs = require('fs');
+const { stringifyStream } = require('@discoveryjs/json-ext');
+
+// output will be
+// {"name":"example","willSerializeResolvedValue":42,"fromFile":[1, 2, 3],"at":{"any":{"level":"promise!"}}}
+stringifyStream({
+    name: 'example',
+    willSerializeResolvedValue: Promise.resolve(42),
+    fromFile: fs.createReadStream('path/to/file.json'), // support file content is "[1, 2, 3]", it'll be inserted as it
+    at: {
+        any: {
+            level: new Promise(resolve => setTimeout(() => resolve('promise!'), 100))
+        }
+    }
+})
+
+// in case several async requests are used in object, it's prefered
+// to put fastest requests first, because in this case
+stringifyStream({
+    foo: fetch('http://example.com/request_takes_2s').then(req => req.json()),
+    bar: fetch('http://example.com/request_takes_5s').then(req => req.json())
+});
+```
+
+Using with [`WritableStream`](https://nodejs.org/dist/latest-v14.x/docs/api/stream.html#stream_writable_streams) (Node.js only):
+
+```js
+const fs = require('fs');
+const { stringifyStream } = require('@discoveryjs/json-ext');
+
+// pipe into a console
+stringifyStream(data)
+    .pipe(process.stdout);
+
+// pipe into a file
+stringifyStream(data)
+    .pipe(fs.createWriteStream('path/to/file.json'));
+
+// wrapping into a Promise
+new Promise((resolve, reject) => {
+    stringifyStream(data)
+        .on('error', reject)
+        .pipe(stream)
+        .on('error', reject)
+        .on('finish', resolve);
+});
+```
+
+### stringifyInfo(value[, replacer[, space[, options]]])
+
+`value`, `replacer` and `space` arguments are the same as for `JSON.stringify()`.
+
+Result is an object:
+
+```js
+{
+    minLength: Number,  // minimal bytes when values is stringified
+    circular: [...],    // list of circular references
+    duplicate: [...],   // list of objects that occur more than once
+    async: [...]        // list of async values, i.e. promises and streams
+}
+```
+
+Example:
+
+```js
+const { stringifyInfo } = require('@discoveryjs/json-ext');
+
+console.log(
+    stringifyInfo({ test: true }).minLength
+);
+// > 13
+// that equals '{"test":true}'.length
+```
+
+#### Options
+
+##### async
+
+Type: `Boolean`  
+Default: `false`
+
+Collect async values (promises and streams) or not.
+
+##### continueOnCircular
+
+Type: `Boolean`  
+Default: `false`
+
+Stop collecting info for a value or not whenever circular reference is found. Setting option to `true` allows to find all circular references.
+
+### version
+
+The version of library, e.g. `"0.3.1"`.
+
+## License
+
+MIT

+ 791 - 0
node_modules/@discoveryjs/json-ext/dist/json-ext.js

@@ -0,0 +1,791 @@
+(function (global, factory) {
+    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+    typeof define === 'function' && define.amd ? define(factory) :
+    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.jsonExt = factory());
+})(this, (function () { 'use strict';
+
+    var version = "0.5.7";
+
+    const PrimitiveType = 1;
+    const ObjectType = 2;
+    const ArrayType = 3;
+    const PromiseType = 4;
+    const ReadableStringType = 5;
+    const ReadableObjectType = 6;
+    // https://tc39.es/ecma262/#table-json-single-character-escapes
+    const escapableCharCodeSubstitution$1 = { // JSON Single Character Escape Sequences
+        0x08: '\\b',
+        0x09: '\\t',
+        0x0a: '\\n',
+        0x0c: '\\f',
+        0x0d: '\\r',
+        0x22: '\\\"',
+        0x5c: '\\\\'
+    };
+
+    function isLeadingSurrogate$1(code) {
+        return code >= 0xD800 && code <= 0xDBFF;
+    }
+
+    function isTrailingSurrogate$1(code) {
+        return code >= 0xDC00 && code <= 0xDFFF;
+    }
+
+    function isReadableStream$1(value) {
+        return (
+            typeof value.pipe === 'function' &&
+            typeof value._read === 'function' &&
+            typeof value._readableState === 'object' && value._readableState !== null
+        );
+    }
+
+    function replaceValue$1(holder, key, value, replacer) {
+        if (value && typeof value.toJSON === 'function') {
+            value = value.toJSON();
+        }
+
+        if (replacer !== null) {
+            value = replacer.call(holder, String(key), value);
+        }
+
+        switch (typeof value) {
+            case 'function':
+            case 'symbol':
+                value = undefined;
+                break;
+
+            case 'object':
+                if (value !== null) {
+                    const cls = value.constructor;
+                    if (cls === String || cls === Number || cls === Boolean) {
+                        value = value.valueOf();
+                    }
+                }
+                break;
+        }
+
+        return value;
+    }
+
+    function getTypeNative$1(value) {
+        if (value === null || typeof value !== 'object') {
+            return PrimitiveType;
+        }
+
+        if (Array.isArray(value)) {
+            return ArrayType;
+        }
+
+        return ObjectType;
+    }
+
+    function getTypeAsync$1(value) {
+        if (value === null || typeof value !== 'object') {
+            return PrimitiveType;
+        }
+
+        if (typeof value.then === 'function') {
+            return PromiseType;
+        }
+
+        if (isReadableStream$1(value)) {
+            return value._readableState.objectMode ? ReadableObjectType : ReadableStringType;
+        }
+
+        if (Array.isArray(value)) {
+            return ArrayType;
+        }
+
+        return ObjectType;
+    }
+
+    function normalizeReplacer$1(replacer) {
+        if (typeof replacer === 'function') {
+            return replacer;
+        }
+
+        if (Array.isArray(replacer)) {
+            const allowlist = new Set(replacer
+                .map(item => {
+                    const cls = item && item.constructor;
+                    return cls === String || cls === Number ? String(item) : null;
+                })
+                .filter(item => typeof item === 'string')
+            );
+
+            return [...allowlist];
+        }
+
+        return null;
+    }
+
+    function normalizeSpace$1(space) {
+        if (typeof space === 'number') {
+            if (!Number.isFinite(space) || space < 1) {
+                return false;
+            }
+
+            return ' '.repeat(Math.min(space, 10));
+        }
+
+        if (typeof space === 'string') {
+            return space.slice(0, 10) || false;
+        }
+
+        return false;
+    }
+
+    var utils = {
+        escapableCharCodeSubstitution: escapableCharCodeSubstitution$1,
+        isLeadingSurrogate: isLeadingSurrogate$1,
+        isTrailingSurrogate: isTrailingSurrogate$1,
+        type: {
+            PRIMITIVE: PrimitiveType,
+            PROMISE: PromiseType,
+            ARRAY: ArrayType,
+            OBJECT: ObjectType,
+            STRING_STREAM: ReadableStringType,
+            OBJECT_STREAM: ReadableObjectType
+        },
+
+        isReadableStream: isReadableStream$1,
+        replaceValue: replaceValue$1,
+        getTypeNative: getTypeNative$1,
+        getTypeAsync: getTypeAsync$1,
+        normalizeReplacer: normalizeReplacer$1,
+        normalizeSpace: normalizeSpace$1
+    };
+
+    const {
+        normalizeReplacer,
+        normalizeSpace,
+        replaceValue,
+        getTypeNative,
+        getTypeAsync,
+        isLeadingSurrogate,
+        isTrailingSurrogate,
+        escapableCharCodeSubstitution,
+        type: {
+            PRIMITIVE,
+            OBJECT,
+            ARRAY,
+            PROMISE,
+            STRING_STREAM,
+            OBJECT_STREAM
+        }
+    } = utils;
+    const charLength2048 = Array.from({ length: 2048 }).map((_, code) => {
+        if (escapableCharCodeSubstitution.hasOwnProperty(code)) {
+            return 2; // \X
+        }
+
+        if (code < 0x20) {
+            return 6; // \uXXXX
+        }
+
+        return code < 128 ? 1 : 2; // UTF8 bytes
+    });
+
+    function stringLength(str) {
+        let len = 0;
+        let prevLeadingSurrogate = false;
+
+        for (let i = 0; i < str.length; i++) {
+            const code = str.charCodeAt(i);
+
+            if (code < 2048) {
+                len += charLength2048[code];
+            } else if (isLeadingSurrogate(code)) {
+                len += 6; // \uXXXX since no pair with trailing surrogate yet
+                prevLeadingSurrogate = true;
+                continue;
+            } else if (isTrailingSurrogate(code)) {
+                len = prevLeadingSurrogate
+                    ? len - 2  // surrogate pair (4 bytes), since we calculate prev leading surrogate as 6 bytes, substruct 2 bytes
+                    : len + 6; // \uXXXX
+            } else {
+                len += 3; // code >= 2048 is 3 bytes length for UTF8
+            }
+
+            prevLeadingSurrogate = false;
+        }
+
+        return len + 2; // +2 for quotes
+    }
+
+    function primitiveLength(value) {
+        switch (typeof value) {
+            case 'string':
+                return stringLength(value);
+
+            case 'number':
+                return Number.isFinite(value) ? String(value).length : 4 /* null */;
+
+            case 'boolean':
+                return value ? 4 /* true */ : 5 /* false */;
+
+            case 'undefined':
+            case 'object':
+                return 4; /* null */
+
+            default:
+                return 0;
+        }
+    }
+
+    function spaceLength(space) {
+        space = normalizeSpace(space);
+        return typeof space === 'string' ? space.length : 0;
+    }
+
+    var stringifyInfo = function jsonStringifyInfo(value, replacer, space, options) {
+        function walk(holder, key, value) {
+            if (stop) {
+                return;
+            }
+
+            value = replaceValue(holder, key, value, replacer);
+
+            let type = getType(value);
+
+            // check for circular structure
+            if (type !== PRIMITIVE && stack.has(value)) {
+                circular.add(value);
+                length += 4; // treat as null
+
+                if (!options.continueOnCircular) {
+                    stop = true;
+                }
+
+                return;
+            }
+
+            switch (type) {
+                case PRIMITIVE:
+                    if (value !== undefined || Array.isArray(holder)) {
+                        length += primitiveLength(value);
+                    } else if (holder === root) {
+                        length += 9; // FIXME: that's the length of undefined, should we normalize behaviour to convert it to null?
+                    }
+                    break;
+
+                case OBJECT: {
+                    if (visited.has(value)) {
+                        duplicate.add(value);
+                        length += visited.get(value);
+                        break;
+                    }
+
+                    const valueLength = length;
+                    let entries = 0;
+
+                    length += 2; // {}
+
+                    stack.add(value);
+
+                    for (const key in value) {
+                        if (hasOwnProperty.call(value, key) && (allowlist === null || allowlist.has(key))) {
+                            const prevLength = length;
+                            walk(value, key, value[key]);
+
+                            if (prevLength !== length) {
+                                // value is printed
+                                length += stringLength(key) + 1; // "key":
+                                entries++;
+                            }
+                        }
+                    }
+
+                    if (entries > 1) {
+                        length += entries - 1; // commas
+                    }
+
+                    stack.delete(value);
+
+                    if (space > 0 && entries > 0) {
+                        length += (1 + (stack.size + 1) * space + 1) * entries; // for each key-value: \n{space}
+                        length += 1 + stack.size * space; // for }
+                    }
+
+                    visited.set(value, length - valueLength);
+
+                    break;
+                }
+
+                case ARRAY: {
+                    if (visited.has(value)) {
+                        duplicate.add(value);
+                        length += visited.get(value);
+                        break;
+                    }
+
+                    const valueLength = length;
+
+                    length += 2; // []
+
+                    stack.add(value);
+
+                    for (let i = 0; i < value.length; i++) {
+                        walk(value, i, value[i]);
+                    }
+
+                    if (value.length > 1) {
+                        length += value.length - 1; // commas
+                    }
+
+                    stack.delete(value);
+
+                    if (space > 0 && value.length > 0) {
+                        length += (1 + (stack.size + 1) * space) * value.length; // for each element: \n{space}
+                        length += 1 + stack.size * space; // for ]
+                    }
+
+                    visited.set(value, length - valueLength);
+
+                    break;
+                }
+
+                case PROMISE:
+                case STRING_STREAM:
+                    async.add(value);
+                    break;
+
+                case OBJECT_STREAM:
+                    length += 2; // []
+                    async.add(value);
+                    break;
+            }
+        }
+
+        let allowlist = null;
+        replacer = normalizeReplacer(replacer);
+
+        if (Array.isArray(replacer)) {
+            allowlist = new Set(replacer);
+            replacer = null;
+        }
+
+        space = spaceLength(space);
+        options = options || {};
+
+        const visited = new Map();
+        const stack = new Set();
+        const duplicate = new Set();
+        const circular = new Set();
+        const async = new Set();
+        const getType = options.async ? getTypeAsync : getTypeNative;
+        const root = { '': value };
+        let stop = false;
+        let length = 0;
+
+        walk(root, '', value);
+
+        return {
+            minLength: isNaN(length) ? Infinity : length,
+            circular: [...circular],
+            duplicate: [...duplicate],
+            async: [...async]
+        };
+    };
+
+    var stringifyStreamBrowser = () => {
+        throw new Error('Method is not supported');
+    };
+
+    var textDecoderBrowser = TextDecoder;
+
+    const { isReadableStream } = utils;
+
+
+    const STACK_OBJECT = 1;
+    const STACK_ARRAY = 2;
+    const decoder = new textDecoderBrowser();
+
+    function isObject(value) {
+        return value !== null && typeof value === 'object';
+    }
+
+    function adjustPosition(error, parser) {
+        if (error.name === 'SyntaxError' && parser.jsonParseOffset) {
+            error.message = error.message.replace(/at position (\d+)/, (_, pos) =>
+                'at position ' + (Number(pos) + parser.jsonParseOffset)
+            );
+        }
+
+        return error;
+    }
+
+    function append(array, elements) {
+        // Note: Avoid to use array.push(...elements) since it may lead to
+        // "RangeError: Maximum call stack size exceeded" for a long arrays
+        const initialLength = array.length;
+        array.length += elements.length;
+
+        for (let i = 0; i < elements.length; i++) {
+            array[initialLength + i] = elements[i];
+        }
+    }
+
+    var parseChunked = function(chunkEmitter) {
+        let parser = new ChunkParser();
+
+        if (isObject(chunkEmitter) && isReadableStream(chunkEmitter)) {
+            return new Promise((resolve, reject) => {
+                chunkEmitter
+                    .on('data', chunk => {
+                        try {
+                            parser.push(chunk);
+                        } catch (e) {
+                            reject(adjustPosition(e, parser));
+                            parser = null;
+                        }
+                    })
+                    .on('error', (e) => {
+                        parser = null;
+                        reject(e);
+                    })
+                    .on('end', () => {
+                        try {
+                            resolve(parser.finish());
+                        } catch (e) {
+                            reject(adjustPosition(e, parser));
+                        } finally {
+                            parser = null;
+                        }
+                    });
+            });
+        }
+
+        if (typeof chunkEmitter === 'function') {
+            const iterator = chunkEmitter();
+
+            if (isObject(iterator) && (Symbol.iterator in iterator || Symbol.asyncIterator in iterator)) {
+                return new Promise(async (resolve, reject) => {
+                    try {
+                        for await (const chunk of iterator) {
+                            parser.push(chunk);
+                        }
+
+                        resolve(parser.finish());
+                    } catch (e) {
+                        reject(adjustPosition(e, parser));
+                    } finally {
+                        parser = null;
+                    }
+                });
+            }
+        }
+
+        throw new Error(
+            'Chunk emitter should be readable stream, generator, ' +
+            'async generator or function returning an iterable object'
+        );
+    };
+
+    class ChunkParser {
+        constructor() {
+            this.value = undefined;
+            this.valueStack = null;
+
+            this.stack = new Array(100);
+            this.lastFlushDepth = 0;
+            this.flushDepth = 0;
+            this.stateString = false;
+            this.stateStringEscape = false;
+            this.pendingByteSeq = null;
+            this.pendingChunk = null;
+            this.chunkOffset = 0;
+            this.jsonParseOffset = 0;
+        }
+
+        parseAndAppend(fragment, wrap) {
+            // Append new entries or elements
+            if (this.stack[this.lastFlushDepth - 1] === STACK_OBJECT) {
+                if (wrap) {
+                    this.jsonParseOffset--;
+                    fragment = '{' + fragment + '}';
+                }
+
+                Object.assign(this.valueStack.value, JSON.parse(fragment));
+            } else {
+                if (wrap) {
+                    this.jsonParseOffset--;
+                    fragment = '[' + fragment + ']';
+                }
+
+                append(this.valueStack.value, JSON.parse(fragment));
+            }
+        }
+
+        prepareAddition(fragment) {
+            const { value } = this.valueStack;
+            const expectComma = Array.isArray(value)
+                ? value.length !== 0
+                : Object.keys(value).length !== 0;
+
+            if (expectComma) {
+                // Skip a comma at the beginning of fragment, otherwise it would
+                // fail to parse
+                if (fragment[0] === ',') {
+                    this.jsonParseOffset++;
+                    return fragment.slice(1);
+                }
+
+                // When value (an object or array) is not empty and a fragment
+                // doesn't start with a comma, a single valid fragment starting
+                // is a closing bracket. If it's not, a prefix is adding to fail
+                // parsing. Otherwise, the sequence of chunks can be successfully
+                // parsed, although it should not, e.g. ["[{}", "{}]"]
+                if (fragment[0] !== '}' && fragment[0] !== ']') {
+                    this.jsonParseOffset -= 3;
+                    return '[[]' + fragment;
+                }
+            }
+
+            return fragment;
+        }
+
+        flush(chunk, start, end) {
+            let fragment = chunk.slice(start, end);
+
+            // Save position correction an error in JSON.parse() if any
+            this.jsonParseOffset = this.chunkOffset + start;
+
+            // Prepend pending chunk if any
+            if (this.pendingChunk !== null) {
+                fragment = this.pendingChunk + fragment;
+                this.jsonParseOffset -= this.pendingChunk.length;
+                this.pendingChunk = null;
+            }
+
+            if (this.flushDepth === this.lastFlushDepth) {
+                // Depth didn't changed, so it's a root value or entry/element set
+                if (this.flushDepth > 0) {
+                    this.parseAndAppend(this.prepareAddition(fragment), true);
+                } else {
+                    // That's an entire value on a top level
+                    this.value = JSON.parse(fragment);
+                    this.valueStack = {
+                        value: this.value,
+                        prev: null
+                    };
+                }
+            } else if (this.flushDepth > this.lastFlushDepth) {
+                // Add missed closing brackets/parentheses
+                for (let i = this.flushDepth - 1; i >= this.lastFlushDepth; i--) {
+                    fragment += this.stack[i] === STACK_OBJECT ? '}' : ']';
+                }
+
+                if (this.lastFlushDepth === 0) {
+                    // That's a root value
+                    this.value = JSON.parse(fragment);
+                    this.valueStack = {
+                        value: this.value,
+                        prev: null
+                    };
+                } else {
+                    this.parseAndAppend(this.prepareAddition(fragment), true);
+                }
+
+                // Move down to the depths to the last object/array, which is current now
+                for (let i = this.lastFlushDepth || 1; i < this.flushDepth; i++) {
+                    let value = this.valueStack.value;
+
+                    if (this.stack[i - 1] === STACK_OBJECT) {
+                        // find last entry
+                        let key;
+                        // eslint-disable-next-line curly
+                        for (key in value);
+                        value = value[key];
+                    } else {
+                        // last element
+                        value = value[value.length - 1];
+                    }
+
+                    this.valueStack = {
+                        value,
+                        prev: this.valueStack
+                    };
+                }
+            } else /* this.flushDepth < this.lastFlushDepth */ {
+                fragment = this.prepareAddition(fragment);
+
+                // Add missed opening brackets/parentheses
+                for (let i = this.lastFlushDepth - 1; i >= this.flushDepth; i--) {
+                    this.jsonParseOffset--;
+                    fragment = (this.stack[i] === STACK_OBJECT ? '{' : '[') + fragment;
+                }
+
+                this.parseAndAppend(fragment, false);
+
+                for (let i = this.lastFlushDepth - 1; i >= this.flushDepth; i--) {
+                    this.valueStack = this.valueStack.prev;
+                }
+            }
+
+            this.lastFlushDepth = this.flushDepth;
+        }
+
+        push(chunk) {
+            if (typeof chunk !== 'string') {
+                // Suppose chunk is Buffer or Uint8Array
+
+                // Prepend uncompleted byte sequence if any
+                if (this.pendingByteSeq !== null) {
+                    const origRawChunk = chunk;
+                    chunk = new Uint8Array(this.pendingByteSeq.length + origRawChunk.length);
+                    chunk.set(this.pendingByteSeq);
+                    chunk.set(origRawChunk, this.pendingByteSeq.length);
+                    this.pendingByteSeq = null;
+                }
+
+                // In case Buffer/Uint8Array, an input is encoded in UTF8
+                // Seek for parts of uncompleted UTF8 symbol on the ending
+                // This makes sense only if we expect more chunks and last char is not multi-bytes
+                if (chunk[chunk.length - 1] > 127) {
+                    for (let seqLength = 0; seqLength < chunk.length; seqLength++) {
+                        const byte = chunk[chunk.length - 1 - seqLength];
+
+                        // 10xxxxxx - 2nd, 3rd or 4th byte
+                        // 110xxxxx – first byte of 2-byte sequence
+                        // 1110xxxx - first byte of 3-byte sequence
+                        // 11110xxx - first byte of 4-byte sequence
+                        if (byte >> 6 === 3) {
+                            seqLength++;
+
+                            // If the sequence is really incomplete, then preserve it
+                            // for the future chunk and cut off it from the current chunk
+                            if ((seqLength !== 4 && byte >> 3 === 0b11110) ||
+                                (seqLength !== 3 && byte >> 4 === 0b1110) ||
+                                (seqLength !== 2 && byte >> 5 === 0b110)) {
+                                this.pendingByteSeq = chunk.slice(chunk.length - seqLength);
+                                chunk = chunk.slice(0, -seqLength);
+                            }
+
+                            break;
+                        }
+                    }
+                }
+
+                // Convert chunk to a string, since single decode per chunk
+                // is much effective than decode multiple small substrings
+                chunk = decoder.decode(chunk);
+            }
+
+            const chunkLength = chunk.length;
+            let lastFlushPoint = 0;
+            let flushPoint = 0;
+
+            // Main scan loop
+            scan: for (let i = 0; i < chunkLength; i++) {
+                if (this.stateString) {
+                    for (; i < chunkLength; i++) {
+                        if (this.stateStringEscape) {
+                            this.stateStringEscape = false;
+                        } else {
+                            switch (chunk.charCodeAt(i)) {
+                                case 0x22: /* " */
+                                    this.stateString = false;
+                                    continue scan;
+
+                                case 0x5C: /* \ */
+                                    this.stateStringEscape = true;
+                            }
+                        }
+                    }
+
+                    break;
+                }
+
+                switch (chunk.charCodeAt(i)) {
+                    case 0x22: /* " */
+                        this.stateString = true;
+                        this.stateStringEscape = false;
+                        break;
+
+                    case 0x2C: /* , */
+                        flushPoint = i;
+                        break;
+
+                    case 0x7B: /* { */
+                        // Open an object
+                        flushPoint = i + 1;
+                        this.stack[this.flushDepth++] = STACK_OBJECT;
+                        break;
+
+                    case 0x5B: /* [ */
+                        // Open an array
+                        flushPoint = i + 1;
+                        this.stack[this.flushDepth++] = STACK_ARRAY;
+                        break;
+
+                    case 0x5D: /* ] */
+                    case 0x7D: /* } */
+                        // Close an object or array
+                        flushPoint = i + 1;
+                        this.flushDepth--;
+
+                        if (this.flushDepth < this.lastFlushDepth) {
+                            this.flush(chunk, lastFlushPoint, flushPoint);
+                            lastFlushPoint = flushPoint;
+                        }
+
+                        break;
+
+                    case 0x09: /* \t */
+                    case 0x0A: /* \n */
+                    case 0x0D: /* \r */
+                    case 0x20: /* space */
+                        // Move points forward when they points on current position and it's a whitespace
+                        if (lastFlushPoint === i) {
+                            lastFlushPoint++;
+                        }
+
+                        if (flushPoint === i) {
+                            flushPoint++;
+                        }
+
+                        break;
+                }
+            }
+
+            if (flushPoint > lastFlushPoint) {
+                this.flush(chunk, lastFlushPoint, flushPoint);
+            }
+
+            // Produce pendingChunk if something left
+            if (flushPoint < chunkLength) {
+                if (this.pendingChunk !== null) {
+                    // When there is already a pending chunk then no flush happened,
+                    // appending entire chunk to pending one
+                    this.pendingChunk += chunk;
+                } else {
+                    // Create a pending chunk, it will start with non-whitespace since
+                    // flushPoint was moved forward away from whitespaces on scan
+                    this.pendingChunk = chunk.slice(flushPoint, chunkLength);
+                }
+            }
+
+            this.chunkOffset += chunkLength;
+        }
+
+        finish() {
+            if (this.pendingChunk !== null) {
+                this.flush('', 0, 0);
+                this.pendingChunk = null;
+            }
+
+            return this.value;
+        }
+    }
+
+    var src = {
+        version: version,
+        stringifyInfo: stringifyInfo,
+        stringifyStream: stringifyStreamBrowser,
+        parseChunked: parseChunked
+    };
+
+    return src;
+
+}));

文件差異過大導致無法顯示
+ 0 - 0
node_modules/@discoveryjs/json-ext/dist/json-ext.min.js


+ 1 - 0
node_modules/@discoveryjs/json-ext/dist/version.js

@@ -0,0 +1 @@
+module.exports = "0.5.7";

+ 31 - 0
node_modules/@discoveryjs/json-ext/index.d.ts

@@ -0,0 +1,31 @@
+declare module '@discoveryjs/json-ext' {
+    import { Readable } from 'stream';
+
+    type TReplacer =
+        | ((this: any, key: string, value: any) => any)
+        | string[]
+        | number[]
+        | null;
+    type TSpace = string | number | null;
+    type TChunk = string | Buffer | Uint8Array;
+
+    export function parseChunked(input: Readable): Promise<any>;
+    export function parseChunked(input: () => (Iterable<TChunk> | AsyncIterable<TChunk>)): Promise<any>;
+
+    export function stringifyStream(value: any, replacer?: TReplacer, space?: TSpace): Readable;
+
+    export function stringifyInfo(
+        value: any,
+        replacer?: TReplacer,
+        space?: TSpace,
+        options?: {
+            async?: boolean;
+            continueOnCircular?: boolean;
+        }
+    ): {
+        minLength: number;
+        circular: any[];
+        duplicate: any[];
+        async: any[];
+    };
+}

+ 56 - 0
node_modules/@discoveryjs/json-ext/package.json

@@ -0,0 +1,56 @@
+{
+    "name": "@discoveryjs/json-ext",
+    "version": "0.5.7",
+    "description": "A set of utilities that extend the use of JSON",
+    "keywords": [
+        "json",
+        "utils",
+        "stream",
+        "async",
+        "promise",
+        "stringify",
+        "info"
+    ],
+    "author": "Roman Dvornov <rdvornov@gmail.com> (https://github.com/lahmatiy)",
+    "license": "MIT",
+    "repository": "discoveryjs/json-ext",
+    "main": "./src/index",
+    "browser": {
+        "./src/stringify-stream.js": "./src/stringify-stream-browser.js",
+        "./src/text-decoder.js": "./src/text-decoder-browser.js",
+        "./src/version.js": "./dist/version.js"
+    },
+    "types": "./index.d.ts",
+    "scripts": {
+        "test": "mocha --reporter progress",
+        "lint": "eslint src test",
+        "lint-and-test": "npm run lint && npm test",
+        "build": "rollup --config",
+        "test:all": "npm run test:src && npm run test:dist",
+        "test:src": "npm test",
+        "test:dist": "cross-env MODE=dist npm test && cross-env MODE=dist-min npm test",
+        "build-and-test": "npm run build && npm run test:dist",
+        "coverage": "c8 --reporter=lcovonly npm test",
+        "prepublishOnly": "npm run lint && npm test && npm run build-and-test"
+    },
+    "devDependencies": {
+        "@rollup/plugin-commonjs": "^15.1.0",
+        "@rollup/plugin-json": "^4.1.0",
+        "@rollup/plugin-node-resolve": "^9.0.0",
+        "c8": "^7.10.0",
+        "chalk": "^4.1.0",
+        "cross-env": "^7.0.3",
+        "eslint": "^8.10.0",
+        "mocha": "^8.4.0",
+        "rollup": "^2.28.2",
+        "rollup-plugin-terser": "^7.0.2"
+    },
+    "engines": {
+        "node": ">=10.0.0"
+    },
+    "files": [
+        "dist",
+        "src",
+        "index.d.ts"
+    ]
+}

+ 6 - 0
node_modules/@discoveryjs/json-ext/src/index.js

@@ -0,0 +1,6 @@
+module.exports = {
+    version: require('./version'),
+    stringifyInfo: require('./stringify-info'),
+    stringifyStream: require('./stringify-stream'),
+    parseChunked: require('./parse-chunked')
+};

+ 384 - 0
node_modules/@discoveryjs/json-ext/src/parse-chunked.js

@@ -0,0 +1,384 @@
+const { isReadableStream } = require('./utils');
+const TextDecoder = require('./text-decoder');
+
+const STACK_OBJECT = 1;
+const STACK_ARRAY = 2;
+const decoder = new TextDecoder();
+
+function isObject(value) {
+    return value !== null && typeof value === 'object';
+}
+
+function adjustPosition(error, parser) {
+    if (error.name === 'SyntaxError' && parser.jsonParseOffset) {
+        error.message = error.message.replace(/at position (\d+)/, (_, pos) =>
+            'at position ' + (Number(pos) + parser.jsonParseOffset)
+        );
+    }
+
+    return error;
+}
+
+function append(array, elements) {
+    // Note: Avoid to use array.push(...elements) since it may lead to
+    // "RangeError: Maximum call stack size exceeded" for a long arrays
+    const initialLength = array.length;
+    array.length += elements.length;
+
+    for (let i = 0; i < elements.length; i++) {
+        array[initialLength + i] = elements[i];
+    }
+}
+
+module.exports = function(chunkEmitter) {
+    let parser = new ChunkParser();
+
+    if (isObject(chunkEmitter) && isReadableStream(chunkEmitter)) {
+        return new Promise((resolve, reject) => {
+            chunkEmitter
+                .on('data', chunk => {
+                    try {
+                        parser.push(chunk);
+                    } catch (e) {
+                        reject(adjustPosition(e, parser));
+                        parser = null;
+                    }
+                })
+                .on('error', (e) => {
+                    parser = null;
+                    reject(e);
+                })
+                .on('end', () => {
+                    try {
+                        resolve(parser.finish());
+                    } catch (e) {
+                        reject(adjustPosition(e, parser));
+                    } finally {
+                        parser = null;
+                    }
+                });
+        });
+    }
+
+    if (typeof chunkEmitter === 'function') {
+        const iterator = chunkEmitter();
+
+        if (isObject(iterator) && (Symbol.iterator in iterator || Symbol.asyncIterator in iterator)) {
+            return new Promise(async (resolve, reject) => {
+                try {
+                    for await (const chunk of iterator) {
+                        parser.push(chunk);
+                    }
+
+                    resolve(parser.finish());
+                } catch (e) {
+                    reject(adjustPosition(e, parser));
+                } finally {
+                    parser = null;
+                }
+            });
+        }
+    }
+
+    throw new Error(
+        'Chunk emitter should be readable stream, generator, ' +
+        'async generator or function returning an iterable object'
+    );
+};
+
+class ChunkParser {
+    constructor() {
+        this.value = undefined;
+        this.valueStack = null;
+
+        this.stack = new Array(100);
+        this.lastFlushDepth = 0;
+        this.flushDepth = 0;
+        this.stateString = false;
+        this.stateStringEscape = false;
+        this.pendingByteSeq = null;
+        this.pendingChunk = null;
+        this.chunkOffset = 0;
+        this.jsonParseOffset = 0;
+    }
+
+    parseAndAppend(fragment, wrap) {
+        // Append new entries or elements
+        if (this.stack[this.lastFlushDepth - 1] === STACK_OBJECT) {
+            if (wrap) {
+                this.jsonParseOffset--;
+                fragment = '{' + fragment + '}';
+            }
+
+            Object.assign(this.valueStack.value, JSON.parse(fragment));
+        } else {
+            if (wrap) {
+                this.jsonParseOffset--;
+                fragment = '[' + fragment + ']';
+            }
+
+            append(this.valueStack.value, JSON.parse(fragment));
+        }
+    }
+
+    prepareAddition(fragment) {
+        const { value } = this.valueStack;
+        const expectComma = Array.isArray(value)
+            ? value.length !== 0
+            : Object.keys(value).length !== 0;
+
+        if (expectComma) {
+            // Skip a comma at the beginning of fragment, otherwise it would
+            // fail to parse
+            if (fragment[0] === ',') {
+                this.jsonParseOffset++;
+                return fragment.slice(1);
+            }
+
+            // When value (an object or array) is not empty and a fragment
+            // doesn't start with a comma, a single valid fragment starting
+            // is a closing bracket. If it's not, a prefix is adding to fail
+            // parsing. Otherwise, the sequence of chunks can be successfully
+            // parsed, although it should not, e.g. ["[{}", "{}]"]
+            if (fragment[0] !== '}' && fragment[0] !== ']') {
+                this.jsonParseOffset -= 3;
+                return '[[]' + fragment;
+            }
+        }
+
+        return fragment;
+    }
+
+    flush(chunk, start, end) {
+        let fragment = chunk.slice(start, end);
+
+        // Save position correction an error in JSON.parse() if any
+        this.jsonParseOffset = this.chunkOffset + start;
+
+        // Prepend pending chunk if any
+        if (this.pendingChunk !== null) {
+            fragment = this.pendingChunk + fragment;
+            this.jsonParseOffset -= this.pendingChunk.length;
+            this.pendingChunk = null;
+        }
+
+        if (this.flushDepth === this.lastFlushDepth) {
+            // Depth didn't changed, so it's a root value or entry/element set
+            if (this.flushDepth > 0) {
+                this.parseAndAppend(this.prepareAddition(fragment), true);
+            } else {
+                // That's an entire value on a top level
+                this.value = JSON.parse(fragment);
+                this.valueStack = {
+                    value: this.value,
+                    prev: null
+                };
+            }
+        } else if (this.flushDepth > this.lastFlushDepth) {
+            // Add missed closing brackets/parentheses
+            for (let i = this.flushDepth - 1; i >= this.lastFlushDepth; i--) {
+                fragment += this.stack[i] === STACK_OBJECT ? '}' : ']';
+            }
+
+            if (this.lastFlushDepth === 0) {
+                // That's a root value
+                this.value = JSON.parse(fragment);
+                this.valueStack = {
+                    value: this.value,
+                    prev: null
+                };
+            } else {
+                this.parseAndAppend(this.prepareAddition(fragment), true);
+            }
+
+            // Move down to the depths to the last object/array, which is current now
+            for (let i = this.lastFlushDepth || 1; i < this.flushDepth; i++) {
+                let value = this.valueStack.value;
+
+                if (this.stack[i - 1] === STACK_OBJECT) {
+                    // find last entry
+                    let key;
+                    // eslint-disable-next-line curly
+                    for (key in value);
+                    value = value[key];
+                } else {
+                    // last element
+                    value = value[value.length - 1];
+                }
+
+                this.valueStack = {
+                    value,
+                    prev: this.valueStack
+                };
+            }
+        } else /* this.flushDepth < this.lastFlushDepth */ {
+            fragment = this.prepareAddition(fragment);
+
+            // Add missed opening brackets/parentheses
+            for (let i = this.lastFlushDepth - 1; i >= this.flushDepth; i--) {
+                this.jsonParseOffset--;
+                fragment = (this.stack[i] === STACK_OBJECT ? '{' : '[') + fragment;
+            }
+
+            this.parseAndAppend(fragment, false);
+
+            for (let i = this.lastFlushDepth - 1; i >= this.flushDepth; i--) {
+                this.valueStack = this.valueStack.prev;
+            }
+        }
+
+        this.lastFlushDepth = this.flushDepth;
+    }
+
+    push(chunk) {
+        if (typeof chunk !== 'string') {
+            // Suppose chunk is Buffer or Uint8Array
+
+            // Prepend uncompleted byte sequence if any
+            if (this.pendingByteSeq !== null) {
+                const origRawChunk = chunk;
+                chunk = new Uint8Array(this.pendingByteSeq.length + origRawChunk.length);
+                chunk.set(this.pendingByteSeq);
+                chunk.set(origRawChunk, this.pendingByteSeq.length);
+                this.pendingByteSeq = null;
+            }
+
+            // In case Buffer/Uint8Array, an input is encoded in UTF8
+            // Seek for parts of uncompleted UTF8 symbol on the ending
+            // This makes sense only if we expect more chunks and last char is not multi-bytes
+            if (chunk[chunk.length - 1] > 127) {
+                for (let seqLength = 0; seqLength < chunk.length; seqLength++) {
+                    const byte = chunk[chunk.length - 1 - seqLength];
+
+                    // 10xxxxxx - 2nd, 3rd or 4th byte
+                    // 110xxxxx – first byte of 2-byte sequence
+                    // 1110xxxx - first byte of 3-byte sequence
+                    // 11110xxx - first byte of 4-byte sequence
+                    if (byte >> 6 === 3) {
+                        seqLength++;
+
+                        // If the sequence is really incomplete, then preserve it
+                        // for the future chunk and cut off it from the current chunk
+                        if ((seqLength !== 4 && byte >> 3 === 0b11110) ||
+                            (seqLength !== 3 && byte >> 4 === 0b1110) ||
+                            (seqLength !== 2 && byte >> 5 === 0b110)) {
+                            this.pendingByteSeq = chunk.slice(chunk.length - seqLength);
+                            chunk = chunk.slice(0, -seqLength);
+                        }
+
+                        break;
+                    }
+                }
+            }
+
+            // Convert chunk to a string, since single decode per chunk
+            // is much effective than decode multiple small substrings
+            chunk = decoder.decode(chunk);
+        }
+
+        const chunkLength = chunk.length;
+        let lastFlushPoint = 0;
+        let flushPoint = 0;
+
+        // Main scan loop
+        scan: for (let i = 0; i < chunkLength; i++) {
+            if (this.stateString) {
+                for (; i < chunkLength; i++) {
+                    if (this.stateStringEscape) {
+                        this.stateStringEscape = false;
+                    } else {
+                        switch (chunk.charCodeAt(i)) {
+                            case 0x22: /* " */
+                                this.stateString = false;
+                                continue scan;
+
+                            case 0x5C: /* \ */
+                                this.stateStringEscape = true;
+                        }
+                    }
+                }
+
+                break;
+            }
+
+            switch (chunk.charCodeAt(i)) {
+                case 0x22: /* " */
+                    this.stateString = true;
+                    this.stateStringEscape = false;
+                    break;
+
+                case 0x2C: /* , */
+                    flushPoint = i;
+                    break;
+
+                case 0x7B: /* { */
+                    // Open an object
+                    flushPoint = i + 1;
+                    this.stack[this.flushDepth++] = STACK_OBJECT;
+                    break;
+
+                case 0x5B: /* [ */
+                    // Open an array
+                    flushPoint = i + 1;
+                    this.stack[this.flushDepth++] = STACK_ARRAY;
+                    break;
+
+                case 0x5D: /* ] */
+                case 0x7D: /* } */
+                    // Close an object or array
+                    flushPoint = i + 1;
+                    this.flushDepth--;
+
+                    if (this.flushDepth < this.lastFlushDepth) {
+                        this.flush(chunk, lastFlushPoint, flushPoint);
+                        lastFlushPoint = flushPoint;
+                    }
+
+                    break;
+
+                case 0x09: /* \t */
+                case 0x0A: /* \n */
+                case 0x0D: /* \r */
+                case 0x20: /* space */
+                    // Move points forward when they points on current position and it's a whitespace
+                    if (lastFlushPoint === i) {
+                        lastFlushPoint++;
+                    }
+
+                    if (flushPoint === i) {
+                        flushPoint++;
+                    }
+
+                    break;
+            }
+        }
+
+        if (flushPoint > lastFlushPoint) {
+            this.flush(chunk, lastFlushPoint, flushPoint);
+        }
+
+        // Produce pendingChunk if something left
+        if (flushPoint < chunkLength) {
+            if (this.pendingChunk !== null) {
+                // When there is already a pending chunk then no flush happened,
+                // appending entire chunk to pending one
+                this.pendingChunk += chunk;
+            } else {
+                // Create a pending chunk, it will start with non-whitespace since
+                // flushPoint was moved forward away from whitespaces on scan
+                this.pendingChunk = chunk.slice(flushPoint, chunkLength);
+            }
+        }
+
+        this.chunkOffset += chunkLength;
+    }
+
+    finish() {
+        if (this.pendingChunk !== null) {
+            this.flush('', 0, 0);
+            this.pendingChunk = null;
+        }
+
+        return this.value;
+    }
+};

+ 231 - 0
node_modules/@discoveryjs/json-ext/src/stringify-info.js

@@ -0,0 +1,231 @@
+const {
+    normalizeReplacer,
+    normalizeSpace,
+    replaceValue,
+    getTypeNative,
+    getTypeAsync,
+    isLeadingSurrogate,
+    isTrailingSurrogate,
+    escapableCharCodeSubstitution,
+    type: {
+        PRIMITIVE,
+        OBJECT,
+        ARRAY,
+        PROMISE,
+        STRING_STREAM,
+        OBJECT_STREAM
+    }
+} = require('./utils');
+const charLength2048 = Array.from({ length: 2048 }).map((_, code) => {
+    if (escapableCharCodeSubstitution.hasOwnProperty(code)) {
+        return 2; // \X
+    }
+
+    if (code < 0x20) {
+        return 6; // \uXXXX
+    }
+
+    return code < 128 ? 1 : 2; // UTF8 bytes
+});
+
+function stringLength(str) {
+    let len = 0;
+    let prevLeadingSurrogate = false;
+
+    for (let i = 0; i < str.length; i++) {
+        const code = str.charCodeAt(i);
+
+        if (code < 2048) {
+            len += charLength2048[code];
+        } else if (isLeadingSurrogate(code)) {
+            len += 6; // \uXXXX since no pair with trailing surrogate yet
+            prevLeadingSurrogate = true;
+            continue;
+        } else if (isTrailingSurrogate(code)) {
+            len = prevLeadingSurrogate
+                ? len - 2  // surrogate pair (4 bytes), since we calculate prev leading surrogate as 6 bytes, substruct 2 bytes
+                : len + 6; // \uXXXX
+        } else {
+            len += 3; // code >= 2048 is 3 bytes length for UTF8
+        }
+
+        prevLeadingSurrogate = false;
+    }
+
+    return len + 2; // +2 for quotes
+}
+
+function primitiveLength(value) {
+    switch (typeof value) {
+        case 'string':
+            return stringLength(value);
+
+        case 'number':
+            return Number.isFinite(value) ? String(value).length : 4 /* null */;
+
+        case 'boolean':
+            return value ? 4 /* true */ : 5 /* false */;
+
+        case 'undefined':
+        case 'object':
+            return 4; /* null */
+
+        default:
+            return 0;
+    }
+}
+
+function spaceLength(space) {
+    space = normalizeSpace(space);
+    return typeof space === 'string' ? space.length : 0;
+}
+
+module.exports = function jsonStringifyInfo(value, replacer, space, options) {
+    function walk(holder, key, value) {
+        if (stop) {
+            return;
+        }
+
+        value = replaceValue(holder, key, value, replacer);
+
+        let type = getType(value);
+
+        // check for circular structure
+        if (type !== PRIMITIVE && stack.has(value)) {
+            circular.add(value);
+            length += 4; // treat as null
+
+            if (!options.continueOnCircular) {
+                stop = true;
+            }
+
+            return;
+        }
+
+        switch (type) {
+            case PRIMITIVE:
+                if (value !== undefined || Array.isArray(holder)) {
+                    length += primitiveLength(value);
+                } else if (holder === root) {
+                    length += 9; // FIXME: that's the length of undefined, should we normalize behaviour to convert it to null?
+                }
+                break;
+
+            case OBJECT: {
+                if (visited.has(value)) {
+                    duplicate.add(value);
+                    length += visited.get(value);
+                    break;
+                }
+
+                const valueLength = length;
+                let entries = 0;
+
+                length += 2; // {}
+
+                stack.add(value);
+
+                for (const key in value) {
+                    if (hasOwnProperty.call(value, key) && (allowlist === null || allowlist.has(key))) {
+                        const prevLength = length;
+                        walk(value, key, value[key]);
+
+                        if (prevLength !== length) {
+                            // value is printed
+                            length += stringLength(key) + 1; // "key":
+                            entries++;
+                        }
+                    }
+                }
+
+                if (entries > 1) {
+                    length += entries - 1; // commas
+                }
+
+                stack.delete(value);
+
+                if (space > 0 && entries > 0) {
+                    length += (1 + (stack.size + 1) * space + 1) * entries; // for each key-value: \n{space}
+                    length += 1 + stack.size * space; // for }
+                }
+
+                visited.set(value, length - valueLength);
+
+                break;
+            }
+
+            case ARRAY: {
+                if (visited.has(value)) {
+                    duplicate.add(value);
+                    length += visited.get(value);
+                    break;
+                }
+
+                const valueLength = length;
+
+                length += 2; // []
+
+                stack.add(value);
+
+                for (let i = 0; i < value.length; i++) {
+                    walk(value, i, value[i]);
+                }
+
+                if (value.length > 1) {
+                    length += value.length - 1; // commas
+                }
+
+                stack.delete(value);
+
+                if (space > 0 && value.length > 0) {
+                    length += (1 + (stack.size + 1) * space) * value.length; // for each element: \n{space}
+                    length += 1 + stack.size * space; // for ]
+                }
+
+                visited.set(value, length - valueLength);
+
+                break;
+            }
+
+            case PROMISE:
+            case STRING_STREAM:
+                async.add(value);
+                break;
+
+            case OBJECT_STREAM:
+                length += 2; // []
+                async.add(value);
+                break;
+        }
+    }
+
+    let allowlist = null;
+    replacer = normalizeReplacer(replacer);
+
+    if (Array.isArray(replacer)) {
+        allowlist = new Set(replacer);
+        replacer = null;
+    }
+
+    space = spaceLength(space);
+    options = options || {};
+
+    const visited = new Map();
+    const stack = new Set();
+    const duplicate = new Set();
+    const circular = new Set();
+    const async = new Set();
+    const getType = options.async ? getTypeAsync : getTypeNative;
+    const root = { '': value };
+    let stop = false;
+    let length = 0;
+
+    walk(root, '', value);
+
+    return {
+        minLength: isNaN(length) ? Infinity : length,
+        circular: [...circular],
+        duplicate: [...duplicate],
+        async: [...async]
+    };
+};

+ 3 - 0
node_modules/@discoveryjs/json-ext/src/stringify-stream-browser.js

@@ -0,0 +1,3 @@
+module.exports = () => {
+    throw new Error('Method is not supported');
+};

+ 408 - 0
node_modules/@discoveryjs/json-ext/src/stringify-stream.js

@@ -0,0 +1,408 @@
+const { Readable } = require('stream');
+const {
+    normalizeReplacer,
+    normalizeSpace,
+    replaceValue,
+    getTypeAsync,
+    type: {
+        PRIMITIVE,
+        OBJECT,
+        ARRAY,
+        PROMISE,
+        STRING_STREAM,
+        OBJECT_STREAM
+    }
+} = require('./utils');
+const noop = () => {};
+const hasOwnProperty = Object.prototype.hasOwnProperty;
+
+// TODO: Remove when drop support for Node.js 10
+// Node.js 10 has no well-formed JSON.stringify()
+// https://github.com/tc39/proposal-well-formed-stringify
+// Adopted code from https://bugs.chromium.org/p/v8/issues/detail?id=7782#c12
+const wellformedStringStringify = JSON.stringify('\ud800') === '"\\ud800"'
+    ? JSON.stringify
+    : s => JSON.stringify(s).replace(
+        /\p{Surrogate}/gu,
+        m => `\\u${m.charCodeAt(0).toString(16)}`
+    );
+
+function push() {
+    this.push(this._stack.value);
+    this.popStack();
+}
+
+function pushPrimitive(value) {
+    switch (typeof value) {
+        case 'string':
+            this.push(this.encodeString(value));
+            break;
+
+        case 'number':
+            this.push(Number.isFinite(value) ? this.encodeNumber(value) : 'null');
+            break;
+
+        case 'boolean':
+            this.push(value ? 'true' : 'false');
+            break;
+
+        case 'undefined':
+        case 'object': // typeof null === 'object'
+            this.push('null');
+            break;
+
+        default:
+            this.destroy(new TypeError(`Do not know how to serialize a ${value.constructor && value.constructor.name || typeof value}`));
+    }
+}
+
+function processObjectEntry(key) {
+    const current = this._stack;
+
+    if (!current.first) {
+        current.first = true;
+    } else {
+        this.push(',');
+    }
+
+    if (this.space) {
+        this.push(`\n${this.space.repeat(this._depth)}${this.encodeString(key)}: `);
+    } else {
+        this.push(this.encodeString(key) + ':');
+    }
+}
+
+function processObject() {
+    const current = this._stack;
+
+    // when no keys left, remove obj from stack
+    if (current.index === current.keys.length) {
+        if (this.space && current.first) {
+            this.push(`\n${this.space.repeat(this._depth - 1)}}`);
+        } else {
+            this.push('}');
+        }
+
+        this.popStack();
+        return;
+    }
+
+    const key = current.keys[current.index];
+
+    this.processValue(current.value, key, current.value[key], processObjectEntry);
+    current.index++;
+}
+
+function processArrayItem(index) {
+    if (index !== 0) {
+        this.push(',');
+    }
+
+    if (this.space) {
+        this.push(`\n${this.space.repeat(this._depth)}`);
+    }
+}
+
+function processArray() {
+    const current = this._stack;
+
+    if (current.index === current.value.length) {
+        if (this.space && current.index > 0) {
+            this.push(`\n${this.space.repeat(this._depth - 1)}]`);
+        } else {
+            this.push(']');
+        }
+
+        this.popStack();
+        return;
+    }
+
+    this.processValue(current.value, current.index, current.value[current.index], processArrayItem);
+    current.index++;
+}
+
+function createStreamReader(fn) {
+    return function() {
+        const current = this._stack;
+        const data = current.value.read(this._readSize);
+
+        if (data !== null) {
+            current.first = false;
+            fn.call(this, data, current);
+        } else {
+            if ((current.first && !current.value._readableState.reading) || current.ended) {
+                this.popStack();
+            } else {
+                current.first = true;
+                current.awaiting = true;
+            }
+        }
+    };
+}
+
+const processReadableObject = createStreamReader(function(data, current) {
+    this.processValue(current.value, current.index, data, processArrayItem);
+    current.index++;
+});
+
+const processReadableString = createStreamReader(function(data) {
+    this.push(data);
+});
+
+class JsonStringifyStream extends Readable {
+    constructor(value, replacer, space) {
+        super({
+            autoDestroy: true
+        });
+
+        this.getKeys = Object.keys;
+        this.replacer = normalizeReplacer(replacer);
+
+        if (Array.isArray(this.replacer)) {
+            const allowlist = this.replacer;
+
+            this.getKeys = (value) => allowlist.filter(key => hasOwnProperty.call(value, key));
+            this.replacer = null;
+        }
+
+        this.space = normalizeSpace(space);
+        this._depth = 0;
+
+        this.error = null;
+        this._processing = false;
+        this._ended = false;
+
+        this._readSize = 0;
+        this._buffer = '';
+
+        this._stack = null;
+        this._visited = new WeakSet();
+
+        this.pushStack({
+            handler: () => {
+                this.popStack();
+                this.processValue({ '': value }, '', value, noop);
+            }
+        });
+    }
+
+    encodeString(value) {
+        if (/[^\x20-\uD799]|[\x22\x5c]/.test(value)) {
+            return wellformedStringStringify(value);
+        }
+
+        return '"' + value + '"';
+    }
+
+    encodeNumber(value) {
+        return value;
+    }
+
+    processValue(holder, key, value, callback) {
+        value = replaceValue(holder, key, value, this.replacer);
+
+        let type = getTypeAsync(value);
+
+        switch (type) {
+            case PRIMITIVE:
+                if (callback !== processObjectEntry || value !== undefined) {
+                    callback.call(this, key);
+                    pushPrimitive.call(this, value);
+                }
+                break;
+
+            case OBJECT:
+                callback.call(this, key);
+
+                // check for circular structure
+                if (this._visited.has(value)) {
+                    return this.destroy(new TypeError('Converting circular structure to JSON'));
+                }
+
+                this._visited.add(value);
+                this._depth++;
+                this.push('{');
+                this.pushStack({
+                    handler: processObject,
+                    value,
+                    index: 0,
+                    first: false,
+                    keys: this.getKeys(value)
+                });
+                break;
+
+            case ARRAY:
+                callback.call(this, key);
+
+                // check for circular structure
+                if (this._visited.has(value)) {
+                    return this.destroy(new TypeError('Converting circular structure to JSON'));
+                }
+
+                this._visited.add(value);
+
+                this.push('[');
+                this.pushStack({
+                    handler: processArray,
+                    value,
+                    index: 0
+                });
+                this._depth++;
+                break;
+
+            case PROMISE:
+                this.pushStack({
+                    handler: noop,
+                    awaiting: true
+                });
+
+                Promise.resolve(value)
+                    .then(resolved => {
+                        this.popStack();
+                        this.processValue(holder, key, resolved, callback);
+                        this.processStack();
+                    })
+                    .catch(error => {
+                        this.destroy(error);
+                    });
+                break;
+
+            case STRING_STREAM:
+            case OBJECT_STREAM:
+                callback.call(this, key);
+
+                // TODO: Remove when drop support for Node.js 10
+                // Used `_readableState.endEmitted` as fallback, since Node.js 10 has no `readableEnded` getter
+                if (value.readableEnded || value._readableState.endEmitted) {
+                    return this.destroy(new Error('Readable Stream has ended before it was serialized. All stream data have been lost'));
+                }
+
+                if (value.readableFlowing) {
+                    return this.destroy(new Error('Readable Stream is in flowing mode, data may have been lost. Trying to pause stream.'));
+                }
+
+                if (type === OBJECT_STREAM) {
+                    this.push('[');
+                    this.pushStack({
+                        handler: push,
+                        value: this.space ? '\n' + this.space.repeat(this._depth) + ']' : ']'
+                    });
+                    this._depth++;
+                }
+
+                const self = this.pushStack({
+                    handler: type === OBJECT_STREAM ? processReadableObject : processReadableString,
+                    value,
+                    index: 0,
+                    first: false,
+                    ended: false,
+                    awaiting: !value.readable || value.readableLength === 0
+                });
+                const continueProcessing = () => {
+                    if (self.awaiting) {
+                        self.awaiting = false;
+                        this.processStack();
+                    }
+                };
+
+                value.once('error', error => this.destroy(error));
+                value.once('end', () => {
+                    self.ended = true;
+                    continueProcessing();
+                });
+                value.on('readable', continueProcessing);
+                break;
+        }
+    }
+
+    pushStack(node) {
+        node.prev = this._stack;
+        return this._stack = node;
+    }
+
+    popStack() {
+        const { handler, value } = this._stack;
+
+        if (handler === processObject || handler === processArray || handler === processReadableObject) {
+            this._visited.delete(value);
+            this._depth--;
+        }
+
+        this._stack = this._stack.prev;
+    }
+
+    processStack() {
+        if (this._processing || this._ended) {
+            return;
+        }
+
+        try {
+            this._processing = true;
+
+            while (this._stack !== null && !this._stack.awaiting) {
+                this._stack.handler.call(this);
+
+                if (!this._processing) {
+                    return;
+                }
+            }
+
+            this._processing = false;
+        } catch (error) {
+            this.destroy(error);
+            return;
+        }
+
+        if (this._stack === null && !this._ended) {
+            this._finish();
+            this.push(null);
+        }
+    }
+
+    push(data) {
+        if (data !== null) {
+            this._buffer += data;
+
+            // check buffer overflow
+            if (this._buffer.length < this._readSize) {
+                return;
+            }
+
+            // flush buffer
+            data = this._buffer;
+            this._buffer = '';
+            this._processing = false;
+        }
+
+        super.push(data);
+    }
+
+    _read(size) {
+        // start processing
+        this._readSize = size || this.readableHighWaterMark;
+        this.processStack();
+    }
+
+    _finish() {
+        this._ended = true;
+        this._processing = false;
+        this._stack = null;
+        this._visited = null;
+
+        if (this._buffer && this._buffer.length) {
+            super.push(this._buffer); // flush buffer
+        }
+
+        this._buffer = '';
+    }
+
+    _destroy(error, cb) {
+        this.error = this.error || error;
+        this._finish();
+        cb(error);
+    }
+}
+
+module.exports = function createJsonStringifyStream(value, replacer, space) {
+    return new JsonStringifyStream(value, replacer, space);
+};

部分文件因文件數量過多而無法顯示