From d245565b23ff89bfc8b5041b3e3ab21310cec67a Mon Sep 17 00:00:00 2001 From: zlin Date: Mon, 19 Mar 2018 16:58:32 +0800 Subject: [PATCH 1/5] add d.ts --- excel/cat_config.xlsx | Bin 0 -> 17734 bytes lib/xlsx-to-json.js | 110 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 94 insertions(+), 16 deletions(-) create mode 100644 excel/cat_config.xlsx diff --git a/excel/cat_config.xlsx b/excel/cat_config.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..bc275a9a92fefee01fa8868dac2c563d2c446ab6 GIT binary patch literal 17734 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 UQh$(&C;(y~t-gnU>{0;yfBshYIsgCw literal 0 HcmV?d00001 diff --git a/lib/xlsx-to-json.js b/lib/xlsx-to-json.js index e5fb8e5..9d1cf23 100755 --- a/lib/xlsx-to-json.js +++ b/lib/xlsx-to-json.js @@ -57,7 +57,7 @@ module.exports = { * excel structure * workbook > worksheet > table(row column) */ - toJson: function(src, dest, config) { + toJson: function (src, dest, config) { let headIndex = config.xlsx.head - 1; arraySeparator = config.xlsx.arraySeparator; @@ -70,7 +70,12 @@ module.exports = { console.log("parsing excel:", src); let workbook = xlsx.parse(src); - parseWorkbook(workbook, dest, headIndex, uglifyJson); + + let idx0 = src.lastIndexOf("/") + let idx1 = src.lastIndexOf("."); + let excelName = src.substring(idx0+1,idx1); + + parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName); } }; @@ -80,8 +85,10 @@ module.exports = { * @param {[String]} dest directory for exported json files. * @param {[Number]} headIndex index of head line. */ -function parseWorkbook(workbook, dest, headIndex, uglifyJson) { +function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { + console.log("xxxxx", dest); + let dtsstring = ""; workbook.forEach(sheet => { // ignore sheet with external keys only, or start with a '#' @@ -89,16 +96,85 @@ function parseWorkbook(workbook, dest, headIndex, uglifyJson) { let parsedSheet = parseSheet(sheet, headIndex); let dest_file = path.resolve(dest, sheet.name + ".json"); - let formatedJson = JSON.stringify(parsedSheet, null, uglifyJson ? 0 : 2); //, null, 2 - fs.writeFile(dest_file, formatedJson, err => { + let resultJson = JSON.stringify(parsedSheet.result, null, uglifyJson ? 0 : 2); //, null, 2 + fs.writeFile(dest_file, resultJson, err => { if (err) { console.error("error:", err); throw err; } - console.log('exported successfully --> ', path.basename(dest_file)); + console.log('exported json successfully --> ', path.basename(dest_file)); }); + + dtsstring += formatDTS(sheet.name,parsedSheet.head); } }); + + console.log("xxxxx", dest,excelName); + let dest_file_dts = path.resolve(dest, excelName + ".d.ts"); + fs.writeFile(dest_file_dts, dtsstring, err => { + if (err) { + console.error("error:", err); + throw err; + } + console.log('exported t.ds successfully --> ', path.basename(dest_file_dts)); + }); +} + +// NUMBER: 'number', +// STRING: 'string', +// BOOL: 'bool', +// DATE: 'date', +// ID: 'id', +// ARRAY: '[]', +// OBJECT: '{}', +// OBJECT_ARRAY: '[{}]', +// UNKOWN: 'unkown' +function formatDTS(name, head) { + className = name.substring(0,1).toUpperCase()+name.substring(1); + strHead = "interface " + className + "Template {\r\n"; + for (let i = 0; i < head.names.length; ++i) { + let typesDes = "any"; + switch (head.types[i]) { + case "number": { + typesDes = "number"; + break; + } + case "string": { + typesDes = "string"; + break; + } + case "bool": { + typesDes = "boolean"; + break; + } + case "id": { + typesDes = "string"; + break; + } + case "[]": { + typesDes = "any[]" + break; + } + case "{}": { + typesDes = "any"; + break; + } + case "[{}]": { + typesDes = "any[]" + break; + } + case "unkown": { + typesDes = "any"; + break; + } + default: { + typesDes = "any"; + } + } + strHead += "\t" + head.names[i] + ": " + typesDes+"\r\n"; + } + strHead +="}\r\n" + return strHead; } /** @@ -116,6 +192,8 @@ function parseSheet(sheet, headIndex) { let head = parseHead(sheet, headIndex); + console.log('\t parsing head', JSON.stringify(head)); + let result; if (head.sheetType === SheetType.NORMAL) { @@ -138,7 +216,7 @@ function parseSheet(sheet, headIndex) { throw '无法识别表格类型!'; } } - return result; + return { result, head }; } } @@ -161,7 +239,7 @@ function parseHead(sheet, headIndex) { //表类型 普通表 主表 引用表 sheetType: SheetType.NORMAL, - getIdKey: function() { + getIdKey: function () { let id_col_index = this.types.indexOf(DataType.ID); if (id_col_index < 0) { throw '获取不到id列的名字'; @@ -267,7 +345,7 @@ function parseRow(row, rowIndex, head) { result[name] = parseBasicArrayField(cell, separator); // } } else { - console.log('unrecognized type', '[' + rowIndex + ',' + index + ']', cell, typeof(cell)); + console.log('unrecognized type', '[' + rowIndex + ',' + index + ']', cell, typeof (cell)); } break; } @@ -313,7 +391,7 @@ function parseObjectArrayField(value) { let result = []; - obj_array.forEach(function(e) { + obj_array.forEach(function (e) { if (e) { result.push(array2object(e.split(';'))); } @@ -329,7 +407,7 @@ function parseObjectArrayField(value) { */ function array2object(array) { let result = {}; - array.forEach(function(e) { + array.forEach(function (e) { if (e) { let colonIndex = e.indexOf(':'); let key = e.substring(0, colonIndex); @@ -360,11 +438,11 @@ function parseBasicArrayField(array, arraySeparator) { let result = []; if (isNumberArray(basic_array)) { - basic_array.forEach(function(element) { + basic_array.forEach(function (element) { result.push(Number(element)); }); } else if (isBooleanArray(basic_array)) { - basic_array.forEach(function(element) { + basic_array.forEach(function (element) { result.push(toBoolean(element)); }); } else { //string array @@ -386,7 +464,7 @@ function toBoolean(value) { * is a boolean array. */ function isBooleanArray(arr) { - return arr.every(function(element, index, array) { + return arr.every(function (element, index, array) { return isBoolean(element); }); } @@ -395,7 +473,7 @@ function isBooleanArray(arr) { * is a number array. */ function isNumberArray(arr) { - return arr.every(function(element, index, array) { + return arr.every(function (element, index, array) { return isNumber(element); }); } @@ -421,7 +499,7 @@ function isNumber(value) { */ function isBoolean(value) { - if (typeof(value) === "undefined") { + if (typeof (value) === "undefined") { return false; } From 40baca07d265e705ae974da01476d84e915a44fb Mon Sep 17 00:00:00 2001 From: zlin Date: Mon, 19 Mar 2018 16:58:41 +0800 Subject: [PATCH 2/5] add d.ts --- lib/xlsx-to-json.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/xlsx-to-json.js b/lib/xlsx-to-json.js index 9d1cf23..8cfc502 100755 --- a/lib/xlsx-to-json.js +++ b/lib/xlsx-to-json.js @@ -73,7 +73,7 @@ module.exports = { let idx0 = src.lastIndexOf("/") let idx1 = src.lastIndexOf("."); - let excelName = src.substring(idx0+1,idx1); + let excelName = src.substring(idx0 + 1, idx1); parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName); } @@ -87,8 +87,9 @@ module.exports = { */ function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { - console.log("xxxxx", dest); + let dtsstring = ""; + workbook.forEach(sheet => { // ignore sheet with external keys only, or start with a '#' @@ -105,11 +106,11 @@ function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { console.log('exported json successfully --> ', path.basename(dest_file)); }); - dtsstring += formatDTS(sheet.name,parsedSheet.head); + dtsstring += formatDTS(sheet.name, parsedSheet.head); } }); - console.log("xxxxx", dest,excelName); + console.log("d.ts file", dest, excelName); let dest_file_dts = path.resolve(dest, excelName + ".d.ts"); fs.writeFile(dest_file_dts, dtsstring, err => { if (err) { @@ -129,8 +130,13 @@ function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { // OBJECT: '{}', // OBJECT_ARRAY: '[{}]', // UNKOWN: 'unkown' +/** + * + * @param {String} name the excel file name will be use on create d.ts + * @param {Object} head the excel head will be the javescript field + */ function formatDTS(name, head) { - className = name.substring(0,1).toUpperCase()+name.substring(1); + className = name.substring(0, 1).toUpperCase() + name.substring(1); strHead = "interface " + className + "Template {\r\n"; for (let i = 0; i < head.names.length; ++i) { let typesDes = "any"; @@ -171,9 +177,9 @@ function formatDTS(name, head) { typesDes = "any"; } } - strHead += "\t" + head.names[i] + ": " + typesDes+"\r\n"; + strHead += "\t" + head.names[i] + ": " + typesDes + "\r\n"; } - strHead +="}\r\n" + strHead += "}\r\n" return strHead; } From a9dcfb753182692ec5abe42a65b870ca8818d2b7 Mon Sep 17 00:00:00 2001 From: zlin Date: Mon, 19 Mar 2018 17:05:09 +0800 Subject: [PATCH 3/5] use enum repleace string --- lib/xlsx-to-json.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/xlsx-to-json.js b/lib/xlsx-to-json.js index 8cfc502..7350530 100755 --- a/lib/xlsx-to-json.js +++ b/lib/xlsx-to-json.js @@ -121,6 +121,7 @@ function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { }); } +// const DataType = { // NUMBER: 'number', // STRING: 'string', // BOOL: 'bool', @@ -130,6 +131,7 @@ function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { // OBJECT: '{}', // OBJECT_ARRAY: '[{}]', // UNKOWN: 'unkown' +// }; /** * * @param {String} name the excel file name will be use on create d.ts @@ -141,35 +143,35 @@ function formatDTS(name, head) { for (let i = 0; i < head.names.length; ++i) { let typesDes = "any"; switch (head.types[i]) { - case "number": { + case DataType.NUMBER: { typesDes = "number"; break; } - case "string": { + case DataType.STRING: { typesDes = "string"; break; } - case "bool": { + case DataType.BOOL: { typesDes = "boolean"; break; } - case "id": { + case DataType.ID: { typesDes = "string"; break; } - case "[]": { + case DataType.ARRAY: { typesDes = "any[]" break; } - case "{}": { + case DataType.OBJECT: { typesDes = "any"; break; } - case "[{}]": { + case DataType.OBJECT_ARRAY: { typesDes = "any[]" break; } - case "unkown": { + case DataType.UNKOWN: { typesDes = "any"; break; } From 2436a8c9f5b24b4a5bb84b8070e1dacd6ff406f9 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 26 Mar 2018 23:22:41 +0800 Subject: [PATCH 4/5] [fix]:key missing when value is null. --- lib/xlsx-to-json.js | 130 +++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 69 deletions(-) diff --git a/lib/xlsx-to-json.js b/lib/xlsx-to-json.js index 7350530..befb007 100755 --- a/lib/xlsx-to-json.js +++ b/lib/xlsx-to-json.js @@ -87,7 +87,7 @@ module.exports = { */ function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { - + let dtsstring = ""; workbook.forEach(sheet => { @@ -121,67 +121,65 @@ function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { }); } -// const DataType = { -// NUMBER: 'number', -// STRING: 'string', -// BOOL: 'bool', -// DATE: 'date', -// ID: 'id', -// ARRAY: '[]', -// OBJECT: '{}', -// OBJECT_ARRAY: '[{}]', -// UNKOWN: 'unkown' -// }; /** * * @param {String} name the excel file name will be use on create d.ts * @param {Object} head the excel head will be the javescript field */ function formatDTS(name, head) { - className = name.substring(0, 1).toUpperCase() + name.substring(1); - strHead = "interface " + className + "Template {\r\n"; + let className = name.substring(0, 1).toUpperCase() + name.substring(1); + let strHead = "interface " + className + "Template {\r\n"; for (let i = 0; i < head.names.length; ++i) { let typesDes = "any"; switch (head.types[i]) { - case DataType.NUMBER: { - typesDes = "number"; - break; - } - case DataType.STRING: { - typesDes = "string"; - break; - } - case DataType.BOOL: { - typesDes = "boolean"; - break; - } - case DataType.ID: { - typesDes = "string"; - break; - } - case DataType.ARRAY: { - typesDes = "any[]" - break; - } - case DataType.OBJECT: { - typesDes = "any"; - break; - } - case DataType.OBJECT_ARRAY: { - typesDes = "any[]" - break; - } - case DataType.UNKOWN: { - typesDes = "any"; - break; - } - default: { - typesDes = "any"; - } + case DataType.NUMBER: + { + typesDes = "number"; + break; + } + case DataType.STRING: + { + typesDes = "string"; + break; + } + case DataType.BOOL: + { + typesDes = "boolean"; + break; + } + case DataType.ID: + { + typesDes = "string"; + break; + } + case DataType.ARRAY: + { + typesDes = "any[]" + break; + } + case DataType.OBJECT: + { + typesDes = "any"; + break; + } + case DataType.OBJECT_ARRAY: + { + typesDes = "any[]" + break; + } + case DataType.UNKOWN: + { + typesDes = "any"; + break; + } + default: + { + typesDes = "any"; + } } strHead += "\t" + head.names[i] + ": " + typesDes + "\r\n"; } - strHead += "}\r\n" + strHead += "}\r\n"; return strHead; } @@ -224,7 +222,10 @@ function parseSheet(sheet, headIndex) { throw '无法识别表格类型!'; } } - return { result, head }; + return { + result, + head + }; } } @@ -283,13 +284,17 @@ function parseRow(row, rowIndex, head) { console.log('parsing row', row); - row.forEach((cell, index) => { - - // if (cell) { + for (let index = 0; index < row.length; index++) { + let cell = row[index]; let name = head.names[index]; let type = head.types[index]; + if (cell === null || cell === undefined) { + result[name] = null; + continue; + } + switch (type) { case DataType.ID: // number string boolean if (isNumber(cell)) { @@ -357,23 +362,10 @@ function parseRow(row, rowIndex, head) { } break; } - // } - }); + } return result; - // switch (head.sheetType) { - // case SheetType.NORMAL: //json以数组的格式输出 - // return result; - // case SheetType.PRIMARY: //json以map的格式输出 - // let map = {}; - // map[id] = result; - // return map; - // default: - // throw '无法识别表格类型!'; - // } - - // return result; } /** @@ -548,4 +540,4 @@ function numdate(v) { out.setTime(v * 24 * 60 * 60 * 1000 + dnthresh); return out; } -//fuck over +//fuck over \ No newline at end of file From 327692ba6f309c77d34ee2f64a28328b85080128 Mon Sep 17 00:00:00 2001 From: yulijun Date: Mon, 4 Jun 2018 18:00:35 +0800 Subject: [PATCH 5/5] [fix]:array separator. --- README.md | 47 ++++++-------- config.json | 6 +- excel/cat_config.xlsx | Bin 17734 -> 12154 bytes excel/product.xlsx | Bin 26633 -> 10737 bytes index.js | 18 ++--- lib/xlsx-to-json.js | 148 ++++++++++++++++++++++-------------------- 6 files changed, 108 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index 9dbc315..74f66b3 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,16 @@ > 让excel支持表达复杂的json格式,将xlsx文件转成json。 ### 日志 -* 2017-10-31 v0.3.1 - * 修复: 对象类型列,对象值里面有冒号值解析错误。 - * 功能: 增加#id类型,主键索引(json格式以map形式输出,无id的表以数组格式输出)。 - * 功能: 输出的json是否压缩可以在config.json里面配置。 +* 2017-10-31 v0.3.2 + * sheet名字以`#`开头则不导出此表。 + * 增加输出d.ts功能。 + * 去掉config.json中的arraySeparator配置。 -* 2017-10-26 v0.3.0 - * 修复中文自动追加拼音问题。 - * 修复日期解析错误。 - * 去掉主外键功能(以后再追加)。 - * 增加代码静态检查,核心代码重写并改成ES6语法。 - * 更新依赖插件的版本。 +### 分支 -### npm相关 -* 如需当做npm模块引用请切换到`npm`分支。 +* `master`为主分支,此分支用于发布版本,包含当前稳定代码,不要往主分支直接提交代码。 +* `dev`为开发分支,新功能提交到此分支,待稳定后合并到`master`分支。 +* 如需当做npm模块引用请切换到`npm`分支(尚有功能未合并)。 ### 使用说明 * 目前只支持.xlsx格式,不支持.xls格式。 @@ -48,15 +44,11 @@ npm install /** * 导出的json存放的位置 */ - "dest": "./json", - - /** - * 数组的分隔符 - * 有时候特殊需要,在excel单元格中里面逗号被当做他用。 - * 已过时,将在v0.5.x移除。参考列类型是数组类型时候表头设置。 - */ - "arraySeparator":"," + "dest": "./json" }, + + "ts":false,//是否导出d.ts(for typescript) + "json": { /** * 导出的json是否需要压缩 @@ -116,6 +108,7 @@ npm install ``` ### 支持以下数据类型 + * number 数字类型。 * boolean 布尔。 * string 字符串。 @@ -128,6 +121,7 @@ npm install * id 主键类型(当表中有这个类型的时候,json会以map格式输出,否则以数组格式输出)。 ### 表头规则 + * 基本数据类型(string,number,bool)时候,一般不需要设置会自动判断,但是也可以明确声明数据类型。 * 字符串类型:命名形式 `列名#string` 。 * 数字类型:命名形式 `列名#number` 。 @@ -136,25 +130,24 @@ npm install * 基本类型数组:命名形式 `列名#[]`,数组元素默认用逗号分隔(a,b,c),自定义数组元素分隔符`列名#[]/`(a/b/c)。 * 对象:命名形式 `列名#{}` 。 * 对象数组:命名形式`列名#[{}]` 。 -* 主键:命名形式`列名#id` 。 +* 主键:命名形式`列名#id` ,设置此将会输出为json map 格式。 +### 规则 -### 数据规则 * 关键符号都是半角符号。 * 对象属性使用分号`;`分割。 +* sheet名字以`#`开头则不导出此表。 ### TODO + - [ ] 列为数组类型时候,嵌套复杂类型。 - [ ] 列为对象类型时候,嵌套复杂类型。 - [ ] 外键支持。 - [ ] 将主分支的代码合并到npm分支。 -- [x] 数组分隔符的设置放到表头,默认用逗号。 - -### 感谢 -某些想法也是借鉴了一个clojure的excel转json的开源项目 [excel-to-json](https://github.com/mhaemmerle/excel-to-json)。 ### 补充 -* windows/mac/linux都支持。 + +* 可在windows/mac/linux下运行。 * 项目地址 [xlsx2json master](https://github.com/koalaylj/xlsx2json) * 如有问题可以到QQ群内讨论:223460081 * 招募协作开发者,有时间帮助一起维护下这个项目,可以发issue或者到qq群里把你github邮箱告诉我。 diff --git a/config.json b/config.json index d643e4f..8d5ba1d 100644 --- a/config.json +++ b/config.json @@ -2,10 +2,10 @@ "xlsx": { "head": 2, "src": "./excel/**/[^~$]*.xlsx", - "dest": "./json", - "arraySeparator": "," + "dest": "./json" }, + "ts": false, "json": { "uglify": false } -} +} \ No newline at end of file diff --git a/excel/cat_config.xlsx b/excel/cat_config.xlsx index bc275a9a92fefee01fa8868dac2c563d2c446ab6..5ed102294994781d70e73950b1e8b1c81e009144 100644 GIT binary patch delta 7834 zcmZ8`1yEdH^7SBt4luYTFu1$B1cv~@f+e_1(19R>Tks*cyAwRPTL>O3cnAb{*N^Oe zwZHxEeO0fXoO|n4-|q9ePY*;Q+`c1GS4Ki60H6TS00004@aoY<%ohOwxCYjcKoDVl zTEnk>w#mV6w?N@c!Nh3>Co_(@%aGBjBITrqoS& z-wg>7(J=<3*5vG1*ks^k`7K8pXjH)ZF|MsSzy1lCd|9vN+hq(t0VSDg-u?Dco0F%* zwlyD~p5*+nsq)r9H{`e=(W&9SKf#a3{5Pq?mkQREc+dbjY0th(Tjx70lO=8866Li2}5ZN^CWkzEIm`trz@B0oXG)M@yfOn4V_>SaaSbIyPpXy5~4BrJ$Gh?ij(oucr2t4DqO>5?%acC|t z$2N&oio;qGJv*WN69x2?14PDJF$AP7l zp;8L15G_A{#U-4E=zLo8f zt+P8SGrdcaoO8u`AFjvD#mr@@ypk8AM|&)D`PY(M<>6Htx#^QvHQ;e}T{3k1LW)o# zvD5(l0XtQ_71Qe~gc)hggUZk^O#(T)@bPrmTvE{vmPELa%KlU;;gGAT)k2lekUiw$ zhD=-2TFB;$X_kvHwby%d`>wNB>7DowK5VZuhTc%~;$3r(%Ma4!T)_0}c~3?%z4`>u zd&`H8hXX%RmcZ9hh%l5&i%f2xZ6S|Thk(k2081FP?c)RmABA)TO}0BHJgR>a_GSuc zZ(Ky>ticOYwKpr3@VZM&JmmjUkUWu3%X`N4-SST8{MQQ__Z23_S_1<-ge&oOw7w(|b z@TtMfH}a@}f?*9ChtFPF5IVy7rIJV`!37q!FCprbqMA05n3`{FfmhP2YGMJYuf(K_ zRs(Y{z2&yw#Otfuc!O1i8YNc~E4Y!;sGI`u-%{>Sa*l($Q>MDNqWJ=hIKDcI*5^dhwFB-oNwnx4%fr@?HiL$4~nAD@z=jSS=JJ0@7f`^9r&ebcF= zBdKArO1~$on>w4t;@GIH?{zv3+q`NjM7xPJPy*GiwKF zZFiCjx%I}z&*K@mW_qfmISc|4voOEOP)1`{ZKexdG<~V?zC5J$^J*DdeI7u6&GtBMMYyP77%zU#|iY&yDjH|kr_Fb?^Mlf++o)@`V zK*ZdI)g2NE4oDV0%Eu(2Y&CjdAOQgN7ytm) zzrEJg&CA}x^{>zN=_orb%7HtGw_#M5ug@SFNyr)jgsGDL^=QV#L+-NdrLtELR^8Aa zdBhCuTM04&D?u4)$PSagjq4=_toJhRiG^Ef>29@)nRa)n4q`kyZnkRbcv_l%eHWrG zD|pk#I1hVv=vT}<%#kF%&M9Agetp!!Sy?nf$pi2bBs1RY1tQHBiEs=Vx295Jd5D0b?1fawJ}y;lHO(!vn7`j zEFtE>(ELj=qvf3N$AG8ro(sqmq2$C6PfEv04jXgk<4@y3AIXDSS#s761D!B)f-#Ds91b4& zPRDZw<=E-XZs6mE681aR`P(zPY~0WDa*maHr4gGR0yU3LSKd)Xf%wxi{#n|d1+W78 z(ng%EVtGrtF2#@?FiPr-c-Xxy(hPkODd7fx-%?ExnzQT z^U|ap_S+v$_Gg@qI=wIcT&Yz{2EcmR&VrQH7kT}m3$_N=jn?&EO9!9luQ7p1@e~}X z;!F3W`3JW=36pfFJQt<%=L)u%xcLVy!VPvA5SE88!GFMhnT2^=w;y4(A}NOqxrFdf}V#4!erAV7rNR*udEM<=C&asLftb{7kK*NV6iTO=-! z>{ZBP(4_dR3Q=yNXDxb&z055_&#dV7b--rP@akOdga_4xDl~yzSlGI?^;$1eXoMgr zKt~`)aDKaplf+Z3y&_9eF?Y>6CIHJ&&v;Hu+&)%Rvs9V;wW3xbG8bo3LKbd+%)X+V z3We>|;J!iW4}P4Kp^nL}ua0S0TdSaLA{F-!D5u?(Qkhky?;g`%-1*hE#a=GEGD2VH zL_ZQKTD*Drm1N@9dwzEp!}ERqgIaW5_EoC*ZY(kNp&k7-ys2eYfWh#-^$r<+LPCJO zNh$J^<(a;8&;bAv06bfY3>KB77@N*XFnIL&_66%Is`LvZ(z2F}7iNKc z{-p=@s~tG_h#qhFk^z3>PxmXoEKXdQUEGY{IBT#wuVHbT(h;I_K$Y*$1{bG!gOyzJB-j`HzrB6)~})rk_bI)X%;JhRyp~aFU84n{ym$@rk}HiRy$NnphqV>_UCaH z>j{8>V1%?%IS@@0o7L2-qc0usaVK^%SQmU=9rsl5VR)h^P`)!^zXz54d3G4n4HJQZpFtArjGTArsps#Q)!9IL ziy?9^f)=DUXrvQOTQQ8sSvgBpf5equ_F#tYUZrp#*&<*k>tl?j-%19uNa zn)147=ll+U;}c9|G8!tOHe9A%ILMs);?gg*iRTFvuzFc>hP46UFOH{pOEEJ-^v| z`l!AhAa)o*mOPrGu;1_R>Y+`yqG<-LoiCI5h#(g$!Qw64$_QFN5=r}Zc`QmT#$1Gc zcq>F`^t{xX7E^81VV=!-MxR3klhHS}js>HR)OFWy?I^1-j^qw5x2Al#YH|l~8dBbZ zSUHHDDos-m{6=H7gO^eZri4#k-B+eci7 zLT=BO#n5{GcCi|C$O!WI6@a=YLMYutnUh}kBKOb8C}3C!740UAH*DcTuKpJDZwSF7 zWWaSO^yMhn1AzFq-<}iLaMb@FON4LWzrU-9+l^ z>TwdtrwCfDE|1eIBgtCeNqs40)Y=!TtNkACPFR(aoB4AzaeN@7BdJM?jGDUxKA!lx zx_*kEDi~8>vTf|*P+7m*yn~*>1?mKK>Wv9C;;r9eDX^Q%^1@U$ z#dV_1Y3t;)NpTX)@pOad=DEKAHV}N3<@#+l@Fla3ojkRkB5z+c#!5*{Wu8-RdAN@- zuYi^omioTu@Wm&({*t^pwL5)u`p;6MR;>u9AI} zUWJk^`9@QV=B`+pk~OD2B=K%3pUa7-!!`%|?hb{-nhXl1cDzlFtR2L*z(tRfazS5n zpZC^pU&v3_3V_(Y?hUN46gA%Mnvh?qycuAwUesUEGETx#f!cqEE<~jkJ5)3p^ z2AIhM24Gx(A0LBjtd8ZJ;IkwHW1iRV*IyeTl86M-l1bY><_dUt)$!@!t0uWJy+%7k zG?(Y=TdHv557~WFcMT|y69S%XxbVits!RVgrM#V=AJp-+-!`+uX+7&66c;?HQKd}3 zoo|d?&Z;5l%OvcffDUSIfs^KkvJ5u z+cJ-Y;uDl$KH6vjnzzg4o&55kXnO zhxA3b*{c(qlz)?5j6D8h&gN$iA4G*Kzo39|v3oe!?`s>`Epih0QtnHjT|hWI@LNl# z%bauE&K=12gT#pX6U-WF%~|`MFZZBy3pScRYiim-L<+2{NBOSodY28ajW~}#{5rw6V;iyBK}vlwPVKH283;f2{JsN&gk1rXJ%PSSX(^HXhEuTi z75yK$D~lAa^c7H%PGdfY7}0PIW!JVY&G)7swagm!r4?J91o2o0p${N&D1T-l388+| z_wXapL7Rk8%lM~$G+W+@h5oL$CAp2?oL>yDImuLjVzY31r5F}>QDY7p)CUgfv?@b3 z9a2Euj8)*D^@-?J6=7wRF7`&f(k!rk%)PDe&X~oxtwGaq> zG=C39C7KaATT{||A$2|n0qOpP7RYcZ&pvV;p(0#aP}k6&SvkRr zD6n%-nrj8#H@6pzYX=EghAVLn%xF8fwb|L=-wB1gFW_roFk!N}r*FVrj9`|my^MxS z)|*k9X%vn#bO6n`_)r2rgdZ9W&cqZ9#C5p$o;8r^(*9y>?p@?nvDo`E6)8F^8ky;_ zVnK*di$A0Ys!-lF`IBHVDJT@h5j#rUOwFdBQmBdQSHmGfzGh#a5e9yYu`zAY6kbci z$6p3{bok38+oxR|{E>n&^sw?xf;JQ06jw&_6>k@s%z~9}=A76)?~=!U%$=adAkoQM zh9mdEPIQCi4@}YTiTxMg<6i(ADb?B*u3W#xj#AWt}s2=C;AfQ_BZRoe)Zo$-6fu0EUT@rdS4*@ zBQ{B(@PiD1oJ*m=1w?|>lK6@7$> z=+7aWwnb9zs_k$77KF%hH*Snermi5?2q_xvaE4&{HwDUZ#s=@Lz-s2W&N0nV&duKLPC??NX|#FPrA*4A}yt8 z@99l7+tKVh0T}sxk3No>LSz?_uGjmMQ>C}5EwtVw1bA^$qWpRWt*?^3az}g+{Q?`B zPQH!Ij;vqcq332SApEosQxQ%-RJn8R~I$wV99>pYSs#X2 z(bSb{m?^z~HwqooKs#KlLv<3oorBB?L~iClP60&fo!cO$eDGsQ(TgR^4(8tEhJ=-h z7J7JtweNp#Km8?bbmEm43K`GJH)9=@0M)b9*zGti34YdE+kzUdESLS62`ZbUnMzQ> z@d=mW6@$ZNmxs1cQ#w&hVr+#r1cnt9+Lu8!l`XHmOZprvA19B-pDJ2JdEIACRc2eI zGsa!wb9p-I9Sy?MNAKzcsFjhcf`5vz_Tj?6{@{3DqJ54)qo+b@@Kr1Pg~nTj)bH3Z zas{5G7c8G+vA|8vEWX-$LAopZnrr%wtON4Yq^ z=s3xgR3iN9{6Se6A$}8C3q=iTNYK>aS|%G6*B9P39JVQ+MX@!kt*Od+UGlqE(ul?_ zx3X)XKwJ3}5!Ou#-Cc-T`lo#!+Wik0uu19qweXsjhTNS!VcN*s@$sWhnD4{gL0Ccs zPF+Vv)oZ&u{qZ{>`)gv6pn#wd&7SB&vgu-5V0;$RAt}ldLKr-wCpradX#K+}G1RJO>{Y!kmxNADcVIvxHIV^} z^rV(Pn9nQCymnaoT`t2yG%>JRIoU+$Px_g_ACW;rLmZ^~0qPx0$Mt=f4+_n|i}hQd z{vM}y9AZOew1k`NSjbjHE5>*nKkImkXnNwD>2Q(Prh2m8$OeITJXs4|-Vu<7r3Z#f zmq|wJgtN*;wM?0*gdhxCaAVRIhz~X@Du2U|&%n6ET#X1O0EWCH!szH#UlQGOdY?+m zRbPzgSzsZ0RoJ4b-iJX1^GoPwtbuLmldRB*>6=H`r$<%>$sqqByiba7_|{|{jWQ9$ ziZY5D5FR&f)Hv29CV`Mo*R5^JXPX`SvvZ>4q0ZoDxzf3e2F$u zo@V$>r#-vGzz}U^E$Zs-?QbI=uku)ri+-u2k5+HR_T0(pc+kZ4V5gtsQ)ynop3ssW z)GEJvm3A)m4Q~2vl#4G%;@F-zVCD8Lp$DI)@TzgbKn~ z#*Dx4cgff{=BdKvQ&0pikOG-bqTnk%f8mx*rB0vnz2vyJM-2(o36U3J4nt*oy6s~f zE9IbXGv^+zlwBt6xF%3`6+|(H38#em?1KG={-x=sfM##YA78yU+!`PI4WpB%;$(AX zd%n0Q$l8H=XD`Rq&J|U&b#CRuI8}Gv9`J^SZFcVzi9hBxiO1^M8||eRRlnVCy>jKZ z;8UK*9|2c$e|M<1z`jput1o<(>5lki zq|o8m&CjIhwury|Iq(|%?jysssPOyV`bFEYz~o_}RgOPCv@6+vQlXeX(dbYaL1?Fv z-2EXLpotsL?W=ez*3TK1N<9F!uAB#RD1)VJUt*|cCB}q~{|SX+S~wvRZ$o1^jFaCU zLx?ZHRe_;M>Ccar{H(RWT03EcCF+7O*Dr~h%FgKLpVGo-6~=7Mo%8E3x=2GoE^)JK zoMK#TR zD4C8?7X|1S!sCtgNk8i!(W(NGU`Km57G6(88==KZR&voVnrDg;ue+&lJYm;9zJ@De z{nt&~*V>sgG+koEocc2hjKl}M`6pmHHoQyUsY^vCmCHP$h?dOq(}T(z?&DqR_YBv` z^Jj|1v>x6X^G;v^|AKGr4~hv+&*A*H^`)+ifXD{;uf`<$e>#(JL`eaye|5#4u`16r z@Z2N$uhICd)4cyHMREK~kow<+{^= zGymtu_iVSnWctror2zoUoy^o-oIbd6n0)vEKan9|{$K9>2VO(}uWrv8{4*RJ2{Qb6WeT@CTVOpHX5t3o&3_?=eeJI@9R7N%sI2y znwhot+Dq>>Px^zApg4*$;1C!fP#`cMARr_lgu-Y|(V!q8$S`#{Bw&DXH64XsW( z%P;hP96F#(ETKI?hlPn{U-GJ<7iz!DDg1c#nS{eJaSW;z)nBkZ_2Bur{P@(TrX>pR zSQag>#dTB*<7!?sGn?es{$=Q%UYMy7BV;2lrIyc}au7c8aJ+bR3>Ypz82?5Vl9_riDjC zs#sQ2r%cw9b+l5i6T7)=fT8iljFA%3+5pqnYVBk;O-mVo{PQ-?jhGy;57J4WSW8)~_yqFm zh~uT%%79<~8@^xS=`cGY?wIY;$%XQ>{rgB*X#hAszk3FT3^^3F-A2NlSN;eq zR!!Kb-st7X%#;m)B{@oRrDg{Q6bx+Z+f5cWphM@&usc_qREM){kSF4C1=PT=@K3&_ zTStyvt)R)QUNS(>1;<^8w*4#P=VA0cXPR3P$qGf^nW+N;dsN`jvQhT(^q9iIO+%{=c zzCiBJQPFCsQ2eL$k8NX<=b}UD^k%|j2^u6RNydcI)dsxk<03SraS<-U8t=GBlj$91 zKKc>D5A3}IM3%omfwkZmC=C~Tqi7#`c?JOjf(HTv3bd!kYe0vF1qCFHS@$y|h~0<0 z1xw8qBqi$)9ZecwcwGee9xNzzWUm~&2p0AzR~JULR~ zTmJG;S0ZEjU!HfVkiH+trB9Zt+Jp^MdbEeDL|XAe0O@UGHxUhILX2iMQWLPdRPPY~ z%oVI)O@!A77zoHckRBEXpy!aujNzBt`2O`p{u4|*a)_$cjAcSe`R|3hWfu91ZDjMz z5c?It1_wK?ok8myd`2Yh%j- zVX8D^3Dd<=ukX*zCG3!Ns*piZs51*^eppA=6;lBF^$#OyxRlS{svj=GVD!fp$8GI*IO*d}&{$fLQGRmNLufexg= zpAqUPV@UF@pCogd(h;9hN-K<`bQYv!;o03z=z(CKiFS^1;cZg?R?eAp*R6e?xcjO) zPeuC500tST>7nO11c)RstDTp)I|(VTtjvJtju|>476;AAwQ(|eK}uo@HW5c1O3~(F z{ynn&&QZLlpMocivR3cF!G%D3-jP1JDRr1+dy42}rihaL{ z`A|7e8%zlrlg5z*yLO$@&bVgKB4cR-1BJ|+eVra>@Whh)2w3PiII( z%5|55gY0dkMgQQGk_qG7qE#>TLR4EqgrtNpKnz%>xlsITnRqvIlDs?zJ-i_?)i$;@q)H~(e0Jji$Vno>n1wu}JHMt<}J8JTV z51fL>gmpIge*3ZiD=>hd__zReMo&B2q%=K;N^X?UbB&evuPt9lC>sN)N2W=#tbOWc ztiKa2B5}jg8e+|sJl^whZrRAfttC+sc8%}g`cVGzf0sqy3Bn}ZU!EY3Dz>Vn-&M-W z_SoM5bojc+i6pT{S@yCuu{p@5ZQOUg)puNN%jx3KAu0~{PqZhQb=CpsQS~*Y2Lcc1 zgA&l0l(l<@wrwNY4cV1}GyV0cV-|G9PUh-xnZ}V&U$VF3A^Ck3wA9r}A!RIK-=bu) zqO?!hGK#Pso?4)mW5q|?A^ zROr4(*n^^zkRx-q)+VEqC~U@DEJ~XEfH#adD)rVsX9})~l}%!*OJa?=&`aX4>L}-^ zSSBtv@4NoocD$^Lsp(J*Hn|eE2R2+X;c<4or8Vh6Io@1RtSAI)DRsXZXn?pR1;XG= zd(X4{72jHF%Mu5mtE?%_vlo_CXx>`@I~)-w;MBYT4Z+)<`Oq41dLxGfPO0Dr6y(yX zd8YgVt(t?64o{4)9IlgkBO_dEx0J)I;}K7vFd6nn9f9mc(L2iu*Q?f?KeWw5ms55^(QE$UW9^M=wh}{O%qK2s+x-3x(Ahkv;GFFc6 z=W*h0f2|8OnHR4d0&O#A9Rh9(5&*tFNZQmnbE7=Yy=_7bs1kHWXFnuf@8z8 z;&uWl>TU^80pF&Lz1vkOKa~kVMOyE_oubjrL~!cX9Ghk|iR;Vk*`h&ejPfgI?#<8i zY{{6TtT5c_5A4C(6@pAS9oY^4TIZXfj#CW9>pLAtH0Sfg$v6XxmziHS+>=tG_fuaJ zhW6DU)wjShzO-{jFk#xV0&SgvixJLo>JVY(YqupJF@b0AQ*>Bjw+5*R_mvnmx8(+8 z%mlH#2ZcIvBw4!3UXSKh9&ql@sCTi)cg~YaWhR3e@lr(pFN^yaKFVr7fnx%`HJ`w> z>yJ1Y?RD|8dk$S?I%jjx{IYmBa#h80H!F}g;&u)>8P5#xvW2qj_dEz)nXkC!Zd|G= zUI7r;01DO=Tkl5?C;Zt%gl*U3uIs!65*IuWW_2IvW)Nvp1PKQ)-L;?Wyg}USoZVhi z6Y)HLAUJdcYp~P_ECe0cnp-&~)42Ud?%)$a)uH27(A}C_o1uac(OZWM0hL>>K45ET z!>R04nb&zg>MZ6y8Q`9e|DGs*-*FxEItPr&;8P1ZDvv~A-QqX5+L!w;A7Hmk)9s*C zYsmA{?fs1Tme)+cn9S0Uw?o-N36h^{hI#TRrRomZX%{{}I z=U2DEa$ksTt%KdXSk1nJhRUab4|3x07;b+I2&p0K*QKNGQxf3t8p(tHxlV?jT0@0! z_hx96fVyvL1CEf*Y;m>(MP^~T4fx<#2M8{8pmMrcBYbcm;j9|&evKGgL@&vFonm+~ z4CbL||MwHTJA0fe7RPZiNwb2n?|9-tQTak?MxS_-1QM80zW3eU z=)RT83DWQIDy45PQurB0+;P}6tMU#K&rZlAEo`(Lz z*Sryl^6Mjd7J&J?rC9%NDYezu6=oE_nmIu2OXrW;ZpQH16~xrLd}X!UD_epvP5hy9 zJHyB4*ld)~?@R$BaDvL^5G=K-ItHnc3H`Vc zYeWz|OW48KEyigTI^3oi&ZAg~XApFO((&`q3{xcEPJihD-?jpr%WGn zVZ*J5%yI=dV8hPa$ok}J6KmVfrQE5rX@j-}Ld`yg`+XEOz-ZDq**17ptrbJn8|HJY}GgPrZ%z&0o6nQ;{7-P}Nm-N}!r zs+A=`QB>8cCJuWZaw7hE)1AXSq7VMM1ur(RnG*|2fN6)5_h>}NRnCVr<>Lt z!L`*oi@>$}ODcB{)SA#fQ#M7S?W%PbYH)oy&Gmr<|W@r5>=B%0XLyJ!c;mL&Ji8z&sTp+ z6G+y^+XqEoM#jTglxyhmo&0LwqY7<7Or#6{+f~l(dgEm29=PY%n42TwRSP!h|I6a3 zVn~g4FCYrEYWj6|xBA!b75IlGtJhq4&Zo?3`e=V(RrPzD)#mobI@g~X3WUZg?~lK7 z{>>i#FF8&BL(ai}%c=ICa>}I5r^6}G;AtL1VTh%^U_gVPmp0GCQ&)3(^OZ_MRrl8( z=j1j?WY{H>5SEThQzsxsf8W;-bti)y<28#^K2m{g(w5eQ8ei~R3aGWqKuqz0a)mG9 z^#tGBT+EYSq|baeFYU}FI0ZfpZwdLmtSE-~@Qmo*`%B3j10Q4M+As>?8Knv~vs z$<~GA($mLzrPN{gPdVYvEVRVWKdhMOA1g)-kO6KJqjWmVzd=Vn?-~(&VsNt_9O4eE zT3I>3g=Lu|CxI{9>DmZQ!$}ipAw;;CHsCVg`gwBMK|hrsH6X?@PfM$;e|qq6 z5chK(TwEGROA%7GM39@_8y7X1YfeS7p*oQ!-mO^9Gx5E;)TqpILb?DCFc0r8#G3uQEi^ zs6BI1u(iLbj5>x(I{`?|lS#)C%L5D_)vMF7qY3a%t>BZAEluPG|2&Up$hM@GI8w+N zgD`#SfWvm9nQyMm5-(U)wCU_kyK$s&HF3Y8A+n?xXwD{4GC?FGXw^vDYmT-Appcjl zv2c2mu<(dQDjkCgA_TFnG9%3fO(EbZcjha(`7!!Q$Sm#fffMRb!vzdY0rtf*C^Tb>Yj;1S zhM(i1vCYsFI2V%VxppV_<}hS40Ezpo8%6XeDIl>$3wLRihV8D`_bkZC_10WWueGcu zCTNhb)m=&9CML@J(fg^-)16rcLJZ_ zqfet+JI-lj8DD=iqXc5YU_F~LR5A~Tc=|ni??RK!Qc?*7b~Jcuy`P_W{kiJ_{;wBT zIyNf~`q2M12p}jS0f3d!-Oe^zRnKANU$rp9AIR+x3C!X;sl;m8Pfc>#i>Gz0mmw`~ zzJ*J{ja~kWPBX$Bav~@M&;D61lTzw>W;n0k(CsGfV=$|!^Aqj0j|zmsbiOduqS=`} z3?Yk*#$A2RQJo19k;9x|K2`QIdZx8go{fURDBFJp>w`#jiPxwDKK`zx51T ztoba!9r{iPS#1!7xm3|=_hsNW0I?M6lC@RZrY@*jn%q=`xi0sjw z=0~958o>cDm#Y(`gKh;Zd`EvEXTvvQ!4ZKRwCB%Do`jFkRhdZJC+O=tW1&yVdy1m~ z@v`sms^am(%+I%IYb#9~X5Fm~j|aTepDT^}Oc?fEeWpfJNp-SjTOm5=Xl#X!Q_Gv+ zcoS~bv`=ru@lSKb%9FwPjCAZ|1E4aqa_zWQi?spHSX69hfnYQZi*+FoGr_F;ERc+n z#+eOaTB)_k;J{G z9T|XWt6*{Nu=>kRbS_HIefabozYTun+uRP7&U~VmA@%HsNQRe%&UR1}-FHKjpYm%7 z^Y8V3c2Q`VFwthP&snwXM%Tf91?Q|rQNda#K@vwIG5z}kxodBBmyozC5?w3}CvIM~1Sykk#`Y)S(JF9Jp9i-v{{ z-uxu=?!Jp&P>Zw@IOvGUDqUt|lwpZg#xUBc9%i_H@2@dHOnI_MX{8tIk$UjDIs){B z-9vtnRuK_P{*D;2lYwPm?R6~E2C#wD7h;f+lNG~fJkoby_ziPz7t4dbV9@5%W4)5K zMl8T4AfS3srbj&>B$Yu-rxH`E&Zji21T{*p!#l)EoImV8FlwX!SP92u=l0Z3x ziLTy)xI|kDXTqeyH<#=@Wq_oXW%(*WZt}77#6C_)K#cYTckz)?#sp{{SR8%Jg-dsA zMGU@eQVx~L?2ceiXBI^Y5!GFN;!k!6hHh5-x;6{=3RQkqr}E8P3tCA4ilArUT+mEWP#eH}ezPC;%oUyjyk zow($2k{1O>wX1${zlsw35U*WM=`URw;rchiMBN}`8*zHr0=!V`muE@ov-r=1?yd-5 zN?*F9yd<1G!FB?kE+8jLbD99Dmkk?6z6gM`%JaWk%}Shd*88E=3W@l50FJ*oQ}W+3 zMCduy=@-pThp$PAoN(pZ71nKO>~ha7?$NO7J?2e7_ILk-G!WQRc6W3~Tf(jbfuW(w z=fzf1AER$`w8hi(MWWQzF6B)$ua~cnzf;hT(?+$5lO>OoG`+jt9*o?k_6JggxxpaJ zRJ3^)>4Unjl;_4L0Ip;h;}|P*<2_Th;Hx-2&hJWkkk`zzff-U_I=wTpMu!FQy8Kq1 zl_Aay{o#>3Qw}oAOR?(LG%XqFsd_F0ZtEb%WOPTdgwj$!Q*)c8@tewt&lai8+fAN( z@O>G6OsiwtL$%~#K5_21Z8Cz)cqhw*gV<4tW6=18rz{610t`E@pk9-<4JUuWK6Ok# zK~jA_pg{yR5~JW2m&f71BSlwBo}q6I&3e64eMcJ43(M*9z~_G^_v0|_`!?))E3;o6 zZ2i@ESgglA`MCr+H+U@t=}oR1%GD&DC^vX79!ild)8|xI10=*iS>_v6Z9>P>!B&5? zg%n!Y$V+Hq450Q*i!>3fvq64weehFdG02L_rdPo@i?Bz3|4Sx%V?jH(!g$^7=plH3 zb&#E1U#)u~1;_>>TwqTzaxGS{HnU%syuC&bq3>?#hy;WeMPFju7{&7A{dG|;f}nH_ z^mgVq=!LsXhH43K6xVVpxC1hwgRj&CFxZh(`{hV_J^+V;1PpRrX|1*Br0ztLqzgZr z?ROM3ACf{(q6B6%)}o#R?jVYwc#?Q{iM%yRKIff~XkZWoMqn~~HCh@z1_G)s_17IP zEun3X2nik`;ZkC}MM&8@wC%1m5I^hs;E+`2(MK{gZ&$WbwYH@Pm^jK?6nJ+25{pkM1+IRS&)6>a;SnN)IKFeCbVSb%@@<-46HG~{?L@_$aE{W(j^j4*^D3!9*X6I(4+sc%q8W$r3#W5hYwInq$`eYWtco}#U&m8$X~U5vB_}JCZj^ouWbX! z)6t}NrB~~#=n46ASQw|0z~+iKgq+ND-~o%{7UWp`2jy#^E{qB)XgkN$&-NRTGKEH? z>El&t*s`IV5aRfs_$^*ku*wxsy07Le(*Wk##Bh8JtIiUAX)28Lu=${-oxhB!`}W5n z8kX4tiBTL`#c=cKuJh-z$r41eVmjOfOBVUiX$K7xtFp4obVSayxkdk5?}@VSG-Dtb$xwbezO%NeqfW{9msUN6vil&=WfE z0gqFSyNUwAGj8e4s$zYEmN2K{#(*ADlyA;{?b?DoY=_Ziw?{$E1i7${S2{u}ee)Wz zp(>1MhXZO+O6&c$F`*cx%EbZ14L|fHI~A{zWJcJ&OT%P1g_dczC2RixsWFy4O0Zs; zoVkUxYcWjM{x)17`#ID!OjYGmk#->8-pmpmWQ$=YR!gz(4=H#CEZ1A51UW!m_)TG6 z&1@TO$#?bzrLsK%X>(+wP-YSUa-8 zEJ;?WH7hgAz-Q-88X0^~?>S3yg7|jl@K&fG6@923rBm?M5Uos}dIiutjwv+QTEQLm zyFfcIizdJ}JCp$U^Ud;TG93W@{MVt?X6%iQ!07@~Z*3G>*h;Ie3a86s?DNj2(@CbT zsw84wL<&!*eR8SVjI(ia<=cSYgIr(q+TUK+7i-?1_UAct;$;wZP?F?y++u@*M(XY9 zODK!+`dufro)L)9vI+u6cW#HKsuvZUgd-6cX%#*tqBDMv__(k?R}Hv>X4(T1m=iuY zUd9p@4>5r`frg0E9Oz7u!=v+m**oJ8k z;tFn>L;$NA82rLKy7b z(D&fyKGo-$TRQp3P?WHvO6Mp2VVSJ^VJ7_mdJEd^=CmCi1s)SH4h9 zt!i$l>-`l^0x%InUGIo_EIKn6Ao!r_A=q6}HbB9_g7WZKdfv&4juIX)$DPQ5i3~B5 z1~DPl^+GBfPSV{#iwi@JNOtQ+E!t16j>1!1Tnpy`#i1tz2_zp3B@Od# zZBq!tATI|Mnv?NKeJqx@{}uF%4S5`#j62Vf~6FGrNQWTYX4#hsR8Z{A^}Y7HXE7tMg+~R&e1#^>z!DsDz*X zv+Qyg6TsO7u9llwj4Smd;(#;F!6jfCy#l&nVn34Oc~qaS_J>dm6AAGBNoB#wn#;7V-_`bPMr>{XlTgl0#1Q$gFdr*`u za6Q_ETRJ7_Z`jE&nZsp_L=dp&v9}2|=-fRt33vdp>gR)=1z+tRW509n{nGQYchGHi zIGd?U^s5oPo&sT*{;9{UoBf(;4xhZe`z0OU)xTVsep>Bt0{Po=6<0ccM{X&bPZwaG z$$?ct_rVs?lT?LA6B6fnlZAh)eI+Oq&c0)0cXQFc;^NIacg4U#)vMy=y)me>)ley*yq+St#618Tw#Gd+)cuw1nOhFhIZ?BLIA z_jDWKSWC5pe*%BEc=#wLQ~>&{a_6KvB+BN73PkCjrvQ&@S-dD$)l=;{;Rre1f~m|S zu`Tgr(~*!1r1kurhm;wQN|KfZ(HJ>Ef*bKbUTY#rK&t#AS}Uf-mPl2Y2nAqoTU3*# zOP&dOs&26I4vC3@iopz9`#oK8Za-*|wRgKEHr<1drU) zkSF{zbK!~!vnt;aeLfJ0a&s(v{HKzUfHbrlVDFU0IzIz!bsIrc7t}9kCuv!d39|Wi zgSe;L;laS!^XpqXY8^fW1U>v-*#+4V>Q}@>GjkM9DbHEW>!K5v0(YaaKlro+>G4_+6yq(!PgWLoCVfOV-7xpl>bi!cuBLm(-_X3t>umXr* zWHWHYuTU~+6Bu!i80S@uH7#6XWkf|;_d$y;CC@S?N@BeXr3y-}x|I@oLx`M5{60lOOQ0}k#S`mulOPI@ zfcH6FmU6SAAPdxuVFjk{75ocsg8gQ${Ilhwu`RISj*J)-0PL|xXZdJnk!n`;JEd*AK!7?F0$Wbb6u@Dle6^K;B}lofXyUo z%+I9$Q)pQ>!_p(U1+Mm^-y`t8cB% zJAXCMHs3>KNb}j#p%F}4Zxp{OFsi!X1S+X%*Erj6jgCDqZcKDrw_pWI4mutF^XJH7 zu%K(#kZ;|h7%wa&)u=0%41!_Q1F`0Os=LBix6SO`0QeNYkZ=ag9(NRWP3f<8T7X02 z9Wuzr`}@h~FB|W#4-}p=&$`&LGDCI#bftPiaIx?@K{;fwL&0=%P&=vCpaJqA3PatW zMB-L=iqd1Zpk$jVcGmWb7P_ID--;kA^roex&<`zK4kojVeWibxT7aXEVlaYHjF=taIQ`ZQ72zlK6AwueiLtKNn_g z#^p-9LH`K?U^||BSoJ^F5zxR(^RbT6i9+&y%ow8gl4~SapX+85Bekt)L4QZWkp~K% z&_9=cmpmEfEb0J--b7jZir>TGnAn7YNuF{y4#;_Q=G9X(yFeI}uA-!lg@F@vVkpv< zowEB3ub^c3NhL5@y9c7Gr@+eHH|Z+F*=}>?5HA{N2(F-S0a=X;Foo|17Zz^;8-j2_Xzs54g*pvI^MIuFCA}UTCN@79E~$Y#*7)Vr z&5-u_Sg`bjhwf#aAYq1{h``?B@I5oZboJ{>TI3B%K2!!#~ zT}fS~_2|2f@(ryAjZhF_MHr!`GT|j==kc-xzN9(q++)vEPJRi$63f|i?+2r_&GyJ8oFQkr_jpvK_Il5JBNQE(kQPL>HXdng4SiMIUK z_GGPzbfT9rIp)i$4%ysxR{rQh8&>tw_L>m z^i^>BqDP{D{I1^@pDmvMB_X?Z`swG7f{NTn!`uHz$nq!c99LPF#uviq#P$s{s;&YS zRShTVIcVok&FD8GGoQ)VN42pTStKo0rV&*x8TJV3phnrz3QwzQqi}qdV_n{*t(hup zxGdOoYeN{za_GEfyUqq0P)m?#o7EveG&{KiID=4ksxQFw8!s~#qmcJm5+j}CLIc_G zYgi(%vyRH!=?cP~C{Q6bX9hc!DWXu0p6Cml)st|-fPvv;72VNMqAAAW0!M5m1@XJA z={#uDUrneKG?JK%d6v1Ez__rKF)+Nfs390dq>epny>h5R4`n$w6H+eu<9|;Gvd}F7 z9;C3y`T+aO+~8Iibl^0hw{ZS4;oM%2SXDD9j7X-;dZ>{&kZUGpQ1aJMG1!nApEw}Hgs{oH+GSJ>Rsg>C0$ zA&pmU?qc_O0@%1K7-)MmXWlG)v8l|oYBYsS`py!aX?jW9$6Or*Y_eaxRdREzMgE!O zKCkZ5Xn;#tb=*hfy>lHCo(=D}42KZ~cJ4nyxt*S$sX6lq4(z7Gg8Qe_AGk@!rTVwI z{9`A{e&`(h$N8UQ;G^s zUp8IT|C5dF4;#Th%^m;CHjV-GW1uDYgM%-8yv84wO!i-|vxyD-kOq_u2%yI$_yZ&V z-(>eVf63VYkm3J>!v62$kbvNfbY}mcR3ISu|MfJsPk*H_bvE+&lR`3mz*nOG`u!Km z`rk$PH>d#pzc)H30!lM7u>QL~`$6#E(|ketf6f=jpZNloGT?z7QULoHCqG z7SaPR>4^ybHx2%WV1yY6WTYhccc}BBP=8F?KL;!qaGsHr;NL#APnvhBsc_3aEG9Q;1(>nyT3W- z+;?;Cx$o_-f9(FMcJHsdR&}jf5n~9)S|sW!NXP^L6aX3k0H6iXM$133m zh>&jW0q0I`+!nnZN!eE2h#(mq9b|0d_Z;|VNH4``i6TJ0C>W6C2z_lGc4?aPc;@O& z(8Wtgqr;9BIzmj%mn|F04}lyRf?i2cl>^`#27CtVx{}NgqcVgZS69e%cA2knYD^dwjViohFnEO2tEK|m9C_H&_8RYhACUmRBLbr#K}N6B;if->n_kuoAW#zcXuO%{x#0BH%h`!>HQ7PHe&d$G!27KKkBN?-3?9-4gP z_6C*pnR}AFTiHrCp4a60#!vlV{*PPFIO zWI9@QBKB1lS?P&ZUpkVVGR1 z>0Q!<*YSP5#3qbZtSaZ^5*(dzR8_NTdO=q#tZA0o6`Y`LNWpI{k)x8_+b88gX2}*@ zfdly}r~m6ZGrCP6C(S-GQv=ug7g=|}lYwg&&@#VqOl)fa`PeZj=0F4{EayGPXQ=(1 z36VY`&^IgB2)5GIhomnn;YOjyP^9t&S?i8($bz@Qu`_NGZy2*rTjF^EpCK2cM-A(f zSpS`yYBv61$qRSg#~sYS0Ru)(f(}U)OYulS1OT*w000jBYD&bV*|m>>&9>i!l++ayf5}AgztWhj!m8$DLX5R;Qg`hs9%2HR>_#qD^Jlf4>M4b6EvXYk^BjJc} z!s6TS;ZG*?#-MnNbz*63fe?3;_{yDgqrTJ7c;Zv~wX=Y@#m+bPq*0uh3PgQ#PVP2# zS$QPVzIj|k+FHx}(Onh9p{-FFJupHr5aGzgT}CGa%Xr{h;LA4PgQ?QnJsp+~z;052 zV@lpnaM6$jw&_d!jBRnjf=TAAJditc3QPLlnET?5X6r!~3dOd;7^#ri9Rc{Xt93#&qa!G5N$#TcI!I2^K*#0AgvYMy6yuIH|9RJ& zUFZG^J`#Oab8d~MW=PoAyZvBJ9@jSE15=92+ab&6P?1@-Qu4P8GuggU-q8AAFu{AY z!fJy1l%aYJ;q>nM1`~NN60p{7FD8>$qk&6jx;_DW@b;)JQWvBN<6tN?Mkx2Z)5`B< zpp|ND@@YocGE^U(M$K@<448W#5H>Dd5zBn zyxzZH*6+ruFcPNO_pcMe2Ahd+w4snZ^yoIM&4_k!5A6l1j2my??40Z9tTq{rWboxV zu*yN9^wc7<>z^Sx7MVFrMX924s^!(p+%PDEoq~g>(EW8$>vlP34~I&{6~Nn*uaWhmYN<#5WJ!Ybh8%=!SeB#Azr>P1C;(Ggej= zvVHrsq|d&7AONQsErTGm;77)-bp2h~y+);n#zFPAZTt`~&wWaes~gvQ?lMAZqaKIrYoDR=Eb$|4C9bX+1ER-x z>udb#0Oe}#aeR+&UgZm{a|V0V?ii^&m135sdAYM#>Ze$`0zX>LUHJt|rVSm2N?qP< zJi6jI$Is3~HgcjKMQg-A_q3VUgM1x7aar%RmyK~_BHKTC^)UjU)F|Wr+EWjq68X$q z1?To4ZQ3!!TZ#mWK+KUlMo*KFTkW|js@WI90v`GT6e8xYODQfKY*$7~<+=OgjX6FX zK%3CK%-#pU%KE$Nr+gk+NvL~xW-clU{9Ws z68Ajl0M%Z|>Z|WuCde1`@an#zA5wH*Cq2_!ClQ>CRB{)_92Q5xC-(I0`2O}((zIP{ zxoM*eLiUZH5S59GHKPrDy>Tv?ZF2v88`g3n{ z=CY{~6mb=6Xq5BC`9|PYBxo6sBsNzjI!_knLmLZZaqBwUUg<+V-!xT}BFDD5sHB?U zE9Q`e-gw;ZyhjgpI`1M&Lh%!g$wPnZ)!fJjF{HB16+I``@)o1}AR0xaB1E=q%APzs zgmZs8iVD7jI2qqkBQO(3Zwdr2mR)olWJ+#Zqmvm?rSVK?A}vteNMJHOv@jnnI<2D~ z_&|#eJb5D**fBacteS=2f42Jx_8b&H1WS$WUxRRm1vcJke4i{S9aG1UgYF7JkG?9S z`rK1jotXmu%tcWUuSy3z2c_YRkN$TV@vyVD_VnN~b+>l%;QDjI`$uwe{xN?S+Y#Bx zO(1uP^dRE{hE0V$kTm2rr zI8Nf%tWtz8_rP@&`B+(r1L(vQwU$e@?vQ=mUoZH%xTgNY-g|#)G3SqMBZ?=Z@03L1 z%p~#@Mf&CTPXaBZcD*mM9R0D83qeDJrx)-G=fCL{MhQ;VMLWEdcA>yHNk}1o?lf9w z-g%W9*Wc9svEu~n5j2j7SdvsSr`$B|(3EVuCfr>DJDx-N7U19KhRAQuXwse~;_+)J zdVlC(Nm;JG^ELWpMxlmu#3x~^&jzF0mDy@~mda(8I=uwi7OIz><4rxAYBiK8dWL8# zXuR59s+gN+{O>uqWCxs(AqLu8104xND^q2br7>pul-eaeaSTFk16FcKT|bOE5qvqn z_#n5k$Za4-;6;l3aKS7F4eFk#Y$@BA2;D@=6o0T_O!S1)pZIvS>}f)hdd=6DhHr;` z28~_bo)xU4u&;AUe-%dCpB9T?;^F16N$tk)n~%V|&R8m%*a+{9g6J=1FKh1Y4WtRz zzr|B_W#XlH%Gi3(7O02gC$9yKu1E2a@6B9@EKqk)Z7W1;fb22^#IUT&yq|cJeppO3 z>n+3kp(e&%MIB=G3u7oJC1nCA5)#Vr4kyj^ZaL(rgGL&G7>JW@cIN^On}v z^Q~?ubT?Fjw~vSqNffFuD`dYo@LL9EoicP@uLCL;`J1^qLHyreVxH1HnxCLEnlZGlpCd^Wkwx>p ze7@7B#GF#Bz;VATKct=KaGDW9ymxf1-;DG}Zr9*wG@)RaqB8eZ!@=G82e@e<1J3jC zW{!AE61Q0)%A34CxLaxr0K&`PO)O-N3h&oYntOkHPU%ohIRNy->(O6oPF;yRofk@k zWpe96O~!=7neozO=+14VAbybMRCNo=3G_j!D4;l+ic2!JMy>`7ssTr|6GYmOq$7S@X~Uc=Qa;y0a{|NMrlKQ|Kha1Gu*{lk4789P zp*U$sWp@fLyb^GYOq~X~bx9GTRVRJ%48u>r@3B=Q#|ka?7`o-4;$AXKPRDMJUkD8O z0YoF#m2DDH>#`459Q38*K{EBSko}tDee5KVzv6B(wOK>}24AQ-K~Qd!L7Y{JGkI-* z9dg^O*9)S{kn@d^`ElENyzE(o`jNFMgXMOC_EKVTMk=DU2qRZh?o=lWD`4Q=-FaHJaNWU~%a~ zxi%y@h`A!`;lZYPkbKFEnWq=J6}M!T2IjB5nN_6Fmkm%$&^3a!4_f9Zr{`LxG2_~G zM(*cGr{}&%HjWeSv(9~dKz=0Od2`dZ)taEwX)Q&aVmbIFNW9~{<*$0Pfc{l|>iO=L zqY)Jq%Bi6|&jyOouFSAvj)Nv5*da3N^b;MKPz$SjV zI>=CUL#*gi%(TLWtMGlGfqlaNS;!(?vIyoBIs}1bB#!(L& zcW~7AUXIsXF)gz`%KJx3+6m-1@;LQWhBiNk$%Wzs!6?F>1NZMHgNphoF`A?K%U(=Z zMo_mRa%FK1aXRJKGZ3?Q(O~o@q&SQXLQv&cUp@T;UY+#djSc|-W@bwS$xl#o{PBXM_Yk^lo+3U!kiAG3pC1POS&k|m z5oXW(N?!0V|5U-t8fUd!u^P1;8l}+kiJeY-yTPqt-epC!3E1=#%8+c@zn+?WnYua5 z0RH$^F$*1(4^0RaMPNj9*HL8Fy4hN}7xiZ0Ns{RZ!;n?(>l|y@yD0A_QE}yhq$KE0 z30{)$`7$~hip1M~yD^nCzn7lQKErpAT8KiIM-X4oi8;|zD?1bl8GtbuYDtZ0`a))JbDDa40X z<%K<)B0`2(c0G&JnsCS7?$+MUF!26iX{7G;sxNR}sw&E(DnU!d4gD-CEnHV|#KFq# zV+}?-Y3LL8xT&92gsaq*z|3?>RMvu(p^!}CiV0R{*zl}o*&-jk!HKO9}(G&X`Gk6peWmp&g<2n2J|=uhdh5odON{0?B;r&&1dYIjlinDZ(xPBydj zWIyJb_vnPql<_Ki<~-O~(zV+k|BX`Z1Wg5kQX=>i#<2Vs6Fix;F8ByPegHE7!1Nar zbal6P_Oy1_vi9_}ceeH5`p2Ay)56|)FQr|2ebzY0NeT6uw3F}kdy z6Del0+rrAMJXcmiFsAN&IGFfSD?W=E(SHs%kxx~=Wh(lN#1tj>dyw#>-|k$}9Yxz> z$dLA3ty;A5>t_Ljc_MA5VU89ibbUQxh2nY*uO~vwO~^sMy3>^DAU&%};O#~8>4~$D zsa!O}90LMA&Hs+8Tja*u>q`@pyC8I?w3DaYD+tctLc1q4ZYHePEO=AL8Wd^hXqE^? zQ?ka?6$6p~HF9K;CH_jS498Zj=yEE)Ue7E+%> z^`fkHeyM20%5r5UX+IQev@-+=-=)3S1qna4gF$1$3H)MJkneHpa+B0BgPIIhN0R4N zZ&nnQVQrVlR<}sJ=WuzjE-+|;Xb5#9!kjX<+B~`Dt41HOR3x*MClVwoQyr)jjxFg$ zfviHURFpTQks`*cHY-YMJ28u#$!jCHPVb`EXmdHL#g1XLccEAW{7D+ooBTt=gOH>489h-SHUpY$VbF`Q|IyQ@ESh*XYS?UKxFki_?8PT1| z%m-p?L<*K0Xb*(2?{M+gGY&e_Sj1{oL5QFz>1d@c(GBcM*Pd*M%AKXbJ|3r|=GoL{gU=ZQHaRsViJ`)d}iMu93N30GZuhWkR_S+L&)IjXIHD z=2!)0KLlrC+#`LVf&__)8?JMC%-xqgyXpcbL*SwMt4~2dl2|%)rPG zFaw7G0FVH744d$wbO3Oj836czL-Y=MezybNZU-W*LjBzW92HT%w~m%D(#sYB^w9SI zd-`9v1wLdsn)RIGkKZ(*z>NKdtaV*eUHtI_<(Y|yq8bl}a-ad$l_I0QDbg-br4tCrtEc3tX>ZFzMHLZUxY$c=iV%S z{6Z7)s8vJL*=VcUPo^?wkMn)+VYhs1nv)qRtiFHBJv+#+I&S1qxop&v8#S+da$C3# z@2KjUpGk3j_IO0}I~VQsr}4AD%{a!^mDu2KPoL#WUsJ}v-jzv@3K8-|i(^zuJ`}_* z;*4StTS18>`%itoM|CnKoCvuawJ_s&1XU>W(Kf?td6A@e>&DAUQw6qYcKYV-NkMuC zgVeFoSuPXnfJKFQ6{_f^1<2WGGzP%@{}8beAFK*kpopD=0+JnySma%|TLDUne?I?r zr2a1)p8t*MRhivJy{EY2H)A%r?=C!ROHRDiD#WubeHHGkmfQSUE%*M-rv2?pFz;gi zZf#TdpTj##!@=q^(H$;{@lU_5m3-yMKjwQ~ZrA6av2{sa+FykEuI#R`$c@bF55qnVkbO$tPF(-MFh>PJE2r}OHtHj)pUEYi$nQ*#7=VQ zz_zmD>D@<@EPop}yX5z`*`T;_VFUmX;1C_^meRk3PKe)KpBsLDK7VrEKf;I(N_fz= z|7%a}kA}T*r#SjIV>@C;Bkp7dI|>Jd3CB9M{Ghv1(p#J)Ccj}eA1UqX$R^cx?>a~3 z$j-t2dm;O^%{=hs%3$mBynRPUzSlhWEnnOK(Jf5pt9*+^JuJ>=Fz&B!yYIxLeIL2_ z?8jwB0b@3ffE`(>Z_ExR57tKFjaJYv&)vgj=6^J6y^z~azO+}zd{ZcoU@l8axWPpD z6wKM)VBcM#Byk*LvDlEi$+X1(uDCv#{`A|mQ)_W9Q?!UJp=HFOcDackOxX+r z=@tz7JY{wtRrHOk3@xN8Z7+>tHZLb1saTQlRXUb1NPMFHOQr2rnSa4!wd+|Yeky5w zeUa$sHA!2pySTDbVC_I(?}jB|Aaiu1d*8eY)GdQOBU4UN&yxbkd}me(W{{r5nE@>iMqH`qIWalPl1VYY(KK_C%Ty!qy4*Hv+Mh9<=B3rjifz}Mo6|34N7TM?H{Z2>vde+JXZmjH3%A4B zCczUuJIrT#!}S@v&$Z}x^rf9LAq_p}ZHPY;J!~cAXS^-c$~$8iEwNvKM^Amk*xblK0-;!%p9N{rY7r<*=EbpYib{?#N@j zgsKr^T+OWnMHcSzET-3E_C8T|J*LUdthej>Bh{Kki=$D=k*U&aXY*2dr;!Rb)Qu>0 z;ol4-)$MC)N?#ftQS2cP=LjZKhaS%}nlU5QB2~m9eRZ{5HLtR_Jvi?1l1(h+Xbem$)-n9|O-syrh8J9)rQH{h>H|~pf{0S$Y>{w*o(-CE&<`ARHZarf+ zNf~-?$DSF>wEv>V(0L+KQb2S1gj3uRNH1FV`|tp|_a?g6iYBdR9Iv@44fmhz_2%{PwKVFC%n&p>+ z{w(oaz{d|awOYf6um0@M5*l-%RiWG*^hZrD$eX{YzOc)1ByeZ#NYZV&I?}6CNtk)#iX3mGvORn39nls z+veD2A27Y)7gr6&*NI=(93bUr(XDIMiECM`D2t!Zm9oh^ry6+X>Rsaz*=AohZ^V@6 zp+^mNmx4D&!=LKUtA;K5j;*D~sPkuUq*=0mT}(F!+mdX^!*t$$I-MHZO2$uog2}l8 zJXyT6QPU^8KPS6OX8U|?y)S!9{n69C5YgPng(9W#OSsB9c)m@HV5`01>@`U?+@Vg= zq2-fmO_zfd4y^Uq(yc0&)jxeyDnU$K*Ia5Us;HeBtMu~X&bKd%&z_AJJaW$4EBo8A z*8B#8X;)&ln00#n&$bi1*TXKIO0BW|-fyZuo8Lwspq8VYyXj}D?!v|~3Ad`&uQ7b@ zs@@bPZt=~QJwi*=?vvdVZlL86v*hY4WB=2w7C$71>mEIuaei&T$fW)xhQD#qTSA9B za*?N!F}}2Iuir@`%fjk##&Hylu305tsArDLnU!atL+sP!f%YzxHU2ri1Z5q6_(SBR zpZi~puQPw*>(OJ!41yY@!{oLQ7vC%#=Zd!Der2C%?O0iDJsZ3;!^kjt{EkS1%W~~z zT|R7|(Y4r(tdkxI$>pG;*IpgN?>C;U`GTQRf8tBm67vMZ z^T;vPU*!0HRBY9D$}6>p3Ci?)vm9ZoyK5HYsE9@$m&vxolQRWQ-Cew9>hroP9V;t$ zX~+9&!LAGU2g=iDaWBOLClA9S&z7;Kgx>vVXW{cO*{zW|@{W=5XzRCkhufZ74=?@H z>-ohiAMBMqW#hK05n2z1$)of`gtd0$l03)4UZzAx6i5pQQOv`gmwZO>%EJe5V5V!| zbmC<0yM&w!wtZ9h?wEAIG&6T2R?qwgb{iIJ05$wX&GlLW^rxe~qC`J1WNBU&f7*&OZK9Md*hr+${rS<}>|1`9FF5eRq(-YAg24PJ!=Pta zWz&jb)S{Z+kd`h*{rFocaU*xLmR*Uh(%o|FpM$R-I!DzcNW?kby?k%PfkiKd_i$|4 z6Zl+oe0XYnwmpN0TUcp=!ZP61T&)iiEP2}d?EG(X@N<{b>Cdw5W5Z%zT!%SKSn{t< zbw~AIqtDcth!C&Zi|_DJX`B!lk=+&5zIA>l#i)9-I{SWe&wV`(oEWLmESgC^|`;wEzB#+eXr#G&qOYLbH#R>W&Q$%cy|MBy5 z3KPd1O6AqWjDu66O;Psa5s8yK)!ALozSIdT3O-ryBDN**OKMzid_STX!|iJ~d&!l& zrK7f>H+TC}{DteK7k%cxu!*GgP49m~XZ%(^b4yu5@!ciYpC`N78GD>g={ zKT`xr&qi(0u|mvq&GJ~y{3NZhyhn%0#apdjDuVDIW@-I|w(;1vk|vjve6g%QE~fRb zVq(D+r<*^8b%GDH$NavgsM>cv?A{X#&iCZ*Y~J|2pMrP&mAk?8p0Lp}+1z;;8@pAk zYE2<+8_X!Wf?pgu-PJ>LYJFwmH;bt8+EP7!L1n%tgG%PV>L-7*#-vZcI) zuCU{8t{0^T->)?)JfJtj(vz-=g9XmQ>nP5p*W0U%2%+b{YFLWT`a6XP{bZaups%CC z{|=?TP%j^^g;)TA{a-~X<-btM+Ad(`6nEt26jCxXa3PP^UAvB4F|+I zGX#rOu8~I9xK`~o`bF-@{VO52^v%#pStV@OPR#jJOPmy1j9`bmcmRV569Vhv9J<|uGOOy_%ek{gxdSOWHqu_94~n_ zRifuHV#H5)sqdogv$50WL{liAGvb{x8r!j-VgKP-{;EKKfy8sH(#^S=Q>@V{#4)MI zJ}Eey%Zn)a<*@yUs-`iYB~HDBERL$C0POh5k{9vsd83BxnjMcBS|VPZWAAj4uQWFB zr8>AdYJI(~t>cx;e|0)zW}wBe!4s2 zy}HhFmcvAL@xs|F`>s2HiMZ9L4XLR$XaD#vMdqbL>na_Afz8CYbCzI3mE+w-DlT35im>u+5iUY70IPP&IPxy2m6-;%R9 z;*W{f#o^A;bHWhEMo9kAx~0rN6uYr58`_yFY&Vm1OLfJ$J^A1MIhEYa`x3kNZums4 z8Q(`OEtXjIWR2)#iOr>T>1&mW_(fN|``MKHwsUaE=k4hyb&QMq%f*E}pY%gNsIx6{ z<+^?f%g`;Y$(C|~p;hw8W2`q&V4^IitMwt37i8AxOWe*{mea`TbE00suI!hc#8n(&Zb%(QSr5&G3BGe-3oq$Y{CF>`>ug2;5pZ7c+mW)JQ_CwY zB*PhhR@{{X{%+aog!3%7xX$Ga#pd z4!f4wVdyGg_3J1rG3uR>?z0zLTHw|%@{J>>)=*hw-jnBG!DGxVDZ_>C4yS6H?~k3n z`FveV_UX$Ci<|lqsx1-|^*y;qQonO0xQl(Bxm>WT-S&Xf|*1{oHu?LdBcVxd|cqz%+ijYbRTNmC=pg*lVomB3(;biZoMv zG|5D` zvwyBPj ztG8ccWCN>kO)us{0pqN;VP1T!jpQ3-+D7D7;uqmYWqQ%w>C)5Nvy#0Y8M=z<13OL# z{{bOo28VdzD4kDvk{1Rn5NztBW1Ne{Qd+J4f)uT7H^6GTTCM!vL>zdCi z=f4ys3!JSI*?8VH@IGgjJ2sc$H7=^=JO03d0(tg7{GRPUm-!?BUbQ%n%Vz-K&;K70 zeACa>{H~vWfKs4mknfG#E?&13z5U%hXrE|{0JqU4!%F}iR3W+y{Q)#Q5T%duat8nt z6W}DY?;(JZP6U8TM1K_$b?8L@%km{USpdqQ(0VAu61)J2^Z&JtDK!5xK}Y-R`@hT? zis=6H*3hYn=>M@b9ZGyvv6TKc8C8=^n>C< zk{9Z_1+I>gjw|1|8^g*bD0Em@L`qsl_QXjQRWR&RrY-nU@bxG?)|arkDdRR{>8HY&Mv4C z=;#?485mjq*hNPl^2cx(Ol0XP^S2j^kn z0T2LnM`cdk^r7jikn#2W`S+7^^HYKz?lEURd@#>;Kb~p$PDVy+glS>DT8SFn3Mt-`Kgw{0Xyo98S3%1^eH7 z|A%ii+6Z+ouy&VerE?4KK?BOjBTRdMEQD%NZ2!+@Fxu$f90}hZ5cj%k%LCb7gf}=g|YU8Cd4m|`t?;mWwjFK9!Sq7;m56V=KEJF%4 zl`=!gRYK1`n;W1(kcmr6!v!s=>}~i@EZqj1-DC<~a~HaIa}d zX}}&HOEJbPrHG%JZiI<@GW5G|;?cT9>+)j6{d(CH7sYlva4;+lii)$Tlsr+KM zFm%T0JX2$X*UpMJU1g~uEHMZ!xFVv|=f}UW>cm85YKcQTcyT5~XPfZ#3Ka;DhSN40 z+e($9EW|_6azr@Cn$gsT{IOY^mP_}q%abqCjbM6|t1+V&$O%+B6ax)-Y!4vt!c(2g z#V8yN0NUwjzy}2YPD))v{x)y_6R%DH4frk?1p_Yy)$YkUouUCB8eVtnbtBZU2eHuti{L2TG})rojI4nZycBOHQjcS@Q9&X z=O}eV1A+7DxPe2qACyR8N48oq5-TF&VwWZ>up7qH5$MOKJ}prHN>7LFC;Y0 zido{srAS#D?|nqzNxywv&tsc1EXHr+b-5(*of~HR+7xTja1zCGv2&))V6uuL^o(LW zO}SQKhkCjAth#pDi5D~>q?z>;oF>;47cXmY)jh}I*?s2DDfy}{NUn!yI8_%r3MQM_ zkIi+R{*9bjT5N72CQ;}+1*s}48qcTDO85AG*!t4U6xuX`<(5I%u)G!)2%;$|{ zR`{LRukTaqs2 zSA8qbbGId0tge?X)QrITF^TYc_d+s4pIjTK`X&bt#|lw$$4)St{N&~UjAM-t#NeOB5jqp*g$fD5 zZ%DuTs9YoKn?%wM4o;_!pPtw#A!9S1cjY;bFtyd*3wzdrPh&9$UC=tB^Q#&QeMv}Mstc5r4fB0Co7h8Y&d%9h1a>I7`Yw|*3rx|*Uc6HT!pz+rtwO7U0;r1#9X;Uu)ub5u&7O(qym?3t+> zRe=i{(Y29@+u<74Ig7Ok7{&*bJEbV4ZG(d%3J)G}WS-&$hLYxoyBGKyVVvMy+_vRq zis)jR4Sp)N7HsI+F^(ulpTcHz&mSS}L`U`(@@)CRmpggdPvg^!?STy`Qh!~*Vu!L5 z=;r6Pn2{E?up!|~%;2Wzfdn0xw=!5^-2z@CY$zLo4a8x3G%NW>LfID-64%<2s6qqi z?3RrQoa_Xqop>#&(od^-z0G%)_tth0sEpFWxr?-z%}nBsPgD;nZlr42CO`iNZxzN>qg<<}D?)I}qAx1;G@%Nv$h% z2T)S%30=hO9ce!S-9y0)8t^U(-8&oSGDftj12;V4tvSlz7hs)6!0v2cXH#t#4PaR=6A1XYIIl#mCgY}PKHE`O5q;U$^yvb z3yBFhwSCCb+~Bm)9|bEv@P!q-l0dJBgCwzSSgX7iP5ERDf%? zqwVZ3K+CQMFrzomCT%Mp-o00lmHgQpC9 z7Y<(10QVuk3r%GHy{w(Mbw!FD*`~+8B8_?&ob3@Bg+e5Y972(R^J*cV+pb{+>)(t< zilC6ayem^0!@YA}Dx37nIbk0kmix4B=hQf=<#01$_#&r~4J`428HpNirVD$GNn^y` z=19r$b}`as-~7o*#aapng7XmZiU#RQI&g~NWaIE5^o4{T-ZdmC+DB;H z9M!omaC>9koXtt%pjw9&bR8JzwjWN=vU}#Web-K(06XFXXQPA^qttt9XaFZxf?_?D zkfb`~(H*RDI~^-T3W;fqu$QBRT86DZ0@_*RuaeRe{5^fUC1qA z=QJ1B3#3S^l#7#FgN5u~VeoBLa`S|igWICdW>O24vw_UJVt`Wy$4$Y2itFI!RT4U^ z4a_kmrP!n5_pihnP25ua5v85;?;1#41_OIex$r28@9{9-dv^`+a9#}!dxw{$HECh* zmj@5IxjD1FIvR84P`@VwZQ}0`36b=0-a&t{vPvG)STjD5r+40M`*9UzN91i9zhqu+4c8DP&uY!6ft}n!!>ez+Tw<2FAZogNTne0zb7N%PVb0*ypiu| z01rihEYu~`IjbHf=`DVwnang0OVKU{e-4^@5hnv{Vao=%VY~y5@FYVBh=7CxD=Y)C zoUcR`*faYJov6HUam=U&k|OuJka`-DW5;#0AQm3j3EHe6{-70j868RkF0NomwPP5t z4^nma!C%xQs1k!mmeGJe2!@v+FCFleL-E!LK^>7FN<@0Z;XN6sdJ`A<@Gn$@m~_HG z;cwF%8o+iSLjzLHp$ztaaVA0U0>hr z<3}@^9gnLO+}Ty2&;T9Xt1=vPzk-I>f05zuvE#q1J^DmUlb%tm$m;zxAVK4*6I!i9 zhYKtuDkbd=^kH~c!M);agq+AmzBu(oW zT}CPOT}a-wie8n6W@Md;7ijYo{J}tq>dRqX@TA-VH`(XG^f;=f&P$SV63|A0!`#$S8MB0b zEFWk>2lR(imyiE4vP+=#m|qzCon;`b?Nt@Vv-GO<;x)DAynG zV?qj8YuDSCL9XSg{>Wv{t@X+|v$D{1OC;jAlLYDMn#+sGNqD2dJ%pDw@>=F-m8tgi#e1WJGjLwaT0feqLVdG{FSkD=uCz+uPdw@WtmPT(XY@sY&msp44o}Em#eYq9Sm5?z}RTp|4EeFh3Lc+4^1hQKKs{32^;vc>MJ@mjpx*fm&P?40bx*%e**eTQ(w5Zz9 zl+!~!n*M#0%A0?Nxc*A#VQ|CsgMzacAMWyG=e)Zh?%2j3?+n4%)kV_e@__MHf72?^}OM!H|$AMBe@M=-(Lu+XnJ7HsHiUc4XiFNwh}+oDWpr zzqErNSclMWrB$6GHEvRt7T${yjD)SuaI{tw`rh3vd-uFON6bAZ9ORe zO#|qcv8N^wc)pP!B-`@5?1;_w4RAEz__h-Vs7gSHqjq{@uOo#zTJ2UNrNAbV`sKV& z4XY;t_tXmSww#*v77~{LeqxxY5TrJmCF}5`FOySHOO_6Wyf~-?MitM+xM9*xeW4)8 zwHvI2woZO;n>_KyRK>itUY|u69r`vH;8HTzLr}Pg(mbC|_&l?vsCu7~T)1(1UvG%i zg14H1r*A1}BEh;6iYFL{AG$leZ3~Wv1O>SeJK+#_h@=C(*UVD-c?XN^KOqJ%j6QW= z9I>SeRaA}CvgU3OmOmr;f!aQ$EEx(pfQVM_F^&UJqf$|RLEAl{Q<_W;Zxvusx-Y?qL; z3ULR<+lfzb^*+evgU%Q&{qj|$=oXS?4I%g&9)oH832}1qv|?{3^$9HR8s}mhDI*5$ zwO9-D>g1@YZYmU5&D8gbq#gx5FgJ>hv}~{wH#1rh35sxhO%r*BXfTR#ZzRK0f|L?; zq`@T@SJJbdHG<7XX@E@Mn=&wz%-&NV=(t>p}SuKm8U=QVh3`g*#-)$@p z2qSzgf;oe4hzltq2*^YBt)0NHXqV28&VwR^=kOuadj)v6ID#zImw?;v1f_R+L)%$k zX@Rv&V2Fi|Fc=_|bi1A5xdSS;*V^9Z-mRv=S}q^^f|ugO5q{zRbn6TCPQ_%o-n^EL zInpBKmX11k7$;^-5J*TxbCw}ueo)1{F=CMl3lwv5{>M6eHL`miP8uHgMOwpA#X3Ph z5)l`6gJRJ?fL^TNIKta6 z7JG<1*^<1aB<@piY#gme+Jws5Hl$2~pRf;B3CtkgpF#ARg!Dwpkw3+GeBDngR#IC;2BtWN&904dA|YgS<4bk71mnjyq|BEyNAJ9($$r4T8e$ zJ*B9HMk`E1NKXrhfag@LiNJ8f@nHz4T$})LZduTVU=vF*APkFoJF!ixD$%W|+ixZY zX-0U`XKb9fLuMcpcGG~*r33SFUMg)*t$T7aXbc8KLmxKE91%RzqYN=&GieI&GUD`*q?+y{GfA_{SV2Dm6#_NgNn ziDZ@xijPZ;6F5ll>vdGdkp`cmVz0i={MGGrj0}qj!nqJK1kg?(cK%Ew*}8HO#*02r z!lBG;Mzo~LK=`%sz*w0w=<9J4`+Qjb#9n@BWZpp$2rs!3WH;56%+hl44k%|-RzT1GSX5994Ea^~dMTJ)MuVAHDvkT-#sG<}E zsk5(83}sBrn!XqGxKTUYbQCRtFHDM5JSY!*0!yeH!e@w6$7V8mF$^defl*LgTO0uf z-53MeuccUx`L(l$TjU__&QB3s`IkI69!@9=q zhDT%|S$=5gxl}o#kWNp!UcOvw)p_{bYXBF?KjqiB$&FmK04;Im-gj5CHGI2RCVm6v zbh=Ey9mwHmz*k-Jz(EpKng)z3YycSA)ZgT+UuH?cX%X<4>Z{wo%)Ht|%Z|3aLbaaC2WM>DzQghx~xJsj9kGAj5fWKuf@usk_UUG+O>Z6>=cMOUg=D0k|7Nw zh+HTT_8LSbn3L999iJ%k-EHM4uJbKxn~idP2i@N#)4EAVtep2$YjA7@nBz40AtX}7 z!9?8@@&SkCg5wi47oCKDmZWrtHQm#=o=FTY41K2E^z7!iyMsTg5&;Z<<~5ZUUrM&Q zRzDWFVT>dVrELst#vglCH_^`H@d8Zg4ZBvhfiGryiE^Lr(r7M!ZopoqfyVOX=a;-0 z%Q^~lC?v#gP|kB@AbJ;g^av65Vp8~5*-N<5H6apMKklGm`*XHuE#TDTy3Uccn$gy5 zA0-w??J<47vX@jVdV2EUY~^rJZGnmn>+T3K&@@T`55whWc~$?zWhkLHNpgV6xx z2}n)wLErQ?GY}-id8ivH3=$<5{1D3#D>(GC&&*fIN^`edb5_yQ0pqA5p40(lYCI zq{6O-Wvb5fx(Xt}KBEVdAY|dW|v{vCe9`zI^!QBEY+>O$QGR5bPw${2?b zRGIU@9}MG=DGw=Hq@8saa`=UMQpE4PokU5{j99IAWgIH@JP{MUh)wC$;UY^-$ErF& ziuk%c66I3noAY`J> z(F9$xOutzo)Oqpn;+V>YO|J-oA{AzkuA&`oF%cvhdOK3yQ%Cld+79!Sqmw!8r6L7J z61_;0!PTbquDar=he*@0zZc^6vMLg^gw=`{&A7m1UnQK5__&s^djbDITy=4ZUBg&e z%6T;}-|~be8=pg2hZ)A&)%R7y@sC zF?SFT-)gL7v$r20IQkh(1%-@+9;f1^xEj7jX6kb-n~n8~vsZog=>#ZmCAx9W@FB zaGxcv`r}K&@P>k<~33l;tQ5c-t|- zeMmcT2vDL(s2Bd$0e{f|hTm|i$MZk^anir22@B$w#mHEwk9iBKM%lMAA|;T zU9)98KgV27)f-`YM;3hcefp|~Urw19mX4&lZY(vFRo)tfGK;4Hu5YW+C&=^zP)%b! zh`F4scM){KZ}NLhA=$Ogs(gJlrK93gC>W_V$wCyKaYp8 znQfns#0}A^P_56`CpciSU>mgXWjYtz2C#tm(pPS*}T-bbk?GZ{O8JSQ-Hra{U z$RTj(cj7rnLa90mcBs3np}9&G5GP=ot1_M15kav$yH5RRf2m^sLSeFfMiS=cXtAe# zM{^}UWQDUKpjAP*_QC#Nb1@7wNSi=M)m_Saj_uQ7>Mt+Kf#VLtTd0H9+ zzmSZPZ@E1eI8+zd)*??HWR#KNi9u$c3olM8%2N-cP|K~I(K?6cQD%J$yq3MqoupUC z{J2-0WXS1tWQUD2rV8K5oE^UrerhBiSru+(9~w~49|jfQsoW^jC8&y4x9h9ijXl)> zmih*f25>F*cI1$Lza$#K1@(U==T+QOVCj{$G0U6nuBX_H2c|4LvAX&i$(d-b-|@NU z=?t$H2}z@hugpZG7s688VH|2|!BcniT&q2stt||EIQ+|kv%MmY+1r;CIfT1~*dAl$ zZDX9%6++-$Ko)9(-yx`QW>`uCemX+V`-;K7*(-ZSqh5&72NO)q#K^+al#8H$8$W%BJ z+Rv4Uyr-i%g=U8eKQK>=$ORg}ht*zn5_&Uo3oCC@grY(fz8RaoUqlQaYQL8%N?Lc~ z9YwPU#bHI3TWb^15d^p>8Uf54)S_YJ0fJK0Zv;E2)aArWmac@Pxl%WD<7+Wq`7i<; zhY`gl?OUTc!IYAS<^dusy>XZy?4L1S2$QDCk2dOqePZ!t!8lFHc8` zk2NLzXo3Nt0WQxYS<8-qWcxC^A}-Q7S+zLvt(h!V#dltpoB9^XOqHf6lRcuf9Hn|O zY>G{o&t}%3Tk&eaDKMHeO9-ckg4OB?Sdnf*0~y{G=GQm+Yz@wiwjay2Zt&Rm@@csVdZACz(#Lkc_-ca?gF~T|iIv+c0z`q$t>2nnc`G5WPG} zJ+cO`SK7uTiC!ElZ6XEOdN#uamL|}0m2==vyy}qkrqvW&ufD@ikfKkPNz+AK(Gi%L z@xjz#x|I?zyzK@Mm+FC-Zk!p(bcvvoQ%lh!{Ya_oBMTWdkrI;H{RAtkywse|jIICJ zpg4HE)Y`U}&I&IPmekNm-n;#1DkmF&J7IcoB-jDhJP&lNhXxRdhsN^#zZV`1R6%$Y zW;vLYLFLaw&;Y4FLx|X6U5MYBDClHtCU6>%xeSF=T*4xJPpn-MT9W=p59&W%*f(?# zv6FEgCE2f*U2uxjF*!LMht~7+_4TV=vAll$x>=c%0SC99*tntm*xSJ)clxV-tiLF# zqmM%T?O?Zms-JcK&EPj8C4dGTbx_(rq9cx3#o+UR_5ZU$azv^Gls2P@8T)(`6B_W$ zVFviy;c>tGl3?K?phV+-xX;Tv;@nXj)3-0pYGa7)+f8xVtD*`QY^|Qszw!5_p3BYfY zcMjNf{@mFGTZpVPN5NW9`_#C?Ke*>th55yx%QD*@K?5!fL#Wp>h1iWQV%V71fiTYl z!aRpHIHhZZZhI4s8EJq3Phl&A>g);pn=a)p_H;YB!AtPQ5)Lbri~x<=+1`^-xNENi z{ITk!U-rGDoiV;yE_o|1@q{~)+Kn)U55YTkFJ{+A1tI_ASn(gKK{cQTg(5*N1i#7N z?L99*X8SVaN943#C5Q%;IkA?<%$PCG4BSz<^8>Y*x%yekzpknGWdB9rZ$~x#&kBXV z8y~Pl(Z{#J_#EtJkwecNQaCShULA`#vlpT9Lv#>Tb2RyO3+8X(8bfi$Mw+5#mX%GE~&F~86Jp{(rM;WXgkU!0YG zm>Q21$KX9`F+YQ#tRH0urSn0Ev&wI6QceGGR(8am@E^$=SI_~C?wY1VPi-l8aak6y2jUdwM4@A5Ucc^ zHEC0CeBs+WMRSb_kGIc`&%3LKr-;pZ@maBz-?H}$yH!}YN%@{?CipZo_krYPd6PKg1%XDS%v+BePO2TjQ_)4_RC6a-mrjG_#WN$#v zojXSZjx9=MCA)GOWbNwL95Q8-?9E;9ZGlCkSL&ML5(nC3@wRi>p>o+;19=~1OT)Z^ zBr*m{e_gp8=fP2=s1b3bHgFafA7<(*#h$y$V7@e{QhxgL#dE(CbUfJxD*0PUH|*HN ziuBBV;{}zKO_-zc^}M~b3_9l z`2*f(|LA@dEsuE4n(5|<#Ku!GT;6aKd%%*>c`q zLW)1fP-PM?&yn_ItkZXM3jO!X*SfOF!rNEyZWWrIM&Q)Vvjv7(U0>~0%T}~Q1k!~K zn@;HJH@uN*{4f+M-IV>soV72P|FQ54GU*y4N`SAw=0jqe;WTrYv-5+nlCM0|ONLQJ zZ%z1WF8fy;%g3$)%*}@9F``KEhdrSmvxTGzc?3T5cn^Jc;2Ymlsk3-Kym@$tQO5lu zosOJ;Wtntcv*f($cQxJn+cbu^e#~FuI(c@xBOf5k9IlQeoO`49ed=e%aokWA%bi=^ zaTcu#_lG@$PQ=&SN62i;zOexkO!pnSd`%@%(r$;17_U7F|E@{*@ah@qO+!LQ!ujIE z0xhJZrW5ycarmKw-uv?s=wq6CU99@l+yM&!4d%($1zt&rIYq^Rhq+_pqp zOSkjdZv&>-YQt;u*2}f4ZGb8l{DW4o;V(M%)cGu-$PV*(3=~uUc;xH9z5sE>zpN}7 zdii03$e$M={uOnBo^HNw&?8^a=U-1buG`Jso>k+=!e51O2X5LoOMT{A<)@l7OZ$$# zo(p^Tsj)Afm-B(CH$T%hBLj1wo*y$u+vmR9Y`26Mwl(w;YQhu6uGU|i`8`(1zZ~DM zd(;9BLlgvnyq@RU1G}uk_vv9Lps2(dLHAsE_lT=?3k}>X>yP0us3hFO}m-p z(vi`0c21MeeTNaeHF`Wkq+(*&>TvZBWNk@DJFkG|s`u8VRi)Y-o5ux{*Pg6U8a*d= z7!d1%+X7L^zF%IQ<4ACEF{2x~Nv}Qh`mx%REo`Bys`<8Oowg^Jh$=(vXTMu_elY*^ zSQLaoy&blk(iQ|XZCL69H& z+tg7#xppzI)LmQMspP0=@_MGp2is%8-|SPx>jN19*0Rg@dwE_m6%@0UkpY=sN~}gt zCC_9W{Us>ta^!tStNKq75|WDED!Y)peQNB5@eSQLKLNuFT!m#fB{Y64IZsX=g=K%F z9*da^R84L~$-OO7wtklAd{v{Db4 zQz?GsBb*;S=y#4~Q;MbI!kDHSRrJgxdJk6^i`bBN^_w}TVDG#p4U!S5%~D#|Bhly; zdo_i|cnis+f=kX9x@zq22B!6G#lbWf0;qF+Os7L$(6BJ_Q|FYm+gCAJK~@=}$)2o= zx3tF3P0@BHf4RflzPllmmLFT4=E+C`i;NoQu<>?g*E3#!-cFK|6vrI)dAI+22(0UM z*(7GLJFAr?voniq=a}abx(PnTwB}P?O}|Jc7Sd0uS*0V;r}W2P*kk3u3KwW8%&nuNl# zR6F{zr%~+=xog;|H%l!}Yq35Lxl*WcVKRu((*9`|WhP50@LJg1(0(d=O3Z0QDb9}R z#1=*f2iRTgoL}#Y7SvCU!5#OQf98?SI~>QfnHE94cd)W&#pk;4*~>=f9lBnl^6>&` zh<8efFWmlF0RJb4uo3dgyyK`61F1+gCrPjZJX7akk2OI})V$CfGfiz!G?3w@-68>N zULr2Q(#}Gken?_aYp|}`@&?seF=#9NdxRU@1Jv2&n!W{e5v}9xZ-=nyCO?$dC2F`H zpW9|%cgoXOa=vM{l`x5AJ1fSLD{7zM2vQZ93?~VH#FqQOpM&o+6&1iKl%d#}^>#?u98Uh5opaA}^3<=>@~J(pS6?pMv-=E1Ja)Xr;^(v^sa|0d?D(S)1m` z&gG;|kg#NTPCNi1n@C5H|2Gv*BiaprT0KaXZ^r|X7b59pN2D&?tn{Dd$j!MO7tMTU zDoC3vr?3E$+t>Zic4-8d18U8-SS2HUs-ddY=$E&9s#NP}m>KPejPeqT2`!OciBTO&375|u2j^OQbS2(o zq9D7GvUh~<$LbL#8_c?8)$JVB+b){8bnq%6NV@HNK$~9mzFy*IN`71s?J%h`!#+|& z?e|-K#D}-54eya`_!X!J`+d!wQ?D3}WM;$^zckltG2mJlU{S7E>%I5<)~ClTd#cMW zN`c^cg0jp;QL9=*5|MegF<)1;^^A?prUa%F#(&P>P1N`rLSHfCOG}peUOt_{i|r% zH8{^!=v2w|)=(cox&w&e!-ICe0m`YJ+b5yot_H0pO%~r3wMRVQyjo57cTW1M@?ChMm0G51b z@N~p;DZNu8>4pv1S$Nj>sd=plmwKs?G`(9H5=Z-)KDT|m@_|aSJn2sjglVAJamvpX zyo+PiLIwA>#4JL*WWc_PtW`iDRG5a=;NWA&=GSaH-&wg`52y?cH_hEYdL4m-lrIwU zvkiLjpET9wIdgPBz8v4vZ7k(ZD5a+8;G%p51-UYtBnU!tGMvdUzr?lO;%u4JTG2aA z0r4dCuZh1Ds)~bzuO7cOn5#;5NqZgN@0dcM%ETBeXulxqRqJG{Vn803O6D{h)tdC| zi0tfsm7lgiD$R-(eB*u{S{1E$fU%+x&^j1!EBzx40Me|~n4jE9bpNhBdl8Xt|>6sXPus@hC+O#Eo(OC15Ej5SqjGNU4%bMUhjVARkTdRme zGfhVaMndZA+?phP)i#B{81Ut8)J}KGi)Pp+G{;-2BrtIM=PRbg$<%3l<*b;QwtXPa z8U&`-Ji!lbc=QvLZCl6>9-Y7+8Yn%Pw1uVNZ1hy$QUC?UDo-6*K%y_I2d5L_cNu2FPj z%Y4rE`X7`Byrfv@1jST|?pt-~=Ut&5fE6t~$|Uzk#2KNFf@Xub1))hQ6DMH(5@X&N z8NOSTX|KabUkIRoaMX4m$}~DxFDR62u2BbnRHxy=08tWZFw;h(@w(;WiXW<-tO-~U zi&o_4(c{Z36f#IJ@%ULwr;R&r8!=fC@Xj(e6-b9JtyB=~1;5@mZ;}|Ng-NdP9vdXe zk&#el3ixNH;XHq&(6#0r=gxoB&CMeROT0#qAzd=9Q>iU;ESs8{`%-71@3}4r1C|lX zQdXg)9mK8ZZUxQq-XBsWsVFVCK%Xb0AVeG_g!mHASMNN;dg=Hg$(rypdw}!0Z8kej zcVc1T;ehrEVKl%XGmb@X>%uP;)a6Q>bN=C0km(0ch1i0 z#oq2>UAWWRU=u1TlRcIK-Ryg~Aifi^#KM-j@WkJzACI$@T+;y@ z#ljJ9LASyh&9F=-*Nj}Q*a{3u=Pjq2BwvWyYBedV38`?GH7?LlXouU3?nwAJKcFuEsFn&cLD%)#9$l?$+l)=lh+<@l&G&9$|y!qZKgxLA74b5l2S0= z2&ucax|MQf+wCUm5eDGDl-JO7k->~K6yS?-)LP%vr%4!2G4&l$Sr;_FgG|y0XzPzvE+yQCBB$ucM>jd`^()4ux53^yn-MO&p zitQ~as^G&@Wz(lM>uu_?+Wio`W)t&oyUT8UO4uDsdeM+~A~;^64Mx4Pdd*_37gkZ zer%hrBCzBLA>FW{)`IsWk^_i4l2SYGE%L@KUJgF0GQ6K}BgE+WrI$`$KL2uYkw*k) z(hO2bB$_f;J%6{IVZq8@lBseNM}(ega3p18V&dD}PWoWBu}6p{nr0Np4H3;n?H|b- z1oT{qYfkLxFh!hXX|pXj-JHZ;H}?)3$rSypyrM==|0I zvk|zy$LOJsDP5VhB&8^{_np6}Q6wysdowotrc=|_GZiqA*;t@*?ZZg-ZG?Zab{Q^K zL{2(QnKwXuDWEjG=7VWAk%wbn^^5w&7)z_uT;j7sOt;H$S>2Cuw;cM*P2fovhRSr; z*g0}?dMdbGBgBA3YnDc=~f=Ah_nX;&x^CJXk zeYTUH?bV2n_h0k%Cw9s422q&J(fLMYEEx^#^Pr6m zy^Dr3O|%3m&4o#Y2sA)NA~#ppbPFnPO$VR#P1d?rFS-d&Mlm2hIHvj)uyR^Z58R}W z6lmTz>yb>;z*i`Ag}IUk>Xs*~yN|^8K(`w<#g^3afLnt$F^|FLcAzG(DhyXmSi)z z)9PY{1ZRXGQ5&R4>hFJv9yT7{c7HZjkj(7=!+w#;Lu`W9y*5FLup`wOmOUA-(4Oq1 zLb9AUujN=NqcZK9-cmssK1IA0n@76=ruSs4y>{<&1kkQ!Br7P}AuHpap}~41__ji~ zP&Ak%h&gRhfxpu+OZ(hsnO1`XR*)cg*G14Vfq|)@lvC5GcC`4K8#c{gd_GGleWv;vN^uZICo~(5Y&l?f2S_};dI7N+I(>ByGX1P>lLZE&VEyIc{ z7sHA0DH!+i0bs4?Ok#)|(}80X`AYUXuSnN{+txexX@}`w7UHGn$1Lor9DDiu%o!Yp zy9RWi*>O9BIpr9xyK<%)-ld#q0N}SYpN3u@KRDI=-aNWpo!>by^Nj%g%sWK6awh zdt5Bt*w8j~FPx9{Gp9_Pr^x90-?l>&!A$2HAfQ^7EYjT>oaS5gm{_^&QM zD6yz6sNBXY7a?Tr_#2m7f8K^rT~NVrS1wdYPTX%?el$@3a`|`6)|Cqp{l7xDP!9$5 zamkfQjMk4sxq5hlDn;%2UP;k)e@Ia~z^DeOmG_mwd!xVhjarAJI{Y&)xzeMd&ENm! pFZh|IpvwO_eEcd8wE9K<_h6! { + alias_array.forEach(e => { alias_map[e] = key; }); } @@ -41,7 +41,7 @@ parsed_cmds = parseCommandLine(process.argv); // console.log("%j", parsed_cmds); -parsed_cmds.forEach(function(e) { +parsed_cmds.forEach(function (e) { exec(e); }); @@ -53,21 +53,21 @@ parsed_cmds.forEach(function(e) { function exportJson(args) { if (typeof args === 'undefined' || args.length === 0) { - glob(config.xlsx.src, function(err, files) { + glob(config.xlsx.src, function (err, files) { if (err) { console.error("exportJson error:", err); throw err; } - files.forEach(function(element, index, array) { - xlsx.toJson(path.join(__dirname, element), path.join(__dirname, config.xlsx.dest),config); + files.forEach(function (element, index, array) { + xlsx.toJson(path.join(__dirname, element), path.join(__dirname, config.xlsx.dest), config); }); }); } else { if (args instanceof Array) { - args.forEach(function(element, index, array) { - xlsx.toJson(path.join(__dirname, element), path.join(__dirname, config.xlsx.dest),config); + args.forEach(function (element, index, array) { + xlsx.toJson(path.join(__dirname, element), path.join(__dirname, config.xlsx.dest), config); }); } } @@ -120,7 +120,7 @@ function parseCommandLine(args) { let pos = 0; let cmd; - cli.forEach(function(element, index, array) { + cli.forEach(function (element, index, array) { //replace alias name with real name. if (element.indexOf('--') === -1 && element.indexOf('-') === 0) { @@ -170,4 +170,4 @@ function defaultCommand() { } } -/*************************************************************************/ +/*************************************************************************/ \ No newline at end of file diff --git a/lib/xlsx-to-json.js b/lib/xlsx-to-json.js index befb007..3aceee0 100755 --- a/lib/xlsx-to-json.js +++ b/lib/xlsx-to-json.js @@ -1,9 +1,25 @@ const xlsx = require('node-xlsx'); const fs = require('fs'); const path = require('path'); -// const moment = require('moment'); -let arraySeparator; +let _config; + +// class StringBuffer { +// constructor(str) { +// this._str_ = []; +// if (str) { +// this.append(str); +// } +// } + +// toString() { +// return this._str_.join(""); +// } + +// append(str) { +// this._str_.push(str); +// } +// } /** * sheet(table) 的类型 @@ -45,48 +61,13 @@ const DataType = { UNKOWN: 'unkown' }; -module.exports = { - - /** - * convert xlsx file to json and save it to file system. - * @param {String} src path of .xlsx files. - * @param {String} dest directory for exported json files. - * @param {Number} headIndex index of head line. - * @param {String} separator array separator. - * - * excel structure - * workbook > worksheet > table(row column) - */ - toJson: function (src, dest, config) { - - let headIndex = config.xlsx.head - 1; - arraySeparator = config.xlsx.arraySeparator; - let uglifyJson = config.json.uglify; - - if (!fs.existsSync(dest)) { - fs.mkdirSync(dest); - } - - console.log("parsing excel:", src); - - let workbook = xlsx.parse(src); - - let idx0 = src.lastIndexOf("/") - let idx1 = src.lastIndexOf("."); - let excelName = src.substring(idx0 + 1, idx1); - - parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName); - } -}; - /** * convert worksheet in workbook and save to file for each. * @param {[Object]} workbook json object of excel's workbook. * @param {[String]} dest directory for exported json files. * @param {[Number]} headIndex index of head line. */ -function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { - +function parseWorkbook(workbook, dest, headIndex, excelName) { let dtsstring = ""; @@ -97,7 +78,7 @@ function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { let parsedSheet = parseSheet(sheet, headIndex); let dest_file = path.resolve(dest, sheet.name + ".json"); - let resultJson = JSON.stringify(parsedSheet.result, null, uglifyJson ? 0 : 2); //, null, 2 + let resultJson = JSON.stringify(parsedSheet.result, null, _config.json.uglify ? 0 : 2); //, null, 2 fs.writeFile(dest_file, resultJson, err => { if (err) { console.error("error:", err); @@ -106,19 +87,22 @@ function parseWorkbook(workbook, dest, headIndex, uglifyJson, excelName) { console.log('exported json successfully --> ', path.basename(dest_file)); }); - dtsstring += formatDTS(sheet.name, parsedSheet.head); + if (_config.ts) { + dtsstring += formatDTS(sheet.name, parsedSheet.head); + } } }); - console.log("d.ts file", dest, excelName); - let dest_file_dts = path.resolve(dest, excelName + ".d.ts"); - fs.writeFile(dest_file_dts, dtsstring, err => { - if (err) { - console.error("error:", err); - throw err; - } - console.log('exported t.ds successfully --> ', path.basename(dest_file_dts)); - }); + if (_config.ts) { + let dest_file_dts = path.resolve(dest, excelName + ".d.ts"); + fs.writeFile(dest_file_dts, dtsstring, err => { + if (err) { + console.error("error:", err); + throw err; + } + console.log('exported t.ds successfully --> ', path.basename(dest_file_dts)); + }); + } } /** @@ -154,7 +138,7 @@ function formatDTS(name, head) { } case DataType.ARRAY: { - typesDes = "any[]" + typesDes = "any[]"; break; } case DataType.OBJECT: @@ -164,7 +148,7 @@ function formatDTS(name, head) { } case DataType.OBJECT_ARRAY: { - typesDes = "any[]" + typesDes = "any[]"; break; } case DataType.UNKOWN: @@ -192,13 +176,13 @@ function formatDTS(name, head) { */ function parseSheet(sheet, headIndex) { - console.log('\t parsing sheet', sheet.name); + console.log(' * sheet:', sheet.name); if (sheet && sheet.data) { let head = parseHead(sheet, headIndex); - console.log('\t parsing head', JSON.stringify(head)); + // console.log('\t parsing head', JSON.stringify(head)); let result; @@ -213,7 +197,7 @@ function parseSheet(sheet, headIndex) { let row = sheet.data[i_row]; let parsedRow = parseRow(row, i_row, head); - if (head.sheetType === SheetType.NORMAL) { ////json以数组的格式输出 + if (head.sheetType === SheetType.NORMAL) { // json以数组的格式输出 result.push(parsedRow); } else if (head.sheetType === SheetType.PRIMARY) { //json以map的格式输出 let id = parsedRow[head.getIdKey()]; @@ -282,7 +266,7 @@ function parseRow(row, rowIndex, head) { let result = {}; let id; - console.log('parsing row', row); + // console.log('parsing row', row); for (let index = 0; index < row.length; index++) { let cell = row[index]; @@ -310,9 +294,7 @@ function parseRow(row, rowIndex, head) { } else if (isBoolean(cell)) { result[name] = toBoolean(cell); } else { - if (cell) { - result[name] = cell; - } + result[name] = cell; } break; case DataType.DATE: @@ -320,9 +302,7 @@ function parseRow(row, rowIndex, head) { //xlsx's bug!!! result[name] = numdate(cell); } else { - if (cell) { - result[name] = cell.toString(); - } + result[name] = cell.toString(); } break; case DataType.STRING: @@ -345,7 +325,7 @@ function parseRow(row, rowIndex, head) { } break; case DataType.ARRAY: //[number] [boolean] [string] todo:support [date] type - result[name] = parseBasicArrayField(cell, arraySeparator); + result[name] = parseBasicArrayField(cell, ','); break; case DataType.OBJECT_ARRAY: result[name] = parseObjectArrayField(cell); @@ -353,10 +333,8 @@ function parseRow(row, rowIndex, head) { default: // foo#[]| 处理自定义数组分隔符 if (type.indexOf(DataType.ARRAY) !== -1) { - // if (!type.endsWith(DataType.ARRAY)) { let separator = type.substr(-1, 1); //get the last character result[name] = parseBasicArrayField(cell, separator); - // } } else { console.log('unrecognized type', '[' + rowIndex + ',' + index + ']', cell, typeof (cell)); } @@ -365,7 +343,6 @@ function parseRow(row, rowIndex, head) { } return result; - } /** @@ -383,12 +360,6 @@ function parseObjectArrayField(value) { } } - // if (typeof(value) === 'string' && value.indexOf(',') !== -1) { - // obj_array = value.split(','); - // } else { - // obj_array.push(value.toString()); - // }; - let result = []; obj_array.forEach(function (e) { @@ -540,4 +511,37 @@ function numdate(v) { out.setTime(v * 24 * 60 * 60 * 1000 + dnthresh); return out; } -//fuck over \ No newline at end of file +//fuck over + + +module.exports = { + + /** + * convert xlsx file to json and save it to file system. + * @param {String} src path of .xlsx files. + * @param {String} dest directory for exported json files. + * @param {Number} headIndex index of head line. + * @param {String} separator array separator. + * + * excel structure + * workbook > worksheet > table(row column) + */ + toJson: function (src, dest, config) { + + _config = config; + + let headIndex = config.xlsx.head - 1; + + if (!fs.existsSync(dest)) { + fs.mkdirSync(dest); + } + + let parsed_src = path.parse(src); + + let workbook = xlsx.parse(src); + + console.log("parsing excel:", parsed_src.base); + + parseWorkbook(workbook, dest, headIndex, path.join(dest, parsed_src.name)); + } +}; \ No newline at end of file