From 24c9fa43cd5c981dc0dc4a73a5373ea8de1febd3 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Tue, 12 Oct 2021 15:08:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A0=B7=E5=BC=8F=E5=A1=AB?= =?UTF-8?q?=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/metadata/data/WriteCellData.java | 7 +++ .../com/alibaba/excel/util/StyleUtil.java | 54 ++++++++++++++++++ .../executor/ExcelWriteFillExecutor.java | 40 +++++++++---- .../easyexcel/test/demo/fill/FillData.java | 4 ++ .../easyexcel/test/demo/fill/FillTest.java | 43 +++++++------- src/test/resources/demo/fill/list.xlsx | Bin 10029 -> 10744 bytes 6 files changed, 116 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java b/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java index 60413385..cf60f58e 100644 --- a/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java +++ b/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java @@ -12,6 +12,7 @@ import com.alibaba.excel.write.metadata.style.WriteCellStyle; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.poi.ss.usermodel.CellStyle; /** * wirte cell data @@ -47,6 +48,12 @@ public class WriteCellData extends CellData { */ private WriteCellStyle writeCellStyle; + /** + * If originCellStyle is empty, one will be created. + * If both writeCellStyle and originCellStyle exist, copy from writeCellStyle to originCellStyle. + */ + private CellStyle originCellStyle; + public WriteCellData(String stringValue) { this(CellDataTypeEnum.STRING, stringValue); } diff --git a/src/main/java/com/alibaba/excel/util/StyleUtil.java b/src/main/java/com/alibaba/excel/util/StyleUtil.java index 70c7ac7a..023f789d 100644 --- a/src/main/java/com/alibaba/excel/util/StyleUtil.java +++ b/src/main/java/com/alibaba/excel/util/StyleUtil.java @@ -156,6 +156,60 @@ public class StyleUtil { return font; } + public static WriteCellStyle buildWritCellStyle(CellStyle cellStyle, Font font) { + WriteCellStyle writeCellStyle = new WriteCellStyle(); + if (cellStyle == null) { + return writeCellStyle; + } + writeCellStyle.setHidden(cellStyle.getHidden()); + writeCellStyle.setLocked(cellStyle.getLocked()); + writeCellStyle.setQuotePrefix(cellStyle.getQuotePrefixed()); + writeCellStyle.setHorizontalAlignment(cellStyle.getAlignment()); + writeCellStyle.setWrapped(cellStyle.getWrapText()); + writeCellStyle.setVerticalAlignment(cellStyle.getVerticalAlignment()); + writeCellStyle.setRotation(cellStyle.getRotation()); + writeCellStyle.setIndent(cellStyle.getIndention()); + writeCellStyle.setBorderLeft(cellStyle.getBorderLeft()); + writeCellStyle.setBorderRight(cellStyle.getBorderRight()); + writeCellStyle.setBorderTop(cellStyle.getBorderTop()); + writeCellStyle.setBorderBottom(cellStyle.getBorderBottom()); + writeCellStyle.setLeftBorderColor(cellStyle.getLeftBorderColor()); + writeCellStyle.setRightBorderColor(cellStyle.getRightBorderColor()); + writeCellStyle.setTopBorderColor(cellStyle.getTopBorderColor()); + writeCellStyle.setBottomBorderColor(cellStyle.getBottomBorderColor()); + writeCellStyle.setFillPatternType(cellStyle.getFillPattern()); + //writeCellStyle.setFillBackgroundColor(cellStyle.getFillBackgroundColor()); + //writeCellStyle.setFillForegroundColor(cellStyle.getFillForegroundColor()); + writeCellStyle.setShrinkToFit(cellStyle.getShrinkToFit()); + writeCellStyle.setDataFormatData(buildDataFormat(cellStyle.getDataFormat(), cellStyle.getDataFormatString())); + writeCellStyle.setWriteFont(buildFont(font)); + return writeCellStyle; + } + + public static DataFormatData buildDataFormat(short dataFormat, String dataFormatString) { + DataFormatData dataFormatData = new DataFormatData(); + dataFormatData.setIndex(dataFormat); + dataFormatData.setFormat(dataFormatString); + return dataFormatData; + } + + public static WriteFont buildFont(Font font) { + WriteFont writeFont = new WriteFont(); + if (font == null) { + return writeFont; + } + writeFont.setFontName(font.getFontName()); + writeFont.setFontHeightInPoints(font.getFontHeightInPoints()); + writeFont.setItalic(font.getItalic()); + writeFont.setStrikeout(font.getStrikeout()); + writeFont.setColor(font.getColor()); + writeFont.setTypeOffset(font.getTypeOffset()); + writeFont.setUnderline(font.getUnderline()); + writeFont.setCharset(font.getCharSet()); + writeFont.setBold(font.getBold()); + return writeFont; + } + public static RichTextString buildRichTextString(WriteWorkbookHolder writeWorkbookHolder, RichTextStringData richTextStringData) { if (richTextStringData == null) { diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java index e91e2834..cd20a2b9 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java @@ -7,7 +7,9 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.enums.CellDataTypeEnum; @@ -176,6 +178,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } } + AtomicInteger integer = new AtomicInteger(0); + private void doFill(List analysisCellList, Object oneRowData, FillConfig fillConfig, Integer relativeRowIndex) { if (CollectionUtils.isEmpty(analysisCellList) || oneRowData == null) { @@ -190,7 +194,6 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder(); Map fieldNameContentPropertyMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getFieldNameContentPropertyMap(); - for (AnalysisCell analysisCell : analysisCellList) { Cell cell = getOneCell(analysisCell, fillConfig); if (analysisCell.getOnlyOneVariable()) { @@ -202,6 +205,21 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { WriteCellData cellData = converterAndSet(writeSheetHolder, FieldUtils.getFieldClass(dataMap, variable), null, cell, value, fieldNameContentPropertyMap.get(variable), null, relativeRowIndex); + + // Restyle + if (fillConfig.getAutoStyle()) { + Optional.ofNullable(collectionFieldStyleCache.get(currentUniqueDataFlag)) + .map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell)) + .ifPresent(cellStyle -> { + cellData.setOriginCellStyle(cellStyle); + //WriteCellStyle writeCellStyle = StyleUtil.buildWritCellStyle(cellStyle, + // writeContext.writeWorkbookHolder().getWorkbook() + // .getFontAt(cellStyle.getFontIndexAsInt())); + //WriteCellStyle.merge(cellData.getWriteCellStyle(), writeCellStyle); + //cellData.setWriteCellStyle(writeCellStyle); + }); + } + WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE); } else { StringBuilder cellValueBuild = new StringBuilder(); @@ -235,6 +253,14 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } cellValueBuild.append(analysisCell.getPrepareDataList().get(index)); cell.setCellValue(cellValueBuild.toString()); + + // Restyle + if (fillConfig.getAutoStyle()) { + Optional.ofNullable(collectionFieldStyleCache.get(currentUniqueDataFlag)) + .map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell)) + .ifPresent(cell::setCellStyle); + } + WriteHandlerUtils.afterCellDispose(writeContext, cellDataList, cell, null, relativeRowIndex, Boolean.FALSE); } @@ -295,18 +321,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell); Cell cell = createCellIfNecessary(row, lastColumnIndex); - Map collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent( - currentUniqueDataFlag, key -> MapUtils.newHashMap()); - if (isOriginalCell) { + Map collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent( + currentUniqueDataFlag, key -> MapUtils.newHashMap()); collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); - } else { - if (fillConfig.getAutoStyle()) { - CellStyle cellStyle = collectionFieldStyleMap.get(analysisCell); - if (cellStyle != null) { - cell.setCellStyle(cellStyle); - } - } } return cell; } diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java index 8890b82f..589f838c 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java @@ -1,5 +1,7 @@ package com.alibaba.easyexcel.test.demo.fill; +import java.util.Date; + import lombok.Data; /** @@ -9,4 +11,6 @@ import lombok.Data; public class FillData { private String name; private double number; + private Date date; + } diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java index 309e410f..04e8b53a 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java @@ -69,27 +69,27 @@ public class FillTest { // 方案1 一下子全部放到内存里面 并填充 String fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; // 这里 会填充到第一个sheet, 然后文件流会自动关闭 - EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(data()); - - // 方案2 分多次 填充 会使用文件缓存(省内存) jdk8 - // since: 3.0.0-beta1 - fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; - EasyExcel.write(fileName) - .withTemplate(templateFileName) - .sheet() - .doFill(() -> { - // 分页查询数据 - return data(); - }); - - // 方案3 分多次 填充 会使用文件缓存(省内存) - fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; - ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); - WriteSheet writeSheet = EasyExcel.writerSheet().build(); - excelWriter.fill(data(), writeSheet); - excelWriter.fill(data(), writeSheet); - // 千万别忘记关闭流 - excelWriter.finish(); + EasyExcel.write(fileName).withTemplate(templateFileName).inMemory(Boolean.TRUE).sheet().doFill(data()); + + //// 方案2 分多次 填充 会使用文件缓存(省内存) jdk8 + //// since: 3.0.0-beta1 + //fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; + //EasyExcel.write(fileName) + // .withTemplate(templateFileName) + // .sheet() + // .doFill(() -> { + // // 分页查询数据 + // return data(); + // }); + // + //// 方案3 分多次 填充 会使用文件缓存(省内存) + //fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; + //ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); + //WriteSheet writeSheet = EasyExcel.writerSheet().build(); + //excelWriter.fill(data(), writeSheet); + //excelWriter.fill(data(), writeSheet); + //// 千万别忘记关闭流 + //excelWriter.finish(); } /** @@ -233,6 +233,7 @@ public class FillTest { list.add(fillData); fillData.setName("张三"); fillData.setNumber(5.2); + fillData.setDate(new Date()); } return list; } diff --git a/src/test/resources/demo/fill/list.xlsx b/src/test/resources/demo/fill/list.xlsx index 717cb498a406f09ac0751c7c8d7403936ac940ec..8e3ed67dd26ab212946ab9a5c5e9caaee8a0730c 100644 GIT binary patch literal 10744 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 literal 10029 zcmeHtWl){V(k|{AEI7d-xVuAe3+@oy7Vhru5Zv8@1$Tlc!GgO43GNPek({%$!`a`d z@BX}1cdA$~YrQQq-90^B^R&DaI0PKX(+HMb6L@<5d%yz!F$BDmw*%PN)5`irp|)lu?ef)3L4?=Bhc2 zK014^S`I=y`=ETw9BPwSTet#z@we`?JRHcr2t?r+nD*_&CvRWLf5=vGL9xQk7!TA? z;0Y?QF*0LG=knC`Cu1Z)iiRkMwFK?$1i-tRr?Z_ck9Y4RAp@{*34M*6);x{savK$O zaPaY(<7Q?xgcC#CQ?z}|`$rOCDQklY5l!uUb6i7C`_mVx0_xeeBH_f;!_KW}@VT^I z^NIL%vX++#__K7FQ12b42fgY(e91|7@TGL}w-Q_n>7!fimWOmv{;Hg<>qFtW67_18 zJbf1fB=W{XbNnmLqZQfsL+L>V@iH>;@%`HktUnEXHnt_I2sE@L(9o!VH}pGzozat} z17iiHdKg{?9r``yY%Gy$+gcXv3m8#A`=Rw}inm+!vLQ;;%`3OMoK&iIrEM>EFb6+& z*X{lg>3Zjq#pBvRKc<&y@|Be`1Cv;+{Y?zG9|jM`#LJARU~6Q~Ir%O#6_}7QFcuur z7H-t|SFh3W%7pxws7(7)1CUZ8#y-EqHYlG(uq)-2g29!AOMLq-+B}TR=)D76qp&#E zmL6qM(3<4-&{PNxnMsABPDweYP0%ZUynwNpOOLxRIPy&or$QN)v99Kr<6pmhTXeFo zN78hwoWP_R9)IoM9JGJ9emXWL!CRUZX0D1LueeWv)Ecr zVEz8XWftHN^+857eUewW&Z*XBi&0DdZ@~ z{D7i@0Z@8pau%AX(${7!?nk>W7W1vm`@!o3@=pg$hW8jh01fXAbOPER4sf)009gGD z_81wdPYmdymwu1047121l_(1K_2yF|;UW8H-?L=EvJjG*eGGYAOc=90Jh3GVwg*(- z%abGro{n$7D1`MDFtv6okt6fq-W!7gBjj3i&Kt`O2tTsXTwFq@|Ejj?hfW|8a6!fs ztY;s=%MU+!P1?sr?r&QPf9ybE86;>ohQmjd16~-g@Q&|V54}beul4AJ^A2kkw|(w< zUB6nPf!b>Y{-sikCoKPbx!HV#VaS1+zhc}}$YM3L2wT8tDx3R7w3YRfRZ(ghGi02K@jlxV!flSE@PGM?aj@D{r8l%=ORt z0~}~B7t5cS@4g}jf@e zKnXg8yg`CEL?tWIL>LxaBQo{Hgh{0{NySkY5sxM7R~aulj0r=>8hnM7mj0^a+9XG1 z>vF0JJfK)x_q3Ff(_g1a?6M{G@y^!sB(yf929R&d`|S>tm|wTUvld6IF&rO+iTJE~ z6F*lM4pkXirLWs{dvKyzk8GT6Pvi{LFrHqW1k>nRP_4wB??uuoE5dZWMpxoncX-~Y z7!Wbyo#>1U+uTL=4{NM~NC~_7TjFbz+bOP-EhabRDqW(}207^%d39UrnW43hCv`ut zw*w8-u@5dD0y;C}=FRhtUlnn~f_bbV^vEOdVU~I;*(zoK$OBo}BjIuiy=1nO$)$`mt5Zre+JRg9YK(^ozVTpvyiloZ%fDZposF11p)K??{ z?i`d&Px=e{p;_3&#>={V5Q8Y2*34Y(t(+#Gluj|rUicxa8pM4!e)C+~Dt(s70>e>TMlpI1M7 zZ)h!{c8W8dO=;#+8{~rfW6bS6m-&6)LQ$PEsLZH0qlaz? z|J?8!9vAt|z|C$34B!7D=$L*6UHtG<(1~6`-XKFYKguPDY9( zlwnYRP$A)LS4tsvy<6L`z%>N=5-GTMKW}Ug)I;7>s(r}rYvh6iZdx}Is={`(F4q_tF2g#P z_gjPku|p>*HtV`Qo%PDBmem9ZYN@XX>hg>E&xQg6FJ@Z9rd>G2K7?nYh0ZtGZ&WO0 z?J$>KysRoH7b7t?+oGE`xQ~{5o8|k!Oha<7Z-a%pm)q1f9+nxmD2g%)Z-Uov>F}y- zzcwr$w4xGn)EFkf__f4IsW`jMmZ&ldwXAKk+hz{!brD8%@3)5%Jp>BIv;+5Omt-8> z)VM7)7?y7n8z~W4&@(<$q21kwXxSVu%GStqwp;36IcKtt4hc>`ozqXs>z=UcnlIbj zA(ZY?Rc;$OIVy2thlOSAt(2W*)cBg2uIsuweM!lZ%TFFH_<>>Kp3f0Zw!1DVq?O3i zvQaLYPv*M01dbTRxzo8^#(xYcqP(rF)m~>$=Da;9B^qChT`!f89JWqU@&NXK?QiD) z@9+QD{r%4e&{KsAJfR#+jjW8GRk&9VcqoxjARx)Ozs~)?$bJ(4Ja+cgmjSq}c;0W; zysHj8Eyl^U-_mBJvZ(9ts<6(E5@dwiZ}mF!&C0g4%FM5ml713!7Zhqe^6`;KgLtu? zmGjON!R!%Cci#EEy?xHUim#8Tvb~A--TnRjjm6el0XM4ft%&&0dZ8+>?lDTJCttqp z=$Z9d%hnVRDMnOq@^Lat8&&L5LFDCfOUSgcII*9eC(X3&1bm|8)cd4-rbKq7_DJ?W|T*uqmeV?b_F%f==wPBlzpf%ZG1QiS=n3s4`(N3Z#ot{LA;m5`to{w z6w31nj#9SGkUpuKR`u8_lWZu}rwH68v-0Y(Z$Nw6y>SiEFVV~0QU2VoIoH@2Fg+nE zO{=D1@M~akDPZJMjz{&_Er!F)^_c$G%RWt zbsUeN43Ep~uMPtH%)j*F$`6?GWC~jZJGD@q<1wvSwxG8|9etF9%gQ0bIoTek5#vz_ zH=ylqXxau70LNBg5i?JXLA`jDJkNmx6UGYODr=+PhjeXcEq*FAj>V!NbJznRZ18!z z&Ff-+*FI~F zwjr0$;757qt5LdFiwZg5t!%yJ2-C!s$JTI^1V)|1@$*sTZSvCSw5uLu5qK*|Tjjl? zC7_k2I*{;}6t?nTwWPxuc_S`|T^eln8ta)QvdxVJcV^o0U%dIO9rP{``~_Oz86F{; zV(ucXB!0_*yspjQ8@R>X;y|+!i5rI%h;hp?w#ZKU38sv$$tWu)>s(9|BMm^TCl)NM zuX^Z_XEz?RP9Iue9#fnrUUhEQ2Lp^G*x59=j*wk($V?=d^3S-I>J9N4)KEKUvbH4 z0Vu9D-d+jW_(MgB*Mf{OqbaNn4+n4`&!^R(k{1pMNH|kFimZ1~&qoL?*5fTD?iV(| zrm3l)SQ1iAh1)!Kzi11jIHvP0PhQSlQr>pPn7bWO-4<=~xNvk;3Coe(4f=F3S9ltQ z$+ko?q$VeW-9#;ONUINy~Mwb7)?Cw0(!m{)Ts&zvcv1dMM`HkW$B@;Sn6Je zhpdv^OSDEmHEeU_D;o(KhVhi~vqt$>!PE%>-wxqS@uc^COnqPLBnM^tm6@N?4zxei zbDEeX*9FDr&*g!>K))ctfD>}cp-I{14pL)XY@v}zdclOMjG{`evIja#QU1YVrF3bY z7hR}0%{(p%)Sny2`@lU_&|iR^v)99(TD|>p4)3akn=tKjc7kTGjBxxcKNceZ*|?=t z8<1q;4p2blWwfX@S62b4?N%8TpLjqN<@l~*@p>w~Z}?oA<7ln5k0F^|1Xhdm)jjeB zKedOL^vhkuk0Y1a^~6{ALTLU~zQuedxXAhN`S^GO>xR%)3}%W`b!NNy6-ic8CJQ^8 z9?>r~rJP=PXN}Le+Hcm_+a1$HW@yY*f5g``H9y)LLl4YRaEf7!V&qT8@cz8!Kfkg~ zdo`=qolsYYXu2-q3}8^RAFyn%1P+5)6DUSAa=RKoz1+WEO&QoTQ}FnvqB|)pa)pRJhrg7OvbP)`*{G zX$sL|ly!$6jp{`17VF}`Wn*#hO{gqQSeS1}{?*cL>m}diL6q~izR4b6ibcEb0mQrd z^2*mW8&`|jTQ}}j*Zu6}ACqWAtM@N0>5nq%JvKy6CchkdnUI7<^K9L;uYY<`e3Vz; zO4tvrYW}gfc+6;LnOWF)F{0)4dv^A_)lQsG zvELAbycUuo_u>*fPV)$~z8O-DO~JZ>d@nq^&qDOS`uOO1%fQ)4qkYp=AT=bj!`h|F zubp;mMBI_&p?6KVl(3-@77nS84qjdPxi9vX7yA2;$yvQ`W(<}vbW-Ib?dB&N^@n3`*vP}^QF*6^-mh50QZwh|>6WTP5l>mKj>#xF2( zUGJY3T^?)SI=uwFeId9gFwJl|kO4l8EaXs~G?Q#0A;>=RG2qaRjJubI+SCNg^}ck> z9b1zt4D&sehmrN&H`PI<#)kPM+TlG)d2Y-MI)l&6Qwu6|3AjD!>8Sp+HkFP!P@)j8 z`W&PhQn7G`c*K~X9LvfV)KP|OgkTet=%>_lC?(8VSD^aUEpiZOYh3N8l50B3Rf0nd z5__d;CyI4xlow`M3(Ru(6DFDB8*weli&bACC}q&b2A#UE+jC@)>Oby?)r8;vVzEdrdwVPwq(k zvT|ADvHQ*0u*QUhBo&03?gn)BRVphDmtiA13Fdbl3*B;i>?M!G^}5z~wNU_*VH&fT zUZov7PhRc;s%gH^^N(CNuZ!LoyWEF4Ldr4eYqa17@Twie4oHT>G7oKxZw76hy-Q{e zI#}YniSP$!@kdzWc-bj9^6?UE`C_FiNisjngiL=7W-55jt~GkvxsgI*5FPzn(cDCu zdza0$JxJ`z1w_BAz9CXRIh5=OJ`$$6!BBX4V7I;YT{=W=un^aBB04jcaIUqKuy;rR zE4oMAN52;wJse$-kPuC&;6I2x@{udTZU)5BPh(Ljw@FBBQTcMW4hPqda`~8E^m-UV zz&*V@M-8DY#ii;vN!4aEXB>4{G{upeD7J_Um=U!q68nT0Z7VjaxH*&_d8~yhn6NeU z`6MwxlX6MB|Fkl%`zGE?r3+E18~OG#4r}>pUaxGOaTL<3AQ`9hkfU8qlfL^wCclk` znvi4n%ziH93|%_cVCjy&x1?3g1E1UnLqa^4H<&a1Q}N6`0weV{$RZ;j3OKe48oG&` zni-ekeN;k6;1feZ=2!%XLFC@dz>tbB;~_a^jCQx6Q~KC3c5id`7I%+xL&6Hv;t4Pg zKtg=&oX1rm?uS~st9l{d>!7sCB*U8iS=_P717fbgBcKOPpXI18L3x;yn3_ru2TzqU z6M<2gd}oWOP}#{Wn3%7_zD$DxVxlntR5^-P7}`Oc1HKKdfaVODc?f-ZpFZ2$0EMYS zGVn?<#AXB`M6)1@Ps#WSv@y(&rcJrpR$xP@9wo{fY!1G>u4647 zOBsPYRaE3s|CkDmDh;hVBBgwDP_x%@X5>*^h7GBsOy(1a8-7oO)!rl_PSSu8B%NK&RGRR{`}n^Ky!zvk}I2P>%*svnCePn|U; zE>W&`WF}J0nN@NQkx657;F+Y@p#DZ^g;5h3v^*)t&aPRa*zpCyw{D0H4|9Xsf!$P3 zT}HMhR*S6xX(Cw-dvYZBNcx z;(a7-WVSGJHvN&ly3UQ|XfZjjYX4+GqoZNI38vH&UNadS&(re_Lgzk0{AdDx zj{CcbK|p&#wkP>P4x2#Y_FzlkjtUf*c?kq{nGzU)F%62V z*?H@F!aYy-@yA&_GB%b%MPA(1_cSw!ca`DAyE&2$t@|z-!`o%?=(Im%clJ{mDrpv! zkRq!}@Vr1B<|NVce|~o5|Cv+{--k9^);gk7OGte|=Iusv z4CeYslpOzK9>g~iA)drI)uY1u44#MK?Mp%dVQlZ42I-h08`Bmq+P znwW9Y8Wh;dH8@&$;TM%#e@61#WaZ4z(iimIPb|rdT)tmZ5$QT#G?EO+s=UgEHp1xaWAXJ{aFJ)_;n!~|5RkFv z0m`VYGLp;|TaoQksT&N#Cxih{4F@XWw1DYJ)$}R>z7MK`gq24*lSHFr6(>lnGI}hIBCc8}Fb{x4kTrVBH+)2+Wur#O* zXln3#S!OzXcI9}c^Jd(NJNS4PwUq@VYn;Jh{=}VIQ^wxCe|$<~NX6pIXvR&d`tqDk z8E!_!zSXc2OTnpqvB`E(dnI0JUrN?3PU9j&h@V&MQsA_xpV#s}mx=e$aCyp(oR@Fh z>sV;#z)$L64_s|iNh$FVe3CkddK8cED9jZu-WsMoLjPG3iq%G~cL7VmJK*0FkO#cb zus7AWGctVZU}t7+^0P9uiV~Cr7X;pE`Z=4LAD)Q_q3j&cfN}Z~WM@z@BTh`lSK=^2 zM5Dk!45HS+xs)8^MTHQ>eRq#WUjD56u1tr)UffV$F(EsqR0&!`-Ni#~X~EavSm~Ax zRbz&zXF*#R+gM>eX-0@-e9_{Ivj3QUELVOtPZ3^QM6zmXOGNu7l!8GSVA!rO4;i9V zk~cJvsyMT|xxbg5yQd4=wr7W7&si*-`DXrZX5=z@)#DD(0C^n(z;YnWVt9mg^Ehk= z`E$vz4}yXMz^hzNAclbaYspVog8=|w@$*J6RvQSNp#x!qN8y1ssp$%){yE>`MqKRT zQ!ch53$=D}Cho_!A}XhD>(-%b7gv{&w8@)%jB7B$d{(jyStiNOZz|%o^gFln6JPw| zP?}J+)WON_g9N50&nHW3ACAoSeTg~);_4Zj$=>By3!XAmBOzGh?6OAB-0;GG1;@&P z4AH3O8MaQ@93S0rby~hv%^!gdQ8O+jZFfBv%-s9w*4baI>Ov|sa5=D&h_0QH<#RyC zox`d15%_Ky=n(k7Xy~3OE8<2ZKQW;69Rd;K&2|}Q4AfZ%dg479LrBmuWv^e$s z_BKHUns3d}(J9xPY0DmlEx3zBI*f%;t$vOQegc32r*?%S4;QsXKk@RmNpM#sn{J4f zA14O40sfmj33GI$vDzMrqfEivRPknGJ4*5bS=_9mMV$QaNc`E_tmUnTPQ?1M2;^mW zdY7m}+*_b*IRaa+0f5rouPeMMdBP*iuQ!xpGaM~rFe3at@@6_v&PAc1I7jRp`Gyaj zC4ae9r>DQ7a3?s|_axE}1vDMubJEmDTEY1}`mb?2%%GCd9 zBgvJIRae~ZgtpB2f41en?kNAsoJ3a#*tbA4egi@kIKU@xOaCJKdzAmQZd?4YdCwDA z5%}Pr>`6OsCJY-}OBHB2e+C}F>xH7pl)BU7z1$Vv7_?$7&E}UPc$qmSdfOv6T}qGe z&BcT$)IfgQPM4*U>B!d2(*;V@Qd?j1aJ170B6#n?`Z1`&s7b_eBK`%&8z}QluOim( ztWHV9%X#qhaUBkg8W8h|q17Y`BC4R+PQ2ntrwvCnS(Bg;6E2xZvbfKvjRHNUofrzLpWtoWZl-A+8r0F7xc#+5& zQ;k7{i}>LKRD2@1bn%>CUl_^)_!cGnDA?QG&QWRWHca0juc3?>W=6=RL#M;WI&vS_ z40(&H)fHGf#t%X#t@+Cq6a>_UgX?bkUxt!xDya)#HWKI~=JFia0urd#acCri*$w@V z{R7-KojVH;B6E)m{0wP4Trg5CZH&IpXa=Vv6!a@2&D6Q-ND@Uh6~ZVMYpP^(MUi#| zzwqKAG?LoQ;q*vT&|XaD=+|?!-_+@08cK)NRl$Q_6>Ni+qj;e?G3JT_2k(7`I{P+i- z{Sxp$CnF#ya6EOYa1s1YO@AtVo}8XIeks-Yi|6NN`ftjfcI&V4r0i+@t%K%Ieb0Mn zo``?xqxd`9zdCB3o9KCC$Zzf#V0izf^xthF&)J{1HT-5r1tycm{I^9v0sX(m z)1n1{Xgx3!{Wpd`trSG~x777~qR(^Olb&Bzs`xwGe`LJpa-NqzzvavU5uSf4hMr4! zey8?ZLO-xG=Sjj}H*Ej=wXXqV7RdT<1nSQSd5%H-)(8tcJ^y0+jYvJ8^78`dw}3Br zKLz~VZ2xW2Pn{aS#*>Hje|h+c`LDi>KWF~DbK{Bkm)9cygZFnI$MfkwhvI)r0fYW) q`v022&&N+-{(mp!1m+*5{Dgbur68ZG7~mm+1`-dPa{%$vxBmmzSzi$V