From e3742a8db38902b93b3f2d4b98ca45e44e7faa5f Mon Sep 17 00:00:00 2001 From: cwchen <1048842385@qq.com> Date: Sat, 28 Sep 2024 15:29:52 +0800 Subject: [PATCH] =?UTF-8?q?web=E6=A3=80=E6=B5=8B=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aqgqj/basis/dao/TestReportManageDao.java | 18 + .../impl/TestReportManageServiceImpl.java | 640 +++++++++--------- .../bonus/aqgqj/utils/CreateSheetUtil.java | 212 ++++++ .../mappers/basis/TestReportManageMapper.xml | 39 ++ src/main/resources/temple/model_excel.xlsx | Bin 0 -> 23447 bytes 5 files changed, 607 insertions(+), 302 deletions(-) create mode 100644 src/main/java/com/bonus/aqgqj/utils/CreateSheetUtil.java create mode 100644 src/main/resources/temple/model_excel.xlsx diff --git a/src/main/java/com/bonus/aqgqj/basis/dao/TestReportManageDao.java b/src/main/java/com/bonus/aqgqj/basis/dao/TestReportManageDao.java index bb138cb..486d92b 100644 --- a/src/main/java/com/bonus/aqgqj/basis/dao/TestReportManageDao.java +++ b/src/main/java/com/bonus/aqgqj/basis/dao/TestReportManageDao.java @@ -123,4 +123,22 @@ public interface TestReportManageDao { * @return */ TestReportManageDto downloadCertificateList(TestReportManageDto data); + + /** + * 获取基本信息 + * @param id + * @return Map + * @author cwchen + * @date 2024/9/28 14:40 + */ + Map getBasicInfoMap(Long id); + + /** + * 获取签名图片 + * @param id + * @return List + * @author cwchen + * @date 2024/9/28 15:09 + */ + List getSignImgs(Long id); } diff --git a/src/main/java/com/bonus/aqgqj/basis/service/impl/TestReportManageServiceImpl.java b/src/main/java/com/bonus/aqgqj/basis/service/impl/TestReportManageServiceImpl.java index 5be7d49..dd69fc2 100644 --- a/src/main/java/com/bonus/aqgqj/basis/service/impl/TestReportManageServiceImpl.java +++ b/src/main/java/com/bonus/aqgqj/basis/service/impl/TestReportManageServiceImpl.java @@ -24,16 +24,12 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.ZipOutputStream; -import java.io.ByteArrayOutputStream; import java.util.zip.ZipEntry; /** @@ -48,6 +44,9 @@ public class TestReportManageServiceImpl implements TestReportManageService { @Resource private TestReportManageDao testReportManageDao; + @Resource(name = "CreateSheetUtil") + private CreateSheetUtil createSheetUtil; + /** * 查询列表 * @param bean @@ -238,324 +237,361 @@ public class TestReportManageServiceImpl implements TestReportManageService { * 生成检测报告 */ public void generateReport(TestReportManageDto bean,ZipOutputStream zos) throws IOException { - //先计算出总共有多少列和动态生成的有多少列 - //总列数 - int totalNum = 0; - //动态生成的列数 - int trendsNum = 0; - //获取所有检测项目 - List configItemsVos = bean.getConfigItemsVos(); - for (ConfigItemsVo configItemsVo : configItemsVos){ - List itemList = configItemsVo.getItemList(); - trendsNum += itemList.size(); - } - List basisVos = bean.getBasisVos(); - String yj=""; - for (int i = 0; i < basisVos.size(); i++){ - yj+=(i + 1)+"、"+basisVos.get(i).getBasisName() + "\n"; - } - totalNum = trendsNum + 6; - List devList=bean.getExperDevVos(); + try { + //先计算出总共有多少列和动态生成的有多少列 + //总列数 + int totalNum = 0; + //动态生成的列数 + int trendsNum = 0; + //获取所有检测项目 + List configItemsVos = bean.getConfigItemsVos(); + for (ConfigItemsVo configItemsVo : configItemsVos){ + List itemList = configItemsVo.getItemList(); + trendsNum += itemList.size(); + } + List basisVos = bean.getBasisVos(); + String yj=""; + for (int i = 0; i < basisVos.size(); i++){ + yj+=(i + 1)+"、"+basisVos.get(i).getBasisName() + "\n"; + } + totalNum = trendsNum + 6; + List devList=bean.getExperDevVos(); + XSSFWorkbook workbook = new XSSFWorkbook(); +// Sheet sheet = workbook.createSheet("检测报告"); + /*******处理检测报告start******/ + // 模板xlsx文件 + XSSFWorkbook wb = null; + InputStream inputSteam = createSheetUtil.getInputSteam(); + if(inputSteam!=null){ + wb = new XSSFWorkbook(inputSteam); + } + Sheet oneSheet = null,twoSheet = null,sheet = null,fourSheet = null; + if(wb!=null){ + sheet = wb.createSheet(); + wb.removeSheetAt(2); + wb.setSheetName(3, bean.getSampleTools()); + wb.cloneSheet(2); + wb.removeSheetAt(2); + wb.setSheetName(3, "封底"); + createSheetUtil.handleOneSheetData(wb.getSheetAt(0),bean); + createSheetUtil.handleTwoSheetData(wb,wb.getSheetAt(1),bean); + }else{ + oneSheet = workbook.createSheet(); + twoSheet = workbook.createSheet(); + sheet = workbook.createSheet(); + fourSheet = workbook.createSheet(); + workbook.setSheetName(0, "封页1"); + workbook.setSheetName(1, "封页2"); + workbook.setSheetName(2, bean.getSampleTools()); + workbook.setSheetName(3, "封底"); + } + /*******处理检测报告end******/ - XSSFWorkbook workbook = new XSSFWorkbook(); - Sheet sheet = workbook.createSheet("检测报告"); + // 创建样式 + XSSFCellStyle style = wb !=null?wb.createCellStyle():workbook.createCellStyle(); + style.setBorderTop(BorderStyle.THIN); + style.setBorderBottom(BorderStyle.THIN); + style.setBorderLeft(BorderStyle.THIN); + style.setBorderRight(BorderStyle.THIN); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + + // 设置每列的宽度为20个字符的宽度 + int widthInCharacters = 15; + int columnCount = totalNum; + + for (int i = 0; i < columnCount; i++) { + // 1/256字符的宽度单位 + sheet.setColumnWidth(i, widthInCharacters * 256); + } + + //第一行 + Row row1 = sheet.createRow(0); + //单元格-创建第一个头 + Cell cell11 = row1.createCell(0); + cell11.setCellValue(bean.getSampleTools()+"检测报告附页"); + //合并全部列 + addMergedRegion(0,0,0,totalNum-1,sheet); + // 应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(0, 0, 0, totalNum-1), style); + cell11.setCellStyle(style); - // 创建样式 - XSSFCellStyle style = workbook.createCellStyle(); - style.setBorderTop(BorderStyle.THIN); - style.setBorderBottom(BorderStyle.THIN); - style.setBorderLeft(BorderStyle.THIN); - style.setBorderRight(BorderStyle.THIN); - style.setAlignment(HorizontalAlignment.CENTER); - style.setVerticalAlignment(VerticalAlignment.CENTER); + //第二行 + Row row2 = sheet.createRow(1); + Cell cell21 = row2.createCell(0); + cell21.setCellValue("报告编号"); + cell21.setCellStyle(style); + //计算占用行数 + int num21=(totalNum-4)/2; + Cell cell22 = row2.createCell(1); + addMergedRegion(1,1,1,num21,sheet); + // 应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(1, 1, 1, num21), style); + cell22.setCellValue(bean.getReportCode()); + cell22.setCellStyle(style); - // 设置每列的宽度为20个字符的宽度 - int widthInCharacters = 15; - int columnCount = totalNum; + Cell cell23 = row2.createCell(num21+1); + cell23.setCellValue("收样日期"); + cell23.setCellStyle(style); - for (int i = 0; i < columnCount; i++) { - // 1/256字符的宽度单位 - sheet.setColumnWidth(i, widthInCharacters * 256); - } + Cell cell24 = row2.createCell(num21+2); + cell24.setCellValue(bean.getCollectSamplesTime()); + addMergedRegion(1,1,num21+2,totalNum-3,sheet); + // 应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(1,1,num21+2,totalNum-3), style); + cell24.setCellStyle(style); - //第一行 - Row row1 = sheet.createRow(0); - //单元格-创建第一个头 - Cell cell11 = row1.createCell(0); - cell11.setCellValue(bean.getSampleTools()+"检测报告附页"); - //合并全部列 - addMergedRegion(0,0,0,totalNum-1,sheet); - // 应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(0, 0, 0, totalNum-1), style); - cell11.setCellStyle(style); + Cell cell25 = row2.createCell(totalNum-2); + cell25.setCellValue("样品数量"); + cell25.setCellStyle(style); + + Cell cell26= row2.createCell(totalNum-1); + cell26.setCellValue(bean.getDevNum()); + cell26.setCellStyle(style); - //第二行 - Row row2 = sheet.createRow(1); - Cell cell21 = row2.createCell(0); - cell21.setCellValue("报告编号"); - cell21.setCellStyle(style); - //计算占用行数 - int num21=(totalNum-4)/2; - Cell cell22 = row2.createCell(1); - addMergedRegion(1,1,1,num21,sheet); - // 应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(1, 1, 1, num21), style); - cell22.setCellValue(bean.getReportCode()); - cell22.setCellStyle(style); + //第三行 + Row row3 = sheet.createRow(2); + Cell cell31 = row3.createCell(0); + cell31.setCellValue("检测设备"); + cell31.setCellStyle(style); - Cell cell23 = row2.createCell(num21+1); - cell23.setCellValue("收样日期"); - cell23.setCellStyle(style); - - Cell cell24 = row2.createCell(num21+2); - cell24.setCellValue(bean.getCollectSamplesTime()); - addMergedRegion(1,1,num21+2,totalNum-3,sheet); - // 应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(1,1,num21+2,totalNum-3), style); - cell24.setCellStyle(style); - - Cell cell25 = row2.createCell(totalNum-2); - cell25.setCellValue("样品数量"); - cell25.setCellStyle(style); - - Cell cell26= row2.createCell(totalNum-1); - cell26.setCellValue(bean.getDevNum()); - cell26.setCellStyle(style); + Cell cell32 = row3.createCell(1); + cell32.setCellValue(bean.getDevTypeName()); + cell32.setCellStyle(style); + addMergedRegion(2,2,1,totalNum-1,sheet); + // 应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(2,2,1,totalNum-1), style); - //第三行 - Row row3 = sheet.createRow(2); - Cell cell31 = row3.createCell(0); - cell31.setCellValue("检测设备"); - cell31.setCellStyle(style); + //第四行 + Row row4= sheet.createRow(3); - Cell cell32 = row3.createCell(1); - cell32.setCellValue(bean.getDevTypeName()); - cell32.setCellStyle(style); - addMergedRegion(2,2,1,totalNum-1,sheet); - // 应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(2,2,1,totalNum-1), style); + Cell cell41 = row4.createCell(0); + cell41.setCellValue("检测依据"); + cell41.setCellStyle(style); + Cell cell42 = row4.createCell(1); + cell42.setCellValue(yj); + cell42.setCellStyle(style); + addMergedRegion(3,3,1,totalNum-1,sheet); + // 应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(3,3,1,totalNum-1), style); + //第5行 //第六行 + Row row5= sheet.createRow(4); + Row row6= sheet.createRow(5); + //第五行//第六号合并 + Cell cell51 = row5.createCell(0); + cell51.setCellValue("序号"); + cell51.setCellStyle(style); + addMergedRegion(4,5,0,0,sheet); + // 应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(4,5,0,0), style); - //第四行 - Row row4= sheet.createRow(3); - - Cell cell41 = row4.createCell(0); - cell41.setCellValue("检测依据"); - cell41.setCellStyle(style); - - Cell cell42 = row4.createCell(1); - cell42.setCellValue(yj); - cell42.setCellStyle(style); - addMergedRegion(3,3,1,totalNum-1,sheet); - // 应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(3,3,1,totalNum-1), style); - - //第5行 //第六行 - Row row5= sheet.createRow(4); - Row row6= sheet.createRow(5); - //第五行//第六号合并 - Cell cell51 = row5.createCell(0); - cell51.setCellValue("序号"); - cell51.setCellStyle(style); - addMergedRegion(4,5,0,0,sheet); - // 应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(4,5,0,0), style); - - Cell cell52 = row5.createCell(1); - cell52.setCellValue("样品编号"); - cell52.setCellStyle(style); - addMergedRegion(4,5,1,1,sheet); - //应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(4,5,1,1), style); - Cell cell53 = row5.createCell(2); - cell53.setCellValue("样品信息"); - cell53.setCellStyle(style); - addMergedRegion(4,4,2,5,sheet); - //应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(4,4,2,5), style); - //第六行固定数据 - Cell cell62= row6.createCell(2); - cell62.setCellStyle(style); - cell62.setCellValue("客户自编号"); - Cell cell63 = row6.createCell(3); - cell63.setCellStyle(style); - cell63.setCellValue("生成厂家"); - Cell cell64 = row6.createCell(4); - cell64.setCellStyle(style); - cell64.setCellValue("生产日期"); - Cell cell65 = row6.createCell(5); - cell65.setCellStyle(style); - cell65.setCellValue("规格型号"); - - //第五第六号非固定数据 - AtomicInteger num= new AtomicInteger(5); - AtomicInteger rowNums= new AtomicInteger(5); - configItemsVos.forEach(vo->{ - List childList=vo.getItemList(); - int rowNum=childList.size(); - num.set(num.get() + 1); - Cell cell54 = row5.createCell(num.get()); - cell54.setCellValue(vo.getExperTypeName()); - cell54.setCellStyle(style); - addMergedRegion(4,4,num.get(),num.get()+rowNum-1,sheet); + Cell cell52 = row5.createCell(1); + cell52.setCellValue("样品编号"); + cell52.setCellStyle(style); + addMergedRegion(4,5,1,1,sheet); //应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(4,4,num.get(),num.get()+rowNum-1), style); - num.addAndGet(rowNum-1); - childList.forEach(child->{ - rowNums.set(rowNums.get() + 1); - Cell cell4 = row6.createCell(rowNums.get()); - cell4.setCellStyle(style); - cell4.setCellValue(child.getItemName()); - }); - }); + applyBordersToMergedRegion(sheet, new CellRangeAddress(4,5,1,1), style); + Cell cell53 = row5.createCell(2); + cell53.setCellValue("样品信息"); + cell53.setCellStyle(style); + addMergedRegion(4,4,2,5,sheet); + //应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(4,4,2,5), style); + //第六行固定数据 + Cell cell62= row6.createCell(2); + cell62.setCellStyle(style); + cell62.setCellValue("客户自编号"); + Cell cell63 = row6.createCell(3); + cell63.setCellStyle(style); + cell63.setCellValue("生成厂家"); + Cell cell64 = row6.createCell(4); + cell64.setCellStyle(style); + cell64.setCellValue("生产日期"); + Cell cell65 = row6.createCell(5); + cell65.setCellStyle(style); + cell65.setCellValue("规格型号"); - AtomicInteger row = new AtomicInteger(5); - AtomicInteger cellNum = new AtomicInteger(0); - AtomicInteger serialNumber = new AtomicInteger(1); // 用于追踪序号 - - if (ListHelper.isNotEmpty(devList)) { - devList.forEach(dev -> { - row.set(row.get() + 1); - cellNum.set(0); // 每次处理新行时重置 cellNum - - Row row7 = sheet.createRow(row.get()); - - // 创建序号列 - Cell row71 = row7.createCell(cellNum.get()); - row71.setCellValue(serialNumber.get()); // 设置序号 - row71.setCellStyle(style); - cellNum.set(cellNum.get() + 1); - - // 更新序号 - serialNumber.set(serialNumber.get() + 1); - - // 处理其他列 - Cell row72 = row7.createCell(cellNum.get()); - row72.setCellValue(dev.getCustomerCode()); - row72.setCellStyle(style); - cellNum.set(cellNum.get() + 1); - - Cell row73 = row7.createCell(cellNum.get()); - row73.setCellValue(dev.getDevCode()); - row73.setCellStyle(style); - cellNum.set(cellNum.get() + 1); - - Cell row74 = row7.createCell(cellNum.get()); - row74.setCellValue(dev.getManufacturer()); - row74.setCellStyle(style); - cellNum.set(cellNum.get() + 1); - - Cell row75 = row7.createCell(cellNum.get()); - row75.setCellValue(dev.getManufactureDate()); - row75.setCellStyle(style); - cellNum.set(cellNum.get() + 1); - - Cell row76 = row7.createCell(cellNum.get()); - row76.setCellValue(dev.getDevModule()); - row76.setCellStyle(style); - cellNum.set(cellNum.get() + 1); - - String val = dev.getDevData(); - JSONArray jsonArray = JSON.parseArray(val); - - jsonArray.forEach(json -> { - Cell row77 = row7.createCell(cellNum.get()); - row77.setCellValue(json.toString()); - row77.setCellStyle(style); - cellNum.set(cellNum.get() + 1); + //第五第六号非固定数据 + AtomicInteger num= new AtomicInteger(5); + AtomicInteger rowNums= new AtomicInteger(5); + for (ConfigItemsVo vo : configItemsVos) { + List childList=vo.getItemList(); + int rowNum=childList.size(); + num.set(num.get() + 1); + Cell cell54 = row5.createCell(num.get()); + cell54.setCellValue(vo.getExperTypeName()); + cell54.setCellStyle(style); + addMergedRegion(4,4,num.get(),num.get()+rowNum-1,sheet); + //应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(4,4,num.get(),num.get()+rowNum-1), style); + num.addAndGet(rowNum-1); + childList.forEach(child->{ + rowNums.set(rowNums.get() + 1); + Cell cell4 = row6.createCell(rowNums.get()); + cell4.setCellStyle(style); + cell4.setCellValue(child.getItemName()); }); - }); + } + + AtomicInteger row = new AtomicInteger(5); + AtomicInteger cellNum = new AtomicInteger(0); + AtomicInteger serialNumber = new AtomicInteger(1); // 用于追踪序号 + + if (ListHelper.isNotEmpty(devList)) { + for (ExperDevVo dev : devList) { + row.set(row.get() + 1); + cellNum.set(0); // 每次处理新行时重置 cellNum + + Row row7 = sheet.createRow(row.get()); + + // 创建序号列 + Cell row71 = row7.createCell(cellNum.get()); + row71.setCellValue(serialNumber.get()); // 设置序号 + row71.setCellStyle(style); + cellNum.set(cellNum.get() + 1); + + // 更新序号 + serialNumber.set(serialNumber.get() + 1); + + // 处理其他列 + Cell row72 = row7.createCell(cellNum.get()); + row72.setCellValue(dev.getCustomerCode()); + row72.setCellStyle(style); + cellNum.set(cellNum.get() + 1); + + Cell row73 = row7.createCell(cellNum.get()); + row73.setCellValue(dev.getDevCode()); + row73.setCellStyle(style); + cellNum.set(cellNum.get() + 1); + + Cell row74 = row7.createCell(cellNum.get()); + row74.setCellValue(dev.getManufacturer()); + row74.setCellStyle(style); + cellNum.set(cellNum.get() + 1); + + Cell row75 = row7.createCell(cellNum.get()); + row75.setCellValue(dev.getManufactureDate()); + row75.setCellStyle(style); + cellNum.set(cellNum.get() + 1); + + Cell row76 = row7.createCell(cellNum.get()); + row76.setCellValue(dev.getDevModule()); + row76.setCellStyle(style); + cellNum.set(cellNum.get() + 1); + + String val = dev.getDevData(); + JSONArray jsonArray = JSON.parseArray(val); + + jsonArray.forEach(json -> { + Cell row77 = row7.createCell(cellNum.get()); + row77.setCellValue(json.toString()); + row77.setCellStyle(style); + cellNum.set(cellNum.get() + 1); + }); + } + } + // + row.set(row.get() + 1); + Row row8= sheet.createRow(row.get()); + Cell cell81 = row8.createCell(0); + cell81.setCellValue("技术要求"); + cell81.setCellStyle(style); + + Cell cell82 = row8.createCell(1); + cell82.setCellValue(bean.getExperStand()); + cell82.setCellStyle(style); + addMergedRegion(row.get(),row.get(),1,totalNum-1,sheet); + //应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),1,totalNum-1), style); + + + row.set(row.get() + 1); + Row row9= sheet.createRow(row.get()); + + Cell cell91 = row9.createCell(0); + cell91.setCellValue("检测结论"); + cell91.setCellStyle(style); + + Cell cell92 = row9.createCell(1); + cell92.setCellValue(bean.getExperConclu()); + cell92.setCellStyle(style); + addMergedRegion(row.get(),row.get(),1,totalNum-1,sheet); + //应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),1,totalNum-1), style); + + + row.set(row.get() + 1); + Row row10= sheet.createRow(row.get()); + + Cell cell101 = row10.createCell(0); + cell101.setCellValue("备注"); + cell101.setCellStyle(style); + + Cell cell102 = row10.createCell(1); + cell102.setCellValue(bean.getRemarks()); + cell102.setCellStyle(style); + addMergedRegion(row.get(),row.get(),1,totalNum-1,sheet); + //应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),1,totalNum-1), style); + + + row.set(row.get() + 1); + Row row11= sheet.createRow(row.get()); + + Cell cell111 = row11.createCell(0); + cell111.setCellValue("检测日期"); + cell111.setCellStyle(style); + + Cell cell112 = row11.createCell(1); + cell112.setCellValue(bean.getExperTime()); + cell112.setCellStyle(style); + int num112=(totalNum-2)/2; + addMergedRegion(row.get(),row.get(),1,num112,sheet); + //应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),1,num112), style); + + Cell cell113 = row11.createCell(num112+1); + cell113.setCellValue("下次检测日期"); + cell113.setCellStyle(style); + + Cell cell114= row11.createCell(num112+2); + cell114.setCellValue(bean.getNextExperTime()); + cell114.setCellStyle(style); + addMergedRegion(row.get(),row.get(),num112+2,totalNum-1,sheet); + //应用边框到合并区域 + applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),num112+2,totalNum-1), style); + + + // 保存到 ZIP 文件 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + if(wb!=null){ + wb.write(baos); + }else{ + workbook.write(baos); + } + if (StringHelper.isNotEmpty(bean.getReportCode())){ + //将字符串中“ML/BG-”去除 + bean.setReportCode(bean.getReportCode().replace("ML/BG-","")); + } + ZipEntry entry = new ZipEntry("检测报告_" + bean.getReportCode() + "_"+DateTimeHelper.getNowDMS()+".xlsx"); + zos.putNextEntry(entry); + zos.write(baos.toByteArray()); + zos.closeEntry(); + if(wb!=null){ + wb.close(); + }else{ + workbook.close(); + } + } catch (IOException e) { + log.error(e.toString(),e); } - // - row.set(row.get() + 1); - Row row8= sheet.createRow(row.get()); - Cell cell81 = row8.createCell(0); - cell81.setCellValue("技术要求"); - cell81.setCellStyle(style); - - Cell cell82 = row8.createCell(1); - cell82.setCellValue(bean.getExperStand()); - cell82.setCellStyle(style); - addMergedRegion(row.get(),row.get(),1,totalNum-1,sheet); - //应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),1,totalNum-1), style); - - - row.set(row.get() + 1); - Row row9= sheet.createRow(row.get()); - - Cell cell91 = row9.createCell(0); - cell91.setCellValue("检测结论"); - cell91.setCellStyle(style); - - Cell cell92 = row9.createCell(1); - cell92.setCellValue(bean.getExperConclu()); - cell92.setCellStyle(style); - addMergedRegion(row.get(),row.get(),1,totalNum-1,sheet); - //应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),1,totalNum-1), style); - - - row.set(row.get() + 1); - Row row10= sheet.createRow(row.get()); - - Cell cell101 = row10.createCell(0); - cell101.setCellValue("备注"); - cell101.setCellStyle(style); - - Cell cell102 = row10.createCell(1); - cell102.setCellValue(bean.getRemarks()); - cell102.setCellStyle(style); - addMergedRegion(row.get(),row.get(),1,totalNum-1,sheet); - //应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),1,totalNum-1), style); - - - row.set(row.get() + 1); - Row row11= sheet.createRow(row.get()); - - Cell cell111 = row11.createCell(0); - cell111.setCellValue("检测日期"); - cell111.setCellStyle(style); - - Cell cell112 = row11.createCell(1); - cell112.setCellValue(bean.getExperTime()); - cell112.setCellStyle(style); - int num112=(totalNum-2)/2; - addMergedRegion(row.get(),row.get(),1,num112,sheet); - //应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),1,num112), style); - - Cell cell113 = row11.createCell(num112+1); - cell113.setCellValue("下次检测日期"); - cell113.setCellStyle(style); - - Cell cell114= row11.createCell(num112+2); - cell114.setCellValue(bean.getNextExperTime()); - cell114.setCellStyle(style); - addMergedRegion(row.get(),row.get(),num112+2,totalNum-1,sheet); - //应用边框到合并区域 - applyBordersToMergedRegion(sheet, new CellRangeAddress(row.get(),row.get(),num112+2,totalNum-1), style); - - - // 保存到 ZIP 文件 - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - workbook.write(baos); - if (StringHelper.isNotEmpty(bean.getReportCode())){ - //将字符串中“ML/BG-”去除 - bean.setReportCode(bean.getReportCode().replace("ML/BG-","")); - } - ZipEntry entry = new ZipEntry("检测报告_" + bean.getReportCode() + "_"+DateTimeHelper.getNowDMS()+".xlsx"); - zos.putNextEntry(entry); - zos.write(baos.toByteArray()); - zos.closeEntry(); - workbook.close(); } diff --git a/src/main/java/com/bonus/aqgqj/utils/CreateSheetUtil.java b/src/main/java/com/bonus/aqgqj/utils/CreateSheetUtil.java new file mode 100644 index 0000000..6ddceba --- /dev/null +++ b/src/main/java/com/bonus/aqgqj/utils/CreateSheetUtil.java @@ -0,0 +1,212 @@ +package com.bonus.aqgqj.utils; + +import com.bonus.aqgqj.app.entity.TestReportManageAppVo; +import com.bonus.aqgqj.basis.dao.TestReportManageDao; +import com.bonus.aqgqj.basis.entity.dto.TestReportManageDto; +import com.bonus.aqgqj.basis.entity.vo.ExperBasisVo; +import com.bonus.aqgqj.basis.entity.vo.TestVo; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.usermodel.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.repository.init.ResourceReader; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.awt.image.BufferedImage; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @className:CreateSheetUtil + * @author:cwchen + * @date:2024-09-27-13:32 + * @version:1.0 + * @description:创建sheet页工具类 + */ +@Component(value = "CreateSheetUtil") +@Slf4j +public class CreateSheetUtil { + + @Resource + private TestReportManageDao testReportManageDao; + + @Value("${file.linux.upload_path}") + private String uploadPath; + + public InputStream getInputSteam() { + // 使用ClassLoader读取资源文件 + InputStream inputStream = null; + try { + inputStream = this.getClass().getClassLoader().getResourceAsStream("temple/model_excel.xlsx"); + // 确保inputStream不为null + if (inputStream != null) { + return inputStream; + } + } catch (Exception e) { + log.error(e.toString(), e); + } + return null; + } + + public void handleOneSheetData(Sheet sheet, TestReportManageDto vo) { + Cell cell = sheet.getRow(2).getCell(0); + Cell cell2 = sheet.getRow(9).getCell(2); + Cell cell3 = sheet.getRow(13).getCell(2); + cell.setCellValue(""); + cell2.setCellValue(vo.getSampleTools()); + cell3.setCellValue(""); +// System.err.println("数据:" + cell.getStringCellValue()); + /*for (Row row : sheet) { + + for (Cell cell : row) { + System.err.println(row.getRowNum()+"列:"+cell.getColumnIndex()+"数据:"+cell.getStringCellValue()); + } + }*/ + } + + public void handleTwoSheetData(XSSFWorkbook workbook, Sheet sheet, TestReportManageDto vo) { + for (Row row : sheet) { + for (Cell cells : row) { + System.err.println(row.getRowNum() + "列:" + cells.getColumnIndex() + "数据:" + cells.getStringCellValue()); + } + } + Map dataMap = getBasicData(Long.parseLong(vo.getId() + "")); + // 委托单位 + Cell cell = sheet.getRow(8).getCell(2); + cell.setCellValue(handleValue(dataMap.get("customName"))); + // 委托单位地址 + Cell cell2 = sheet.getRow(9).getCell(2); + cell2.setCellValue(""); + // 样品名称 + Cell cell3 = sheet.getRow(11).getCell(2); + cell3.setCellValue(vo.getSampleTools()); + // 样品特性和状态 + Cell cell4 = sheet.getRow(13).getCell(6); + // 到样日期 + Cell cell5 = sheet.getRow(14).getCell(2); + cell5.setCellValue(vo.getCollectSamplesTime().replaceAll("-", ".")); + // 检测日期 + Cell cell6 = sheet.getRow(14).getCell(6); + cell6.setCellValue(vo.getExperTime().replaceAll("-", ".")); + // 样品数量 + Cell cell7 = sheet.getRow(15).getCell(6); + cell7.setCellValue(vo.getDevNum() + ""); + // 检测依据 + Cell cell8 = sheet.getRow(16).getCell(2); + cell8.setCellValue(handleBasis(vo)); + // 检测结论 审核人 + Cell cell9 = sheet.getRow(17).getCell(2); + cell9.setCellValue(cell9.getStringCellValue().replace("该样品按DL/T 976-2017标准所检项目合格。", handleValue(vo.getExperConclu()))); + handlePicture(workbook, sheet, sheet.getRow(18), sheet.getRow(18).getCell(3), handleValue(dataMap.get("pzUrl"))); + // 备注 + Cell cell10 = sheet.getRow(19).getCell(2); + cell10.setCellValue(handleValue(vo.getRemarks())); + // 主检人 编制人 审核人 + Cell cell11 = sheet.getRow(21).getCell(2); + Cell cell12 = sheet.getRow(21).getCell(4); + Cell cell13 = sheet.getRow(21).getCell(6); + handlePicture(workbook, sheet, sheet.getRow(21), cell11, handleValue(dataMap.get("zjUrl"))); + handlePicture(workbook, sheet, sheet.getRow(21), cell12, handleValue(dataMap.get("bzUrl"))); + handlePicture(workbook, sheet, sheet.getRow(21), cell13, handleValue(dataMap.get("shUrl"))); + } + + /** + * 设置检测依据值 + * + * @param dto + * @return String + * @author cwchen + * @date 2024/9/27 18:12 + */ + public static String handleBasis(TestReportManageDto dto) { + List basisVos = dto.getBasisVos(); + if (CollectionUtils.isNotEmpty(basisVos)) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < basisVos.size(); i++) { + ExperBasisVo basisVo = basisVos.get(i); + if (i == basisVos.size() - 1) { + sb.append((i + 1)).append("、").append(basisVo.getBasisName()); + } else { + sb.append((i + 1)).append("、").append(basisVo.getBasisName()).append("\n"); + } + } + return sb.toString(); + } + return ""; + } + + public void handlePicture(XSSFWorkbook workbook, Sheet sheet, Row row, Cell cell, String filePath) { + if (!new File(uploadPath + filePath).exists()) { + return; + } + try { + // 创建一个图片单元格的引用 + CreationHelper createHelper = workbook.getCreationHelper(); + ClientAnchor anchor = createHelper.createClientAnchor(); + // 图片从哪一列开始 + anchor.setCol1(cell.getColumnIndex()); + // 图片从哪一行开始 + anchor.setRow1(row.getRowNum()); + // 图片从哪一列结束 + anchor.setCol2(cell.getColumnIndex() + 1); + // 图片从哪一行结束 + anchor.setRow2(row.getRowNum() + 1); + // 读取图片 + InputStream inputStream = Files.newInputStream(Paths.get(uploadPath + filePath)); + byte[] bytes = IOUtils.toByteArray(inputStream); + // 将图片添加到工作簿中 + int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG); + Drawing drawing = sheet.createDrawingPatriarch(); + Picture picture = drawing.createPicture(anchor, pictureIdx); + picture.resize(1, 1); + } catch (IOException e) { + log.error(e.toString(), e); + } + } + + /** + * 获取基本信息 + * + * @param id + * @return Map + * @author cwchen + * @date 2024/9/28 14:40 + */ + public Map getBasicData(Long id) { + Map mapData = null; + try { + mapData = testReportManageDao.getBasicInfoMap(id); + List urlList = testReportManageDao.getSignImgs(id); + mapData.put("pzUrl", urlList.get(1)); + mapData.put("zjUrl", urlList.get(2)); + mapData.put("bzUrl", urlList.get(2)); + mapData.put("shUrl", urlList.get(0)); + } catch (Exception e) { + log.error(e.toString(), e); + } + return mapData; + } + + /** + * 空值处理 + * + * @param value + * @return String + * @author cwchen + * @date 2024/9/28 14:39 + */ + public String handleValue(String value) { + if (StringUtils.isEmpty(value)) { + return ""; + } + return value; + } +} diff --git a/src/main/resources/mappers/basis/TestReportManageMapper.xml b/src/main/resources/mappers/basis/TestReportManageMapper.xml index 37a38f3..e20c8fd 100644 --- a/src/main/resources/mappers/basis/TestReportManageMapper.xml +++ b/src/main/resources/mappers/basis/TestReportManageMapper.xml @@ -276,4 +276,43 @@ GROUP BY ted.exper_id LIMIT 1 + + + + \ No newline at end of file diff --git a/src/main/resources/temple/model_excel.xlsx b/src/main/resources/temple/model_excel.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ae2ee99667190deea4b4019d057627c577ca233e GIT binary patch literal 23447 zcmaI6bC@U1vM$=1wr&2VZQHhuY1_7KyL;NUZQHi3Y3t6n*4=0Cb?!O0{>ZAQ>Wz$y z$jXTK$w+xAP%vnqf38s3eg1#$|8+tAeK4{$ly|VTbEK313q$?;0`gz5U`Of)X<#6r zU=Sc6#QzD?x3i;lv$o1ksFNDtM;&(U``&Bq>S{)fPbh>WZeN96`jpmP4?MhX^$b~_ z8X8)gg2w|BOI1Ytu(c}t4o(%epv>Of_S|tL=s}pikgHER{8cGGUvgyZTEqXZ4e#5EWNitu0c&^H1 zP&pwCQdY$&(_eVmyeS4#8qo;WUdR^IJb88Et|zZ90-D#8C(8l?*NsfGgn0i{6FhZq zx8LwF(iOhb4A(*5YWHY$f=JLf49&ILF*E_kCU5lKd^&m;S;s`bBE>j@#MRDlO zl5hz`@{RIm>6b*H){B2}iz$YLGm27KN`=%RQH{1iX$!U4DV%0$J(s1n9`1+J0fz>` z+QFwt*>F_*`>Y|&!BdEYQs+7^0~Pkh3BZqIOM^!Ewxc`QeBqiUbeZI=%bZ;|E^L`f z)xmWv5+j=J5B^>D{xbJ>6D z6c@;`PFS0IJX(3bI2q9j@-2y39<_}p zU5db$CZ`!#CY$_YO-6x}ENPDSBD=LLTU_g$`ab))2U~xKti)&4Y>||ucF7D_!f|+y zOR^jIKd0rVpdj!+3j!Jx2ngjrrp4LO$=3RxiD^oZvkaui47~~T4vp&|9oB3rEt=yT z|3y=I;T$%sIxC#esD<@@9qF`1ZkQU4KS0NQ^Y9g3T%!X6FI_Hri^<6v;&-R047W3U zYo4tI3?_-uNvYYV0UImbXYSyMQdM}Gz6ht(OV}E*Cwt)&5J%}+NtI-6V3VLZT0MJA z(IUR+tW+3f7v8@QYn=M?Yv9{=3nBhBea3QNah*XmP?z@^lq%j=6;Q(VH>z zB%SZUfzH=uvjQ@DTF^C$NyE&ZBRO=*!9KZtJGQ;o%830SvJUqBrOBQ-YwRp65#b-_ z|DS`_U;hKSS^Xlz`+gtwc-B^Fii#i`=kIF0L)2V7 zcj)=9Wr;j?@!HeUn311Xc_-9sbIIc6y5TRODBOd{!RL>Ygy$~Jl}$v5h2tlgPFrzy zx!#l0T#62~dql$9vllY#M80sG1Y0F3b4LO$Yvjx|TGn+F+0LZOPhs`6Ji$q?Gs&`f zn+cze%(cTcaSs9LZ3}6lUD_NK@wx8Os5(%p_$oWO6Rz^w{cR=8Qb!0^HkOE~T{#c0 z+#IQo0NNE6`wHR}Xa1?939N}ttrg5!&kwaH;nntQqN znaACZpCYfL2=hl8;Cr4Mijlh#VK(*~KSB2fW+Jv5-^~kM^zBVo!fcg{tiKG52fR4i3a93xqnuOB54L25gB9Bv$OcIU$pC}^z#$4zF4Svu+z1ht2#O8G z^G&fD(^4o@M@E8Sh2`Ak!P9K8jCCL+4ljMB#OWomRkk<=t01?ammr8>KM_`2BqRNG z{kL9fgYykII60eYyQH#(j^I;}ThL1oSWu7-7C1_gd|0;F$>v>ih-~M z@I`nCRnBd5eBPT_W1h2q4DydsoWT4&Lk&14hxpRRBc z{x$;MrK$|H={zF;mfwSnPE9z2WmAtuN|hQT^m0nJXPchMac1;3Mm$t1^UJRlX@`s5 zVt~5@cU6YyD1{9~*SWg+FYWq~)#|Y^j)um}JkZWtVqZSE?x|Sm@BUn1?#ko;SYS1m zpc-Z8M(+Q@Az>$j+t{vqv37M> z^l;X|UbAu3#JmNlYSp>X?mi=vZO5>-^v5Dx@aH4AEzcpJhutgFN*#ih@517Hz>Q6HDiF^Wzkb_q~B@-16Zw(u$*E zKAuZCi$$!BTNn55ITf^Imo|UifpRg>c1G;%!QKJ@HnUeXD7r>=xVd+*YkZKvOUJ2m zpUD#^^OOY%YI+N~ZjJ%-fi(1jJr%3#MWse)MaWPWR-365*EUM1kh)`|%rW&b{MJlm zHDnF>)I8`ritdcEzg(z=qIRM8ziNQMIkqA*wtW9HCx%NGuYf`T0g+?>Un42wzapu| zMna}2qPLvNm;e4&0=QGnQagaiPFrFKjqHvoGENu^3gmM9Y2{=R4l~1O&AaxH$=lzHDz%k7@v^yY&CEdSj%GY&?5eZw`)$FurLn3W+IEC~%I0qP3qSSgeI(b{ zqt$e1P8if*E?o`y?mduPqU8^2@HH z43doc6Y>fKurh|EH&xx{s3i;thmU2HPE@QQ(C?1GdN)1|oV_SSF8Uz;FQ~zbe-aE| z7E+A^w)gf?d~EZQ)jUH-O4$@?m{=UBfL8#R^&maYQty;Yonpvfjv7NJKkLOR)AF6* z_~c;(x(EOXqOL-NDe;gZ;Z!mI9vFmtF03$~r5ma98vn)P$`RylhQ+Z~Nif9MyR&TUf&6BcOOK46_vlAP zsQHDWzN2F|LIztE=$nE73~+j$U{yDMd9l>}I%&LS8v12Y98wv+E?F;r5uQhhR>s0> z5{6k0QYk5e31sc95v1-}T}833QSLzlv-{~ax-`qcvZPwvnB^og)kZ<55W&n@qnO@9 zMlh<`wr`NYp<;ps2n0=&7Gs& zY=Ryau-K(TmZ~XOpjN(ts^S%LeuDk{s$r;%{j&oXZU+p4T;!vrV5!uI{V>cmcswm- z>P*n=*Z1U;Y6WNsEQj2^{AZ$lSEx_2P*@6aomj<$>ii8ii@t(0y4IoYluj+jLs-^xwN1KYco%sBeqt?Q=L;l;pQB(3uc^O zaQ6vP$sX63fz$bZE>_F^pjm&t$PwbESsW(__JaO_o&V}sE9?G+o2pkC+6D=&t=*_N z+LSh%BZwai|Ic7CpfC3<-p%BW_2;_bu@=zYnXeNKg(A)v0Gs;`g)$I0o(qTbhY6R`te%G4s9rlPZB= ztqOX9#|JkI=2aTb*xfD07beotfvO6XZrLpjzmCK5drg%{FWOV|c6th{Va=#JW7)U) zF-gTun5O)i}5d7FHJ$Kw+F#nl2c}QThy&!>r(24%9iIeG{#95`e;jk}`?7b8A3K6^w z5eEi>8Uj@S1JYth)@*8;V~i*|=cg{gy7l>(S=6q!>~;zH@as~Etf4-pzMl4e%XVjm z?4-$Ry}X-R+m_xT`@X*7dFjY~@9R1CawYwuQOAA_qvTDIc9X#P;;Z@NNYAyU{dF0C zqTaE0ph%~6q`E_NK)-`4EqK!KebV`-=e zKmVAA_k194Jz1j5lOr`XhSPjpX-?qds;<3xbL085_kNHS{Z`*UOfQ>9E=gw4RTl2{E#8fA@=Q={^HTiHjbzkgr9%;TGj;Kj|o_pz$ zEx_st##K0aS<_6gZ4GBpIKYQJExn%7ox`7U1Xre4o z|5N3v&a0W3sGKt%`d)x;xS;Fm>&wb(Z2iQ|CiWk-d z5#|9{2tAMtAw+Vy1XQB-NJnW0H_hvpOe4NlkjuKIfJF#~00ALe-VSIkKO(hy6HpKB zNZ;0NvQr;BRUc7og!&Mq1Y!a)Kxh=3h(nMSa*g=VpSZ7bMnhh36u6E5@K!*a=?0Z! zH0rklQ0^%3S0S#U5PTn!10g^_oDy;9LHIdKgWadpaXDbXbLIyz4+P1U1qu761r_4Z zIEt!}ig21Z0W#8yu<)rsgc+>i5PQa~(j3neW8ap9YU@V z8dVUl@8QZdNFfHL4{uEZ zDeSh3AT=t&gBjPuHOeu?vW-y+P6t_I7_?CO_Lvw%#6#j(1ReZG$(R{TK1J=^^t90C zlmnYmO3^#n!u{j`7p{t*huRE5HiU0QGK7+0q5=|DxCOrp(Phn&Vx#PL!y|*>qVMa9 zarJb53mGn-u=0uS+gjn0=rps&NMp!&h<6}J$jLGjc4dU;#T!$N-;Es~I-kXU+?g@n zlZDjQ{i4Xn;z+99R@Ub!X!(Peb%~eN6pVrmmAJt^+{%hRy(pem6-|O7>d9|3&}z3A zK5roSe0~e2o(BbCyOPdt6<$iBr^8bs3Q|ojRxzza0&I8;ks=g-dAuoyDMqVDA;=h1 ziIhNM6c|S%^yVn52a8XE{O3quA;Bt^PfYq4YMQaLy$Ta--=6%KTBTxkmT3)s5FDUAafwsh2bMK3_Bmdc;Y=RUOQ{A!G^icXhyBp zAU0ip$jk%eCFoCxonnAgEA18d;wL z|G9=8RbsFw^`-BY+PQDsE_t@ zGVy?nt_SVZW?e~-B4-8Ql3i@m-Igd%C(ZUEzs9Zkn! z>xII|&o>r<{jn{jn|VI}`M%zB=@R3t^jS%#V;`}n;4b{}>^q8zJeN5s@$t!=Ba}K{vlvr%fjw3S&v3yF>xk9%m^Fv)m zbkB>Lx7xAPGOViQ-t?f1j+cAB#`xL6xq7I{s#}%sjA}_}=~Ln1xqg>G6k6y~@1AZG z<%3PI1C;j<6+pZi&3y>Ah2(YyR_BN9?;ju$voH0$s3q(wGpRl0*Q3kFFJjr6|X-G30m#f%;y$@VXlIiOMPYre3N^?iuD{EKACK^@ak2JND zuFq$^y->0Z3lUAcg#a}xTVKr7bZFCK#&4S3xV4 z0r4odx z4B*;Xt#;_&7S6)=i~u--5G)Mj}9>R+@hz^iiGc6dF5hZYZ5) zqfsZG)hfO`4|`nfm`JgUf4fYK&eVo5QRn-r!h~$~y>6=%0JTwZPQot_M@J zT-RE@Oa&PJSaz67=bcl3uxUBJT9&f*56xa$F8kPP-GH;wBE|C!z)Dy}Z?*OB#$#Q` zegMZw+LFmh4o@OIal?GU1j7u%6viCH1Yq0oZ`WejL5n(xL*o=)*u}#eGoJSLju7?| z4ifeg4inD#E9TXHK6jV55IFy8w!7u{fTHVV}(e$(e>DF-*@gGFIM8HHu zL`XyoMB%d1BDV*4N`Sg_Bx!C8l-xMKxVX5mxU@K7GLw&oyT4*s8oN>CnPQ^!cRJD_ zf`Wp?f(C-f*=Z5z8N{B!RD1_vm}h{(vuNXRG&i1!X;TbaQW65Xh?CDl|6 zlJm%95^LNELE(Ha3atNAbG^UP6wm(Qs&}c zRGgO>>xZ!vSS`MJ{?o#c{57}Fo7y`wlKC0dwJ4-)^6|W$V?(hfv0cHcSND z3_SnZnEr3;e}_#-P2=J#y{NLdyqI{;`Hs4g{%@U7z*4rLHmk>OV-l?Agg|p$MDi#v zjWk&WE|gk@5G>P6A^n%Z>SV>NkO~%B)8Aqn2MoLyJ7~XM;MX@Px*g#~B_qWC!(gTA z%9nGFQ{H*w2zPDnsWH3SBi*)%u~8(5Ja6Cpo|n{04%h6c=O88I|6MCpT0y6*2j68dfm;awq*+2FDzojxKGh=Jxe-+IByS^`t zmomHYH=Yw>{kxp`zhM6Y|EvCWr6FUB!-m*}aq6pn*%fbeLBdE3(agI~>VhmR8G&1- zW08vF+D1sh)s8k+$M2tSJ}2eB?Loc{F7Bs0uXn&Ik_qw(gXf?|rI>FqGD<{apa;0l z+&h@Og==efc+?l{GMxOOZ$46^Q~ri83yPk=eE#Ap78pzWo)bq7hh$7~{o+XdQPDx* zWB21~6q9Tf^j-P#cMO44`js*zv7bJGwhp%B)~eqv0N{0`@bmB#?1QwiUZska3W~Vw zridK4rG*p)`IoQjUb9@ED`hY?Bsl?Pi5nh{tR*zjalTZWYn0hYD3+iLV?RRCjRF9` zefpyEd7|c0qdY6CFMI^9HDL4m8@i*PFw5qQ!=0IytZD`4@mTjv542Q!q(|dz z0SFbWc0Mcetf6ja`-TO&5_p`C)9YEY>nbCd?ZdXle%rFt7p6v_?fVVehyGL$m8KK? z=w%qYTi4dw`2t-x(80?QZm0bE@to!_is9#(6P%7Ub4y3$Qc4_D0fekuhXO%kGxUiR zsiWk7)7cU?+vhxiLKf$hE{W( zG76LmK}ys-k5MuVE|u53M5@}c;=Sp=P|mi!O3;{7VBrAeE@1R%WI12agJb zTdi#D)obGa;1CjAHxkUb8<4aClu~De2GhbX>&)3iC64>yC9pGBV~0>BQQce8o%&+a zx`Y;8M?odoir?}3RNH6J13G?Zkro;Imy$7Ej~=m1R=(j)pMmLDF%n*;=#l|=lsX@< zwkKRhb`A#H+~HLRJy5Rs$me*NrECpX(JpAty99gG%)WhVW;37eH&%{{Py;0^27dYM zFQ42P9o%^elH-kY4225j_Wof0Z3h%MF003B?~XTN@KWl+DE(`XIHoarB>f|3)D5!$ zR`!NPk0V@oj}uvU7;F>!v38-Qe?h}xu>WIOqoNGQgccuU?8vQ2A!Z<2;P}+U(mj!K z%d$DX`;Hcpe1nZhU)m&b)g{i123#fX&nI@kF=3wCld5_n9yKl1bEI-r9gu~w>Tb|s zUt9SB+xagLQ9Elv)KE$}_i~K2r7^F}^len>3Xt+!#ez~lF6mwsR8PKKIhV@yIH4s^~OY!<{xG92z5+m&D8JcArVJ7mx^_MB_#^8^K7S& zV;4|KQhtq*+}Z7D{;owUmq!Zwk{KN_YLBKKoPl*w= z3AzP-r7EHfEo&ICz3iVW;2Q2LqXP3+fP*nGhXD)N8Qw zJW&HEw$i2_@Bzq{jTV%CL`b(0B`IP|fLqmi)OzF3D&}HAm#LM2_KgQGVaGKl8Wjbdg(`z( z*htn|)WR-JIIHIl4_zTIF>zSSyK8dw?h6G=St&w=1q7*HHOpu5w) zj!mp&Vhl*Q^-qZZBl~VKh3FWsyk+R~nf3j*PUT5`S8T(Ovg@c`To1%Ih1C%UwR;i--96jxhX70l4^a;K=?nd{#S@-aLPQ5Q(-iLEIwPj6n4XxZ34O^n4 z_?}1nFWTN!wf3FXl8J6g84s1Nx12ZIHhw-kap>r51q#9EG9Lb-@=CTU zW5waf8H%;rHVJI2l_1Fyqo|@2?DSI5W1u0JIX{9On@mHmH%@yNB9?@K*vCfAl-CU$ z2UJ3git1Wc&L1*J-w1RHq9crMxM~XumXFoP0rGx^(VCemT(C?+J|L~MCgJA@-bU9B z!|%60uiZl8BNAUZ%XQjqpy7NYIiZDM1V-i=gI5Gny%@}L6NwY>i%Pcz%4KM;Sp2Xg z{4?LIdy6xnG(23F21Gp>XT_hy2__IKGlphbj!`V$3~$+>PWC;7vxP9HDNrj<*gP#2 z1BT&V4oD_Da~7yk%BsSqXDxSXB3CD;_a;9WZ_8+fU1;MZBiHOWhMbj8F8$$#mbZtJ z|7IOf1~LSBI0IJJB!mNoFk5Eq5;1Xh9-q~fKn>Haj%R@7(^sxmdyd$L<|?%Jnh*?1 zf{4*c!8oS+V=bA>EE+aEV_GQ1r~9JS7U%Nj!hz%H%aH{(*}4$)in>Zg^>f16L^r*gl*<%DhSsC_97J_g!ne^+fRuD5`Sn8*Lgub zIBPI0`!iVJJt%gDnULS8%{$`}(*)WF3U*as!U?yF9i8iwXG>yPX>?wt!bFJjC_Ppz zSYY0|OCetGNb-ns&6C|THuG%jF&^bDm70;ZZ27%nR zJn$~AL$>M$B(KPCpkK8cm#sYcoEMSXZYXD}vUcsb$n%LC zXw+!v>68vl8SNBD!S6O=hb?asekHV`=sFuZ%BrCd)RamTv`PdR^VC{ib#5UWCdzXo z$<&+@L0=TGm#I6`4y{fS;@NGtJ{|TwoAg8}RH}-f4~paIJY-0-uZ!at(a^Lr-F*=B zY_~gZm?KZf&ecP71d(4bnPZ(tY%@Fi$_9Hxo(L190`u3q-2 zPPLSwB#aC0CUx5o=N`C{G)c)Vd~k`1=w0hAl4xTgGnD>R2nFCk@}A54>QtPVSqRt~ z+?X62QHZ8sGUerAD#Wh7p_VL?P&#KOfy*G5ERto6ncV8oqRhWwBEorkNE2&dBR0{p zLFrO{+!L{;zzNp2m}rXM*y+)?1S%z6&Qo@X@6t0>%^YI|)q!RSotlR%r;3y25nP>? z6A(wjzFZ=OS2s{p=`y8El$H_L{GvylF!ojAvNRaz<$d(8=K4U-7Y51w>50Q#9HS&{ zYx%^Gjbnw^=+Xy*xHXPkVnQAJY|(!8^)UUUJ5{@{0ckLs-zG(DUOC2&x?)%AXCPZ) zgOe^JE$ps*U{?6j3e-m4jFqr`z@@vWwvn*xaykMje8&K~N3Emt!Pn>HJ09G^ z#SOdMBUttJJ-blHVc2n8 zg}8FU7V4kq4R-pWhjA%TMo@JjriFg|d3njc-g5mpN?L9bq0y8-glQKtbe1@ENpmdn z{W2P)D%Ll8C+$wrU?ioIVQFTC8?}EM&VKrn4;@Fguyc8+9xIM|ANKOT3JKV$ACg8l zA7&ygSQYB-BGl9SBL;-m^pWs8 z!ae(^27HHd zRz^q|H}N$Qgf6W2WOT;De(FI6)56eglM9@tzO$?WFwsb;WhJG>He!{xt^Xa{$IzNOU8mzc+dz2Y?I{p16#YqH0oaAElMifg}Zy6+{JjqE#y7U0Gu_6nRjS z${KjJQF(HKMn>9oG%KPz^MUCmyU&~^@fNC_tB|iGV^}n@e^hAIb~Ecdk5#f9TBA;_ zk-NFdw7eSWVz^IGpmo+rmptlq8kQTpgb+BnCbz9Iuo1+i;J`fuj)8^t&xYd1EVx)< z*cdWLA6VaZnRwz__H=_7RX-Ju%NkOeA$b2Ks-PXqE>zAtcT~q` z3TwaC#4Ii8cdmGQsG-Ib1KEY3*$ z_qX3WJXj#tCZ3JR^le>XeQcuYx)8hoVwRVHU&lZ|$HdlAdMw(IJ24erm9btUG!R8wA2VPS%v zGQ)OWmRf!#TeYMutwmOUrrgvvw_eH8g0b-Z)PJr`k$vt&H8myKwNy!4OsC9sc2v~! zRS_)vEZF5?Q=)lQ{431Fl%Z?k>N;oAh!clvNwml@ze&rwU$0s7O0)=uZ(}2U+NMKu z?Xp%j+GBXyBr;vJXj!_0B+JT57^_ghyr;E=t7XpOQnkJ5QL}5gYd0!cmW5T;$FyV3 zLT&ki|NPZujR1>QEW~D!b-hZ~vceN2WW2Gt*#c(?3A)OlSjW3;xK&A(j)wUeyCT|# ztZ8oD(gkC|-G}Pv>xe7UZb7nSQ>3Pm)jz6fk*~1(F?Q!o)rIEK+U1kL@nvP_%dBSU z^C{~+c40qvS@A524-J0>AAjZQ&xxt)CJgt~Xzpz#iLaBbFflQkbP(G`_~q=|Ae{N1 zqoZAs|mN z^7oFG@8JhB+Xhb@u4ESo<$h~$oju**tIID}Je!w+)dj3!%Aw-nlEHdX0s}LKlJzFZ z?C5qC^Tl%v?HG1z0KTyXO1KcC3{I6tMfQ1s1h5Krq~r*^JBY<%FQsrs+45#(PE7#z zi0L^e@?BEge#GjL2r;UxwHa*}v7u{X#pqr^3pZMy+i0CAGJYju_Si^jWJF`yx+Pqd zU6lS4qF~k|Y@IL2Vi24)7c|)+BluF5ZwxkkBCfBtgdVvI>b_%p2>TUw8&SJ8L_pmO z(VUK5+$APe^>36}n&>MF2}VPu`YgX|{wUPY<}ij@vb(_iHuj$!iiQ}-g&mW2C@?<$ zm9hzk6zabsCYHSzE5*n6(GIja`R9hjgj*A&p+=JgB8oO+4px8(>QrkUl#+Ff;Mq1c zH2qL?Th?u=`(u+_Kl_7qZox9`FpcfTTCW5(ZCj`?s5cnq<~W@+AJ<6>3_L|xJNR)X z+j+e@PC4JgHcJaBOvky-=_AuO4M(X>DA|eAhNRsg&Y058T`V0IZO|vvthTEh#4_uiH-iH7Y6CI&=(On5JNno+c3$($a%z{`o@Y zukqW<#Se4il0%o^CHvG4&GS%Iq%BE$> zFLFxLxMQhuagXuf`Su&`6siqHJdwJ%gDdXXPd@cPM)j$khAs`tunww!1OYD$X-|P* zeOaTRVQ{v%7d#gx&pJ^(k}7<*ERhhU*aZ`fvrXVq+KdJX72tI21{9L6vl<*jfR^38 zx~Ipla$5U$6UJ#C${kHW`>u_CcsK7NszhT<9;l!lQPS;2zF7E&!zn+cNNq7gAHF}# z0ZOks?m7!4$}iz2q?33LvchyEvjZnU{rK!q@LCd4`^eD`Y71%oL{vF(ktBv-;nC&Q zc*!u+!%nXwn^WpQR0_rSIAb^j0(WzKj=S4lhS-$aJ7QN&4h0)K^7;el0nQ0$0SxDa zv+6>Ht;#DF(bRoW3u3w-45I80S#&m}_OR6Kp)y8J#Bc<7FxR&Vb%@+;nL3f(tTo=s zS)NlQHB**+*XyiWp7NNi(4dd!f*w)TbcLXG{c-pTE13BvB3 z4Mr_uvkCr+CtwI-XBJ&PF?iL!twS>p9FSymG+8@>Dvt6qqtG?#`uH6|!U?Wt@P}XO znx%`D8&jf9P{~?LE-lS{<(;g%rcGBy>C?7waG9>>yZys5DlV=U7^?a{rY_GIafCkE zE-55Fx%X#?E!{gd&J{R1CA>^96F8a5C56+Fig~(B+Ug$kOBDCa0cCN}Ou-f68Z;rA znp!$QUbZ!Ly4E$EOGAPhs)@6-^!k&~mkuJ*OIkQ|^~3^Xi0N2$@NRg)w!@rpcVOI5 z2j>3MoGvm%2xCt_e{IoMM84H>n%(pQW-`SXxe z&NBDQq7?pWD2%uE01)&6PGt|+^K<;wLZX1OoH?}ms!*HJWRnD}WH93<2OfjqJQ?z# zeSSc4>6gc85h^(sb_!;4YZL4C)f5~gTkr)DHxrhtnwl#r;}8NqoAQvZ+y|9GHY2{>OL`H)QP%~R;{6&X= zQ==e6%BCiPFi~_vdY~i|d5Tw_i~z-rEu26_E#jY2=HSVq>O|H&L{XB~;YspkRh>U6 zWo{`oxFu)0kP7BuYZSHI4VBl|?~$Q4!Ddo}AO0-jN^GvzCy4N{z;b6G>iLUlb6fy? zvp)Au_v1)w;kS?bG}wlh$wnmQW>^nPjH$Up>#>UI=fV8?QPOaKueZ0Yx@;(J27GdI z!WapH5!_6t7w zHuM$cgwnbVr)f!BhcnN&MR16ev`CShZ7Qe3a{lMeFXyJL;(Zv5A5?HG}D8+YV(jJ4MQdzag#C*i7cZe zP}s+0RlC`M8zYtYJ|J%=4u!s>x|mU3%1yzy!$??^h;H1ObU-~!tTstcp?Ev%cO8{M znY9uPfdH{Qzsp_|#MkX85X%$@HzC!KuUOwyk#PFP43BbB97v=k+wo3Q9!h}ymthZR0CX1l5gk5BILXD;nTcAo9n55&7vX})rVuyHWTIOL< zjKD}0urfsD;D1NUOST6-;2@IbS|^ReB4+&Rf@7agLt+a+<6{We0Ya2g6Kt%Q4NTe}Y)kIv=dU*JU!GO+=Mu^Lvj8ASup zrH(95h#LB851gV{T_^d}N6CcgUdgsVDZ{)s=omF-{+c+yU3GQQbsI<{6wen11&%px zBvar&B64ggpKEH@tyu6znNobo){h|2hsCtrPxDH2OTyn_f-@kRwfJ--8ZrlY2%W1$ zrZK{(6!!YYixv}xJKq?t8}rvK23K#Y-o&y2ws|EUX?soSy%NF&&X-@JFXa>slLg6D zZ};$5fcBK%2Cx=d0)F8^mONMa=EB%S*4|V3Py&3g64o5yVT&yRKuA!j9@vDJY3X-G z{dp4c^pFNcS-*LCHf-_J;`#>XSKMGk(Vpk8i{~D$P3#iZh!kVh37H9ph^Z9& z&!j=kj4tzEAw#KTUP>+7QQ3tXWD5*P(4r5_#-dtq#6{<=g85DZ#2;2I%2vzikYNF9 zVaO4N#3jz-%mInzc)Yd36slw-{TOws#n;RV%91=*CguVvJggnEFXX>(`g~nJ_>mmb zP(uYs1^tm!0eMYi%+#XQNOb49q&Z*t7<{1o8tcVwi^X=tpur(aO~;_|>@q5x_%4nN z*@!4nx9G9qS?d}SXnwUU5f^FvBt}f1FKJ1u-17)AI4>+hpc1TmS`Mr4%)}a2VDWEn zS?b#%@)YSZw>BX4&<#`G;+=~rk_-E2Z@j&MM^(0;vFqOmVT$`jXEYp9_Ab7AZ(6VIF*mcgY?Lw*-Wl2EvT0o5>MWo=^T<6^jC|hiieP?GrHS*4C z9c9+jiljzpA2=+t9oO;l%YR0*Yfe6Htu4niOkn5xUgS{Rmw~+Xe!u0!{3}gu&hA#n+a#h z<5T-D`F|Uznw|%F|AA2!y{wDU4XR2hz-jss`lfi&a$Axk|7RhCng{h3wuAeKvNP9- z0d6W=ydc3ZTeaf}#Z1#*{YtcHt*Uup!Rs@11fm0|E&4QQu|jJLFnT)x7vGAM80MFD zGYAqPfvnh^H!7-}W{^Z4CjQx~v*w-Wu?>tTEX{b*lAw$$J?DGn+}>0LqkxoXIwyK_ z)m1J?wwp*@b#ukCTyeFe+Mys|k=&Y~uSpU)XQVkYlWmAzmV_|5`?CLMAQoy}Ub;iF zvzFA*9O98N#bvcFs)&c!#DGX!|63x_7P5QbxtfC3C_|bc){dV!eJ?Bw-MxXU-MAF? zr*b%UMQxlIW6G2It$l^iM->ZtTGB|eUDYqddv1PZ6Ij=k>{O@vf{oE~qZcv>Un`|@ zfAF9O-Uy1NUfZ;3!QY(srH>w*F#gJuY=%VGtA0^QW zx=V*Pk`^>I8n>g@gPJ~5r+RwbyL;xLQM->`gIr_F@5W*bhpZm8!&X>3BkyY*8+@x+ zg*26H?IasMaXIy2&-2epo3^oJ!;?HzcFc-T4`;}0Jj-j88~s(p#hkC6msG0Dh@p^b zq(F7nuN`@%D?Q4LC(e@)=u8f-92Jdulv#Z(J(7klq@$9Mu$cK6IcygH`6Bz!7h9=M&%O8sW6R2YOi!t$Qf~uBm*kd;N@BD*TSm`u7l?FFw1{ zZ{DBfayMT$5brbaJ8OKckLSNy|F)&R>E}D&16>0XYM)Sjb)tB^b$OWIYa?AP)la_8 zZQoxdK74kh_I#1&D?Q$?w}F{H2*=EOw19UAS3a=)H;kL{1`S4TXaMi#nWFYk`qm&y zg5m?GfYQn?7ab1rOYn^y3hW){9e?A`0Z`q?qH8dju5=@>-caH&*}xLpXIguwS`sqN zco`{}c5Rp#_>^{!{hUsofYHBm5b zQ#5lc!5`v!>M@O+iY4!Q+ShtshjJ&KyQ1PS+Y{o_D;*C(EvZDnH@ZdZJ3A*=#*x6e zmL%&0x*ux~5V?1>jOe>Z)WWIT2cdyGT_Bh@-cQqe5H|?bAG*CMUE0Vn>4U-9pP7r= zly;a{R2;}uuebU}AHCrG)Fqg_QBh^M;S>fO+H`9$`G{(}!Ng#AlGV5ResJ^jfZ-%< zq=C^VaJKP~?Htx$VN;e?nT*>M%eWS@^@kz=y;*j|GOp^GD!w5`K zQJWlLT7NVf4M#?k2Y^ZPKb@paC8nu3h`^GNu*ngtjiK?v)&fUz$`PmTLXQq^{XdOd zbyU<_*T$i{L6ICl8cC7vmPWcHM7oCV4(aYjy1QGXB?W{bB&CrK=L31~^0F#WU9N|&ATi~=?CqQ*y;aYNlc5LA%vy{0Px!8!4lbUf^Iu#f+n;w92Xc6#v$=4f zJqHu;G|#uYz+X?}aMZJrXelbaFcmM_?68TJr&EMZ8?%IL9a^*j6h{H)-Q3a1wJq_( zXI4DC=ehFjByPObr(Ld8UF0$dTOdcBVf-u~v@dHMZyq&Y9Mo>eEgEp7aeKiv z5c9ZV6E=fyxLY&$cNSX5+HGSloITy3-PpO!*6iviS^0pAlBHTY+wP#o!kIxc=VHf;9A8yS2@IO(0v(;FTJG(Tlk!UrPiCjnw!ssq zc>I-$775dkz5t)k1;9eu?g3&y&Jia?M?)GLRE8o@p9y*sAvWfG5U%8PcLT&R>V`yy z^c_$EiI$buVq|T{oX}(>Ces0*%#c&ghd`w{bT0DX^AnlM9uT1CwE1}@1ze0wGeKpM^ zR%9dv=*w|kuXH=XibHri7wjX1RwNr~lDQ2>ItH#Y#w0(=TF`@|1jKA~3q(TPol8AE z+Z}g_X2js-GP-JR78juW3Ei9uAwT1~9T$~nhXEy}OHo_g)KP@-SixkYn3z4$P|3KJ zJ}6j;mewKy7+@Glmn1E>f19!j*4Ck^$5<4jgpSU2m!9Y1Zqi zC~N^kC@Y0=lw_0_=X`P{^fU%??G1Pu>KfCX4h~^YJ?W%{1fADKxYOhE$go)KGr8VR z(S5czM2pG{g(>cO?fUZoz4fa7BYb(c^p`Gl9cONQcL+vol*_U)kKeimXl?@`!Rr`V zk-sM(>$n5SNgZhy$UFgAIgK;~5(if^Q$VXf(^nWY3yjd&bwBK#IiL=+!&yJ@D#4ZP ziK>K`POA|DM=@utC@3H+>h}Phgw4&jw9)}Rcm# zPQbiz#hby5fpHS)FUMs~19@qE&~5tS+OZ9w=i)`{k0{sOTfAyE)-fAokUTQm0?qUOh z*a|aLRlQ)=$OML=XaejihnC(V%3TnlgLbrd#{Zr7{IP?DqRso+=sYw&4G=GkfNlIF zX};xr7m}Y*Qz9UKrJ)(V-h+J=x`-!L%OrL6Q39QINYwGM)6Hs>eBpCZP;xFZ2kDT@ zevB_&d2{3X&(_7RS~W%!&VX-fK!+GAIo?SeCrPAMdxNR*Y1sZ8=`%FlMsaiPADpus z-_$+%^}<-b>$~SByMRSfYo0{ZYJeyMNhW3WUnk}vwZDnY^X1qVXlru3p-qhMOwc{+ z7z%w`G-z|J)AZ3tzhlxwAXR=!cZdSB%SH^}62pj>TJ+tRXcr$e_UN+Sv*@>^4mEv8 zXV$vx(6*93{zwy8tSfA2sEOD}nz%6`l`A@lDC3qFuNNA!Rw%klbC${n3|pGfdnHP; z*B4w{rO(6{7@Ndk^ollv3UZLeql-6}-sf%0x;5{syy_`Wi5!V8D#9&jfIEBdOcz1y z@{`ohFtcrIth@8)gs&XG`%kYa=EFqPSe!<_k){6D?u5mF%DkeMm{^}*(}$N`%RBgIBIueW zi3C;AeWcVTW&!ds_8lOCz~hpPGo+hqQNj$P>x)$N2E5fO$&JDI}2*|WBmdqtGflZX>;g_{g3z>N`Ls; zAi{Yt#%*AG&4TQ`WG|Z|%2%4WQe?+|VD?Ue_U6r~LvhnSpC%s$qM37joo{ZBXb|FW z8=NC8l3*4{$r%lw0Rhe>OuFYOIiw&nA1!#&s!mdt4<)v7#*QOiV8cW@_+yi13Q#FH z3+vPvOgxb*C$j}uaB=oO%`WU84&e|{ny@Bv|A@Cw4~h?qU<5tKr%>cK=di`9U-o|8 zCFK0gAV|*TC6i!Q91}1BBWlPI@%S9Xu`|MOUNjpZOjoWCJ zCw=C-bQaK;ae6n7B}iiFx2eWJa8if%SiaB)q?ZldQGsJf9UG;SMGT6>4|oDb;Y8n> zVcgD=nhq{ot;3nbl}rf#A!JOWlY_D)Bz(@V(SSr>rY(TlA2yhVKiBk)3*t|T_(7FY z%+V*y18@PF$7AnP3bz@~6A*W#N)m|nVgc|pS?(~6cWP&b>;#;@;-B7Ngx~UE2}NcY zo0xe))L(LLraqrFVg)KS0}4@hAe!w6+OVF__!{S%YUi&=(%TpAX%r z$~9Y$_Nq)AjE2{bm_{70o99~HB;8+SZ6MEdmatk#>3h!d<28>sytlJik~ppKr<873 zph(!;x1m}VqQlTk!&H%*h(TRIGY;>Ac@x-R5KjU&hl_U;9F$EB$$XS5fuF4IhgGJc z6hf$DC5s|U%>5kuz$}FVb|R(lmpMgALm#Q3RKjwb_(Ki2B1^yXj=1*}Q8%%Sd@gGX zLfo9;B*4sbUSbd@J5`%&u?10R6Qo!Lb8_YGaiq(RDUYZ)r;PB#OdBH_Wq#X!$1DN0 zN;aP-?x$=Es`zU0!J9;&eRyJ{$d3$bOy^p*qZ2iWdtb{zx3;CG!r9|}yY&-db$d&C zhKhR8=M1-3w+p7tjY#~8;1gtghh?InG?msmM2q@5RgDuB?x}^sDpgkD5+t3TdF@xm zazhD&YtgUi8z%Xqvc@|wciyJw=@y4g9+a@Ewzn){FZ%Y4RJTc;KTIeMFxn z@i*wR&>vtsMLQo^+VsO z)6~GQDnsAvu4RJPc&SSri=;9;(wwvy`dEZao#FK&z9vpQEaT#a5u3am!W&sh;JS4H zk3!KzkfeNFDp@U}hPEf}Cl6Wmen~yk!WgyFIqb*o24T&*!(y|--hKUH+*6j8yOVHNdbku> zt<#I;t&`umgc&~c)_$E^FFlL}Cnx{{z(xi>-v}N$ZM?m z?%I?Q`~PnknwSf)z1q34Oz>GTtPvtbKw9PxEpt_8%cbXhfl zDVzE#ZSB(6+bN5sC92y*d}-KDXuHS0QtsunT%47ip_{OQ$cNB7Y1POb?O~_H9ZgfG zR(W$@x4p#oJ?XLH1!Y(~>c3y?IdWU$_Ic0b)lk?S}7U-ljN?nZruiztK^~s@4;lRyFZNW#Pq;(3~S=qV^ruqAk{*|BaI#28zBSn<9o8o7d zKyI2Cld&yjd4UXWcF}xJegksf7p<1^mIFs(A2W#MWq5kQv_Y=Ta5gXfTQ01uind3V zc$0F3M_K7sm7~(^%_DI`ecf_q+A&T<;ovw&ZSDC6_Z_7IOG@7|po(hwCn|-^uW7a0 z&?oh2$&!RnW)5EnOiXNabw-V8)(lE;`B7$XLnv7KdRF6|`Pg+OY>ya<9shSM|I@wm zPvJb?Sp5dL6(f8D0|j-fy>wTxeLw9^^zM&BwO`R~jg>L&X2S44^9KtKwZ-q|novho z)A*ZfoHM@Y-t$MalwA&F#VY7G+9i-fh zrQVr=#zX$;>M%w98{IAw#Bd{@`@`dee7*Dyzc-%ZPDH(=YZYQjDBGM*+Df?<{XeOO zO9!uhR+sB6!3$8A>Fh!7?onbI>tagaAh+TRSbb33hti#L?sOZuyxWs{C*!CoY-I^D zvIOZWJ6jvsY2Ow24aY6Yb}``u?#s9Z=GDKY%Vhq@)NnAG7afEy|CP0_qE<#u(8+Za zDNz6;vAZXQQq$FA(NVU(gkMY9hz&l_e~f1P84;d$ycn)abk*6Rom(I9Scp!60F_1) zP_?{tl+CZB(GgU{{(=4s47Lkr36#>)r+=r>A6o2}ugS5j@~JQpYTur#UW;H?@M`AE z6Z6lWey@h4NO&1G4+nY#gXvw=EK1aAu&3kwanfI1XcZGlwLGIxesZd(qt*gM{dk7; zJuc(Xc9SYW7#)rX`SSJq0tsI_a`6$hRfUOuF9zl`benOQ0 zapUd@{&!-!Be++yRaE?)rv7g9VWPT2+#7ZH6Z7lA`Zr^DPwxG=lg_;xe^J@}yS;}x zyLXfC?NR*|_8-;Vhaq~X75f{Vb$iDDH2Q~f>_hlNP1E1-m$xdLzu|u>oc`OQ?{qou z$K9f9Z!^*Wxkmq5i%Wod+XTQwgeUzA?04VhLzf@cGyf(4GW;U= zYuNtH={sT7`*F9!)Au`k2mVuL_3xfP6k5H*-tQXVw)6D%bo>STTXyxK`wvA1f3v*0 zeboPf<(K5(Lzah%OTStCZ@ZrUf#sL}(nFSqDhR(>IBs9V|G@G~6G2`Y_U?btZEC}T Nn!Sx$fy&*t{{!