From 1c77e9aaad1554280f9620de799bd20ab29de6ea Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Wed, 25 Nov 2009 11:40:36 +0100 Subject: [PATCH 01/14] Work in progress on delombok. --- .classpath | 1 + src/delombok/lombok/delombok/Comment.java | 36 + .../delombok/PrettyCommentsPrinter.java | 1355 +++++++++++++++++ .../lombok/delombok/PrettyPrinter.java | 199 +++ 4 files changed, 1591 insertions(+) create mode 100644 src/delombok/lombok/delombok/Comment.java create mode 100644 src/delombok/lombok/delombok/PrettyCommentsPrinter.java create mode 100644 src/delombok/lombok/delombok/PrettyPrinter.java diff --git a/.classpath b/.classpath index b59d0baa..8da629d1 100644 --- a/.classpath +++ b/.classpath @@ -3,6 +3,7 @@ + diff --git a/src/delombok/lombok/delombok/Comment.java b/src/delombok/lombok/delombok/Comment.java new file mode 100644 index 00000000..6f6910b4 --- /dev/null +++ b/src/delombok/lombok/delombok/Comment.java @@ -0,0 +1,36 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.delombok; + +class Comment { + final int pos; + final String content; + + Comment(int pos, String content) { + this.pos = pos; + this.content = content; + } + + public String summary() { + return String.format("%d: %s", pos, content); + } +} diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java new file mode 100644 index 00000000..68e503a7 --- /dev/null +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -0,0 +1,1355 @@ +/* + * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package lombok.delombok; + +import static com.sun.tools.javac.code.Flags.ANNOTATION; +import static com.sun.tools.javac.code.Flags.ENUM; +import static com.sun.tools.javac.code.Flags.INTERFACE; +import static com.sun.tools.javac.code.Flags.SYNTHETIC; +import static com.sun.tools.javac.code.Flags.StandardFlags; +import static com.sun.tools.javac.code.Flags.VARARGS; + +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + +import com.sun.source.tree.Tree; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeInfo; +import com.sun.tools.javac.tree.TreeScanner; +import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCArrayAccess; +import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; +import com.sun.tools.javac.tree.JCTree.JCAssert; +import com.sun.tools.javac.tree.JCTree.JCAssign; +import com.sun.tools.javac.tree.JCTree.JCAssignOp; +import com.sun.tools.javac.tree.JCTree.JCBinary; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCBreak; +import com.sun.tools.javac.tree.JCTree.JCCase; +import com.sun.tools.javac.tree.JCTree.JCCatch; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCConditional; +import com.sun.tools.javac.tree.JCTree.JCContinue; +import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop; +import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop; +import com.sun.tools.javac.tree.JCTree.JCErroneous; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; +import com.sun.tools.javac.tree.JCTree.JCForLoop; +import com.sun.tools.javac.tree.JCTree.JCIdent; +import com.sun.tools.javac.tree.JCTree.JCIf; +import com.sun.tools.javac.tree.JCTree.JCImport; +import com.sun.tools.javac.tree.JCTree.JCInstanceOf; +import com.sun.tools.javac.tree.JCTree.JCLabeledStatement; +import com.sun.tools.javac.tree.JCTree.JCLiteral; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; +import com.sun.tools.javac.tree.JCTree.JCModifiers; +import com.sun.tools.javac.tree.JCTree.JCNewArray; +import com.sun.tools.javac.tree.JCTree.JCNewClass; +import com.sun.tools.javac.tree.JCTree.JCParens; +import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; +import com.sun.tools.javac.tree.JCTree.JCReturn; +import com.sun.tools.javac.tree.JCTree.JCSkip; +import com.sun.tools.javac.tree.JCTree.JCStatement; +import com.sun.tools.javac.tree.JCTree.JCSwitch; +import com.sun.tools.javac.tree.JCTree.JCSynchronized; +import com.sun.tools.javac.tree.JCTree.JCThrow; +import com.sun.tools.javac.tree.JCTree.JCTry; +import com.sun.tools.javac.tree.JCTree.JCTypeApply; +import com.sun.tools.javac.tree.JCTree.JCTypeCast; +import com.sun.tools.javac.tree.JCTree.JCTypeParameter; +import com.sun.tools.javac.tree.JCTree.JCUnary; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.JCTree.JCWhileLoop; +import com.sun.tools.javac.tree.JCTree.JCWildcard; +import com.sun.tools.javac.tree.JCTree.LetExpr; +import com.sun.tools.javac.tree.JCTree.TypeBoundKind; +import com.sun.tools.javac.util.Convert; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Name; + +/** Prints out a tree as an indented Java source program. + * + *

This is NOT part of any API supported by Sun Microsystems. If + * you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class PrettyCommentsPrinter extends JCTree.Visitor { + + private static final Method GET_TAG_METHOD; + private static final Field TAG_FIELD; + static { + Method m = null; + Field f = null; + try { + m = JCTree.class.getDeclaredMethod("getTag"); + System.out.println("Using getTag method"); + } + catch (NoSuchMethodException e) { + try { + f = JCTree.class.getDeclaredField("tag"); + System.out.println("Using tag field"); + } + catch (NoSuchFieldException e1) { + e1.printStackTrace(); + } + } + GET_TAG_METHOD = m; + TAG_FIELD = f; + } + + static int getTag(JCTree tree) { + if (GET_TAG_METHOD != null) { + try { + return (Integer)GET_TAG_METHOD.invoke(tree); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e.getCause()); + } + } + try { + return TAG_FIELD.getInt(tree); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + + private List comments; + private final JCCompilationUnit cu; + private boolean newLine = true; + + public PrettyCommentsPrinter(Writer out, List comments, JCCompilationUnit cu) { + this.out = out; + this.comments = comments; + this.cu = cu; + } + + private int endPos(JCTree tree) { + return tree.getEndPosition(cu.endPositions); + } + + private void consumeComments(int till) throws IOException { + boolean shouldIndent = !newLine; + while (comments.nonEmpty() && comments.head.pos < till) { + if (newLine) { + align(); + } + print(comments.head.content); + println(); + comments = comments.tail; + } + if (newLine && shouldIndent) { + align(); + } + } + + /** The output stream on which trees are printed. + */ + Writer out; + + /** Indentation width (can be reassigned from outside). + */ + public int width = 4; + + /** The current left margin. + */ + int lmargin = 0; + + /** The enclosing class name. + */ + Name enclClassName; + + /** A hashtable mapping trees to their documentation comments + * (can be null) + */ + Map docComments = null; + + /** Align code to be indented to left margin. + */ + void align() throws IOException { + newLine = false; + for (int i = 0; i < lmargin; i++) out.write(" "); + } + + /** Increase left margin by indentation width. + */ + void indent() { + lmargin = lmargin + width; + } + + /** Decrease left margin by indentation width. + */ + void undent() { + lmargin = lmargin - width; + } + + /** Enter a new precedence level. Emit a `(' if new precedence level + * is less than precedence level so far. + * @param contextPrec The precedence level in force so far. + * @param ownPrec The new precedence level. + */ + void open(int contextPrec, int ownPrec) throws IOException { + if (ownPrec < contextPrec) out.write("("); + } + + /** Leave precedence level. Emit a `(' if inner precedence level + * is less than precedence level we revert to. + * @param contextPrec The precedence level we revert to. + * @param ownPrec The inner precedence level. + */ + void close(int contextPrec, int ownPrec) throws IOException { + if (ownPrec < contextPrec) out.write(")"); + } + + /** Print string, replacing all non-ascii character with unicode escapes. + */ + public void print(Object s) throws IOException { + newLine = false; + out.write(Convert.escapeUnicode(s.toString())); + } + + /** Print new line. + */ + public void println() throws IOException { + newLine = true; + out.write(lineSep); + } + + String lineSep = System.getProperty("line.separator"); + + /************************************************************************** + * Traversal methods + *************************************************************************/ + + /** Exception to propogate IOException through visitXXX methods */ + private static class UncheckedIOException extends Error { + static final long serialVersionUID = -4032692679158424751L; + UncheckedIOException(IOException e) { + super(e.getMessage(), e); + } + } + + /** Visitor argument: the current precedence level. + */ + int prec; + + /** Visitor method: print expression tree. + * @param prec The current precedence level. + */ + public void printExpr(JCTree tree, int prec) throws IOException { + + int prevPrec = this.prec; + try { + this.prec = prec; + if (tree == null) print("/*missing*/"); + else { + consumeComments(tree.pos); + tree.accept(this); + consumeComments(endPos(tree)); + } + } catch (UncheckedIOException ex) { + IOException e = new IOException(ex.getMessage()); + e.initCause(ex); + throw e; + } finally { + this.prec = prevPrec; + } + } + + /** Derived visitor method: print expression tree at minimum precedence level + * for expression. + */ + public void printExpr(JCTree tree) throws IOException { + printExpr(tree, TreeInfo.noPrec); + } + + /** Derived visitor method: print statement tree. + */ + public void printStat(JCTree tree) throws IOException { + printExpr(tree, TreeInfo.notExpression); + } + + /** Derived visitor method: print list of expression trees, separated by given string. + * @param sep the separator string + */ + public void printExprs(List trees, String sep) throws IOException { + if (trees.nonEmpty()) { + printExpr(trees.head); + for (List l = trees.tail; l.nonEmpty(); l = l.tail) { + print(sep); + printExpr(l.head); + } + } + } + + /** Derived visitor method: print list of expression trees, separated by commas. + */ + public void printExprs(List trees) throws IOException { + printExprs(trees, ", "); + } + + /** Derived visitor method: print list of statements, each on a separate line. + */ + public void printStats(List trees) throws IOException { + for (List l = trees; l.nonEmpty(); l = l.tail) { + align(); + printStat(l.head); + println(); + } + } + + /** Print a set of modifiers. + */ + public void printFlags(long flags) throws IOException { + if ((flags & SYNTHETIC) != 0) print("/*synthetic*/ "); + print(TreeInfo.flagNames(flags)); + if ((flags & StandardFlags) != 0) print(" "); + if ((flags & ANNOTATION) != 0) print("@"); + } + + public void printAnnotations(List trees) throws IOException { + for (List l = trees; l.nonEmpty(); l = l.tail) { + printStat(l.head); + println(); + align(); + } + } + + /** Print documentation comment, if it exists + * @param tree The tree for which a documentation comment should be printed. + */ + public void printDocComment(JCTree tree) throws IOException { + if (docComments != null) { + String dc = docComments.get(tree); + if (dc != null) { + print("/**"); println(); + int pos = 0; + int endpos = lineEndPos(dc, pos); + while (pos < dc.length()) { + align(); + print(" *"); + if (pos < dc.length() && dc.charAt(pos) > ' ') print(" "); + print(dc.substring(pos, endpos)); println(); + pos = endpos + 1; + endpos = lineEndPos(dc, pos); + } + align(); print(" */"); println(); + align(); + } + } + } +//where + static int lineEndPos(String s, int start) { + int pos = s.indexOf('\n', start); + if (pos < 0) pos = s.length(); + return pos; + } + + /** If type parameter list is non-empty, print it enclosed in "<...>" brackets. + */ + public void printTypeParameters(List trees) throws IOException { + if (trees.nonEmpty()) { + print("<"); + printExprs(trees); + print(">"); + } + } + + /** Print a block. + */ + public void printBlock(List stats, JCTree container) throws IOException { + print("{"); + println(); + indent(); + printStats(stats); + consumeComments(endPos(container)); + undent(); + align(); + print("}"); + } + + /** Print a block. + */ + public void printEnumBody(List stats) throws IOException { + print("{"); + println(); + indent(); + boolean first = true; + for (List l = stats; l.nonEmpty(); l = l.tail) { + if (isEnumerator(l.head)) { + if (!first) { + print(","); + println(); + } + align(); + printStat(l.head); + first = false; + } + } + print(";"); + println(); + for (List l = stats; l.nonEmpty(); l = l.tail) { + if (!isEnumerator(l.head)) { + align(); + printStat(l.head); + println(); + } + } + undent(); + align(); + print("}"); + } + + /** Is the given tree an enumerator definition? */ + boolean isEnumerator(JCTree t) { + return getTag(t) == JCTree.VARDEF && (((JCVariableDecl) t).mods.flags & ENUM) != 0; + } + + /** Print unit consisting of package clause and import statements in toplevel, + * followed by class definition. if class definition == null, + * print all definitions in toplevel. + * @param tree The toplevel tree + * @param cdef The class definition, which is assumed to be part of the + * toplevel tree. + */ + public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException { + docComments = tree.docComments; + printDocComment(tree); + if (tree.pid != null) { + print("package "); + printExpr(tree.pid); + print(";"); + println(); + } + boolean firstImport = true; + for (List l = tree.defs; + l.nonEmpty() && (cdef == null || getTag(l.head) == JCTree.IMPORT); + l = l.tail) { + if (getTag(l.head) == JCTree.IMPORT) { + JCImport imp = (JCImport)l.head; + Name name = TreeInfo.name(imp.qualid); + if (name == name.table.asterisk || + cdef == null || + isUsed(TreeInfo.symbol(imp.qualid), cdef)) { + if (firstImport) { + firstImport = false; + println(); + } + printStat(imp); + } + } else { + printStat(l.head); + } + } + if (cdef != null) { + printStat(cdef); + println(); + } + } + // where + boolean isUsed(final Symbol t, JCTree cdef) { + class UsedVisitor extends TreeScanner { + public void scan(JCTree tree) { + if (tree!=null && !result) tree.accept(this); + } + boolean result = false; + public void visitIdent(JCIdent tree) { + if (tree.sym == t) result = true; + } + } + UsedVisitor v = new UsedVisitor(); + v.scan(cdef); + return v.result; + } + + /************************************************************************** + * Visitor methods + *************************************************************************/ + + public void visitTopLevel(JCCompilationUnit tree) { + try { + printUnit(tree, null); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitImport(JCImport tree) { + try { + print("import "); + if (tree.staticImport) print("static "); + printExpr(tree.qualid); + print(";"); + println(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitClassDef(JCClassDecl tree) { + try { + consumeComments(tree.pos); + println(); align(); + printDocComment(tree); + printAnnotations(tree.mods.annotations); + printFlags(tree.mods.flags & ~INTERFACE); + Name enclClassNamePrev = enclClassName; + enclClassName = tree.name; + if ((tree.mods.flags & INTERFACE) != 0) { + print("interface " + tree.name); + printTypeParameters(tree.typarams); + if (tree.implementing.nonEmpty()) { + print(" extends "); + printExprs(tree.implementing); + } + } else { + if ((tree.mods.flags & ENUM) != 0) + print("enum " + tree.name); + else + print("class " + tree.name); + printTypeParameters(tree.typarams); + if (tree.extending != null) { + print(" extends "); + printExpr(tree.extending); + } + if (tree.implementing.nonEmpty()) { + print(" implements "); + printExprs(tree.implementing); + } + } + print(" "); + if ((tree.mods.flags & ENUM) != 0) { + printEnumBody(tree.defs); + } else { + printBlock(tree.defs, tree); + } + enclClassName = enclClassNamePrev; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitMethodDef(JCMethodDecl tree) { + try { + // when producing source output, omit anonymous constructors + if (tree.name == tree.name.table.init && + enclClassName == null) return; + println(); align(); + printDocComment(tree); + printExpr(tree.mods); + printTypeParameters(tree.typarams); + if (tree.name == tree.name.table.init) { + print(enclClassName != null ? enclClassName : tree.name); + } else { + printExpr(tree.restype); + print(" " + tree.name); + } + print("("); + printExprs(tree.params); + print(")"); + if (tree.thrown.nonEmpty()) { + print(" throws "); + printExprs(tree.thrown); + } + if (tree.body != null) { + print(" "); + printStat(tree.body); + } else { + print(";"); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitVarDef(JCVariableDecl tree) { + try { + if (docComments != null && docComments.get(tree) != null) { + println(); align(); + } + printDocComment(tree); + if ((tree.mods.flags & ENUM) != 0) { + print("/*public static final*/ "); + print(tree.name); + if (tree.init != null) { + print(" /* = "); + printExpr(tree.init); + print(" */"); + } + } else { + printExpr(tree.mods); + if ((tree.mods.flags & VARARGS) != 0) { + printExpr(((JCArrayTypeTree) tree.vartype).elemtype); + print("... " + tree.name); + } else { + printExpr(tree.vartype); + print(" " + tree.name); + } + if (tree.init != null) { + print(" = "); + printExpr(tree.init); + } + if (prec == TreeInfo.notExpression) print(";"); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitSkip(JCSkip tree) { + try { + print(";"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitBlock(JCBlock tree) { + try { + consumeComments(tree.pos); + printFlags(tree.flags); + printBlock(tree.stats, tree); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitDoLoop(JCDoWhileLoop tree) { + try { + print("do "); + printStat(tree.body); + align(); + print(" while "); + if (getTag(tree.cond) == JCTree.PARENS) { + printExpr(tree.cond); + } else { + print("("); + printExpr(tree.cond); + print(")"); + } + print(";"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitWhileLoop(JCWhileLoop tree) { + try { + print("while "); + if (getTag(tree.cond) == JCTree.PARENS) { + printExpr(tree.cond); + } else { + print("("); + printExpr(tree.cond); + print(")"); + } + print(" "); + printStat(tree.body); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitForLoop(JCForLoop tree) { + try { + print("for ("); + if (tree.init.nonEmpty()) { + if (getTag(tree.init.head) == JCTree.VARDEF) { + printExpr(tree.init.head); + for (List l = tree.init.tail; l.nonEmpty(); l = l.tail) { + JCVariableDecl vdef = (JCVariableDecl)l.head; + print(", " + vdef.name + " = "); + printExpr(vdef.init); + } + } else { + printExprs(tree.init); + } + } + print("; "); + if (tree.cond != null) printExpr(tree.cond); + print("; "); + printExprs(tree.step); + print(") "); + printStat(tree.body); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitForeachLoop(JCEnhancedForLoop tree) { + try { + print("for ("); + printExpr(tree.var); + print(" : "); + printExpr(tree.expr); + print(") "); + printStat(tree.body); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitLabelled(JCLabeledStatement tree) { + try { + print(tree.label + ": "); + printStat(tree.body); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitSwitch(JCSwitch tree) { + try { + print("switch "); + if (getTag(tree.selector) == JCTree.PARENS) { + printExpr(tree.selector); + } else { + print("("); + printExpr(tree.selector); + print(")"); + } + print(" {"); + println(); + printStats(tree.cases); + align(); + print("}"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitCase(JCCase tree) { + try { + if (tree.pat == null) { + print("default"); + } else { + print("case "); + printExpr(tree.pat); + } + print(": "); + println(); + indent(); + printStats(tree.stats); + undent(); + align(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitSynchronized(JCSynchronized tree) { + try { + print("synchronized "); + if (getTag(tree.lock) == JCTree.PARENS) { + printExpr(tree.lock); + } else { + print("("); + printExpr(tree.lock); + print(")"); + } + print(" "); + printStat(tree.body); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitTry(JCTry tree) { + try { + print("try "); + printStat(tree.body); + for (List l = tree.catchers; l.nonEmpty(); l = l.tail) { + printStat(l.head); + } + if (tree.finalizer != null) { + print(" finally "); + printStat(tree.finalizer); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitCatch(JCCatch tree) { + try { + print(" catch ("); + printExpr(tree.param); + print(") "); + printStat(tree.body); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitConditional(JCConditional tree) { + try { + open(prec, TreeInfo.condPrec); + printExpr(tree.cond, TreeInfo.condPrec); + print(" ? "); + printExpr(tree.truepart, TreeInfo.condPrec); + print(" : "); + printExpr(tree.falsepart, TreeInfo.condPrec); + close(prec, TreeInfo.condPrec); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitIf(JCIf tree) { + try { + print("if "); + if (getTag(tree.cond) == JCTree.PARENS) { + printExpr(tree.cond); + } else { + print("("); + printExpr(tree.cond); + print(")"); + } + print(" "); + printStat(tree.thenpart); + if (tree.elsepart != null) { + print(" else "); + printStat(tree.elsepart); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitExec(JCExpressionStatement tree) { + try { + printExpr(tree.expr); + if (prec == TreeInfo.notExpression) print(";"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitBreak(JCBreak tree) { + try { + print("break"); + if (tree.label != null) print(" " + tree.label); + print(";"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitContinue(JCContinue tree) { + try { + print("continue"); + if (tree.label != null) print(" " + tree.label); + print(";"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitReturn(JCReturn tree) { + try { + print("return"); + if (tree.expr != null) { + print(" "); + printExpr(tree.expr); + } + print(";"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitThrow(JCThrow tree) { + try { + print("throw "); + printExpr(tree.expr); + print(";"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitAssert(JCAssert tree) { + try { + print("assert "); + printExpr(tree.cond); + if (tree.detail != null) { + print(" : "); + printExpr(tree.detail); + } + print(";"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitApply(JCMethodInvocation tree) { + try { + if (!tree.typeargs.isEmpty()) { + if (getTag(tree.meth) == JCTree.SELECT) { + JCFieldAccess left = (JCFieldAccess)tree.meth; + printExpr(left.selected); + print(".<"); + printExprs(tree.typeargs); + print(">" + left.name); + } else { + print("<"); + printExprs(tree.typeargs); + print(">"); + printExpr(tree.meth); + } + } else { + printExpr(tree.meth); + } + print("("); + printExprs(tree.args); + print(")"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitNewClass(JCNewClass tree) { + try { + if (tree.encl != null) { + printExpr(tree.encl); + print("."); + } + print("new "); + if (!tree.typeargs.isEmpty()) { + print("<"); + printExprs(tree.typeargs); + print(">"); + } + printExpr(tree.clazz); + print("("); + printExprs(tree.args); + print(")"); + if (tree.def != null) { + Name enclClassNamePrev = enclClassName; + enclClassName = + tree.def.name != null ? tree.def.name : + tree.type != null && tree.type.tsym.name != tree.type.tsym.name.table.empty ? tree.type.tsym.name : + null; + if ((tree.def.mods.flags & Flags.ENUM) != 0) print("/*enum*/"); + printBlock(tree.def.defs, tree.def); + enclClassName = enclClassNamePrev; + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitNewArray(JCNewArray tree) { + try { + if (tree.elemtype != null) { + print("new "); + JCTree elem = tree.elemtype; + if (elem instanceof JCArrayTypeTree) + printBaseElementType((JCArrayTypeTree) elem); + else + printExpr(elem); + for (List l = tree.dims; l.nonEmpty(); l = l.tail) { + print("["); + printExpr(l.head); + print("]"); + } + if (elem instanceof JCArrayTypeTree) + printBrackets((JCArrayTypeTree) elem); + } + if (tree.elems != null) { + if (tree.elemtype != null) print("[]"); + print("{"); + printExprs(tree.elems); + print("}"); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitParens(JCParens tree) { + try { + print("("); + printExpr(tree.expr); + print(")"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitAssign(JCAssign tree) { + try { + open(prec, TreeInfo.assignPrec); + printExpr(tree.lhs, TreeInfo.assignPrec + 1); + print(" = "); + printExpr(tree.rhs, TreeInfo.assignPrec); + close(prec, TreeInfo.assignPrec); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public String operatorName(int tag) { + switch(tag) { + case JCTree.POS: return "+"; + case JCTree.NEG: return "-"; + case JCTree.NOT: return "!"; + case JCTree.COMPL: return "~"; + case JCTree.PREINC: return "++"; + case JCTree.PREDEC: return "--"; + case JCTree.POSTINC: return "++"; + case JCTree.POSTDEC: return "--"; + case JCTree.NULLCHK: return "<*nullchk*>"; + case JCTree.OR: return "||"; + case JCTree.AND: return "&&"; + case JCTree.EQ: return "=="; + case JCTree.NE: return "!="; + case JCTree.LT: return "<"; + case JCTree.GT: return ">"; + case JCTree.LE: return "<="; + case JCTree.GE: return ">="; + case JCTree.BITOR: return "|"; + case JCTree.BITXOR: return "^"; + case JCTree.BITAND: return "&"; + case JCTree.SL: return "<<"; + case JCTree.SR: return ">>"; + case JCTree.USR: return ">>>"; + case JCTree.PLUS: return "+"; + case JCTree.MINUS: return "-"; + case JCTree.MUL: return "*"; + case JCTree.DIV: return "/"; + case JCTree.MOD: return "%"; + default: throw new Error(); + } + } + + public void visitAssignop(JCAssignOp tree) { + try { + open(prec, TreeInfo.assignopPrec); + printExpr(tree.lhs, TreeInfo.assignopPrec + 1); + print(" " + operatorName(getTag(tree) - JCTree.ASGOffset) + "= "); + printExpr(tree.rhs, TreeInfo.assignopPrec); + close(prec, TreeInfo.assignopPrec); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitUnary(JCUnary tree) { + try { + int ownprec = TreeInfo.opPrec(getTag(tree)); + String opname = operatorName(getTag(tree)); + open(prec, ownprec); + if (getTag(tree) <= JCTree.PREDEC) { + print(opname); + printExpr(tree.arg, ownprec); + } else { + printExpr(tree.arg, ownprec); + print(opname); + } + close(prec, ownprec); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitBinary(JCBinary tree) { + try { + int ownprec = TreeInfo.opPrec(getTag(tree)); + String opname = operatorName(getTag(tree)); + open(prec, ownprec); + printExpr(tree.lhs, ownprec); + print(" " + opname + " "); + printExpr(tree.rhs, ownprec + 1); + close(prec, ownprec); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitTypeCast(JCTypeCast tree) { + try { + open(prec, TreeInfo.prefixPrec); + print("("); + printExpr(tree.clazz); + print(")"); + printExpr(tree.expr, TreeInfo.prefixPrec); + close(prec, TreeInfo.prefixPrec); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitTypeTest(JCInstanceOf tree) { + try { + open(prec, TreeInfo.ordPrec); + printExpr(tree.expr, TreeInfo.ordPrec); + print(" instanceof "); + printExpr(tree.clazz, TreeInfo.ordPrec + 1); + close(prec, TreeInfo.ordPrec); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitIndexed(JCArrayAccess tree) { + try { + printExpr(tree.indexed, TreeInfo.postfixPrec); + print("["); + printExpr(tree.index); + print("]"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitSelect(JCFieldAccess tree) { + try { + printExpr(tree.selected, TreeInfo.postfixPrec); + print("." + tree.name); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitIdent(JCIdent tree) { + try { + print(tree.name); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitLiteral(JCLiteral tree) { + try { + switch (tree.typetag) { + case TypeTags.INT: + print(tree.value.toString()); + break; + case TypeTags.LONG: + print(tree.value + "L"); + break; + case TypeTags.FLOAT: + print(tree.value + "F"); + break; + case TypeTags.DOUBLE: + print(tree.value.toString()); + break; + case TypeTags.CHAR: + print("\'" + + Convert.quote( + String.valueOf((char)((Number)tree.value).intValue())) + + "\'"); + break; + case TypeTags.BOOLEAN: + print(((Number)tree.value).intValue() == 1 ? "true" : "false"); + break; + case TypeTags.BOT: + print("null"); + break; + default: + print("\"" + Convert.quote(tree.value.toString()) + "\""); + break; + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitTypeIdent(JCPrimitiveTypeTree tree) { + try { + switch(tree.typetag) { + case TypeTags.BYTE: + print("byte"); + break; + case TypeTags.CHAR: + print("char"); + break; + case TypeTags.SHORT: + print("short"); + break; + case TypeTags.INT: + print("int"); + break; + case TypeTags.LONG: + print("long"); + break; + case TypeTags.FLOAT: + print("float"); + break; + case TypeTags.DOUBLE: + print("double"); + break; + case TypeTags.BOOLEAN: + print("boolean"); + break; + case TypeTags.VOID: + print("void"); + break; + default: + print("error"); + break; + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitTypeArray(JCArrayTypeTree tree) { + try { + printBaseElementType(tree); + printBrackets(tree); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + // Prints the inner element type of a nested array + private void printBaseElementType(JCArrayTypeTree tree) throws IOException { + JCTree elem = tree.elemtype; + while (elem instanceof JCWildcard) + elem = ((JCWildcard) elem).inner; + if (elem instanceof JCArrayTypeTree) + printBaseElementType((JCArrayTypeTree) elem); + else + printExpr(elem); + } + + // prints the brackets of a nested array in reverse order + private void printBrackets(JCArrayTypeTree tree) throws IOException { + JCTree elem; + while (true) { + elem = tree.elemtype; + print("[]"); + if (!(elem instanceof JCArrayTypeTree)) break; + tree = (JCArrayTypeTree) elem; + } + } + + public void visitTypeApply(JCTypeApply tree) { + try { + printExpr(tree.clazz); + print("<"); + printExprs(tree.arguments); + print(">"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitTypeParameter(JCTypeParameter tree) { + try { + print(tree.name); + if (tree.bounds.nonEmpty()) { + print(" extends "); + printExprs(tree.bounds, " & "); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + public void visitWildcard(JCWildcard tree) { + try { + print(tree.kind); + + if (tree.getKind() != Tree.Kind.UNBOUNDED_WILDCARD) + printExpr(tree.inner); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitTypeBoundKind(TypeBoundKind tree) { + try { + print(String.valueOf(tree.kind)); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitErroneous(JCErroneous tree) { + try { + print("(ERROR)"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitLetExpr(LetExpr tree) { + try { + print("(let " + tree.defs + " in " + tree.expr + ")"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitModifiers(JCModifiers mods) { + try { + printAnnotations(mods.annotations); + printFlags(mods.flags); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitAnnotation(JCAnnotation tree) { + try { + print("@"); + printExpr(tree.annotationType); + print("("); + printExprs(tree.args); + print(")"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void visitTree(JCTree tree) { + try { + print("(UNKNOWN: " + tree + ")"); + println(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java new file mode 100644 index 00000000..2da0d9f4 --- /dev/null +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -0,0 +1,199 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.delombok; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.StringWriter; +import java.nio.CharBuffer; + +import com.sun.source.tree.Tree; +import com.sun.source.tree.Tree.Kind; +import com.sun.source.util.SimpleTreeVisitor; +import com.sun.source.util.TreeScanner; +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.main.OptionName; +import com.sun.tools.javac.parser.Scanner; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Options; + +public class PrettyPrinter { + + private final Context context = new Context(); + private final JavaCompiler compiler; + + public static void main(String[] args) throws Exception { + if (args.length == 0) { +// System.out.println("Usage: java %s ..."); + args = new String[] {"tests/foo/WithComments.java"}; + } + PrettyPrinter prettyPrinter = new PrettyPrinter(); + for (String fileName : args) { + prettyPrinter.print(fileName); + } + } + + public PrettyPrinter() { + Options.instance(context).put(OptionName.ENCODING, "utf-8"); + PrettyDocCommentScanner.Factory.preRegister(context); + compiler = new JavaCompiler(context) { + @Override + protected boolean keepComments() { + return true; + } + }; + compiler.genEndPos = true; + } + + public static class Comments { +// private static Key commentsKey = new Key(); + + private List comments = List.nil(); + + void add(int pos, String content) { + comments = comments.append(new Comment(pos, content)); + } + } + + private void print(String fileName) throws Exception { + + Comments comments = new Comments(); + context.put(Comments.class, comments); + + @SuppressWarnings("deprecation") + final JCCompilationUnit cu = compiler.parse(fileName); + + StringWriter writer = new StringWriter(); + cu.accept(new PrettyCommentsPrinter(writer, comments.comments, cu)); + System.out.printf("####### Original source of %s #######\n", fileName); + BufferedReader reader = new BufferedReader(new FileReader(fileName)); + String line = null; + while ((line = reader.readLine()) != null) { + System.out.println(line); + } + reader.close(); + + System.out.printf("####### Generated source of %s #######\n", fileName); + System.out.println(writer); + + printNodes(fileName, cu); + System.out.printf("####### Comments of %s #######\n", fileName); + for (Comment comment : comments.comments) { + System.out.println(comment.summary()); + } + System.out.printf("####### End of %s #######\n\n", fileName); + } + + private void printNodes(String fileName, final JCCompilationUnit cu) { + System.out.printf("####### Nodes of %s #######\n", fileName); + cu.accept(new TreeScanner(){ + @Override + public Void scan(Tree node, Void p) { + if (node == null) { + return null; + } + node.accept(new SimpleTreeVisitor(){ + @Override + protected Void defaultAction(Tree node, Void p) { + if (node == null) { + return null; + } + JCTree tree = (JCTree)node; + Kind kind = tree.getKind(); + System.out.print(kind.toString() + " " + tree.pos + " - " + tree.getEndPosition(cu.endPositions)); + switch (kind) { + case IDENTIFIER: + case PRIMITIVE_TYPE: + case MODIFIERS: + System.out.print("[" + tree.toString() + "]"); + break; + } + System.out.println(); + return null; + } + }, null); + return super.scan(node, p); + } + }, null); + } + + public static class PrettyDocCommentScanner extends Scanner { + + private final Comments comments; + + /** A factory for creating scanners. */ + public static class Factory extends Scanner.Factory { + + private final Context context; + + public static void preRegister(final Context context) { + context.put(scannerFactoryKey, new Context.Factory() { + public Factory make() { + return new Factory(context); + } + }); + } + + /** Create a new scanner factory. */ + protected Factory(Context context) { + super(context); + this.context = context; + } + + @Override + public Scanner newScanner(CharSequence input) { + if (input instanceof CharBuffer) { + return new PrettyDocCommentScanner(this, (CharBuffer)input, context.get(Comments.class)); + } + else { + char[] array = input.toString().toCharArray(); + return newScanner(array, array.length); + } + } + + @Override + public Scanner newScanner(char[] input, int inputLength) { + return new PrettyDocCommentScanner(this, input, inputLength, context.get(Comments.class)); + } + } + + + public PrettyDocCommentScanner(PrettyPrinter.PrettyDocCommentScanner.Factory factory, CharBuffer charBuffer, Comments comments) { + super(factory, charBuffer); + this.comments = comments; + } + + + public PrettyDocCommentScanner(PrettyPrinter.PrettyDocCommentScanner.Factory factory, char[] input, int inputLength, Comments comments) { + super(factory, input, inputLength); + this.comments = comments; + } + + @Override + protected void processComment(CommentStyle style) { + comments.add(pos(), new String(getRawCharacters(pos(), endPos()))); + } + } +} From 4c73407dc7f68fffd7d3166f6e01118d331d3a68 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Nov 2009 17:34:05 +0100 Subject: [PATCH 02/14] Solved or suppressed warnings --- .../lombok/delombok/PrettyCommentsPrinter.java | 1 + src/delombok/lombok/delombok/PrettyPrinter.java | 13 ++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 68e503a7..aa42f2b5 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -107,6 +107,7 @@ import com.sun.tools.javac.util.Name; * This code and its internal interfaces are subject to change or * deletion without notice. */ +@SuppressWarnings("all") // Mainly sun code that has other warning settings public class PrettyCommentsPrinter extends JCTree.Visitor { private static final Method GET_TAG_METHOD; diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index 2da0d9f4..caea38c9 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -115,12 +115,13 @@ public class PrettyPrinter { return null; } node.accept(new SimpleTreeVisitor(){ + @SuppressWarnings("incomplete-switch") @Override - protected Void defaultAction(Tree node, Void p) { - if (node == null) { + protected Void defaultAction(Tree treeNode, Void r) { + if (treeNode == null) { return null; } - JCTree tree = (JCTree)node; + JCTree tree = (JCTree)treeNode; Kind kind = tree.getKind(); System.out.print(kind.toString() + " " + tree.pos + " - " + tree.getEndPosition(cu.endPositions)); switch (kind) { @@ -167,10 +168,8 @@ public class PrettyPrinter { if (input instanceof CharBuffer) { return new PrettyDocCommentScanner(this, (CharBuffer)input, context.get(Comments.class)); } - else { - char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); - } + char[] array = input.toString().toCharArray(); + return newScanner(array, array.length); } @Override From 6cd3b8a8ca4809efd2001473f31c881c9f2381ea Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Thu, 26 Nov 2009 01:45:55 +0100 Subject: [PATCH 03/14] Major restructuring+adding tests --- .classpath | 2 + deps/junit-4.7.jar | Bin 0 -> 232354 bytes src/delombok/lombok/delombok/Comment.java | 4 +- .../delombok/CommentCollectingScanner.java | 85 ++++++++ .../delombok/CommentPreservingParser.java | 77 +++++++ .../delombok/PrettyCommentsPrinter.java | 6 +- .../lombok/delombok/PrettyPrinter.java | 198 ------------------ .../delombok/resource/after/WithComments.java | 5 + .../resource/before/WithComments.java | 4 + .../src/lombok/delombok/TestSourceFiles.java | 97 +++++++++ 10 files changed, 274 insertions(+), 204 deletions(-) create mode 100644 deps/junit-4.7.jar create mode 100644 src/delombok/lombok/delombok/CommentCollectingScanner.java create mode 100644 src/delombok/lombok/delombok/CommentPreservingParser.java delete mode 100644 src/delombok/lombok/delombok/PrettyPrinter.java create mode 100644 test/delombok/resource/after/WithComments.java create mode 100644 test/delombok/resource/before/WithComments.java create mode 100644 test/delombok/src/lombok/delombok/TestSourceFiles.java diff --git a/.classpath b/.classpath index 8da629d1..3390740d 100644 --- a/.classpath +++ b/.classpath @@ -5,12 +5,14 @@ + + diff --git a/deps/junit-4.7.jar b/deps/junit-4.7.jar new file mode 100644 index 0000000000000000000000000000000000000000..700ad6952c76177568f705f2666ea994da565ba4 GIT binary patch literal 232354 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�oMFXR zO^=sc;)W)slwRAYpqzrAk`Z{tY?a&v;63s^#OGn+R&)4R1V~;GwvQ~_JHl9KkA{+U z2~>>2kDijYOVe(ROHnLG-8Z#yq`{Eu5f4Y4(FNbAd?gn2B1fTXFaydBGv|SAsH89o z2fM<(zSlx~M`8 zKHUHBb7*Vm!60n!YGVSJVplRXG!X_A&!Qg2rvJ7UFGuk&`FTX&ActWTRKYoo^tHDH z4<;sd%uHpJ=@6j=zW_K|F1LxD-21j_8QR~#UzCSihRyS%bY^ZlGu9 z`PJ%G#hRkg3sNPjM7Gk{6~zR$bdb+d72smzvgc|U4pdU>c|~sNlhta4*SNw<4-~-~ z<__~Y8crl(jn?_EP$CPkBnQQco3Bcn0-AfSVie-0;#_v`&G#{+w`1 zlvS^X&U1JszzH6W3$RE1puDa1v|kfNBAdZi2Ty(z%fKCD6XT9XLsf%?juTL}XvN#Uk?jAPXfqZ#w^CQD#!8}yP-07tY7UIa~HfGz z+wI)PNQoz*E_oIaeL>$t>|#Pg-YAKZk1zFRFgxsQPcq!vBG|$xF1J<(1Cu?CjO;h5 zYOIpmPX&bpbttn(J0=0*B;ljlDnG)@#sru#ZKlZ|uzHP(t23ca<`R8Ue zsdYOf?^*2u&_Y7LVEos3UO`s8pMTR(=bh_}$ZA=8HjmP2@u7?ug3}R-+g2k-iCb$> z{IVUy2`Tx6s4-0PafgH$c1yeE8$`3&_p__o2d+iA*I}dWy)gO!|GQ7%l%9x*0V=Xe z0HR9$|LGI|D#iYxn-YqS{!_|YRCEAG?Fw$?B8UlFA6teo3PD1`!oag=4z3(BB6>q@8hZ3b{VI-hL5%<2O*-&%lxPj&6v0VkD%wPP3*{NTNT zDF0TD#u)4ML+l6n&=J2pHMz1>dU65kuX|s7Q#Eo$TIG*q!>OC`=KCK7$kvN7ZY*TB zr0~zd348^#@`d;U;c9P!+Bo~Kv!qP9EWEYw#tvHbtpoA)m$m~6(Iv=rjXSA~mp(K^ z#kiO7^6c#ib^<^T^xwZR2Gh{TxD76>Ok~uwE$kOEwF|A4UA`uUWEM$GoqVT&-5d2Eowe`?{&$I(?C$$9+ovVbhta zv)r;VX_%RuNy-mU?fPg{`-GVWz2p(=bElKm*$VZ}>X)cEvct;HsNEuZOmj%s=#Z(R zXr7(dspg37znCV8UW!ZjIEzTLz$GD$H^>~FtBY!n#%h0YfLn#I+c8+;$>kCBYntgb zYW{*E8N=j>mS^mpz#dEId|Z*^#(d4aUx-AM)qCz9MdPMXzHLf>_}vkp1<&Cl!{Hcp z!b|1>0jTK6tABi@{gM~>x6#ADpj6MCx|kGz2yYSq4x{}4^2UGoVvRbK2hK9mS00^r z$`T zc4ik5DBF|zwnjkQt6m9j_Rqsmx2lZr;g|OzZ>omE?vVU^R0hU8-VT4ip+NIj0G54L zaH1iA-2uX7yed;<17Ym_ks=>Gl*nqieb$oh8mCFr#IKEkb>*+ry`x@zGt9dN&AYG%+R(kz55I1I z^MmiAX{@!BG#QJ_tADHnTw}P|U*c%6&8_Zia?GuCl(f0;{my-kwZ(v8b-7urn=69i z>)_b9Tr+d}Lo%3SmqBHvV-n`b@at81<)Zm+L6X$$P*b$*^+}ix zp)woIXRkJ@n;FI5rHS@!q4;ugf25cshT^#b-)VA*Z6p|h6_`+)TsWIb) zYhGPar98tdmC$XTPXzE@ifm7DDP%D|(!g?8V$nBYjme1c$ab_Ao-KwdiE78VOtCBD zeq6rQn~iX8Udv3KvpxzE=+Ot?Z_ornV|v+07zmnrgQ%Vm3)mE2*v1-OCKKEP9mC&O zds=aL9Z7r5X~Mcn)zNe+wNV(8AJqB|v7c@Fm>R4oVCR3|~hr*eUM|P=NKI;vg zFQBO4g~fR2^Z!zlvn*p}06*s`di8EQcG1W%>HhpaHQvzsE|Sva>4OYGyDWfZkC(cg z78MO0ppBfELqX_=yI%>PDT$CE<5^dFlRh{^r4}Web75yI)mAa6#5??u2(t2Lac(I< z>id!&jqw<4FCrLg-4cVjC@WnzJ?rD4H#R+(Ew}N-X5fhX-QfqcUw#3Kz*0S4ozg7{ zoWQ6&s}2Y=r~iH8D6%lNUu2%82eiPd0~Rv2UqG4Xei}%^Z#5Q4%UseAy%;%hZ>r{U zgj-_4A-HzAp}JdZ@V@z5?cZ|3&}qt$Cs3P4o9}{VvID=^egpff+)}{#kFsEY1@?NaSYRmXCF8PdOXV0W!k8*bxa znU$+^5o{U)dufPa>@n9GIs~qXyi=p-i2S>}@Q*aBV$3Nk5+Yk>Ia(xnATcRoZlwd2 z(6UI*94DvU(lD!HUBtOZD7-_T9R-wHQn6u&{E$;#s3=VuRCX#y{>P^t>+ZXyQE0m4 zs)e4-Sgx;Fw344&M`%i8WoJZQR9qDVx`uP$wNbBUE{EnwabvMJhS;U!vqy(DT{_`Y zC~V$JDRbg*B$vggP9h~aH=koK(vwH`;%-m340yH+%L7^=4Fg68MHbxC2bdY~?*guhc(9Bn#IbGqI=< zQ4mpCx!_9l&+%~<7Pm)%#l_a>L6VY_G-X3DnsBnW4i_C!N6Onqy;oUfk<1!#=-dy% z@g`%Qj3&PrhOkC1BpT4OLqA z&d1#jfpp{sIRjD%dGjEfDH=7%%BB+pb(dky4Mk*A&@C6^n4T%*ctV&PC3+_*D#sRn z3g2o7%58C?3w+QVOc??%Mmq!k^W??s`v~vIA#S|V`EwB)Tl`1M3Tl;(W>8+su+)l_sq+@xT8z51&0?`u=VHZ>H(X7_ z243z4Vil}u0dwsIh)x!aN{Ejt5$v9l)+!7mf&oH|5wemFHWTlaHe_m4k0-9{XVF|^ zx|&SCXOaQ_upYuge3=~vu!;R?iwM35W7IosX`4u9Q+mS46fO3BrfP*P#l^Vu3clOR z+s3KqhNp=Ufh5dL5Fd|yKG$Se7QvWgnBpQYvL*gVHT~?>71LBibF`6NZX;KD!6^_b zF@?yH429GQ3Yq7o;jY_S6CWN6Q#9%N&xCWohNB4ug6o_m%7pO^j#y)S#kI9%AJhjZ zi%Z39S_e!R3x~*lV@_Aye6j^h%#pw%&KhV8JkRqA$KVgFi*wI%xMFxPLWyR2(o^+> z4_Ie5EKP~#O^Kvo7uvv}=-}S@uwF%wQXUBN189OyZx&C#L0-f$*bN{raN~|M^tt}gB7i>gzod1Z{p?X7ZHb>Eu=Bcz8v+0fv z?A#DgbGMD-RlB(8G45G{Ir+Bw5bCN~O)wOiK+i-B+LSwEa2QP57ty;VBVm6xWc95^ zpKd5+mMyGeVCd-HA1Cr!^Zjo3H zb9YPUhnPr{%($$JNtX6~aF^Yd7?BfCf{VDI+td@>^b;)j#5#xEIQ&c0F+?iNff&N@ z16X0|PDLv1%!JXTVdKnjE{(8_r8T`;sz-y6p^`7Gt?}9g8O%y+>rrS;ZQ`?Q!03-O z(+AI^5>46Sl7`Y0AD;V##g~sAy8J7M8`8=f;`f_T?yVrVEorhl$bw#ZudWEj(Fqj( zeC$ErP8nwSisaev(DsRAV?`W`f)R>Du-2F}C-WaP+?Y zz0mSARrjt0q_lsHGye}*m7_vqD?VDM`3gipMvdOOGu_4Ua(v9I{{ry?oEd&5fw|aQyDM--3T22f zZCdQjVB1!2qAEHqg{t}KXEIkv5}y++rrAnLVPy<-U?vQgD>+Iry7_uIfnlQokZ>zo z=$4Z7uL+iDew~66s*xK7MI_8p|9!^Tdi37KSRsI}EE9@L(aT}!U6}7i`OAMiv~aCW zC^?|A^nn5b68K;9`F}mMlBun!tr4IdXlE`1u!E`HzeeD5{<(BR4l)Dr8>B*os*Pnp zBA9Kzc8#D`F!2bGRJ_)uEo2y@3-dsSfydmRBQ2+j+T;6mg5!H03MMF2%TxrerrF${ zKHuG>zOS!q1fWGq3dZmcU0!@r2XJR7pJ-24UB+9+0L+smQ^f`W$$SXuZI576S05|F zI!+p>Y9qRU+1rl7m1RZ7dc!>!;3g+RzDY;ufMakFBTd2+nhlJz$zPffYV5E!6kSHw zr(m7XZWAqmb4egCv%NVJ>fK6i3@+D%mm#$@Jy(H`QMo+?YiJzmC~mZE$vW2Io^S}vxp`d)6DodL%tlWHkz%Ve7f)H?-A84XmdH1U!x6-hg&;WO&3C6Qxp z$5t9Ui94Y!$MG!jb*Oaai}yCJbu2|c=>i5^HB+Tl+@w7NB}0dO_>>B!c~XB#LmzKE z7+rzTiY?+v2+U=qZGvzpr$oY;F z;hBlv{+ws@4Ik!v{+ykAvu3a5_4i`#l32?Cmrbu~!2)D2(GH8MoeS&U?jrKRVVrim z16Np@3u#b!8K00ca=n50@BYq%skHuS%4P@DdTe(s$Zy|vv0rC~UkInrBSCu1!={GW zbFt&e-4vMXtp`VQBh2@3AXdR|K7XBSSvzj~=uYmHik+3zAF(m*vEl`?q|Zv#4irTUsl5#hBc6P#wGS^o02PGBB7w1S4@BL z2q@qOfrl6C>7q)$tU0THv!PeB9k-OSz2#Ww>vG=^i`QrlZIZsTc?G_M5)S{$?2Pea z9zt6rKW=Mqmd%>Xecr_8>7Xyfua!H3+tQ;$=s&2Sr;h%C0eRXEhj3e*J3}8e?UMCS zH_KTD0SlG&4O2%@A}DO7(p@!3;#SCT!=k71eVj9(dV?{Yl&4;2S7LX z5hlO?gJcu1tHLi106a|rJ>vfbd;Yh$`xjy49~|-jmiEd~kyQRmDA)^`*(6;8Y#0s| zi8KpdQAbcA0up-yy6GFxdlBodfq+F!&b)fscfeu)dtyi_9C9}_`a!1`$)ZcYS&J=uI3V6 zPCVuk)a1cTc|{jJ#b?Jm?%6u5Fw=O+cjD577(ve7AFI$?bX=o_=4&f^Hye*&K_;hI zu~&8!)pE)gxHs>mWBq42N+&z%cImwiMSlqFilboO6KgX%RaYWgRmq3PL3;<|w`$L% zZQHYQ_4ml^9X@3D-ktg=``L5mj!bn-freyyOlzAk-|`6-T(wz-&7&JjyafwK|Db36 z!YXamJ1W?I;F78T8GX$|#%~rLYpr+6OLnVrB^niJMmlny8Lfy0uA}Y|L_$$2UNO z)Y*B{B0tK{3F=~t&tRgMlIW8LhcF^?!Inl6lvJ{rCgaLnB7-5^hg4Dsr-rE!7~hbf z#>zo$E;b0U={p)M(hgA|<#osug~U3W$Znya7Mf5kwTL=P2ZP19iKV8nP5T4g(aehl z!u9c-3i-BG%m-ovXxw}-1?qq@Za+(>cPy$N*q2FVc7edbQov0A7)b1#B=ICXZV9Z& znM@6~mv>k(tJ17==1$wTZQHhOR;6v*wr$(CS?Nkt>gBoT-aGo7 z*WIsQ?=kim`*%mginZ2^x#q<8+&8);#n{(H_=tItGqi=A(Itpd9e7VWVEt;T`pY`9 z5q21OiS5}PnL8#o^?1&UQvZ$_@F!vS)VD z%@V3@b0B@0+|5yq-QD&rp50V z%^_|axwZq)uA#BJnPviY#gB!}b>?pBeA#qnZ_0dap1X?now04retHQ-^8)M~p_5EOtBP}-1rC*LRNR{wc`aUi^O}Qx@_<)dG~9ZvJJZ0xS_|(HJTOP`esUJHlxazn`JZ{V^fZJO7y>3R=x$= zEIAx0#`_A{msuGt7=JJ!7&rgpxj zjC(8?^1d)J zJ$-#)hjm3`1Y~#S&GpvQ$H0*Y5+1u$jM`RKR!Yq~beZJJr9vJa*MCJ}4ij;~_-##M zry(d==rkX})M7P%ymO>{UnyLqk{+|#PQida4PI#H+%f9SUhOwVygZXmwtsh9*Qn?} zChO^fpPx0>DcDyYhH<&-mKB73ki6EC>G*-oCQ6j6acI=CZS`GB8wmjWa*2Glzo8(d z(4iV0Oeha1j4hHfj|-ws&C{1`QmYC^;%<&-x6zwkJ)PlXj&)TjPam~`rI7K>49%*m zqf$RvZ;mSczJFg}21}W#(uI5V^XFoWl$AqyNCvZHhQ3srJ8fl9U)+kyZHsIlJ$;Zp zb~nonW{0uCmp6>4cV1=FJ?n_{C+e*^J3U2&G(d0u2K{*gCZ+u*Lt<$+1gRSe*6yq{;4vTin z7C!O2fyTV*YyogKQ9C1NK=68Q9W7rvn8%Ix#Y>Xd`r%}0$=5-Tgs>~`7s;n3!UaW) zm2(PW!bmlrA*npqVgx$@u6eH|6cKd>XY=aIwEmElipkuMX$L5MP6>dej5Gtwwxd;F zjYBiZ4H*QSE=&}f>BJstt${>&k!42PNM=?xRV`v%1P)ReJ{}a0QdCgVAzY7yFzvy{4*g+a8%>xyjwp*O5y8 zS9m0e@Pb@4uuyvsv}>H!!vYo0%8uGL}y5v}Z^HabeA2 zI;6~z9DESA=47bz=g$E0Db3Q@8({8UJ6UI6neXX+nilTW+eTj=m7Ps-d4JC{r6>ip@ltroY2hBflGs` z+5;#J(8Rb>no}oM~ubJCykV7#98gVFrZOM;j{m8W-e$KZ5 z_;v6i1D4vLR(}yccn7{Uwy1?|LHN?pg`dK=ggX#U6n@#z0I?Z-ROj5|_8%q;izPdA zQD{KP>naAj5~zLwI5&P&KzJ8X-9HcrddBX8D=(U@i$zMh%IydL@ly>p++w0Cf2c4I zgBNOX=GyR;D31-Jic($$K3m*koJ|h>@&&(4{W?sJ`F2u7vl=FsQ;1D1^jaS!pwB#U zt1ECYkDvgVd!RVWINw|6>zq26LUb#9K?AiV9qw=4q0U@e>T)%3i0#QMeT}`>t>BgB zzXAq9#e5?lpD(j~pV^V_zs`&f#*WTbPL8zyoNWA~Vg55cMk=i;e3q-+nII&P{RAX< zdx&UwM7;>YMo4HN!lD(3;|kkBD?vp=;udqc*NU$|x{VUK3lzTw(Z2U|%TE)11b38w`S6b?4D*Aie4oD3@^ zM2{XEN)9{^W&)BojeV%%rH*=1x18ZTTxNEt(L`}>?z>V);TCn&)pOAG6TSTet)elk zxZzNhOZIn?>cUy;7^embw`DFE7q?`_68fNFJy7uci+B(&q|i~=^vH}kr7VrIPKDS< zZv7s^yfxZg)XT_?a!nN}p@*`(O_i^%O+rDnj+iWGl`tcUYH~B^LgoEMpojWeQ2Huu zsk@=?!xBa&-*=Cv>2SER^a3;^iKP&&VM?_-Om}stofgxDZ9cscaSPuV4$2raxvrAJ ztCPIx&aUq#A#F}%sfZ)*!5934_2249;&z|wB5cbYkPkc}Jz;KsBKLD7v;y0?hLhu+@ z28gn`(D|_;5DbRQ4J*t3WQxkeEt#@78D?Wew@e-QwrxKpvqLoe<0mG9Ci*ci{;Lr* z0%v<@l4q(bgg0M#&)f(&0H~U7L|kcy(m*j*OV- zpkytpS~Fq~3Kk}=92*HB(5BI|Th=;Z``2Ld^g1|?|Lg*hKAC__|LBsoCA7X`W=WMO$Mg%_G`IQGxR0jZ zbD8{I`h8}KOrG%<+;y}Am#OP$c<_?G!(*0Xmt&VF&g1R!_V-uF9d0g`>s&}*O)wsY z*gghY-1;J;J*+YHHE#pG!GYqZi5_btLo&=3!yE$xpzL(Ou(nQ_)pOrKatmwF%hMR2 zwBAB8|H>RtJ@d5f+Intz!_VLzHc+CM7B*vtVV5n+_6CM%!gy(yHiE?%d0eW%6Cl}OF{dTNl3;T zS3l>DC-6;tQ~9}e5wlPA?OJODo~*Q)wMBz@_{)M7^d~+>Od2X6ItlDpLIDqZ&y

I`e;mJ;2gUC%s96^9t$YsphlJ&P-4TrX2uNzLBdtD3OC zY)Z}%e&nbqG=`zIG1Zo8z2m^zZ$iIOt1Hji!6bUb3PMqJ>G)Gk81m;_)9Q#Hwv1fd zBn6^-O|}!z!l`k|s_K_8fT>V(4X^?w%T6Ri&FvTOi*FNOIzMYM<`xXisNo2OAcnl9 zct$3-1v>ML5m*67Q(5h30&lCE?T|=oUn!NRuRDZ~xzi`}?pEd)C~_Wu`+CVskh^!& z$S96dIAZ9{{rDDoHEQ>|s@41ktZljk&8?}M7i-So(I?O>fyV4cl08F((~nQLl+d=; z>8c36zw-T#1dQ2f5cpU80JBH<^lUjbU7vK}CRts}5B0cXu{KHB<{aB5;90T;`dhyM zWEv4ZmWf@&N)?zsW3Ak)#jlf?_nji$2p!@aX+=c$h6U!}88l8Y7Rc*jSNlqs`LyjY zCPvxAM9*~NQW3-JZr~vVDbSl(GQ{i!y7=p2DCgb1Tm-=chc$Lm-?Zv`v06;P*|mzX zC*9-v;UKrYzzri=Dm1|NBfpWfc*R?D4AG8U>`U3>D$)kUX$l0rv+DLnb{S5P4v)aw zgjV>y+w7PKxKPIV-msmmZqrj=JF;4Bd>nSYN0aV?Y(>lAzW#0gC(=aQ`0+Dis(fb5 zzX|~SWgOsN8S~HBmezMNG&6Q^{1?=o_-_Gsl{K32%8dgO6gkgW8VDU|GUOQyIYZ2d z-+E0yXJ}S0S=u#$wue}Cz368Vndy06awANeFv;-JicTjkQrWv5QyGt!uWWh0OzfKj zHd7L3{FUItKzJ4KCqmtIV44Ng;O`7bZT6!;&|UpoNMono@Nht4O(3qye@o3)V15H0 zXKiL!7-}mEu%k$u`~t>q z3D_7rDYJHro3Kq)QC}@b(%c1SwlP<>VJoXr+o(E^s_bw&wq7JxX)&Ijh__S-T^E+5 zyzUsKLvVydY1AM>5mk46w1_gnFyA#bJr(Mq^SIFusw%S_oGNYC;x$qWd7ExUOA^^e z)}J4DdW8)vWA7NFTdtz%*R!&e-Bd-%*aC3GMP{k6m)~bP{K;v?`I=%tP+B zq!%-?K{u*6JCq*9U1|v#mpo8t->MAhIG$)zK1fe%nSGx}i$~m&XSV_fZ#FRJcT8r6 zsY4lv4>711-RH@QfWV;#$pVeC8x?h^EZ-wGlR2X-Mvb`zDAQNSd(CPq&y#a$ih!N- zTaBy?7^2Ja5vN+vf}zKUFpycJVhPqo4lqnK4Vs=j2uy@DClU8TaM#QmpJ5kKUJnaN zyOuO!uu2$}HyWgkN)1nkcD%;@ZsF7Iz;>7@3em@NdB@9a@tVEMJu~A-JO*E&SNQIH zfom&kGwFwEiYk95%Dph9W?M~$s{wj~%g@^w`&EOwPn4HWBEtKtBv$WZXqOkDpw@rt ziy|OT-enmvh@Qd>(BC5JCdn-aUlhN+``tT$??3?qNBb--Z;MM1GppQt6pRD(gWJy+4&sS7>&C4Obk#NDqF_N&VCpxQp zoLY>npCDu|_4EvfrCJc{@JupCXNHbx43vvFol_Mc$?Z^;HK2ZoRSKbJm4kJ;)ez)v zgv=eK-}sAvo0WPWdCG<}s5*(NRdI#&^MMpn`+6UJS>J6-DSO{9>FLF-fH#WA`!KtW zTJk*-)&A6VzRO=jNi&^ZzkypBx#TOOsWb{#B>NVz4FxM!VN?}zKcK454rb<2`x>pM zYbxo+9_DI&^-nG)VXTGot?Z{=$u_j!hTJd1$oy946OMosgx6i2YK=e)ek}}VK+D9; zg(ump(VTWubcAWg-S70p362Mty+CF9;t3P3Z3x)+Ids zL@T2;n6W5NhV_1+E?5U#vj_ktmuBLgp;Y`Ef^|+gX^h}zF#2(fPLT?dreS+p;afhg z?Le?1X!fBh6@Ttq92jJZfwzm)@#1%Hi*~eEibM$NO2GaEmos#8mC}NAl|`7khr}fm z-;pEp z4@<%X8+Db^AAWdhD2-_P!q*y9D+Hn9@`jKiAJWZ+?MCgIj{sDJc9sf`*nE2E3SHvA8zolG2P(&D&9mRb^v8KcTkV=$vP%)0r8up^5a?RHZ z<=-}42|Dd6-QG*5v%3GH)!ecSwkz7}if2 z4|q@SFpd$_-G(u?{EbFq<$gh~IlHfD%n`e_exw*# zd#QeYLCjpHDHv2%A0QZhdQTo3d zI_Rjfpd<9-*le81lcE6(2Qp{N?+!wMgq7R~DhG=iNkCkeVr12@5sBvyR35q>fEgmrMhm*b8!Fa+o69`exQenxiN-yx)?hq`A%Ru|=vv z`QU+t3U#_>%t9Xk1t)#lSql{U-(Q%MKfWb#3SChCGyoLS^K<0*q~yp$FH?}v6VK8` zmLv3u1mqlY0>-?7&+*=kzvKf9v`){20S?Um>T!%({aOJ{lCK3zUhil@yjTSERZcM% zeI%TK=da8`kHc7ta_vG7hd8)*qC7{Z?J_I&V*w4VzUjMO(9lf7_L#0CB6~CO@ESya z*S#A8hYqLy41oC00AT!ocUpff!v5K4DfRwg6ydE&YHui@xdyhz=PST3Ze}SE9qJIO zL=K-rK&C)UgIVv);$U^qh>)!;BaCDx?EC|=_M_VlHv?GU5k$J6sK&L0>S zs8knfBm1$T!>BMyQcBcDHv>Qx>FlEzA443-4}>NU#M4HJtn>YyBw!RyU{q5Qkz<2#*(XB`e_xZzQ#}?gubJ zC1)_8rERtQ5QQ=Z(favX;zVFx2k@kI!*T*g?Q_4}k%N&hpJCMYb#I~t#CZxcNEB@2 zuIC_=aYmc`R-)JLQPU3}CaCJ7MCfZ+`oq;*C=2B=>=qNd&O`gRpW%Z%_S#_<9ZW}f z9oF}|EL{on+JB|8A1MLNRJI8jn7ubE?PFa#e<#aenst_Nk_fvxn&}j9udsm+j$%vj z*jS>On(g|g)x(So)e@@76zmweD--#ZDa?8sO@Dk}0)k+Ej_zUBw9hU4fFRFXM$!IxW` zm`Otv%YeCq%7cKZ2wF9^z^Xl62ZZxbtyr>!MEb)Y@BF`+K46FJPhnE$LsML*1}6-G z(~T5!5uck+U*qH+QsSnip?>PXuk~&63OtT<^Gc5_2!zKAM5YR?JMoHT;p9m*2`Pvu z#0r=f>*4GPz{sAsjse&3az0n?q{*f#th7ty)utrIrN$X_FVII5ID^-gumy7Y3 zOKWTj;s#sS&L+E`^E~Tth3lwo3Knz)-%kASHRB~R0yc|gOgm2FOv{cMTh@0pL|!*j zp*ZGD$-FJ`Y&-?VtK`1A^0s4tnxZ}DY3qyW3daE)=o4W?9CHHn9mPgr>Uo_vfAKUN zerH{wR3+cy>aY&g!Q(!}RMQ8PON!p$EhH#JR?>_;4?j$_p`9hM#l`-(i7s``%lqtv zD{}SlBb_nqMk47a2G^Gb(dGP4X=_cfe{RAYO}%6IDzOus2=Wu@Qe}SB{@&kg{0(?BkAPYm+Dgr zLlvRe3L%XrIU65P=^7n~l}p}7UN=92B%v2{ZG}78`L{VTrj~q(+0Q$L^>c^+n|W_1 zGhMW;U|Pu0@$r}U=T{)RpxFMde&7BWIyW(E?XgBM{0N#=wUZ$3KWsiLAEJX$ZGI!&Ds z)K0Vg54x9zq|5qQ?Gf6&IAGm>J^SwA*f#T@tHb`eI{yt|{C}^`zb!P{Wj>b&3%pMN zFD4193>mqiq%`IWWT>bUm&dUYXm*me({cFDGTCRX0aYv7%PdyQ)MOkz{IL8uO!@=q zg2RgQf-M3v|7BsRP|E_oZ;KssI!?qgic*I`zuPSTG@Q#k{|?WTp2Tn-8MANKdHBY6 zzwb`BAI$)<{UU)*%fYPv+6mM-$uH^3y$2<_8BUcIEg)Zs)@xCOnbx*i;g~Sb{`!Hc zRK?uuJEi{I`1T|vd8FO-)zG^yxi8&_nxH9g#m8@a76+{3w(%8YEB*Vw;R9<_nqGl^Rqi6H(!zLQtH=f?O=p7R1YT-uxb4HupBsbi8^R8$zlEZ%4sD`Ht_f zzc@{c;>QbEYP?2TFY2eaw%@0CUZmciUXsVZxa_Rc)zJw#QbfQP^`{`rqh~1S2O$hp zgozGH$VeUawS23e%s3KOgfPU34%E*j6Cs|Zf;b!&z6&sufnG(Q<@!|VLUr0Pr*{{r z;9mDTzV?FF=?Tws7avpyeVeoyp`}+!FG^rX|YP=bRnW}Q5!1Fh$Sy1jhK_dZ*L#g z(I880y{|DoH65BX2nBm345UJ6j7oPm{OH>d?@wEhJt7N@L}T!{EU`&7xP06c>fX72v?EA3zXOz_cv>o$G7U$`?_SF z-6IS14hyVa{CLj?GJu#{w4*bXs4#XKz4-A|Ie*TMO0=f9pkNjuIyY~|DB!M8Tpen? z1OJ|@$3m>JB6U$x>9pir#;kNc$nYplNH#M;^Eh$M9pP}Oj4FcoOvx{uyDwMS5P8Ya zCgQfjIv^IkQ*9~V9a7bk(R4 z(#Y*ZYl1c15M^|qiT*?pzCz;QrK$hK68)C?rcX{^Ff_Ev5P*3we_^+CmNitHLTBk3 zN@wvJLua`L^o?R`r?X74nQ0@673E&r{UAIoNoE4<4#86RkmZ*iSV?6kUra ziIfkFZ89~*CWoB^DqJ1VOiJ&R>-4N@;N=p z@PiA*rjQk#w^b{?Bj;Nhz!6{52Y2&c2@b%=N|aMHk8-?v7NE|A?I(aPl(5IQI7;U# zRw(snZ!m&*6;je^4^k0aoFUQ&>HC)N&}ClHwNth=;F?tn^cTa93d%m z{MN=1?j+FREr0p!Gf6+))mcg|d<}|xo#>AG&Xfj^bPDsyDqSC7XG}MQo$Qd%Bwrs| z{o*Ms7B4CHWceGt3)(@{&swgkF;Da|-a{-exzn1N*n0D1Wld9md|J1s_OQHWQN{S2 zq+r#yI_|=*@)4hkrql3^QscT__C0LpCR~ox%X4pZd|O}eOf?{iblT|@BVXX83qJ^j^gH0WUOE19Q$J+nIk_2^c%nDiN`kdK}3ppls7stsWxq!6U| zkG8F?ApH&U+y;(da*;hiI)xaLW%`Cc&Ta_v*jKwBoj=wyUJ*2|5c9T|GejlY>J2Si zHkl2T+9){@;_Bi(+1A48hsDzvbCKX>EaFW)2Ytb@z?)({$qn(HBJSBm1eg$?(JLEW zTvS#dl~+@9thzC81Z4&?BU~m448$KSli@W3&UoRvtCN0cqkuTIfjDt^B}1N67^uVB z_55N#eTslGU4HHIE6#&Y$PH?&zvCj3|2=-lYP2> z?g=~Y!~sKC%M?KXWeTX^T1*-vv@ySG-SG9sw|WxN8AZlzC zulk(05KAP^_Xp%L=`=ry2CE`#r-j17M*@6q4;K`vN1e22ki0-a1(&e3)j(SEfJiOoew`*xCHpHm!EiFLofQ zmP^=j!)v^VOfhp$5RJMq1-c!Zj9cEANy~N$u#DgThH6|KZ~;?&mKBnpjorT-0RI!A zo&O|rI@{SVSh=-f*LeHZDRVK>cz) z#58Pzk-RNj%pr&qEC*t@)K4}U-2xp-rzGn&h=LcjKdqo=1TY~$9w-lU%D9cHHQhUD z|61G0+H%yver~|{=l8#1vHss1;HdcL4j2iz|5?05#!gEB)58yuI$K&bYTO)%%L*gF z_%);Q3+Ku;UX(pLVJ}gc*B!{#Rv-0(U*`^#ifPKt^oyFL;BK=DZt?1Df7tllsv1b2h=rT;Gb{(eblF{6oC#U$01+isu%8Ab2Fnmn1gn(2Gl&orNsomdj)W zg#=<11OpTzK!~sO;zLG#CdC&r61bARc@V!p54@WRrobvlAl1ah1pD#Jl(Ww#@dBC; z7LK9DZrrN5zQ%r7WVFu&)wR|**DAL!hW$t8zH+|Exi2c_ablO;(1NRv zk!?zh?7sqSG7md6swT!cJniOCL^UXQ8{~)sR7@cU5au~5;Ex>IG%{mQ*XLY-SsTi++2fM&0u5GJojW zEZ2gLOY6(noI?KDM-gkxG0{fr0R%j-i>gq-!CF!Ge z=nGyOz>%E7bbCraI@#aX?|@Qj`=mW$Sh#0|cx=~TX0kb?`=hQ!5D!R-^FCz!egJk33}^jj?LE2wLYJ-L6CYho*}C zrGY*^>K>}C%NESlB;6Hmwe6RvT4fO&OCA<4E2sskK?xD=uu6vCwa(;tHlSs>vrFPX zJs2cPeheZ34Kfxca-xk~;ogIE%)p526;?7i$C+pERb7ZqEUcUK)Wr?5e-Lo9s;KCZ zGKn)?09*yr3{J@yThrjoj@%%8B_tj3BMKS^-Zq;;MSF?#_kSEQ;6Q!6+4l7w3lR zswMqi(?{drrQU_uw42*gJEH!L=R>FsbRUtCKM6RnA1&m#qOebGLJUrMXe{sRxZ32| zFBr@cdnscFwP7fUzv-;ZLUDc>{oJ|LPY{azf46gg-qo3k+LnJ%xZD5?~G+9GaN_rQ(OvMGh{#zS*dcTb?%&B=>7RHO(La8; z^V=Aj+5QJj%uHo#S)@-%(c?YtV8g zWh)pD$Bs#&Y%-e{J8;UN`&SgcZ-V3>Vg(F@@wg;Ke9e{|4is8jC>8|`7fB>d zmzZHa2jx(wEr;lesbb6%lw-7weC88~w;izkIH=68#s|dkkWB^r8l14Z4xbd*1Gs;> z9~#tH4LVqB)INX*^R?HX4>1xNW6EUtQM&p=I@V-psuXF}r1-3VtHgIHsyN1;ci|o% z-A?xD)t@bW8Xq$_EiQ%_94pckM zer)XUmhyd^Iwc<1s~WzKEKypzExay1OZt^^^mXQJD5}8^O*7~*vN2dy?n)aQ68j%j zd2AludITG4lg3ONXaH-oNUg$p5K~6 zr&qHJTT|NKVhWN>p*x4|GK^@=k%$C|@<)5ELkgc6v)Hf zlgaEdjWXT`jm`HQ-JC0H_DZ`WCH`$f=9mxVlmrVRou-=8f=VY2Ii&)It ze*Wp|oS%+A7JTz(fY|wJ%PMGMz&Z$CEbG4GMYEm^X&T)4c5LAXJ*Er}|8T}7UWrt> z-^ZelL|FE@-IY3eA0-mnX1}{b_O;e-5wql{7c5ZCCS-O;XSE03`}D_dn=?+_V7|R%mGo1#>beRutkn+IcH$VDcEbMPPDbrG*yl zR@t8gT(W!nuIR@d@Kdl4VrFeaKBLbU(^rY8M{86FNb=N4sjaTgs}9G@cF(KLx8rW! z53m^ED?wh9gX_|;uM=atjG)=&CxaPb{2Pkql{tIR6XWZkD33RVVFWm2PZIp0{Oj}= z38za<)|ZY!n#8I~_mgdg&m7z9M}1}X!>m@D)efp^8}rn|$9?$Y8OQ1@mr z9ZE92i1tauZr`Wq%d2wM^Y-oJYhb7Mar%EU5|8Z?Elv}@8nrotr($GwHE1DqxZ!<=F-#j_kRiEoYj&& zB>Pg^Ngf1k9jpi7DQ)fcF5z5&${L+Q)XCgtd~ULBjVjhl-3>ckV_|(Ga5qM8`qdX> zc_+}~*U^Yj#{`&6^A1j9!=rhZi= zQ)a#3wH4#B{PNDT$2TdQ&$Fwfx zn4ZAc5*PKm1;fBBx5b^>jv!}ZyM`-Pa-F|pN!O}xtrP?=ACB(vJbI-TS-+6eO7%jj ze}fl1mEsiXT?Wx~KJPn#PLis9@Av8??^Qy$i!yJ|I#j}lvUmcc#Gu)+hCPm5po>t3 zMM^2q2vLJ7%`hUjbPHjIjlQn*8^&0=5$bn+(&>f!<2@Qkupdmyf*rvbF!vJymf^Bj zkU<(8r4exjMXt&VOFS6rB7uolpPNE82;p`=_D~gCf12k~5_!7*#bDTnCBf#La_*JM zpuEs$QJ6&nbdgT_a<<(tEN#6zmeX_D7>Qg!K3uxoPFF<{UM}eTbZR|Hufh643Lb?{ zo|f~$$2YBo_N<7O(fmSa66!tw;>-hy=sVUmIr??GJaCq}X-X8LWRT>6d%UD$o&ua| z(ENESX)$wAxh)rRCoEQ%W`SoveW}CHd~r<1+=R@+V>(>4{O>r7oa!ny2J&?PpX!;p z(P`la9Swevt67uCGMje%YG|_FDkd$$xJ;M8^p(+hFGM8dZ>TRmy@z_bQU>;*s=j&; zG+Tu0WRs0wNU05t+_R7D>$LLe1J85UyiXC{)G56?L$k1F8NGhkV?>`85=$GB;El~i za4<&3c?A}DV2HX0KJDqAcvD5kJyG{aP&4mrlTM=fZkYjZJ7r+Dh+9DloTWes#P0vhCE^iXxP{qx^u zRXNvD2?#$61JX~H^8fxm`X~LWQu$x{Y)MPPHc);c$mI=(b%!(|X4Gin6o}?{y~W0# zj+{Sj>e~-*MZFkA@F)uoQE?S&<9l9v)R$u3(p&9kSrCy9;Hyj(vmx| zYT(n!IK{Lh9Fjt-`9V_YJM41DSV9 z&E?5Y_o`J=J9bggX6@k9NVBLYX`-1z(U${>`wD~fo)PgaG+_GDqT}Q&=~OJmpyV)N zB#t7C3?4~jF{EBh^zQs_ZuG>!bd3TXGdziNdeqdTogfPfn9+!q*>2Q9Jg`U6GMWl-2PtW!x>o99`Nh7C&ER$a!Jhj4wYz#cABl zuNYB*Aq$^cUu1~th-iYbQQ)oS^G1w@&Xg{*TkXql|{;JUBk?u$%slfR;i+a_L&}6c z@PR^`cJTc|ZA-Quw;JYk1oPqDg4Y|yakitrIU#mZGQ}5!tAK2xTwsH6S;r21&BgiQ zEjo!%08{%_qj!sNp~{D!uKvo`8D6R+uWXR&7YPG`NSDhzR8Ta;R!i?ZrvPSd z1sh?ykQz(Rq&-*kvXwPAw5gg_2x)G(8igsg++aTM{S5xwwW0HBQVe7Kf&b(_SmL6V(&x(S?svCt7o;BTJ9$153vLD&h8DW^$jxFyz&OKMXD~XCR;)eBRqPGh7UjOT z8*lghS4i0rwP-B>?!jH~(=`z;57j>56B+3%fb^9Om!}t(7rnRm`V@l4fBJUU5s_!Q zxf^dcoS`egl40%In8z#d{5By#9liZp+2`C6v1=;vDJWv|sVKm9^ogYli66X+a@P~F zYkFqqK!JSHo+;QDmQIL7gn5{|uoazha)#b)HGVXlUC}k(Wr~S;U0g=pd{Qi{W|917 zow4q%m?t2O1Z={5ab~`sg4Z!LDcAlwkE4>rvC4)B+^~-g{Y1ZIi!7yF=1N{ zM4z6TSSrr)c60|$(6BpGHYZP9(Eh`1#{kT<`amxT2QD>i!Ju~UUtkjn%!$k)wlUV7 zhKCo(t1dfDuff#GE>4SNo1_o;otgTIc+}ux(2FQM3BU5BAeV_>WAw|brMD^C0wf1y zCEbGb+tK`iD*I`{!Vfhn_Fl`TJhRk;EM!Pzbz4dbH?kU`y#@-gZZhj^`j)V6TlULL zB#5q|L=M6tEQ(+&J2cFDYj|CX11A}SV@obMJ4a?LEY-(d!m}2u=UT1r93%#S(xOeQ z&KYRCvW8XcVMcA$6I0@(jF>_p5` zzQ*z)+I0t|-3banLwN=8%G&|K(OZ$5^X#p)vAa_hW12_S-R$C9Yt-i>sZ2?UhHKA- zwxKUZawO1A1ymL0>nw+q4HmdQ2;~P3z}etNQMf@mdW}$~4EqHLgVGv`_sX^^litMm zi9TIJ*+{e$?kK-X^-ZI^`r&>ccIQb{=2=rbG3(?fD=LT1%iQ<|Y?D1v>m18`WcqFI z!-5Xas4`D`XUyUvzao4$VAHYhqqamh$~JNA4%^DznO57;`sk}^uR~0_Rt5duzm4(= ze80ynmq-r7X`6l&2%^1J0>~@Wu69*i3E&SjY0Vg*YY>MjHv{_`ClorcL;^#>y~iRA z5ri9E_E2yHR^pma5=?cbhF*OJjQpswLIy#Oc;4rsSz%~bNFaQTUcS%@QW`=z+ybOT zzk#IL9*aCG*5|$0Kz&AErk_EtTw556-MX@7qLd>l+E`PnGikyck9-0}vBO-D6@{Yd z6MaUWPusNBc-mieXpImNR!Kw@HWUY`6N&JYDd+63(^7sqgkN@v%!l-~$0`??os`N` zEZyG!-I`(q#>b&Tw@XmsjHfKW`JxW`Yr}GbL-N*7^u=8QabrcPace4rFRSw-gqdw` zoX*U28qO8V7XaUeV`aOz`v=_gTbiJL;@jZC3c}I7+kIw z-X2a@AVUff@p6JW4CYLlPd$I~T=q{SO2`U;qlJB3RZ+$KDg3Iz9fpAcc?$bw?Ztr7 z4_m4b@j*Jt=0+CkYuxiVi6j{q=WHm=mqrNt5#e(9U=;(B4A3~jC2$N(cDDRR0Z+Ic z_{iW>@<5E=z?^%b>LkXk=7}3mP*nnu*0MXq6L0m>@7Plc(e4~cg+zXQi z>xfJ7_ps8D?p6hrb~w`ROtgB6;?X1w=pbVnc3|rezBoNCGyFF#FC18CRr)8zv3!Nq z{pe|}Mbx2O8YT##^BvC|sSZ_f+nejzqNcm`@> ziepP*P5^yICEkU4&95nMfGHA&h_W|H92J-U5*oz=_iBYH+<6^X7ofd=GbOalwPuTK zybwM!iCTG(0riR!DKb53;!$jalq9-gj z#!0pXBdaj5edu|HrQV-Ev*zxI>Kv*mxx$@wt>t8U%w^C#miLQmwwsULQBW+z!!;aH zL%h#jUzAd5tXK}uQs5PHta(4fRy19gc=BX~@STDK45>P|>WH0zy7y$?+`Vc_pU}Ij zLGP<(O^ZYZivc#1R7`}1l!CZN-M43A^w4O<=f$kz-?Xl)luX+&3#tQ#D}bVd1#cGd zv}bi}=U6#$M%uDB-*M-b6WuPMpFQndQW*BoC19N7lxprO_uzE|7n^A1Lrk`jUVQXQWZZMn?>Xq&_q|Znh z6>h%6YYh&Q9tR8E9-R@&Lfw{n>XvRCzG(FtOEPLa~6!OeWNbNzZ z7(Gmlh5AKGab+_IH9Ry0WZP$RA@ds~CGeZ#S_CQ+lOw~4O*3nh__dR!KEA$tw@p~D zo0Gsw{#pQkMwky}0lHyYn737uV8j9tS4X3r4F|XY>X>6kE`-z}|hI~yEsiAPhq==LFqN4$84h8KU zylj2kLn%>$9}n?0Gf8XlqTD-7=}naLzV_i)F(o&mmHU^~2|O#HNGV2UB#M z$dx7ahuq8?mcw%$sRU`2Y51m^qY%Ngd|1u4)BCeN2qduR836=HX7yle`!sE+HUgv3 z{8bnKfVKF?IQjr_28HYZ#7v0o(}ef2hC>^u3d3Q+Z>9=CoD>FAKkNul$5~7^JF$LeGY9rL;&EIf!qWBK=iM?c6{U6f4Dax{L zOEWW&8MbZPwrywFwvl1mwr$(CZ95{v5q)m`w{G?QyGD=d(GUCSJe{@on(JG0euyo! zcAqp_x&-Z|M#0#g^ab+&y6)gToBI`n%t5F}C-<;BNXWJ)*YH9f>#n1~efS=N+$@-< zdhAlm^ik8q;D{V)s!)sirsQ~YgP@&s8y0r&syt*tp*@W0Xz=7wk?I+LTNKuO(-a2j zDmv6o0kDNq!a7nM^I}RUyU&0hUYZ=OYOxLooczs`!x}%Uc3h;E83te;g+<%NHY^J7 z(-&I{EDVnP;x5=j)H(oUT0Bb)9=8!q zC8jCfa#xi+`v&9MDG$oF6z!R4#n+Uta4g6C3Rq3mAp!~G&LB+tGdfvLI2_VAPi-vv zt1IAWa6>1jO`bIc35K`+$`E=BNsa4;K|jIs@d;U?j7PvMMnk12TT#YWCu=y5g>M)p zG$wbIAfw900yy%iOmi{Za@GOQD6`0ny=of4nP%poj!i>^iOr{s`*iF#@)Egv>p}7l zj8dT`6boY~gf#M??^|3_TVlW9ACW3H=esp3l;bI8Xbhl*(vak;V~hE{~jzr zRGoE3s^$FD&uy#c{*f!-&D2tmeN{tx?OcqOutL&YGWQl??K`S8I|ZGX(%lx@+GuC) z#1`Cb99VGZ6Is;U2pA_Atw+g5-;kX*JM{9eQj{l|mF}tvOeF?8IkMWkwrK9StKG@*ZLuZZm3-lm7vVXQ`IAJb)-?>#qb(6F61A*ZI(#p3)Ds) zv%UjWiF3bL^YPoAPlgDv?J3nV>p`KxZf2v&j% zRh8f#UplXughhqYU-Ay<;5s&ZH>q&gT;=Hj2ks}uoBeo`(F<;4GyT%RF8_{}Y>Q3@ z`~Zzs9zeTC<^OYWq>UU+Z4Cd#75@*4#b4`Hsca#ODT>5xpjd5(O;;UI0KMraX&G;9 zH&-MrCIA+YFqTUuBqq;8eICkPv(*S_?|hxYiWRVkRjzqnN0+%9FBhWZ{FdOon8@Tj z-eP~EulMg8ksl-Khg@=jH4xBTf@Z*P}9M%su+k>*X54%&glc1>95Id<8z19%<2=Iic zq|qJ;_~_a(gbZymU&=4PtU+y|C9m}Q+F}Dcg4GU-HEx6XL~Tm*bPA@-CP!x@#d|jb z-7FP5-}Mg|_2mYHT=Wq#7_L<&t7)aI%oOrJeygXCM=Riwec^T*Q>^bH7{VkE%XbgX zZmZFoM{T&=u@}&sfZ&2ByNp-5oRDie3teg5{jaV>pyp3OK7e!VqC3!P*wvwhNe3$s z;n@1UOKM!zd9b-`8!yC0DV7hNHjZlMbA^;r)V9gwh;DGjy`^uUgAiCeZw&m&u%6O3 zx&-jZiHFdnaFt5ym@Ul$OibzIhu?)}6+_E_9hiDl_RO9l)E)&%Yg6+QXEio@%3Tv(T8zv zaaoUC{j^4mgV{KA(gRSbiJ>XP;TBrTt!2a)<_8=?l8D*yvxh=yMM@%Bb5O)}XLhut zt#A*dH=tgH8#W}h-`plYu!FX-j0uxZ&PUk?ksKBj!6z&mlUI?~PE+g~TY*EGMc<`J zyeE+CQYNto(Io#kq!23pN~c8}$E*Oh4SYsGVLwKHA&?u3{{p)*xcQq2%v!LY#t2}? z&me#M#{d7f>;JjIRYQFchmk**k~##abUopLt%NN3k}gX~_%PPl*ofrd*X`(?AZe^n zEv#rOTn5cSNleVl_O(yFT3k-~uLaUau%Hug#M2+FB$}Xd~=f^t=rRY_*_Bm81gf5MXJC30)o8ar*c5 zT?Gc$`_+6EDYo#pu8}&5l{+K{+xuM+;{Bd+kguWhVXhH9wrLAI@gj$ zTKwA*>5-Ho#9%<7xuZBSc;jlNX|Ie2mK;4d#4%JnyJPm~EmZ)ujKyjx+q}1x zvfEM=8}dRG}>xA`NS(Kt9g20fT>JC_#qJ%yoMFJKioB6cEW1E*D@D0wP{eIcCYzoQ(L^JRFok}%6OKjaadhKMQ?+_4 zM(_`&g^#B2-IyVN>PMQZK+M_1Q8dTMGB_v5r%}EKiozpCKD)~|5 zucZ^e8slJ`80(U(UeO@A-vzsHTLrt3`X~K@5c=W1&OW&^CC^ns*Si^E_ZVH#xFxO{ z{fr~#DMO&3={9xlrY#|oRD2G*bGGQb3o!w)teq{UwS1cml@wWvwxFua?_kSF58Hi* zD{5uXaCBd4{jxWT(7gT1$kS%7IJ~O2kkGU{!pPkVHNg! z@BIC^w{c;~%$3p~%u^ zJ)#$Rp&xy<&|BPIMNs3R|A{d45L${J2|14tP5G>w5RQwAZDRF+H}E?}w7Uq24_6`m zti-ER+q)afuJqOaFh{n7P7+ub6LI9!Uu)YiVwi~4f4tI9*wmWUI3Vs|EL#b*AI_XF+5yEY(OUc7CJgU-W5u7cWQ?+08ECX_ql6^u) z%xZYgA)C6(C()=&C~at!Rk_v=68O-zS{u&HpQubYESTI68r1NXb?hq1MF4G1=%fDn z8a&f%)oH3*6jnK+b*4V#7=?0}G$|wh&K}FwW?RkEjNF#k)m|&D&3xEluzHg4TVf?| zHosGAq;RT?{ZAb*Sq3@idA>Aj+sZOk&4I5IHWN{BkIS{Lfws^UpPnNORI89!)Y zJAInMVlr^Y=IzZ8(?_&FC9F++BcUFFSrX{Z_A>3UjP{?a}JSjV1$`)bX|YL86h zoU?R{T9WrA5*#c=f4?Q!P0M&MzHFQfdHv3~+@rV_+lcIXXv#SiSl~5nIXwf7t;E&jm3Lv$_^_i2EWEq1S!RtuzuX4;i$ti;^x?&?JH76@o z^0~z%;Fx*S;x?(X`&Z=%n4gAmN7k7K)Tuec>w$JsqtyME?Lj#k_TlOuP*=Y5EBQg3{P{o;=V0Q=EC%*%I760JzG)`w#;a`VZDBd> z-b~VBtN0I}0}AtH?<=1dUHBULLW7pbrtj--hDc^qJIukX&dq=lXM64uy(_}*F6ubQpQ52rA&fIAH>ochy{_zBXzOf zvnRMH!_x(cWg}G?%V!U+buCe@10SyYH}t$rt(?gdYKwffGsFpu|+i7HUf>`lDV8G zv_K#hz#xuN7=|3w2pQM?J}~?~I?68gY9CCttV1ahm+3`gHYMN0Wqr5~+~~UmY0Bk) zDHRmSRg|7WlwO{PWe%*)q&&zrp4ZyQV*8z%5ey`x=bjNvNuFSbPEWBV_}as+BIfn5 z0-bOU*RJPY`+|tZU@kn9opxYi0RC>e;B$(AHtJ3fH@jTD*x}L0t3FQnymf0l1h>R} zl4-5#b-sN-X$)EPK;}g|lDf6*2sHyrH43pBQHx!i7AHw%*tC2sZ3#AgL)rdFO#B@3 zPj#}LqL{S!dKCRRD2&mHOtn0EUQp!#!2|EVUyiH|wj@XZFi8Rcll~`KlmEIo{!0e& zPepO1>bVY?X!0!A9_PuX@uN_gPO|*B{&_+h5B% zTcEaZHp8<}`7lmu2>#?jo>=40N?6b}1G=O;IdJ_iXfy-x!SJNh!u(qB{e@^e)FZUv zgC+wvt7zJxyY^VruFOHxgR@6jFMeoUXv5l`;uBRvHyT)(uG~SiknA=@Gm+H;x5}Q> zLDi5^HX*y|K*yR8XGfw|nmTli8Gb{f4ypI4j=i&y4+Ykof*V=8+C$`OX@0kLm%F1K zjWIl`bWWs|zqFR9yu=wZBVwIV8aoOtoL>#M@P((*s-SAQnFJOF-s_ErP(9v1?HE;z z#T}T&mu32vCZf>;lxt{z>mo}j)?Yj*@D!t;DyChEk@WIZ#Onn>JS1Uu>2)$|Z&&z@ zpoKzUkT@x((@;&CEtO7W@Jq}a@}$!nGbYh2;n43Y>+)vQ@7G- zgFV+zky8}rSat3s9_HONk6Bf*q{jMGwMJ_PyM+H9+XJ{CF8 zf~T>qv^ORpYf0Fm8l<^GB)OME*et@7)!u_rN|wW@5+^e^nhjP2j2Udu{<43?YpbXwMYW;!VImEuYMEf zmrXF0Yoh%#TlP&u2qDFIYm`l+%21GNe@;zw-7K4@?vno?OAY_o9|YHcm_r5s{Gd|a zA{VbdS-RdOp37nnzPS!~gFz9RkndD0`eGb+992pbg=4;!yPZ8aMsXnBj%rg2Zqh&` zX~FJS!}SnfD>ng?@-0|bF+nJ7nX4KU`9<{Z8-@383ks1NLHc*HAl&k2aPP5)ilQ2I zoWcsM#)^qBF=>2`$~_Y`xmyPFXheh3~4jKi}mChi{6}tV>-L*-m%7l1swe;2*#}l?JnKRp_}5 z7l6E1e&xx~9W(aL>YE^<^v|H6g;=W8Uw(re52F3et+{n({gOc!naBryr(0WC)m{ut zRdMZ~n1#rn1mV@ShkpGETlaR@$M|?I@A_eA&;BFj7ydI9<~Sx$!T>MwL8mPZ-O4udM= zx8GD%Um|bT<2rzeQ`;it>b_X|Mn9V2-4yq54pxH5hH31b6}JQjR-{WkY(o|bJaD4* zzs1z|D^#UG+oQzQ!^%6OMT=L&3@;u#JjNfLz3A=X_Qn)%jwfIqH5dCJ&$`GlCQ5Yq zuV9!9vU#C8nOqTgAHg7$esap$ysRyaGm00OM2S%c zT9?VfV_*{#3yg_AV-6x>1pJr_0bnaUBe!-$WTjbFZq z!b5Kex<_p2S8L-1F3aKeaWidD2%g4pKYS1R*?hIN&Z z0DlgtzQjoD+o4eCH4!BSrTgj4FnNw<)umF2MkqF8)Y|o=6yj+}vy!RljuR-e2 zZo9-T15Y}(K0YJx;KGbc@X#U^h>>lOh^$Be(`Q;g$>S%Hj@TV5k!r02!zhu}v5l(u zY|93Zc&w~s;Kqi{O@L@CZ^(QA7ezjHp99qDZsIsS=Ta~1@)L5}xWV5Zh+QE85&3mA?(DeE8~#=@5K6IebvzWkw4gibUe8Am zH)*gw6aF>@OJC6IFuJU-E0LHrf_te4iyghyH^$*1-Rl^nZ-oKFoHj{|51?&&f%2_L zAp*6Uq$^gUhRxOlpLtSW`qJ$lA9d@eUCOGZks;ULw@Fm~D7h9;K3+LF7PW!2mMg8` zrnDj$KYlVQ*R6F*YWKouiBM`Ab?F>=J-B_*nC*NJj47SC^*jxKpT^~^kxeo*%`}-3 z2jtEQFJIwB5k2n9==eN;ODB z_DIz``(#&o#9?|H$^Ei1@w+T<5rFc4o z*CCwyR+MjA{b)g6u{T*7&XTM-gN%5z)REwxK;2QP=Ixm0H|NTrJ25K(UNDmwMY~(@ zDUybiYh6iI=Emfm>P?k4jh@Qc>_!uz3}&b?qk8O@>LgDk{E_Bf`7;+R+D^?E8#I@w*Jm;t^xE32 z=IU|*gP-G`XBk>UtfEtfUgGtp3-ll-=JtYi$)6tXzt%v1c+JCyAQV_4FM*M?W=clK zEf|s2weQ7KY`*RXsT6w9?dA_e@%4P0shu3-J~NlJjmLqd$?V>yRCZ50LSfi|rTr(JFferc-G5FHdFd#Z_BucY3}uTJIKrPiwk3b0!2pN&MDK!U`EE((+&ie6vn>40MD*MXz4iD zpzd*%H_!mh5(@tkwSd&(27k`cYZGE$JoqrV&s7s1uQF32aoerRW=A|YMdmr0hLCx- z*7_3fHMG?9=<^0QlUcGwGpDk%dvd2dVA2OcU|9OCa~kV6TV-mksNdHesefDvB%$uG z)FDIiIkgHRGeupgy*%m1Hzt~LPws-DxoU&V4uApZNzFg1^aFf+RoTz_$l7kXDNmd< z_8Jm$@kX9Z8A#fE1ecxh64zmdfE1-c9Hbp(c?3^No9{5P@BRS4h9dW4zDqPM?MZhW zZp!DQ^|QquE;|u*tmdcebbPC%x^-S~b1#sU#^F!p5_krS&E}LB!0F3D)hl7HM&utv zvYz?!zsP4<)54^V%djL^6Pn&dFNsx@gV(+Vho#tq-#;Z>kK_S=B;CI2n|z0GdP8?t zCC%QC>secHcmRJ7Ie$MvZNZj`1W9l43|PrGP$f!C=+FLqp>ztMj1%a|r?ooOB#9KJkb)?9ce(;lZ2aiTjMn|7PtH z7hiA8R(_aXXfqYR2jdcDBB)ud+@dJyUjIiH9(7-smsXE*qg+sypHCIg~ihVdgi7298uMX56C|hD3D*qIW#W{ zQw1XPnJu2f-h2w%cnp)Te6+w=q1Oo# z@PmctZxn5(q0Lcpz}!w1pq%9U9~=(<=NkXh4&h%%f+Qf)3+|I-)v&K_WV{4^ds;YF z8A*u`NgfV5x=c+CjTShG2m(8%h130}w|>L?XZETWk2?EH9d z^Y}AdJ-z)+tFIxFn{9g5h*0kY6m#VnwI$3VvL(tp>U$J_ z&_fPH0*<~|TP7pal2{8KdfGijO#ERXJ32R#1CRLH-EPN?iBQ3WgS6?X357A*M6mp* zCRIG4Y?oS6tVWzKN>_3AD4hbspS`=gx@tot4_Kp$!#*Xs67e5oYT{?;yU9lQRHFBB zSW#{5?inbtYH=DOpvn*dG@|x7jNN2ekku85*N4g#qs)pAxWz)kNSXR#NYK~gJvU)d zh7}S}s%N3bSn_Z|Ntb$zZ7PS`&s$NEx0OKBd>88xuj7Zx2g6Muo1LKZxg?P%V!_g$)YM52 zCEcLj&ktvwt85xHTiG;*%0G&ED~wgmQcVDFQMT2Vh%VARPbD*sGGWFuPf$hRvqo)g z%f#GFcKisi#;Q{urIJ*eiG?tQe`>>=FO?WAar(uAW2(;JdUJd(B`^^E9jm{L+y_8T3LpiR^pOM}bjYe)03}rR`BVdfWROA&(({~V3 zU(srIkGD6IWlsC-iULQFj45M7vL|N%IG@wrgAg(yXO2HZlqgPSg2fYc7oCmvFG$YY zycoofE3`x5W|PXeRjx=hY#}U=o+Pvx1}g_~YY#?b6R+j84Zq+#@po5iF6IhGkkXNpZ(Ad*V4sN-2*y1s+qA$ z7ZLlUywAYzC$jR{4smw`bOy$CPZz73CN9~V9$x_GG@b7oLex?46YMF``M?gFXhXjU zQ6khL6gR^2VI{d+qG7QP_CpM&LVnVFn$kdWs||(0m&5Qdbm0!)gx;!!@9IHCLwV1h zL_=%L_7=lrfn`7^R2x;6yz?!0ioOVczvbJR5ZHtiI1Ln5wW4*Fl#xQH7RCo;ks69s zFxD~0e8^bMo3h+PH^dl(I=#@rS()3Xk~wv)H17Mfkq5EeR# zODzuk4%yeM-7hE_+fL`S)wxO6-M*_PjfcByx*7kNpwk-4PD4UAsseJxg)U)Io8Pk!kRcC} zj$CfOQ@@1fQhzxXlDfc4>sa=^%=$?yzz|BX_vO@!(K+$P!_vPH7j?-`{}T80W7CZWLQvhCaxKI7Yoktl+e9+QqP0PpZz0Pf6wZCcSy* z1%Mt}rxjZIe+uI&Mm-_eu`DU#xh`MZG9Il4ys^b|8Q_o{;8eobem9{lb!c5Mi~|Fbc$1N+7-n;UG8MbDCjckW+cl8`t# z*ET={@jw=rhm}60~z+_fiytr7zUJ%e-C2$uhQY*;ACa{kIS2inT;jDwZ!mm zjwOl8+p3770CSyg7J&J`k`Ot)###_n-P)RpuK@CbIe$s0nx+oPC=nIu>f~ys+J(=Y z!|Rm=cX3|B@xw_t?58}=^~BJ7j&Bp!M(f*T=JnR~)a1?4WwsA+OGxmKE-5`E9ccW> z@i8s&*i=b997u6b?g(Kj@_T6n)kXKo9(xE9mAICwCCsr6r6Wz?W~dF88|;2DJkQ`| z)<9ggERX9Y2;lZfTfv>ei=y8k8 zG~=3mCTNO&XE^eD$7$B7* ziVB)6*ws^oC0g6$kkE2&x1xHu5hBrhTOiTt*YOjds^2AA=4|tx`1oI=H0NEzTqMrA ze>+17F9c{I^7mLIJo#@t^rVD=jddv^2uJHNEbEMhZ9xi`CG;oK^w_@c=5X zvq?DoiMg6A%R>`sZ$xhPyf#^+LR7CvV~Yew#MM{u%3`iD-h){xJ!Y1jGJ>{DdB$;( zMv^n6GpW-r7UxDzY^@0O$SIS(O7^NeT%hbz^?V|CNK}kXv~12iJAie~nTRIw_LFY@ z^CjY!HZSeod?-;(kpu>JMks(sIr4 zHa`KI5p?TstrV$Q4{!~azZmfneD@}S#SGrPaeQkb>hZ%Flm4ehv~pqtL}2>A^!Nf#eNjXoOdM+6-jBL9kxNTO*Ql z7duwtU4zf~SgVF6Ad8JxRowhd%Zzzi}t~m=oE!!<Ix8wj~?&651lE8Z@ zjC`mf29BT~h>V$RuoD7CO0OG1uJ7+nlKMwhxan@by(buD0e{3ak_xh|qTHvnPyC=@ z9}CsG*e~GP<&?&`A)Gk)jb^ZrD?PE+Qzg{!OTCm0(h&`xUe6mW(K%5UJ1OC7eM8jY z{+X%*C}ilf0RC6e6A==!Yotq0k;MwduQmo&4hB}!CkN{DxTBXn?0+95ksZ-N)&g2N ze1KNYzh`^?Yp?$oLJ+h!0}v3+^!^DERJI-dVX-dB#d3u|u7kD!Z# ztJdSJ>}~dA5}&WPH{5Sg{n9&lQy6T;`H^JJifpw(mOyDVQGrvfSWvc zike)yB*&I~y0FoqJ&>yHVoy7GNAMFg75SjW4<5OqD$HlOVNniiuz{(Ss!bkJxKYDu zNYi?4X$UCVwW^Lebf`N*f9tXR2WLV#e_DB~_Kt+6@u2(#v&ggER1{#Y1Iv zE7+Y9KG4nMpD&s6I87PT>P_>v#9p|reKS(!#2-zUt;pL?o;VnH&hbS?(nf8Q_S-K&CUehcaD}p>Vy3zyqI!vO?&T?r=0n8%vInu7^Xw<@W(`qmxistgVQUL`F zXG$?ayj1j( zIwSr7*gtyytjumw?!4OENjj966e{Q{{w?7I_RMqGIV2@C{aH=7B!lG^oQIh{RFT6v z^%*KVoy|9%M7tl}_X3hN0333hL?)lA=1V;?7pOd~g#WCBk{3E?h4L52$>GDY3gx9U zmgsO8IA(c;dWhb3YbY(>2?PEz_>C1{yw*wMrA}GkVLaTQUr%w!>@302uw(#<<&~?4 zxU#7Ow>UUi{gwX6sy)X=%v4{(@mY=pbyt>wHNCB!pSe8pQ{Rt$&&M|spHafn*8^H)^}(ub zBS9yy#T=Lgzhe!R%LxvM=O85xV%sAge5jFqLR@-((xMRxp0B*Y#bTz<++l`94YXMD z(OR?$&=*?ur9_C37>uehyh2(d$JPD}Nq*FSX0a#tLJaj_i<3nEZbz3adrEEq%()ax zIjnd~ba^Q?h%%jfeoF}1Y3O<%rfblawV4v_ zFb#$wjJ}xAbI1)MC2{sU*%u6#d(ivyGqS1!pa-7H7&4oDkq%c)|p&ATjJE!OQs5vB0d5~;=Nv4 zaY&oIaS90{6bq6f%|I$SK#Wq)9k0oKIW%;q5MwEX1E?<({k?^Fxej_I(TI0IY{Gof zj=qmTY=jHEqjjjJE@=wiYto8nE^}s!fxb*W|CXPV#xZdw1?U6G0=(P)-HQ8Pl~34J z&)}aCA+cWAip|w$3*iJKcW1{vnhm>I=0MBf9E>xKU=oTDK(=y0%?8 zIwkJX0WS{pkdshYptOa~nPdKJQH7_M8L=#*iJ3orrUy}q2=;{%LItine~dR|+jb2l z64;bB#pZkuu!DX?8^9BH@<|0q>}^So0SC<&u^v@#K(}DD!ur?V#82G`c~FI~CYaMN zR3*VZ5Vf(zH{kX&-3?YQXv2QdIp!i`CFp9bIMhT#2%djk>#?bS*A6VFwq;!fLd)<( zbO)x7k}ufK?*>X?5t_}LDx4ro*0|QSS+z^eW5?Bx%!^-USt7?=P_@6q&JD-#+WO?v z>un9jQI8Ue3n{538gc@n-KtDP=3*lsV4rGQKG1enY&UM?K^7ZQGMOKc2*8j=yOc+p_20V=Otv*$P5 z9@H8UKR-3Rl{@(m#wcMFYDgA`?c*$uzb z0-!EZ8_agHIrayoc!@xL`L`>u9}l5?tGCWSkTy*#Kmd1uk}Q+?+%TOnJwDld+(<*Z znA+;gK6M$Lm(U(--mvIRaS@_rSViPu2HWhwGo`3GYbI_zd4#~t6_b(VHz3G;bbsVj zA_^H;AZBH~G^~y(L%bQsSHu^QHeaadP1OESjKa5L?lddq%q%%ogUM^HAH{^eSaTc^ zb*=^OUB;cCvgYj={Xvmdm?$WqXAW|-V{G-2Z>DLsmKQmL+>`sAcyXnXEF3_YU#r1A ze?U)B57DD=-0dbZ zK46?Sa0K;98_GS`Hg%-Y&MzJ9$|$P-@wcW2)+0?zI^c_G0X#(i{g)%5Y;ESK=mzNK zTKxrMq@!vf`uO04OqfY9FgZET3vO$gP?7lYO?`rhwZyJ=Izm3v0&#alLoq3f(U0is zFW&AwzpLq`>Biv^3wg5gQ>`DF^vyUS9I1CzKT1>XFU(?MhV7^~TL@^hOeJ^FLn9iu z$1~@;Y5_Nocgd=;>6Er1Ru~R#or!!j8s4|Bn`)N!7alPTfb@Oq{1MCb8w?H?A4NdS zJ?a+q-=UfgSo^FZU|UE73Krpi|K}8p^eq4P|K=qpEelA?$Osh3RpCdHgAZZ7=^3iW zMMXrE$`?s^Q($e8HjAIb_)t9)-tWcTiDu|Zq8Ngswb@GVVrATno^E#e=3$CCl53n3 z6-kgNjjhRn!O?_%_j62f7hbSw9-F~*_%qUwOnofgWY&<#pOW4_v{bE&dLtK1iL1B( zWvh%_aQ)7o-h}{RZw%6C2RvCvViyLdC^zF`KCeR+pT9UeWhE5+JiZ(kUgz48T66=v z%F`P@W&jVWAOtqj7ZV~J{VxU_saHMvcc48K{q}WRdirHR31YPqR&>tb`A3qk~BL)zZ884-& z5bK_c=k^8rq~0rU!zSKW#72PJP!N6BEXk2W+8I<3w;`4kO10AjJw*Q8%0k_%LS2#$ zxz{Ow{LPNG^$y?Y2q5Xb1W0;`|ND2MWaR4jkHp`9*n9pbaDLIjIz<2Ksu`C_`W^?0 z5Xz3iY^W~QRH;Iln;<6e%P$l(ZsEbcZlZ6%C}?UTZD1=62dC0XI=Vrlu}Hcx+02Q4 zO~d134)@jNq1yD#%h(uJx3>m&%Pso&g=hK6&E)fOyLlV*hX1`DJG>^Y1@Snp1v1)l zw<2Kx!E)8XP%UZqUcBYT@MyduqbFbd#8s%@%}qNdKAgcrDyka~OviFK`NjxZC-$=1 z{5dUXn3)T|J$dcc$x|@MhUA7CS~l!e5hF`RpEWCXcOB>++t*E{--X#zwrG3#CL?GZ z!#ig;7{j|@ceu`rI5c~w*lK?|O7PS0(G!T4=!P*+=(fS)rKo&{(`(9gVMJX9fEMaL z)VG-<3k4yp@{_Dy3?Q0Kim+YqU8*LGq7aHKFbg*p#A!@u-Md;HO>YteEc;Sfk=u%> z*SWN{IV{>7hE@?=6y{}m$ub$VB$sB5Cv+OP0zZvM9F9PJ)(C2>+V+A`(d5OtvoRr> z4by%Qel})C?_J(WPiK>_$3snPG94p3GygbAvRa#*Own#V2u`!6Q$1Oilgj-iXX4fW z2wK|>z6U=~*|Jn;!|wcTokwR|Zl%6ez)*LtM#3ohWt@dxm$OT`0V0U(fMB#oAx}+t z-6vinw)NfbvISu}33R^t&PdeQ7I>(EcKptJJ_WT^&6t8thSOmQA+nr2Fp7_eK@ey_ zD!-;=Mt?JR2C*;6t2|+RK4F(r!KYF!erpX6A8NO>?m1g^r7O({HMv}>-6eABM7l^f zV#htd86uxG{b9y%v&8B2d6m zxu_x4+J1?=9n@hi?sqfupK1PBnH^zl+FgF^Ctaa&#K(tYN4jRo)g{pROiK;6r? z998q9t-|xn^T*J%0QI1HVw41D-%Y+EI+-T-t%&10ybaM!Q51xVV@Dt+#G7>)6hwy( zZ*Z`9HGi6?=7zgy5O1iB&kzKx4Ay?k)QPLARzz{&BN0+-(T~%GgWdOs(bW9ZqB)s9ndlF@w-A+Lo*y501~U?$c+^&)k|PuPc_o-pTzPV&&w``j^AvnX`mb zcMFk{CIkQQuv8<`X(i6MzKhW-lFf-ejPdazZd#YK0TJkIFgDG-M<=}bfcx_%f+aD< zH<`o*?$n};E2|)~WfI_$ZQRl_`~A$BR`=lM2or9Up!DQ*p6*f;701UL8FkPtTjIi{ zYX=IozC%z!G|()XS}wy<#`t2}IYQrFP*=)&=Dw z_VRmwN^lO{&;x<*xPq{uee=~Y5yf%~z2_vC4+Js3S*E}R?i2OWDhk7dz-T%t32);w4qY@JKtC;y$qoT4&&93awuL)Jp|d*mlvq)h<_L zeb_{29dl(6FvlnDx9x7?wI#eYDoCIqWD~RI*ew zgNWpj4aEv?ES9%NCLZ*fS95AkRl+|*w*)wS=toszowB?04KJxB#=EN~ZYc4~W=f3F z2yq|4(ClbMU!_bxj~cs^zQOMdSs`z9H95Nd=|xg^rm|(j23pGCglnntOXZIX0S?qa z{R*Zee>BqH2G}=Xw8XE8YDPAqgL$pdCXNa@B&kbYwg$PH%WX`tEI2j5TaZEIh5>>> zobWPmD^RGA$(Q!Ab|yhswEa5gMy*%**C6qyW1>KZo}eV}u;w+3uMRcdlk@im4%#Wg zUTqgBux;?0pGt8&drEf%E#5A7f3!qlXo)U>hcTnP1b+PunHjA%{a^s}nZ7~%eJcDf zOt0@`W@-43#4mulRmjL#&&kqJ&IUkN);F^>a|A?13HfuP+K*rgVt1QDqqsG-gW+-21#fYRK~-HvJHBjMw#bBkqFiN)=G=ilAy zv*ROoZJ9(wlv0EP<-xc^t2#F{T_hwg+r{ZRp z2bU*KZs6>jge%?e;O7)riw#BOS{i&`BX~@NI4x@lv0X&?YzefZ`?>&lnr5PmL;H06 z#`Xer%&Mv-Xjz@b&a}?{o+h+BKzdFG=nwq*#7&}F!|M|$f8qW)$wyJ-O?5yppqYYj zds%9Fn!$}*4pK+jF2g~1Q+@HpGPpQBm8=WZq!NWw|Hdq~syfr8k(X+D`j+6jQ)HMP zMpkaS3+DMfl;EPZHF&YLdYfWRCb6P}S@fusoz9zxqSWM?qUWY(lht}qYuyoKUjz#h z)G3aLUzM^2)c!A$s=JUm-5*KRMfm#+{kHyMn~YLMfqsiz>D7bWn~y+sg1@xT^+mz; z#G3GtpqKL(WA{(JUZ2SZ`!nTUHh@;QuYQj_p#wi9UU8S6MRWHzX~Ad1J1nl$GgV*B zI7_Iey?A#rc#Wy*z_RG3j2U|11ixWg9Z7$!F5hQcy^u1G*KtqIyQIOX>U^(V+2tn# zm+-x8(39#0GB`}(#xK}dda=qgWZW!$tL`T*b>1vJ1NBe-P`K7)oD3)0=i*7WgRxU0e_M>kF$5)+aTo)(`zp-5Z*_bxikT=2vVW}kzA zMv7~cqC>3Xfs4?5tpD}rOFTB5=L)HtFA&g_uAeCqSq*}jQeLfixl!JPI4xWzff^e+Z4E#wDk`KD(bbKoVhnAT#ToqU;t; zrhFQ>0+%4B2*V4w&^t&d9Hw~8$43Jm-c~(CIyhI#(?7CtUvkAhe}sI@C49fA28WjS zg2fU`2Z}kr7p;BUlm2FIwFwdw+LJ2tWkHIN6ZF3rd#ivr*JNurxDzzE2AAOOH0}<; z-QAtw?(XjH4#C~s-Ccr1zTUIv%$dFaGygdkebIf_?^AC*RjXF5h51ws{*m8GfaD(J z3y44(Kkgx#jFW2K#ty!KRK6p_Yt^u-$p@k7)7o-B`I{C`Ek>a(GcX@%0depDfHC}c zKC-s9ar|S(^_L8ksPbKPO$6;@5DvC(8J@&9fH)1M18JV@1ck7nKQI8z(i~NR+{_~Y ztA;;`U0rNWM|jFiJb8{)*6TR>^aO8Y84?WUbJFGd`>XNg@b8buSDjD1y)KMx*Wbxs z>|}cz;9;0xgczvf54!?5a-TJOF&GbT_yuKplTp3|ILr6;NxG64z(gC}Z&SmJ!K*q1 zdYV-}ku{er+>8U2Iah#qC?o(mNhqNjf`8YOYG>E&io4 z!p8malWko3l3t2tZL+CpPa~+9qsz!{Xuri@FWDC)a^#vvwSsY`@-HB-O6 zq3-c_R+_9w3!L@ub8J%I+8U|bTC2E%)Rqz%s?A&A6=@;h$M&KM(^o}O78VX^#~vJ` zZCE`N*9~&o`l`NIk(-=;Bh8R%v_(BOp0y%8-B4_kiEh{CX{e@+6Ikr~0>7q@$;&dM z*jFBRbg)OEbAd;M$DZoU%0$jc_a?XFL0n6%7syG8wU%`Gj2LKYMJP1x#*PAFvJ{#@FYFw-nl*Cg9+?(;y#{YUdjphuS1qGnFJDbZKtdZB=0GkgV{$J?5P29c^NYv0 zXqkd*p%AwpdB}v-VeW5&&*IipBu@7u+DF&yQO5pR@2nvJQV!cCBHu$RHIvFW6XJ(r zD&>)W+B=9??TV5`p*Ex#L~Y_YLjUq54{LDCj11k=pAqmtb403u)n@jFiF*k#R9pH~ zpK;~xERCSG5cVlQs=Z93(aS-x^7K`6VS&e|kD1C`c%3au=f+ahOT3}vat5X-Mu|UQ z6|=e_zyvmHFHrYMBW*5xoCn|&pZJ9=kJ9eO(aOQ5%Sh@f%Nc^1Wg>JjP2Q1n_jRXp zC0iof9@$YbRuh%JFLVCRVT|2#tble&-H&2oxD}C^?~6|>n&uw5xzVm#fsc%p`sUurR#n0?QLm*tx>c~cMO8g`;a{fFC z=h%(p5~X@^BBjXdKcSQ;1d#Vy#3Q9*REVTaC1VrFI7F`C>p&vJ<4(GuaSTwrp1H)j z(<9$uN^viOl{ouJ)g6=a<4HzsV%UdG_7E&ML>ytWT{ntx$KE1_W6vBTemcqy{pOeD zSiyOL9~cS6@6NkoiSvQ-)GCHV2fam#KE~_CM^wim9mD)?9dkg2k6NG%O1wQ4>y@~= zXo|6Ch}9Q-pG+>&McpDDM`+S4F!}8gd>>kT8Z8d>GO1?6YFVLxOMGsK#0Nzz`{VO} z13FNDIJmzFF}4E%9a|vI`5zGIf8`)?6Kfm$zh$6E1uaP&p!LL3zopjFQ*6qrY-43k zEjya0A~<@0;4y&KmsciE5AVCl*tuoy@6j$L)7)ra@}cUi$BD--Z29bPwa#%g-s_u($OOl@+lgW8}SBQ7K|HCe&Fs?ImjY(qnA|!7oiesb6dcv9j9Eta}?{TmiLU} zga0|H=J(SAuT;mv1#dnYm5tO%=xVOg$N{%WK|!42irCQO15PZ8^w8#7@k(sm#8)1{ zjl)3-kGR!6A>*v>6^`WWLa~BSVfnSS7ty+a@JC_Yj|jz790d#;2AIlpm2S_rrnL<4 ztLD!go25~aj;%%^Ek*+dA4g=|(hh5?sXH z(p;w7)I=kFWPVHgzGb)~xRJA?44pinA6wXQk6Bbw1ckUpN_;w$I~ty>{YfEvncs_5 z)3Nb$o=wS{=*9PR=z>~GXO@&e3AUC~l%8k5qQ{YLl`0ernw^hjygp_+ zJe*f=@p*$T3oVI4xNs-fEft$=3_)H#w?spsb60F5`}1w0mac@lr7_YxB0h=Y4`@mg zAG!Bz|2hz|i#O|;eq!rFw^o#JlcX|hqTE#fWO~Jv;2ejnyyT$}x^dpef6T)hGUCvf z4DZ%4)!5*CNt5~*=kB&Bc~8PQ49yWY3SH@ni@=B#9Uzm>hMH)~V2^9VR2a}ynbw`p zEDP}A&xA{0oG0t; zKsk{c1K=2`*)(E+95R*+UXiEbhb_%U*0lsyWzzEh7y>D~23`L-0jmzO3Qc_s4is`` z-WyPnl!CL$6bhql_kZx2k~X1FQeVy=3&mueRC|6~PTE;?!@6$`R=557lFGcRqA*F<51>k zZq;FPnfh9(7TeV@fK3d3Oon@svFDPQg?^&;*aM@<9p?^1*boI?Ye5@zy)U|X6NBjf zLkni)dc;cAfR#&AyeSB)PGG!G#SB zuKz#;{8w=O0~}}iOPLd?u=a=1H&1#&t%Z~zw%AxEXrLzS7eA;1l|(|~&lF`;*i=1h zWLmSdQCb(PXuN?w+qoTbFeJP`q6NoSttH~2ktu;gUWdty%nhCH?%&|o(B+7h>yElR zNr6UCZtG39Lp@p*YAq%^yZ}2bNXAv&;Uyd{_(10tYRpkBtdI%Ud5p55S6-tpZ96|+ zxirP=r{V%lWzBN(@hH+=B39K7}pqPTP+Bj05=Y+T#jZ+YU3KOnnZerQt7d)mgtsH1+n6(-rtoOR< z;`NN|kydeLz;5f^BF@T+k1j4suj$)ku=aA<)Uw1FHDg{<7Z24#mgIM!$L@=)Qgrag z;R6>P8t$O6b~NuW8eS{lB@7x>>bw3&fOP@u-KQ<3NoXV8nPSv7SLJz`yc-rs77 zl4sW!6(|3yObiaQf~G9iE4HYhPG*(|@iGT8bRl(!BFqv77Z9!{F|JjVXdO>%pc_9; zv7$U48@QWnx1?WWzdC{MQeWJ*^1ZoXh$XCwd?xa5D?u;^9t(e%dP4#4vj0<*G5;;f zRwVj>1G~A!!9lO`*9XD|DnvhPwbTdE*2TXxR$p>UKm*K9|WYEQoHKN zs3{(onGQ0S>my@ldrUu+$6Jqow)n$fU`cVN*watMY{{tyro*o&w2sECJxq}RbcD@X z3AE-5fN*;>l|Op-w~jJ;s>wP1ZW`x6lhXL|P<#oSD0!9A}6PAxRV z+a{+ih${5%bgqFrqh~*leKfWh;qV_pdWKEzEkt&q~xl(3LZM1fUIyy z)ak&xR|qf=6+$wc0{AXId!`H}3J3xM9MFOp^ff3^@Ec9f5&n8b&7&t+S^&?t2$)I! zYTEw)#cyPsEG_?fy7H2;pbSV^y}hGh9Ro`v{>UMo}dd+#Y2wR`d_J(em3gIAp(d*HD4QW zB-}d1PQe*DmBP-NiZ$Y%DY{A=i_Wv;N9I#R)Vw;k{A8|(gWbcKTm%WbNr~k?I(O&Z zJSJwzTIDT>w_4pCpSh8;ZmrnKVopPA^#w}g1)G}~)4IPnxNDbaZGJJ{}T!T=w~y$5$j4i(+i7}pm8WX%jNC7g(T*H%iFK)n!vJX=v#_1~u-HL%R3 z<7W_*#Jm!f|9fF^ap`ZS3p}yu|3hJ+=maEp{VA08m%~d`)N+`WL*l^z_5DFu=(h#Y zm>4agu5;pu%k>cYAi#N1A`4PQlF59sPU0Q$2MJt~;8c<;KOeaEa?rw-n*f?`fPa}~ z={%LS(f<7FbxrounQNIq-&X`PnsT)nq@g`DbE;G9IMWi-GBxF!0HRhsj->7pr0Ru7 ztOQz@pIEneV>|6V^3mZu`6lruxqA-?9$QFBo&+4|TMgVnjZxG=FM9k!Z3j=9>_L@} zpkw&9J0}}IZ=Vq#rCqMMZyT}fiEVMeHEGov;o#d&H2b@`9UjS_u2zY&;!3&R>$_yvB z0uH45(vMThCe6-Sz`j15_9tsKYI)Tj`ttFk;b93D! zjgJxgTYhn|i`Fxmj1;caY^6`lV@fdtYmz69vGx%Xyy3#FSy zL-GK<*^@Sz0$;ry=Nyb>#xn8kfA6YiNe4N4>2dTuq;pWao*=(fPP}&EGc?E-W=r~e z?&{h%IBMs!Wzu|2H_h<(B1Hm3O&T80#}qT+Kx}iu8lD^p#)=u%39yPZEt_T$Jz%X| zg>;)|0XU3`^+?4Nzrw-FB2yvd7SITreU%9PV&`8Xxo1DCNah${Blz&eI(YXIsVI|> z1j3WpdPLju8_6zT47b1gHN;5fQ>Z=4tYL|%IZ1&K&ks{3p^SWcw_CK5A81OsDcrG} zL$eVLqY(`f6tpNxr1ykEpMU?`_Rt?aQTqbjU?nhOuYp5VrvG`MYNh9BVEPA63?wG% zn_27WTN+9K`O}}3aG}zg!kiqM7J26k$q!gG3PM-9N+fx?+(anb`@&IEF81R&v-Bj# z)q?n<$!l5O;|RpOeBgYa;}TWS-9$*o{$VA#@j?4l%KQD}0re+#)^JQMt}wJXgkAyK z`hWy@IkG9^rJi)ru$LZBh;F7{!J8k~0ARy7#E7;%5AW7}W-&eL@Och?CPSW~b*|1S z=-F31Rf#uyvuNISkRHJ#U5}Lk)5^Esx{nX~4mT@rgF0koxA0QhpEK<6S=o%Vu<- zr_YTl1ewSB)PpLv^7c`)+^#+AMx3s@uohmlIz09@58htf=8IK+&Jk@;Abwr3 zb;S;5(uo3PVUs@*FLx@@&k2;iJH7JOn%?TErJb$*M4HuQ5wh-u>Tzeb4MdxVFJm0# zMi{?Lf|ji-q79V!%P@z6U?IxF*bj+aOLmd*nJP3(bb>|%`b29=_2JBV?8Sv4=NHCn zn#@RHYWq_4Bn?uwBZI7yI6Xa#f+p|}9Na5C(*&hexKDyR{8p-#tBkUp0M#u07A(Hi zq??(KVvuhng6rI?)O*a2Fo3g`W<31^yFD?o95j`fn2ix)Ir*c6;3uvtl!8O=7m=bcpv$V^m-6RL@7}IZ( z?nu{Jzmxhne)>J@b0?YQgyXW#bn|bVv_GO>lb3ML5E%VwzdzeK;Vo`LCqseT43 z{%J4xpw7OEuQ~7qS(sYo0?s~fSCSADLP{(wZCZD?`C_98C}p^`t`*8RN=Js`|EG!2 z`HWa4^ZJ3avx!Mos+;lU(iH(8NX4EoBvVUq^6PiQYrI+o zhuS9h{+LY|?l2>^0+cJr&Lrscj)QpPF65SVzTMpUqg+Nj7sLKfkQO?W$d^ytVc=$? zK>5}mv$h3c!X+(N_mjIqllU%N2Tr5w+={V)+S%h~gcD%-t@Q}QsvQg6KX zZjGP{a$>dw+8KDvq#=n7>C2Z|cqIk3NiJ1-8fjMJVcgNC-5dV+uAAx|9Q;rsEsd{~ z^6`Qb!z%TytIW8Kfs2ZZ*{J>t*6@t_i?_r%s+5t6`^f3Ys>HZH9G#xbn7(GKbQ$4etYT+)J?+>=0Y=qVNMM#& z{h7=F&E>1c&V(a)yg^(w$1`Vz>*s~(hkkmeSe(Lo9V>?*$byhT&YHaMl~_hIt&S@| z_a;oYO_l`15~&foWwk3j#-&D-I;fQ}0@;uBwdK#?nkGkkk=3417u7HSDgWY~_PgVGk>+UXP7RR!Kd@mdn6e1$l zs8*@rssROSnn92PUlwf8M6S}VK~oAe&u)AOw?-fP_DqU}*ll6J{rADa~f zxy~Eo(X`+8x4Px4PK8V@l(WU>ldal((dFjx`?89%U;ox8{*mGQWIt5|0=>ISfrP2Q zZeahbkNDU9F75!Zv9vTY_+!loU}Np5XJ&0?ZSv3gud0>xN_eghI{V0Oo} z4-T|{L?SfD`4B-eyEGB5ji(x2YV~ANH7u<)X9be)H9fE1QVAl%_D01VJR4|H)=WDw zp2#zAZe7Otok6bBL|ykNrg>!$`Z_GJo=X3)zwv5l0z;}d6~3A=kLp!&=Nj(R`!O(>!d)SX*;f$q2KrgRt zs{LrFP%d6?5ncTy-fm3dY@*@7(&Z%Fn`i|%8ZW4trx~I+gA-XG90)K{#*I8t)vz8V ztrTPVo)1WMq;71A75jidi?KmPja@R-vdB8tmtL5y z#VsJF8*ze}gYQ>T<-9>80m_uTk);t{+x5r~(^b#_p zTn$E%AMZUiMPHnpd`;LItfdkuJFNLI+;Tp`!Vv*28(|R1y8Jc6C6!tqIcOB$?-&!% zR}#;%ZKe#BYgie%iBl^My|q>K%@R(_$JPKkG|$kEfNC_)NSoykX6d^{B?|Tkj8fIC zulbIdv)pP1L3|G<#)ZLsI#3&x?VBl?GgqA7kh(2s9&=5=3R)pNdfmhL-&CZbY%UtR`!prMWv6&InI3t(P;j3fS(8QhAHh!?VP9N<&J?v}*OwlrF-X zEz(9Dl1aN~`tQ+>n#nDXuW6_gO_7?2rBlf6!p*bBgSyxHuJ{oBy3apRVX<+H@Z6&b zz%r;Sp3S)baE2xMN^&p`295QLO~^a97!iKf218tzO{h0yZfVEc{q(NF?i1ig`|b2+ z))Q@L$I_p7MC$T3FWx@HlyOQ6PL9)Pqg4R3YcNPtWOVxYXY|h^kP7bC3Y;=*Ig|2y zkYC8^2euL3sV~xeM&gYc>Y_BDhiy@=;Hqb>@mldjdF~}dHX}bo;&{8FUzyS3vZ6AF z+`b^ewzrAJIo*iHRLcjV@IfJRY7HP`tb>KL7xIG{uG4;cqmbE6@VQjpnlRg%fLJwn zRXZd~2wtvTk!Bkwd;-^ULn6{orP;DnL&TLx7?yCgl>Uh8A?iH%Mu_ zQqpO*CS=pcIZ!;(p`(y#b_n+GduUMmUl!=o(ZGZCe&{ z`RNr=C%URcybybgyu!GpZ7?5-N1MzpFPUq&sic}ehEMmC9 zbtO_w6ppfCc61yc70&5KHwr8a;LGOu=N#F{m_4$9<(~?Wp;Q@_-R63Z(Qm19g?^8= z0*kF&=Y{zWi*+lX5vmz1JA@)N7K=+!6&@kvGMUlh#$5xbIlu^WnPLTMe z_Ni}IewsDfDXp`Zgij)z=F8gb`s?}(SEtP=cuEk4E@b^TYlxOet^`BjXozetG3MFd zkOUEfr-mt+XrtQ_jbAr2IXlSJ3cF_m-EisWxV^mUI7_DC=2y>Nb#+WtdpKTR3Lm+R z7Lcc{?Qn&&+{H_=F8Xb!`RD5JHB<~b-_a9oO1yuZc?KxHJBC!sQ&8;C)!Btu>P`|L z)#}DRnzCRm6y3Rj)+q`4-P8uUf@=|v74Q};WVrFs|0?T@UM1PS<@;2f0H#S{kYqO_ zqLr5@UvQ)S{BK;bKWc=1>>x4=U>Af2tP}nNH{-tp$w}YgAF=co2mm+?1KO=)^3-cJ zojbRxfg=ltyHe8DZEFdk`0bRA0@Blt=Nj-u!+6^jn=0sD)Aq|V&DzHd;d@zzl!lHPH{XAeihyHS=|ZGELDlj?8Fb5$V`$6mN@5}87Q?@0^Qa(7gHVa*_a{+To_L2 z+vc3j8#HkyEgQjf$h>sHLgW&Wp_DU*qS!HluQ!FkCNX&Z8$%54?2yI=8R;qEcDzIE z;m-};e#i)|2ADIXndhThIhndjeM8=}Drk&>9tkqprnRCCAsQ_RMQ7&4pI+u*LE<&` zQ$s_y2K$Y_{l+>oJ%t(qz2MwbGcj!(I*#Mrtv{ zx?V)+)3BB;c|>VgV%>81%|&96wHlAUKhDa|h1w%QkLA}7qBxr5cj?JGTDB=9iJ~UV zghr9XX;Iju3AXfKuoy=93SY-ubM>$rX#r}txR~fJOZJ#wU=eELH!M)(7VEUWS>`AG z3WX-8K8tk>>+%(oan_IJ`>ElMpM$GRD2cz(1a!d`y*rHK*^tbfof6AzZ;zzvlS)^- zzQ7hR3eSqpLj#0x1l@hk#!}j2g{Vac;+3?P!d_}Jo$u8AgAi%2%~SA3G)Pmt%sZ&h z&y>ZT?w4V7pHSCq*xp_bo|%40df>KC%7TQFXx!TI4PyE$NsvYBtwc4?RixcgNxC1G z^+VB)r&%9klylg#@p(Da1^w#u2c)%e?!x+7jN;u|=OAF4hF|k{kwP>3ZGj5xGcsdK< zx{MB5bd>a$)PzjtL4Nn=oeib{`Q*sBb-dCl#FpQ~@badmty6&~iYHHd37UEh!Z!Ss?vdchivHiX+j@d`GB*ieSH z2#7&(oPFnNiTJKw?WlHWx=^4G^WFF<{8H4kGya<)8PW&-64Ou!+L7#St`TWbe|KNu zb4pzUN){rYuX{+($u+|ZK$6e1vL?USNAa3}=lF!6TdW zGtRJ6;?=0`AT-!8t#}<~_ZNy=pOPdBWkKi)Cd0UHR!p8!ALs>I-C@n~uc&2WNv`fD z@!O}a(j=SFv(WP+<+7wK?dd7O>8bDL2h&g23?hhjQ4jCrqs^E_6US_FiC-ylMK`U! zi}tt2TArO(3}I{*Xv4gy-Kfdgbc!3vq|Sg2&?&Ih;m;Nj;Eju2dTME&Tu(H5RyU#9 zN4C|UQ;Hn2_;=ilU!{ou1`i}-bPkDSuG|Z@8VFboYuywf+RQ^5ve?(N@(YDRd-0oR ztJ$qA|NU=kNq?lFqUgpMa^Ma62gC8NPJ{pIvh9uRoPe5UKotESOp-sp{n=ap_sE}t z!FoQ_-w(S`73-T$Ec(ezHy*(g#Bkhppj969*|A1^8@N z4ZX*fOGabDYH{4UWd!);zPR|Tt>nhu)=a#s#vYR~ewh;X#D&LPMh19myfAL+sns6E zM5hJAw>r}kuIr1w>ydIOz;)KxKXS;4P zG3{9*lFPG}SeI)HH1>aqI$O)7B7rM@*JG zbiICS!mu7M(N4=|3VeTt^e?mtzn_Msm{N#*$RYp1=4gCE!)ZWY>=YJJ?;Lh+!lRa} zCK9zvJU|NiO+iy6k?QQkLQMc+`n%R#X@!6+q$))-St2KqRH5bqs0umg12j3Hc&EYM zV1F`1TC0js)-kLmDe9ewnJmDBd5|NGWwdICQ&{*;?Uk(KO3n4cQ@}Zb8!xq*p7+E~ zICbeOf^@Q=3YjB3+x`5@zZtju5ptT}ms&c2A(sy<+WrFp;9nspVrB`{kx=;en9Ec; zQvh!4ek5tf1&QTq?(Y^7n$n30AqyiVz;<)81F(!aKO_L^y#?YM1=^eaLqD-VL`4XG z2HSI|LsBRt+)S-()E{MBd8X4H9aY=#eHz!-5`awwe~CdSBad=}U@Rg9g79Aj;;;D! zD*}Rh-^B#j4$-&=JN&@2C}OUadi?@S;O(8}JlB|cvh^B{Z_}EV9BFj+q=y(8#+=nA(6SDqcKgrM=*F$Wc@3K$Jd zJF$V>V2CiP!&?Rq-yZL)iR}hwIJNm8=x1A}o!Kq=zC>$s;jhOUkRF#9x3(W7UI}-4 zggJhGa^;A=R9liq07eDLP(U1Mhc4+lN&moHP`Dl3clv&&fn<9$|PSJioHP_;f5HI=rm zaIYkKIYmgYE9p2k;9-cOSQ4VXNQ zbQ*6O4L`>BIMfRTL3!WcnRdi@yj;c9No4i-)~_|1AD^^ZPr!tDp?vcN)DzC3SLD<9 z432vc>IjV>%^cfcz}q#z`}{VnKvC!mHjxfd(QZGLx6&PR3N?sXkobhCd3U?Qm#%+) z#tgNW2=x+m;UKpDoSQT{qw>}`t9p-1)ydOL5H z%%~?Dlg$hld0FHKTdsG+j0#ru=>50uB}=?a0}1#d2mo{Me_(a~>qSts0Se$+oBZWX z__KFG`zXS2*DIV}73_hdFmJE4j0mMe(x&HSNs}YJv1>zgI(2r=yiB{UW=0lczJYqm zk1#0`wlwYJK2K#jdhj|Ln|vhD=>l;L$RvhcrXq~y8eC^ty1>0ej~(zbz~7%9&K-&2 z<3+ndWeCGso*0*~jz#h?ZXjg(|o(b~%XD3OLuM1XjouKLi zdNe96X4W{(YJ1qNQiLaMzFLsEOLh>=x%lWM6SwtvF>|`WT?ml_QWw#af+*DuH`YUd z_lO6G@Mz}rQ4jLc>^gam)SF5a=4v;QI67RV>-Gu5;_z7zXHuCDrKpTfiOPMkW2zu~ z=r_5x-|ZthMvUoSUWj=c#DgM593TUDA`09URDJ{GYjMa{flZ8_X6mNfP>f>@{E`52 zI3lj5Lya#E{F*8mVr!f{iY;KloV>xzioS)G`#3F233C3~dFsIX4Vjw^P~AU{T}iPqfp0u5MyTS1G+r{Q}1C zfNk^%@tN-~d|#b{q>iZTsz+qA4RW1=G|%#_%G6LG>m+a%p)D6?OCr5s3w@+WH9il z5&U3&Im&RbL^QFhej)nbsnc?l`^z?h3_<<%f@H|PX<2#5*yMD(L%bbk_zk(Mzpkwv zL);^pXJ3txfQO*%WL&)`xp-{S-ra6({RXEG$!2CILLX!p4?Rdzs|r8JhX$^Egt;M5 zS(~Z-w2E9J2tSBYyDV!d-a+-m?lF1d_M_7cF_ITn7Zw4a6@^s<^{FY;R_q`tP|*;z z68B%04^u*$9N|ulsuz{#u${C>h9>%1xxqB+t`()%92l%#(+tV1Q!JAn%0s9-Z;pG! zb9~KKomM6?U&%UI6`5R$l}&i2C^RV^_grmU3=n}BdQ7WuB|!g}DYK$El!BNTLErO@ z9maZ4$a9oTT7~;EFogDo>jCx&%E8s=vFv%SK8KL`#PHY#Fk3g#+IyOJGKqmK6fd(n zOp94XI{9HVtkHzoyX=iGZez_ZGKdm#c5Xk}yXlNVoH{za*n04D!NFrp+W~J%%EMSh zfSzo9K0?ZPu*M!DnOjsJ-SjY7>qrkv#^0nxvWV@S!s?~%v+9A7v)S=W6IP(R$Adp< zMS3a>(^-q4=APFLKXYTaeQ{1_Z;FMngHo1Q>SkShuGmjb%zCa-C2~%+ z1?9DVL}mv(ybr1~oEChxVTFv{s0`0jN_`AjQy40wLw*PQ@P1WjW-F-|Ll%V*j~Dhw zy=TZ#p*0DKC=w|Q*i%5_3QN#3y;6`*?uH|*^=d|KK;mFn9u^Yh6R%NKtMO{gikZQL z`(jzE?g4EZi*6{Mg5BDv>g&cRn`>Ih7bkfm%ckrq z+Nx{eA(yADuh$4+fQ$7+Ms6YfzimKYGiK*Y{iSplX$-XSVQ18)HdU&&-1=rro&i4s zI{-QQ>_U&5_WCq9&m4ELpj9=EWJ6$5O5&5A(W@6VNgcK!4yGSC#7D*~0UQx6(+kr%$N9@^$Cq;^z zO=<95uXO0aS2pCZ=0H~YdLpNO@XtmA*uC;0(Q)qT=6RK@>Zdzn9>UTg`4}Zd_*7hOI|jUv9R8>A2{Y&xhg$PPST?;)Aq#;MHn1j7DO{lT}dSG zNF5XND6WXV5Y0*+DNmb_HY=;cq1y_(lJcZhUX6F%bY7U09QK_cUtc0&q;$=jfzm@)NBPBD=fp0F`1L@v`?ZAf`! z?nt3<#Dk4ejsvdD`K6?)9OcaNJbE9b1re=tc~@TH5nvU(rlw1_RT~`clKi@nGS5`~ zd~(d-CYqOY-aDgg>s;Vy=@y^iUU7pjxd&n~M%b%YC5sV4xqH|Nl2Wk~=_mEVo_ z15hrJeBqg7kA}GLxh9>aD>$}Z`UvkFm zpD3VNAFES0HdB7n`V}mI^7Oa05OOLLITT=uzlZzuiRFLBknI1N;{TzXuV7^R&obiQ z*8x;4R8dvYHsZm_;J-#+KY(<_(1R42HdZRA<1{u#E@PJozhd|D2MuCzrf%n7(OuYF zV>~G@mE~NRC%><5%{0EynLl=>a?^u28ZoSU9CAOb9IZPXUH$fcMg7U_JzGO?v{v&O zgPC^|z5J0`v;Xzt=~Jq+W^ab8rpisO+>=;GJF&`l^gHa;>)Nn#Y)(7r0dnj%JLx{q zsv$dosdw29lV{Z~90J&rf+fw3no_J{Z2`ZQj7DLemeO?M_r^uqdNg(jrad%&CfL=w z$uJ8D(k&JGhxN16+b-Q!>O;@XN9*t55U=Ajl??}O?U)5{DzVz_XY&Oiu$@z5#_)Pe zoO>-Y^yRwTE4uT{%TLM>wGGWej+t0PjYkq}7*;;o9f~o-t{mmI3%7W+p95) z2k%tJ7f||Aqi~kHEYPL8_uHCun5SO5j&y35xcO|?6R8!bTA=Mg-+MVmTL8(j?VQbT^2!y9MEy4qLu{czOtS%V{#d5w08J~I5bE!RICUW znL%WU6?&C!9$j1G=O<95NU)x^YH!nUaY$068Jf#niYI>}aOunRo0m+9Gc(pQ8?7~T zu*ddrdKh4CwprsbQu%V>*xEwg?9c+IMcdk;xIGefXLU@qvA!UQQfAZ{mt9ZCo);gK z)_9T-lD9`;i5G0EHiR{P%>F|UeT-8jMs?>{Z9tU@meaa-VMk9|Ko-@J)A%MSs(R;) zJ={gDKP}FN4&z)?SKD!^lX2N?%w%D5YjPzH5>FVM*^Rd+&ntHuIeul#8-w{+>n+f~d>ktKR_{`zg53*2xn--|>@tN-7-( z4H`T%cv(j%nK0?&)x01s0moJoD3^vksK;3N$zV^51(&nsh0jAFsthQkL=;;#Qm6=J zby$aTM!gLbWB6GHbJhC2N`{zHGKT63mLqa=Qqt@}ylu(IaS0S#m^f(SK@{7?IOw@f8nB*;W5cN(ov0lfKnGP)98c{08nl1e!cT2iYwm3I6v`R*rHH z&<98keZ3C}!wy1rhBcXyj4jtH=l!GJN8xipJN7V9e{J&0MgHA8N`b&Lg&qNU4n?Dg zEok*@(2n4?ogi1JB6$8bO9#GR8@eC11^Ao}n1NIgYwniM!&M(u4C2TrQPK`Q9$u** zJOAkzVZVtHM88^MCqswt96UaGqeiYRTAS41{4N3Vo2OhQO2g7as~SE+YQ3zmWGpDQ|1Dg%z{i?s@k zY|lgK7GGGiyUXzr9g5RJ; zg`skP<{=9D1&HOKLkvAk8be31I`97?_6~;)_4~Y?k5n&7LSe@+beGPycXPD#3iSi^ zd|s|!1-+B12|^u)qjEP!Gq2LE1sf*B!gp{wt)F@ifL^RLIE4(FsA$!|hf0C}0Pvli zmJ!dvG6k@m=nGzI11aO2zL9Dwwd_aKHT&6)#M7TE(ns7z1r=~)Cri}Y<}vXFqY|Uc z+y$Z+XZUlRO%yR^)J%R|bSDov{HjQy&nwIqb4!Cg-z*wDg9zlDS-)AwJWD(Zwp-GU zK_6C2O?|7xny(E?``N=MigNrhs@WyfFuq?K4Qi9f7QmArXRNbR@qm1Q!(i1k|?*9T3@_lN)3# z7>`@gLf?85jWac8e)(g&fN5@3kn;0o-(>6fW9D6E>ht^2E8QnJ*InYkI4~$93>Vua zQj2d0bdhfH-|0U(nJ<|lAO$5iD`4=%bUIhn40NY3gH*lH12h9!HY0>kE}|IH z&VIxs@_a;j$Wx?i3q$S@`zt0Q4D^Y?1+8@5E3DbrFI=;_H2%)AVH?VoP>D7JI0hWZ-s0oG?S1?8=#oS>_h7g)@v~y&0IC>s5N-%% zK~8d^=7*B5RsOS5*5D@64plU$z=R3hz}%4nH#+w#^LiPD~ zpOSDefc2-jLzh6k%iojfMB4QJco&gI!WQ0Q??tYi?2^Z6+z^OaC2EMNYG9t4WD&0KGaPCra|By3^Y(dy zv2hvPRD33p)IoY(FO*o>PAD`hmv%N?HMg1RH?DBPsZZ*d7C`sy{%eokiiYc70W93W zfVt&=Dd7HGxMTmfZO;Fq^d?3K!1mH33I8@_QHN`DIP0wp+8ykqpa{uv{hta*VTo!Op``c-PNZeBGy_v zq@56ciEM6>I{wPYtzI<<#8)HvE)N#DN{TWQIjx=S;F-=W4TWE*M+z_tCGc z{VSgjS2$fzZCswGiqxd3z2gDmt0c7t_9*zQ>$(bE(kRTV+Z{NFa$3_K?6ZoyTbd{Y z&ynqFG;W}OfzI6yPS>kSj|*&<>a{<=gZIkAc!wD~=t;x{TEj)0k$akA9Zla1ja%vh z&sXxR8%lI*V{G9r|mtJ{CD=qf>D_`UtW6zkhZ)lr1MZSge z$OtwZS+s9gyo7-!1p50E{{X4x;YLvyTuaGpO;;&lIWZJK7(bxfxr+QJE(E#;z1eQY zVhdGMZT>DRnX=SQm0w<%mKv4iIgDnB${WW9i`ug&IwGA}1VxUq&dZfZB7fd`Ds}qW zeF;UB`D6mJdS)Q9shGWQ@YDwXzVfCcJZn3@4#Qgf}POzh)& zos@YYtYC7a|#*0@5{$lO6uh5VT;KLg%jL1ZzXD!G`Q>amm z>WbaOX%Yl^H=m@9R$DqcU=yLo5-N#|sN*ons7@mlDHHb+2#^n^u@dfA!A3#z?xF7A zLzf-IIqX9Yjacd3e>~kVlbkrDgecDPj|K-pzJP*t;0$0Atx;HEEBn6}F<@eDuyU091&Mqx=LjE4&H;H7~PVc++Bnfummwjf=rMrydu8O1t9FYVoy6M;^I}$2--Q~ z<~U?8w~wCxKg!-IO0aOf7Om=1mu+>~wyVpwZQHhO+qP}nwr%57lAVm~eQr+1eO|Bs z`Y^ud1R$Feu_<9)2rB^=`J(_QPDzSm>JKGDcF(ARa&qDlsGb7bfmGB z;t)b!&-Xt$ns}EcyzakciyrG|)MZ!2##GI`v+r^(9JeNSV=FE?4pefM_W1-)E<1aI z8`5*73HAQ<5W5f}L~8oO1vx`hNt z8zn_K@tQzosGuaB5420dN&~tR7@DTj=~P9UNjg7bq@-n3Q6gjKT>sW0GhoD`S#`td zE7-&G7p7(QbGj~|DzMke>b3jv=hnV!wKez0^?Ngb#Zb3H#@ua#ud&UVPY?sB+>4*D zJr1Q0^AY`z*RR5-Pvc9Vb zrUSOtFQ?&03p>-_&!ghd;_K1K_EE`a6e|8tqaM31VkaDo0#57&*K;z6);va;HFByH z%h_^sPK?+~GOKCRD;OwE9Bl3NtSjcIFlwEua%JoHrWEcg{!-|T7hZ+|*COa5v!#@-^ zrM#!^!a(XaSSBfU;fIrk$NBRzo{&tC8CChkJ>pop5KA?-?B6mP4%uEc!lWF^xVU2H zXEkc(XMS2rgkY~zxGK4p>{0{uqY{89s>OJHvG9AXYpR;kXbWwb>WsC!y9JA;P0&G2 zP>{>K!)rXNi_vb5<3^U9$+`sVG%@)>A=5%4*M?auGaES=)##*Rz33d)*O~x6Lq%7` zz*XKpSuC3zQ7cJZ(K-d3L07mT@q6KIu{y%9zg|L^ZbXViWDHL1+BF@VshGbIFXRK( z3K^AGYm77W@dw5#$ZU$n`cK!l6{aq1*tI9yG9k@% zOa~N)jhboTq_H&D@6*e+c)HY3XtX8wq@24{MAjXo*JdA%mhtiQInwCL61e4|PhL_( zv-eSnxr4wCYlU&T8F%$y&5e(U_42T>iL3U~z+nZkyXk9TyO(ObwIbVZwfco6T$cxm zZ(2g1Y4!Aw^x3P@U2s_>9{d(N-S9Olu`m;(AFk%)R=o80h=2UN|6$S;-gr2 zzd+HEuh@&uvL!!2aOq!<)JTZmW@t!16^FMaKCr)OZ>7OE-dYW-L$U6NoAlCyBJaa6 z5pC1LZdpoS4SS5BVK>${raF9%oL2pl;wcuHg$FhLQw#N4HwU*Gx=ktVamno2N&c3cFcl;-&HF22=|(Bz0dES25-AcT5OfVBaxdAP>JP<*(V+pcXZ*weU?F-ly8goU``$Hsm{o^hdGuG(mCr z09Ew5p~=c=q)UG*WPCtWYBIq+*@x!OwP68^UQCiD>tdcNtcG`S{-Zr%)OK*jNf97j z!jX`Mr_yhoDfuzC)&q;XwOCMnt4=+{6pZ-{Yx_*trvWIAz>@RGNb}bO7&*TLOYj9_ z6nSN;I9CNnkcm4KTZ8H`T8D%ireu+tQ=&H7#`12v_~PgcQ6qS!OyO!*Ug3&Ba0)Y2 zRsdl#f2Nv@dbYs_!*^I_)K)DpN^~tEjv2`P^!Igm!h^}5`sm|>gD}jHr--~Vf>aY6 zUphau#FU@l1d-o}YGq`&E*aXTnko@iURpQ`X&4^pM3NLI)|gBJvi_e94c8oypRUoei!29d-2+A((Jg5CQnyDL3`$aB z_j_h;P^~Me)>3I;R#kd{IZih2!c!Itt`lG;3k%6OQ&(udZhJF_^}Oj)7WBM59i6M> z{uQAJt_>+j%+pVNiOqr5SK-=~M(qX8%4VTSusW`eztHEeEAgQ-VtoF<a)gVRI36X$OT^jC4 zoWuzA8(>$yg(U$CSh}0{nxsXWfKu54%k0795occ&9zjUp$8qvYV8^Wnzmm)%57E@h zhdN#3PxTO`>Q=wBvuLHQfwinK0g&8t9DaS_$F`chg=k$*XK6#Z5X6`l)o&w~kv}T5mn3(KwP*R)$6s#BB z`X~+W*9|bGuY~j5N`-Q3N7T`C^8=^`<3~IR|v= z^TTzaI3Wd_gmhJMuJdQ(>W1I@3vG*oFbfz&A!bu9Cw|}_M6V3xW@s-7)hZuRol>QoJjvc8NVziNy7DJ+J68`YZ^Zk<4|qc^X(8YD!X-_H!+ zm^n*j1;py`{}w}zk_i5xKxPcH+0$&;*d*G@S|IB4O@WgtITqch#)8mg2-J~H02JQ^ zRQSgI=Oq>f1t6#PXMuJ8Ve|hl0L{NoE{y+QJFL9=k3kh0SNuSQRk7p(v7&puVdtts272UFj#Gy9KFHH8K~|yHlf;}Rf-7}zq7@I zK*g`iEaEp-0$lopeRE_ss-R3VmO_1Wvt8q_*!O*w-fZ@+ki2;$`YhqF9vUdrNRKME zyLC=uQb#}WQJGV6s_1wgF7z)1uI!jVs~zxfjexNWh8lx2U4X{J_E{+)aXz)yIEOU_ z-Pj36W(kxh)tG>+k0ObfH}8*3-xm0U1Le!tzXcB8#Szv1;*jQ8OsrVUS+)~;QU3W; zwJ^bISu_MeWubd-e9xQlTfA;`OuE0&w_3p0T?5FXg{BB5K9$TDQXpfJ!L|Xrx7wN*hc*4C%_^b z{*&+y05JW(V|4%b6QKXc^s4Zm%4GM4jx|4EiY_0uTx&ZJ*#LwHK#7^MP{ogqgnG)> ztyp)wFW?UvFFN0}m)@6ET*Hh_=Azt$23#j&E2Au9BP*xpe`n)U=A{jw-Puu~iR78+ zzz_i$a?aK2#H`NA&eoRbhxW1_Nm1W?%sinVnPqJ^zz`@0B;mGJU8+-Eh2@Xz=H6(O zSM8NSh2HQ2w?g#u!Sb~nIJC|Of-aRu8)$7gxWIKN6NhS`8f@siB;Z1`YnTRV2E7zD zTQd}x_cd+{RdTI=_dH|ONi1}LIy<$}95^qdC0Ek=^lrp9kQYlPjfp%SCY7*t?lwlX zNLNt2uHo?9j<3%x5KMhU)=PpSHnCZIiWFH$LhM-L`3AYPCgU6G&_sHFM5UJ zf5^pFKED>w?ukG!dTSqtDQzv+?>6O2%guqE#}|A7GPMBC8F{QD*ugj~mZ~@xZ-H5kn(3 zkdVT$_ByUf78cWmV#Yit9BmY?3Tn(6gcl3gKq#3JP#dNiU@CWI?!TA47;&UfXD<}l zioe#kNTwyZ{$0zoidsgZ+Ls@kvnCvCSeuzf%zl6?{z5FaL1h@r#@~j*+iNL~dA{Wx z#lne;mHmK8EWA)9qy_)n}RXI@CJG+^j9pXdnuPAUiDsJhB>rjEXu zaJr@{x_jN9AzYC?5V!SQyC=u5M_#J@BrQ^ckt~LukvwpDVs81-dE##M(P719guxzC z8ikvO@(Jj`6+49+^wmhM(0663;p>@2NY7b@@Y9f49KkJ3hcPc5Rl*|zB|I4`VAb)` zmx8GI6oGHAYETG%bhNVeln#VAbQLl1wGIqYzj~ZTSR*;)d1mv+sL|!H)L499Tt}XxKE(-5<2ol1oU zm{0Rn2B)l%0;P$XwcJW0EV}JYHu9zvGoOQ#(Hfe?i-NS-x8xV<9Ez#3aj3D|Axt0$FFLUo9`GCc z${9}ji0PVIk2oLVD~r%4L}2KKj|+*TbW57R>(k>j%{oEwz8BE~i^=PvAt)J>p}3Nl z(+J%v_$Yj0IW;K|(a}xQB>VFxH`r6KvY7sfVWEy=Nu0xtOz&qm74el#ww-pYu>x+? z%w}{9bC-&6W3P(<_nZkqN2(&Ts<=nfM=|yf)56MYQwouRY8M`~;#3@TWG&GnaVm8I z-3Np0_Dva+R{V$n|H!aSx7%5R5N?F$SGENfCKEiGhhnUX1+e3Tr5Wg=Zg2?*)-HJ= zf*E~D4Ab71MemlqRp%_)bIvJIp;taB3E58x!{iMUpd;IVCja^wYFf~nOI{Fhly8kc z1c$U0KcM5ut@Ay<%v|acFBUGEF^3lp$1k83{U3>!qRm1ASP>Xq z#}!H?a+y$QAeKz|ZZ9RkagDhn`Lm)8K6rv#nz)3{A@nO4SBMOM~7@ zUv=cgQ}Fcf2xUZW>(-}>J{|`^CkoYIFEJ8~Ss)6qi_j&j+t|oqmYWYpjpk2%orESY z-%3zm)kPD>*n%a*4eA5V?dPU0CXZM1H$HH+9@rWvTd;LPH?4SyRyvIq@-hzC+y6BB z7gKE5RAH6XlR4RQ_XH@3p>jRP$nJ5#ks6(>U(Fb6k$OD)29b~ zC_8KwCohf!hqq06^-2_bdxuQZq=YD`m5xt(Tl!i%hPgRpTtW$E-1oy1FUiB{uW* z-1)93G=yzHl8C^fGfUZvowYV~^7eGZ!JS@ZY%jLHcpyjJ3_+{4<&qB8 zbWttO^t3E22+w-e4*M4WVnnfn6(J3e6yD#B_59$RPB&Jd6qE48cZ;Z?#H__ej9&r= z2m3nr<5WIZ=TPrz%h!GK&n%$weekw>aKj@ZW@-m$g3<$N%Ec61iNa=FvUwMoTx9~N zbUP7_B$_lgiGGtn%8yo}dpQ9%`7Ol{F_mLd;)pSLyaNe}c$3W!?s>ofEE8dFTH&8P zlo;SZR5lYrq!MUo(x+uh{Cn4Q1uR6B2Q*~WE3N#Y(HYd#$>)gsje8T`Dnx1FW-dZd zO`HTu6N3{{`&VHx2$Vey{5zFjx@7IbuF-sJ)`?8}#SA)Os%l;vdIB_Er73A=C3pgE z&R?#5xk^0BoJ>-uAG?7Cy++||_F#Vqkm-SXxq{+idYJiyHC2vq<{>q6c%4QwV zME<{ZCX0+^h$X3pWxsbE4LTm}(X7!31lGVd4e10SYD*>sIuCxKh^@>!0frN9__C)h zh`9hbdiFZWS>Kk5M^DhJ^M>>Y;kSi)EE1uChAIH5Iw0vgl*RnnrwxFctb&`2fliSa9Yu< z$B^o6!mb+oC&O=;#rLyM%ggzk%qE6`?f_OLIkEd@-n(V2VoCY7%=-uK$TZ1sEIKpLW91R#Nv&y$NkFK0-nHC%T zO-n@T=W&I~`Y5MaaZ*PDQm2F+Sk*SazVqZeomLmkJB!^aGb*(zd!1xS*{=oAFXs-u z&gS@;hlD_>vU`hiO&vCQ+({}6Xn_KU`5zZ4hJM$g}v8GDa+s`%lpuNCz#kL94GHuu>gVzO;6iK z@AvUEllJz_))k@c%(e`kzzlf7tfP{X5s2knX=u$nusyZaZ*ZR^u25a!Zc; znY})JX-P~9dx#Ntx#S3PfT5D_S4B$4<(zWt$wJ|T^ns6~dCT-X62;eYbc%J0-a{JgVc1{+TJKo4yMVpuMe?F5 z*c4RTNY^BD7vZ9PBK8?W_-t@OtDkfyD{0^y;Ur|^_9GWqDKF^_;aw%Hv9@6=`D_L@%0QB zV6zJx@Ywx8l1WHe&oSQAd2m+BWwa(p6Q$nNnM08~b<;I*2Qi4!{f^OXg1TU`0(0lA zviEZf5mHul?{g1-$-GjQIp#>}O5lc0Vn%R@VoLg3`fj3!{S0C;?qSvjW4zXx#%{X1F=9i;LHUIe(fBD%p+?F08NXua7_8 zx3#|k(1N!Ey(GeP$-~gW zas+Eb^pM0~*u!u<5C=UeDM-mwVrM!l*F$^C(yh=$Vo(SjfECB3H)3PvG^*oD1EY`) zC`o9!gqs<(PFRbMjZr3Z&M?NStW=DWB<4|c84!fxsqCo=l!!*ymT8F|%#!p``rm?1 zD^D<)o!=OnE7r@~j6=WQ)9Yp=e-W14^XW}3d2Sy_wJpjc?k_O&K@1nj{1LO+w0r1b zH2HS^aG9!6ns0uTKvQulx?n$?xtAarsbKs}@K$1O{x$AMTGk!f;8+~T)=~Wf8dxTh zoiB~n-Azx}p|xn0h7yRATsEdVZLy}3G{eHdJWKF2px2p`@I>x&3l^Ey49(XTLez zte;NdHdvVxnxq6vKio^LI(d$lGKNBAm8cA+ zg_Xa^3<6Y@pbf@s!Wh=H@~12Zl<5AR{ZP zAOxvFbOeZ#1ZeW%(|-P;9vclo#9d}7)$kYzS*BWV@`%TWHZs5PWFadleF16mYl8r* znsF5$tiDkRqFNuzb0u*}jWNmzR!91i8@z6=B%{f80%lhyTd+Jmp@YG=lfpq16b-KQ zD6z@WxUc~ka9t+0Y9a1FBsD?d})Gknyg%2!Bbs4(~AiT$~ic;%gHQ@ z({@1hY_FqeGWo8xaL?j&!H>H~-brG6wo=Ei8=a}{)W~iZs|m?G_no&iue~3Nb36hZgSM0j+Spj8`!Q@qB(qD@P) z7$#oy($nne^j2PeSk_{Iwtk3g>4mMQeN!Bi)~X>yFv9?dNC9Y!oF^p0Z`Ht;X`mR?!Q3U{(E;(^A* z9vS(F2LR2ELElTwku}VQYI%`iy|*Wv1ZJdp_Y;G3%vVH9?;LYjS@h=vuUBUQ(bJ?F z=C#EYWy1=t;eiB+f(KBpbI;DZ?T|`g;A3j)B&XSDjAX4{|Kk(WysEK}XTLU>Jv<}Z zT)O2K+7QNu?A#{aBx0%frx2@A_}Jm!+Q{e=yEsRoG;#KTAe=&h=NODD9tHs(`oGJM zbKrP<)X|DEesK#SkX2c%We^IsSi5hN&~p~prfanVK<1<68+~3(p>O00?F-NnzBfp3 z&t1i#^a}JJXUme{9dmOJlW06L$xLdy+rRw_h};2Mc;)cZ!s>od#Q#4P=^xo3MDc%RMzCd^YuGe5BSqOZH&}s=ue;*xx=@FP_Gmi|tU169& zPRlVUP@w=^n=}5|Yi8Rthnxo7shr$8a=)&vnNsPfj>2b@j!KCr(G?gC6+ENMI02#Z z{rZOa9q-xaZ^i~DP}-GdwVJbATBHDlBCZA-F{5~eT$KgT3Sn=!hQY{%x7E?5d~WYU zgG;qWE}n!k4$8EZ+S>3AXhbqh)67de>1=Z|NT{eKC$6ftEBR5KK`v%NJy{RF zpginjl%v?dtiLd?v3+cnZAs+a{+{@3N9wh9@l&2zGa`|UaVilU$u$z?e|h%EGg1WW zg+BfjIs4Ra_E!37C#p#QD^2#lx0HWizbdcV8jHx^+-NTSH-7@)@J;oI=^&x_W$H|R z4O-+B_(=K@nwY<*xb}z#v9OB!IoU=!nl_q65SdYyox)rGUX?UM_vuvLZm;A=o^+kXTXBd(GtssiTk+X2$ zlqTx626#FocYltvd|#e@$U`McmPSg%TkeSGvfub7gVSp%*zhGI<+US<=A{Njd*PNS z_O%XG`&LgQ!+R^d`b{RX`jnMOyjc7vGBY1(d!V@>b;ed`xY=_h1l2<&LN=DIoZzq@ zMM4a1d)8Kpf0j2IS=yxJg3|gS(n-l+OlnQO)c#gMJbY0RUCnq{u-;Qhg=vdhmE9Ekp?D&urji~h#!?Nn z@P-qD(gYnrmDUekE5>b*iaAh?39B*_v&T@a)vt#dM@X|8bb88UWv(V?-l^j1z@{7d zobH_<2>=T^HCBtkXuO`|R1|8}7TOW@p7HWRohiZIusaj&Y*fO{%$b60s(7^~A|HE+m(gg@J&2Nt?DGlmO~^a> zz)#WxD^w`3S~WSOXtRMpiPbWFmU4=2ff=KY-lHVV8VK63Di}TQq+f~C3P$bqV>3Bq zbth|oJdD_7+q#Jn2MnA-?iU?gn_=GcbO^MT9AVn*zs?J&JJaOr(fq<_w} z!T?=Or+O+VUScJ72nJt|I4_RK&3i~mFp9SrJNcm9i5snXcz;y)P_i03G6kF><6O&; zd-w`t^oEjk++#eD%PNt!Ug%T}Tz?A7BbE#Za4GX9b+-n~RL-WQ%thRqxAuL3d--fYAcK z4rMV61H@4)J{%5OWTQ1K4yrZO;Cn5057A|u1J;ajg4}tnpEl4rL8;-H33?NC9#fbJ z&w$gsSNB~G`n2DJykd$_iHr7IH#!Oz!=<`qPY2ezXIuggI{ZlVj~qRXC-8X2AaN_- z$L)`45W*A3k}k!O^oZ%JZK z6-qHX%GAtIjyNYm%7#)iOl-Wxikk^$^-oZ*h-|bMvaN+%1|Xhc8mJGsH0IR{DUr)o zKT4(>iVwB^HwtkapzdC4rizxu+M^b<2je5Pk$EL=Z~9#xy&-j|4;bsaF>_>P?`&rT z)jP}=psl%EVIc3mY{!qm9&OvLp7j@XoPbxhk#ijolp|LgbbXBgmF( z3VfN^BQ;JE&G5-s_;FD%`sI@hGM4p%kg^UDd6wa=yfqCXM{ik|-U>1$k}~J?eutk0 z@QPXCmN@T}?r%)|h_ryKWJx>kCey`>M3H8TO^lLOn!_jf1mag9B+O%7VjKOwh?OVR zboQ=NlX|ME!5xwvxzpi>>MtgPq4r8y*H}A+^WyXz$+J8WjJ;BTMG1peN28!L; zv=Ybcx*N^0+TtZy!7AGc>4wEbFVl3z|vA5LG zS%SCU;_ybYpN19*X>PRhMz)^Z!>sHUL$u1s`6!g)NQN2TCN zMWm#lI(K}o+NeE7M?~A7sZ9F49;eV^dph$fMNXZx^_aBd{nI_1{CH`x|Jcd5_F984OO7Dge=pHE5vu|b2~}h&oyVYp9rahT zYEe@xtK*nIkRaNkp-;KmP6Zvc`E3x+6D#AU06>-{N>0>LTFe!_!v@6nm!%p2(n)a$ zkAe@ng-DTg$)OoivGd>z!y<1qt_jQN#0G5w%zj>2ix|F*0hN?5ZmnRAR{b~!nNOy`RBqb1qb{M~Q= z7`g&w^XW^jAq$**AKrFV*F)AQ9)2}s4jc@)d^>e`NG%3Wq?DAXX$(85ln_0&#>WVR zh@5=DX#vyH(k{2bHN-7=_{{M3v5S`5C!KW-!NAS`=odJGC*Id5e@oAmFOJBlH?ah) zt_Fmnr>1#j76@?lFFyeZ#$;O;rercpG=x8Ogl9WAQdDE;o2_Z{dHv#bmtt1@9`_{F zW}i3Nq{Xb9MCF5IQs?Rj2~ENmEq!k=`p8@kAS(|MMx=}LQb$R5DB_Z;&e|D^&)|_N zEp|DRuBXK+KA_WTpO$%I&394Kog0HRBdB%=UF%=eLoN?~GaoHyl%k@Ris+Br9;fgW zz+?6gm=I9lzFY5!?2exe*GkkFlwX-6S+@NoY$}@Jd>>->6+AeaAW})3{6UqyVN^AXFJHOJ8lEy&S z!TP_l$WOJAjL{i`GI5817!khmU;1|#f(4mWTTER}L9f!)y9L#@? z-FmLHjMrLX?u=vf3s@>R4*#O@+*W>lcy~8)O4d}`4|mNves=eIew^^$a=oYa0eW$U z3XYkrh2w{&hjyW{P^CV75s7eD8qR|u0Yw#$d?Dq;ZYBLdgE|1wTC!CgM#k$TA7@hK zCT781z70iNyA|F2R6xo`$(kOSG{(GT^Uz8{b@ads!hX?%((X&ne-T5{Uc7BYbHYO$ zTsHg;+VExwvlhIy^zA0Nan^s)>UsDi_4)%q=0(cFW7gxi5wbV@>w_>X`^-gjcpT&5 zm2TR;Gb4x!F?qs}A@%vv!me-Xl^+A6=psV@&2@TiM$^`l(5JpAUQ~+4<;u{W`X>c~ zNZG<`ZR|B)l|i`FokW8sz9Yfeg2$Aj>yXWe`ScKb_|9$=AG`G|dZmD^EVuc%SH;bk zQ9x*u(b7Dt2HTvzo7LELUN0!M^or!W;gF`~6rI7mSaSQ3 z@VD1!dT_Eor1{3^Yf*gNFT1UUrx30;JwPiOmYp-X-VopSf!X?_dZjVgNSR&>3X_aG z$!#g*$4kl`{t5794y(!Z*9vbX*FLz12dgQQYvO~>`xTL7s%hm~9i`!_f(oK-Cv3B8 zQj=^4;f@JX+pc73IxP&wx0R;9MzN6y%_u8`;eyI*Zp<-Ytz0y{75X8biQ{vR3D>Jq zL3#K|scJJdms_**GWyp`Gi|-ww!|D0W)lur%6w<+7;4PuIe2Erelhcf_ZV3vglu!& zfbs}QSY$YgaM>FN8$fhr00TuE9m#c4D{?HA$ce4e0Wn7{jR&e^pkZuh23MZ$vuU;V z%=Id9B@lH5jROn@JET(d426FpU9wyi$@_cWZwh<~TzEJt7U&7?Bl3JrIfqka`Ecux zG*b~Ji4qJ{ho_-Fu)1e%#eur}CjH9p*8VunNs7RVJrea%BdmK_?x1+}OxrVsAe$Qh$SJ`eV|mEtT<;k;gT#FnN*kBl*W>-c^mIMzxW67?}_0P)giWmuw+Y; zpiCH2)Fxz)uayokjoX7s(!^^wV8tb_{WbWQ?a96=i&}>2h*F07K)0^(y;5ufwc0O= zLIy&u87oCI(a+*x)j_wE!W4EymgQ`0s&=w`yTK2)p+A6VYLJ-WDBGE-zDT|Xr6?gI_KA}urVa3^ zT-D!jJof5J#J0E?oI`VGYu^8A0i(zc-Sy`+&kerTncsVq(xa!3(PhxGy{8rCv1rld z_u&yzshJneBRBg_@^@lkv}IzdYur_nlLa(CDV!mrOE$Dw1UMlFIjDMC{K;+gRD>#H z9~ITqJP@smzv&CCBlf+*qD@x(pJ`+16jP;z-3+TU|lY^xl2X# z7$Hu1Hd#nCu6qMo9_WNfUSV@KS85)YsAwv2YZ~%qWn)Aa|I{+rgF;+mr{@N?T_U;0@;`sVyxkcMKE7)JoL-a7{ZXIfX(pWKK&s#yxTwcC12IQ zMMBktwIT=43#*0md;oh8tOW+q4W_XJaP3Vg_pvhH$O*Zz8UFOVJF;yV>HPOHE51gv z{Ut90&R>e}rzrS&99n&(VL(TWe1t9wdK`Xanpp9Yp!cS{E+=I6XOk9|l27P`+ZMkS zfo}{9rVU;W+gL}m`rBZo*@mDaj0{9`vqUD26W|jwq-Z_JZ&{9-;Bzggob;$iiy8~o z1`AY6FR?)VjF?`o9?nV&F2x4N1PsP2ss>AO!kSvaCppqIkzWt;uK{kI{@PKz7Jz4~z=cvtxf( zuC0v0hDQ-37z8C>AB9ljPw>M~wF9+}-;u=Q04+bEEJD&&HW7&A{PuNbvOF-(Y7Eb7 z%U+~oYYBR;$sx#eaB2@aUjt|3%DXLGwQZ@2f4c1OA9zZ(wR?9I*w<{9LG^yH@$B7j zywG#Jj=EOu)xx_v!nuae(UR)aP?}M$V8P2>^W{M6@bypRdkW+eiAB2lRBUl3U;2Dr z)Q-IFId{1@YQMp*=zD(IJiqRH6aZPSbXF3xbWBnF#cTsqzdd=xI%0%w6s}>!)IBoS zK8fL)-gv7`eCeIC^rR!S9&En`lA$c>8Fq?c6gjzrbv9ec6$Pu8Bx*4$6~E_7W`C)t zt8nvx*YRic`1BVw{VDWXgxQ?hVnLZN@?x+k@&?yrdk(xr*3kl4U;_phO1GQb6wtq# zAxoI#SX%!aZs31nAatIBC)2?Jox9?mq_oA<9Rcvv<+P{1x4tDBnyrr7U@* z05aW}xoz~@UihKajrOQ+%+*%t3+k9`*=E}O)nQcLYRq0yns>rn(wm3zll#i`X*#hK z_1&%8A8R!6mVaY%uNNH`SuJ0m3~stEu^%o8rNJ8I*9&vvZr--a0)MXF4kdFp5^vdvNV_XblGgYE6D!zQ;%osX2Ro) znq#(%&z^k!XAo5M$?UPhOu8j~Z@YRPTG^N_-&d-EB}s2&8S1NJ>qUuN)|D(*ab8MG zi1-h8&Tv^9(tHo*>WnnKL`QPCE!6!b2>GHfim+}^)12u6yV;h(E=_$-x%N7}B+qCM zaK-0BgOWBmdo9|}#!Oxc1g~6)<+ifV;1=7|$-mP2s*aPG`6eVjra(651$2`37Hu0+ z15O z_@jUWP~PyaDZ?`O0z|Hrvzwi}2NJ%){iu zALz8~jfnK@`2-3Qdp>uW89YPW&hQQ|cyd$!>b%qEDF>@uX*l7Ug$@>(a!nSF2c>XpOhS-+7-G zy(9P;-6G6A-h7>YauaOBT!Uvo*tQR{W7oPq{?2;KRAX6CRRMyabOF+Y3Mwg_3X04B zi=il+pz{_hHIg4K5Jjp{C#qwx8fA-n;AT88XZRFl>LWCEjAo=_vWfQ1?ns$f}*{@l9ab)_Sl#`Wxh*Nw3AMFMtX^KkWt_008;_`^Wt+o$7!5wwcQ6&Pa+V zU*wyaXIA9kgoJawK70moS1?rYGJGM3zhnsof&{4dD(6ZGK{Cr^G$VUh^Nmv8T~ckS zK{ID{mnu4Hj84_oZtDzQ5BzDqK)(IFc|WE~&(5wK5N&>v8m744J>H)#H8ZQbzb}Y= zG+(5#o_iy7DW*zUagRBQ^|S&D`=a;*$pj$JZ2+g(4|cQ9}k& z=sn)EYW2}5e8}x|RqP?-c_@-n58YC9P%0^d+#vhjnBTrcx=@zAREBMnnPi}kp1yYY zLF*qsgu4+JtJkBGtyTYF)}2yoQ@4Qv!BozMB@Ql`V>MAL;uyHk!tmLOhv*}CVzh3K zNKK;CO39|r5cMP%7CleNT(l=~97b~2Msqrrc&pQ&a57>zh7g!aNit_m${J?{8K=+i zFq#`_Cjuil<~rsm>!qei0Jtu_6>FiwGS6bt0Cb$NIleH}Yj}EaYXe!HFdUlb5C`Hg z5Aa9!iK2^VsIwaCU!l2!C%O2mKjZ|(H`IcjmHVyH9NK8OT6Kjn?>l?xSf_L@sPRml z)>OFj6^3c(YQ(A%1{suo)gq|%hV|?*#P33t3iPCY{M{sYRr%Gy7O>ZMI6L&NSC61ZL zlty9=%yPN$_`G>^9s=i;XLEP4B{e%`zW5Rqda14Y_z9+Rs<8zNhi&L%70?WUojsj&Rj)A1$f;PumU}s$@HFS3^xGF$81~fjpu51XUyu$R#ok3`dmL zYOz9DmPgH&4jdC^1rPmFNY`0g3I#z^qH`u+5_FFjRb)(=359|{H%?aq6N-TBJ-Ju) z9xO!LwZmk3H^wB_UnU+9OT}g}{knXmvrQ#eca3b+{Z28%K1T_2C01r#)Qk!`voPH? ztca~lzQp2Ss3l?w;xxa3P`|^p`yo*VYrCf;SMpT(zU{`8mnpza;2J5xm^#t&rg`5WgC z{(jjAQx{Be44h$jJ)(@GR!1_SH7o>vDN>M@fC^6n9=K) z^lH`R(4Z#dZFh#%%T`A*W>}*t@od+F528L^y#FMS`@mE(^ZRjRT8F7})v}1Ejl!hf zt)O{HY_yP#i^odCj;IceDrrLjaok>uH^wzM!a~ZKyemkPtJB;oIBjfO2EFfU-HU7a zgFWcM^sce9c!_4$*`2Kgo`VGIhIOKPNlI$O1-07V=3caoz@}lS?OZiJg=^><>B>TA6Jyk!Dpu{j2Y<2bFdo!^K2Qr zv}@3={ZVAn(S>1?mzZ`qw-<{eOp!kkQUf*Uog0oWYa;j{BZ_Ky&$d)CT%yi8)+Ea4 zoG0q%$Lc2n@s_`l;lFs#eyc~ybqTKB*yMFV!x|@dXu^`nff=u-vBEA6{;G278oc(aKwpu`1&FAvhk~QIan|HOqr zF%n}~Un%mt=U>h`J+k9SFg6LlgXx8;l!YYuy5N5yv&V(1xPhEk{}m_s-IfbjTqTrv zsJ>0P{bo(y=(j{vawMJ!)A_UC z^wyLDCNs*c7qleVXo%AhK}UqmiBJq|b>2I<$_Dz&!l+5PDkWhs5DHH(j~BE@`85Jv zpEJ9r=2n%QD+g%br~-b6pL-G<__j*dqh%m&C4CprMKRvfZvKO=%3DKvO1kMMnkN)P z^Sb{=ArQ|z+Honq^5KT5Z$U;eN#XFYD?aBJu5G~LtOI(!a`Xz>JPbajwOt93t%ANA^AEgx62qQl1uNmTRt#6?kheg6iYfk!-{ z1&UO(Bf_<)Y&s|SMH9G1QmGf&$T-(`14$C`&cNqalrC$sM5q-aKDhrv za4B&Ro7MjzxE%dlBq{#)-uxdI$$yYr6wT!^716wy!Br8Gd^Ug+!UFlIMJk#WQNlnW zlG5a;$Qmn~i82BTb(2>&7rs!ueY|QJ9E&3J8Q8tb7`{k{k1wc4`49~0?WeBXU9+Ck zKHsyqzW{9Dg%JEzBz1n9-?ilGafL$v7_uAT?yV#YQz2&)mu|#0Imf*~WtX?44={_7 zUzM)J;yf#Qq|7VFfx|_D^CKQCP@VA6~YZLadLnT%I6nGn>@^F!DFCKP+@ou|aB?%%w@uNHL05%5bkB z+6%6iNYTmF3_F|h*MmG@1L&N$b!zUvgSRK>ywDWzcbn`a(WZ z)58QRI&;lZg*nVOXlyc3%J=Go$m}7iI!0e2t3|`1(rsGbu|`r511J?%2=RxY??WF`OrwJcy6fF}alNq& z(hcs{8zL&vi}Uw%X4 z#uN50wAYFgRm$*V^gxi#6LlWVJY`cj>Q zdS8>ijVg)D+$wdH&x89M`0eR8trVysNjSw?pGsE@p2xL%#oI0|CFaw_ho7RI(+NR7 z?IQRnT*)?@RCguKEUmi^2l37p0ZenI}l}9*Y`O|UY>mJ zNUwb_Xk_YIlS2$pwea8Sk7-Bkf750Cd_7?gMcUedO?le9Aua;AKE*Ocx;~{s5PadB zr1eNU-{PRn@bn#_)q{TM@WXhAuRW2LENd~goAO`wxCh9Z4^0I)qpLI&k>^&(knzUX zn)nRN8mQl>mO(};%4YgIJkx*Axu2y=T_17#3;c+WO#+0FOo&^&l20=LMrUgi%0MS0;u59usrq!kZa8T`|`CE!ALYl-wCon^WkLJqlNfWfH(V*)1DLcMk?lU z(#L~votJ)@R~u;US(E%l>$hjYY7Tte5!Yw?WRpjay4V|$S#yvEI8#A4xN|I{mnJn> z=cT@8UjK>ppT`fRfkrq1ZGc_lSMF)?%^Xm6-pUWK1U?@Mzy(lu3doqa%`rjmVI83A zP3uX=x%n#k{6?8pxycVX%Bf(1jQWH{sW)SRJ2q^ z6h`tQ7EofA&!g)wQ72boTm^vSvjiz`gz$r|g%G-3kCPa&Nz$C|Quq$*&dI(kb+MQ} zt<`?#e`Bz?wqPEGAVY!;=BR%@Y@P13H@;hb|0!Iw;l=DzI$i*59)$yn(AwuB`{__s zx_JJA8p?a>&@2x0+Y2|DQBYPtj(yFEE%^g+2;*WKi#2(=iMlzmwm_>fefp${n%3(Z z;MnLXKis=MhRhL_`d_E)NBuLV95nPdL)g2^oUanAXhSfdBo_zU-kNcjp!}^i5uCyK zDCJP6>sFey2IF(^i8jvSE|^P6l4%;Nm8wpQcLi@ziKjVa|A(=6jIMj%w};cPVPiJ7 zZ8o-T+jbhQ*l29qP8!>6Y};y*XYF(LzT@sa&VByp<$AfsZ+_>;bNT>U!K<7>w>gt> z$*(4KKpQ4V%NN%WePbz}3+9ehin3^Qn@{ddq*ijpC`DoSaZky|8feW{*UUXHoRZoG zR1hipjgnyWVBE-7LAtiyMvsVARUhdkgfH=K|RQAkJg05|}Qz4qt%TEh-s_{}Mt zDsuC-`G#WLyRQ*X=ST3wMj4}F;ZQh)0uky7l5C`~gZRpm+eJLv%!rt2C4_QGMM-vfuBNL#=m7VRMO$4BG)jZG#!IXaf9334)y<=PF7`a%`-*;gj>eCiD%JZVkvL`w3TXOL{Msp&**ZfGm_EXbO9<^W0CR4}UI5YpSTK@v# z)MA$xR8ET7qB`gzUECupwEo>le{gRU9*iAA)Ch}mO7Dk4Meo+~sL-ctaea42IKy)Y z&-Ggr4dF)=(81F}3Yh#9@^q~YoGF=x8=!!ai%?EO*@}O0f;fyczGl|tVi!ikdgBCz z_o>ZOU2V6L&@Gj`=QsUvJ~$0M3ltNs_>YZ7W3hUuQljNsb#C$6 zxo4@}ugRVno%7#XXLCxWTKo`2csW#2 za+o4!@7Sx3TJTCmqmDc)?GEZx#6Oywi=thgh1cG>r@QVtu!kfYMXaf_#9WwXI8D&d z5y|3AV$9wecZ%kWF1khQO??hnqbujJj3oZr8UT7N*`IE#a(XdHnK8K$BGHBVM&lG= ze<$D)17Km@y^bZ2GAtlXnk- zFQ;a#qTAM|KQv)eh%qD^bL9hJ7eXiV*CkFFq0gd`Fi!C}^dNREIh6bPI0EF^uTr8s-2@7_7~KjJtk8Fv`>UE( z@O{m6X*?~log5Zay;Jth%ea0g!AvSPrMRM_*49H1C5azQUeQRBVy{ze&*dRDpo_U* z(tea=UVNpR^0~*;LMEiSX6_%|I+r` zeR=M1!$gM51puuJ)3ChdYi7uYLA*4V9jT}PyxF?(lnhUjVx^Bn>wo@{lIySLP74%U zend>k?hNQo;Ln{brKTgZ>q%ygY8~xlmYwmM;mYO(e3T*j(vOPWku>I1+4zJ!iRK3+ zG9mOpo_vD@xi_-(C({&u-XZoxJ9$}TrBYjdV9jd>iT+$ITawn$9glq=v5Jr=H9kN% zi}3Uk4XFU;r{>sz)sEv&L%b{wm?@P z5qEo_@$Ns#Nm)l}RTYtUiEWrdQhMAhjm06Yp)smwg51J>4K%nZ%xDGsXqw%CE;^LP zg9JpD)6|W&)oU(;$ofG>!IrIaMP~?!XAqM1aqj9 zFmk&~6OZCP7odR~bJZF>lrkqjjWpEBkwu}QJV?Lu#1!pONN=t_&lp+FLNicXK^#`i z>Ycx>K#~@z}&m(VeP_r@!$?W!gjAv4$i++h71jvRn%u%NTUQVTvop;w8w- zGuvt5TbVU@@@dUZ3Q7|#UHcoRAO4|Aeqf^`p6tg8%>XN%n@szNyuZ07RzusJPd$1a zFLXJ0*8aSDMUK(gxc9h<%PG88nf4C(r%tK(^BHQ}x$;pHsToY(g&?e?sqTQnhMXw?~g1|g~6_fMQ9Icu%7a9GVe%8y^S*0pc;A#ZjfbRSdCE6f5KgUwR z=e6Hc?HHJRlolpVA=e$rX>h&Y2!1$k7WaEeWiT;D>?g#&fGl5_OjRZT-8;0lNx!5; z0h~GN=Z@bUM($FhFN1Ti%c;^`SmBS~oh;Kpn>#Uvv*KRIv6R7h7QI^5!B!j+KH44L z!HK;&jMhjOQoe0jns*MWUHMiiZRG5enj|vC@dgdc;u6G9;1aw5iYOEf+#}0-?uh{Q zVR8WkIrMOSVl5Cs?W;j3+ZRTlqE`}_OSKeRuF%=DgSq^4TlA)?pR4nO&n`n75F^lh z`{oXn^IFj%wWfUs){u5^LNFyyXtm|D(BUrPFM;_lqEm;c;) zK#Ir7e2RPA@pwSYzuc(F`AiqP0#ZoCD+G_3%O*OzJ6|=&{f#K$Y#q%vX{l!LhTZ+e ztVw{CL<)N?9X~c`$V8+ph6Hd;gVjf7;6p8 zgP3a(d5}GOp_EYg!xc#A!|V$iB&)GBGovCC2m^gkHYEU>B@G=D2gDYT9?=H$kwZk- zF!_!ho(*%Ql9-ddzoegNh+V3jsiM%4*i#p0Nq8hgs16m2p)aA)X1+#Jl{*sVMKZw^ z%5MBR<%`-EDl^RF;2>IyVP;O|O?q^=9liB7#YZ^d8!ce~|F|5TekZQxbb7Juf3+g( zdxun;CX2DT$)FitRWw#O%aJUWDiQmYw+g$_9WbY+J_Rw9?-XMBjV3)df>u+&X#@~s zlN0JHo}~Q^-eq(@t)p9j)7}66nOcn!&nh_bCrO2|tHtU-=v_pB-_<`vC5TO2Wx;@- zCJmVQ{r9~3$LEo=RkpA(v2$_$>rgLK`CrbrysIfKjCAmcWQgWCLf^G>WMMudhW-eb zOoHQKu`KMc$yBLJsz>iil-p@V{t*hr_dP~%T(e5DP+S~nds|=6Y&Pj`_Vzk8r3V6e zq*fCt1B+&@(GpPv0fmFT&g`H!MT_!9n#Y)eTnVfB1#YU7A+3eHG(L=4g@|YXj9oGb zS>bFDTCQKZgv9l+1&*&QHzSNeMi-?AM}p7}OScJ@(HQ|Na^0Q=QQG-rBhXAzCYGMs>E1FOMIZ#Kq+}x3_ zO$xKwhnNOpI(H%cMS;zO|3^~xkEj1X*!nXmQ(1LfRYuhr zVqX@Noh_hjpxl~nxF?;LmCPN;bR2=eUIVXT?B6c>H58_(VMx-tr}hMew}KV#dL*#v zzLk%;sPMHI0g?-EBEyHytFrT9k#9EJ@9l;AJA`+3FUf{NpA75TEMu_SLPf=PQ#AO- z+%+Gcd|wE5a=iLtO`Z`N{_zv0o6C{9Qb=}*hDaYT{3+=5LmMzu)2V3N6}K$8ROB4F z;EH+r*6ubH=u|+O5^&E#kAjZ4PMnB0OMO>I5pPtZ9lCKdi8uv(U#vR!yoibJb~c&v z)EO#J0!?*o$phK0tt0?Vo_wl3u_>s?ms5xpA+~mQynMkA$zXoCAZj z<@#zQM0+y5{Vu2LzoRsNq~F(W`l__#&h5MSysi`!RUz2uIq6ZTqV>X`0xacwBmp{d zX|!m*1R@tm+3~M3&qDgG#g;XW9WwZxKd)G=?QPi7XCDtG3*!Zdx#MrvU^}~peUC}j z1T7S{7R|S@TLFez90pp-)(7U+LSCeg^tc6T>s3pM<*L6x!GxDkd%GdVG2I~!;WGvr z{3BWnx4!C{Dn%05Mso^wx0J6XThBcfR&($#T&4O?p}C>4`j--3YU z7&T$BIkhGot2fy^*Bx`wx}Nq!yBm4Qv4O$sVV3Ml!RulD5*89!W4dDPV!Wd5LTTX> zqynw~SS0}qyBnjkcj|8f>RYRw>SS_!!ZR9p(2h_EH|dMubKOyQ$i&?cbh+OXP0u@0 zz~Z6%!k`8=r5G!`de3Ew$o6nNccZ%RoC(!daX1jc4PFjjK=en6#V4NvV4(4`-doQTZq}1Akn9ddniUew^w)W^ut$pYM}!ODbGx z6fsm=eA*WB$C%g_Q=q7M<8SG}!VeFM-)nJWNIV&|b$J28OV^A1p)e%KeJ*gsY1%fN&n7|0A9|8*uWVe4vVW%9pgAxVmVRBFIOU!C?E znmf=Pol*>ng_fBoLzX9f0>;u8fj~kYnXzfv$?WI1A$p{uZ!UTUIr%AWIp^ z7#n|{bel|lzP>$m1Cgu2ChCsDLbaa@)B0o^(h|52vH;?SW%`&-)Myuce!>fA1h8ec z{GhZjN}wc_#(uod65o;Od)*OF4>SP!?CAd-kr7h|Nahbg@yNEE^j~W6&NMmexKmP& zarJqg_ezl8R@g8!2~S|yE@6%{9G60E?( zX(UJ6oJXH1v&(Lo^QB)yDHk_gv?m%n105{OILP42vZ}y-w}lp=a-Is_KIS)VW@^)~ z#HxTB_sOBE!p}&_MAAlNf}t9K+3YCD7X0l`s+d{te(P`xelqT->;VSb8THGoFXkLo z3$R`AjigSaQM-M@#f}8=F>q5>335%ZKh!dK1e1J?1oWI?(AZPf@|O3~W;zbUCli{5 zy2RSlKR{Le+`~&>@|E1PZ@P&_V7%jffwzEu`v6sj(uu!%21O@u~=*U(B=~AklbT!$Q zvGagNk~;GiPOeH~6$gDf`3BHV6J|G2fsG@&!gRKOw;!ycLD4?+gC`4>L&fz6&zz*$ zc%CEM!MMrlm1GqvCf^R;^Xl1LRV|qv*F{tX&}n91TR{{iCIvhiW}HM;{(eR>8e@Z% z9I}+3+UW2WmE*&CV7_wKCeUF~IP} za)b`0Z%3$U%I#MP1KI;sr0ZANhDKc()!$#5y-@{EQIO+s04j#={`!Jg;ElgNS^EyS z*p|U86c#9`BOP%$sQQ2R(9L-hSpG2_vdvj#S>voD7U#76tMO!CjTtF(g=W}g%Gnw( z;vgelD|W6Zuex>6x0c(iOs--)a{@c2NCa?t^;)pDh8X(n!{9s9s}e3#e%jyO7{yVWlfJ>D@ztqTl7 z3Y%`#R&}M@U)p)WPVUr!`r{2PU)@)dgYL4vabYebJ9Mt7b9*gTDg88AiG{tOk(42Y zBl>sFr1D|}1`GO#U4<;TO8*vrtl9yIRvnMidi)%~;@YB2CQcwhfktvET~q5(-AHTa zhGq zlUq=%IsvuGICGTo*CoQS_&CR5(Qc2iCu@Y2A$TSQeMHRte37R>u-X|>(tRkdV1fLE z_hS8}Gj|IQuRY}8*@opyu;TSJoh$^y&$pqN)hCkjZp+u7z2k7K^OIkKcef>jbPJP& z;4B=@&11!>@Jb<|p_%-Z>{_L(={F(P7Rwu(aCVnj>uHq6zHJAHO|3pXL5e zJf-TooYTO{=n|+K$@X8zDIoFu+hgZX=E+nBMkxivcUiaNCX-e)VTE!63Y%6Mf|Ad9 z0f;g%WP%Jc#WtKaU##6mbYVJ+;XJTcA`xTS^kZJUthNL|Lp&OWZgt_m3G@^MguuZ+lXjgm z-I>y~=Tv$X*|V-P%h+;jj%e-zfcElq^bT{GhVnPmZ8}@1_)`_9COXW{^*Np6Rks_RSXT0_TF~R8mQ9i_tujPE~C6}OE<7hx;t9QowdX3d5vtWLaDuT z0ib4>S>#inURmNj_excOWpfo{gK^Nvj}FD;Rcg=0E#G2QS$0(yt*65>1=omxwy)f( zx+!$cGV2`u+w+JVE7VgJOhQK{%=+3Ri!CtiDvI24$t%khNlx$iQxWo>Y@|rKi|{eC z%;FN8h*bin;+fp+LgIIf&R@YE1KekI#>n)neYuC&bqrFYK|eaIJzS&dKmR;VCSC-* ztx|E#l;>g5Qtgvq9b8Ed(B3gcYCE^V z@qT2W2)!yyB<0!IsF<#KJ9-QMEI}6eLY&H#-tFF*q^qjnMy1CZbq*h=*Y0y;WrJe6 zys~w>nhw|xWny>5BuluDvzv0qy(hby)+-Ks7ej^*F%{Na%a$jw&?fj=5Mm#O?h-Uc zQXRXGE0Jm}_QI_0ssAPSZVRvAZW?cIoj?!cJk$I$(?}wvWNI3v9JfYwJgZJ?j8zK) zxMsjfy+Hdng3m!_)BpTGVc zjVqJ=l#st+4*jGa{Ame@5Y zjzWj9Xm2@1@2|ufQiF8DL`BvGNoH_lSSYxjNZ)=eKwa73rYg0E?OvjHs;Ow5=Qm1x z3INsMr13OWDOsPjDtq{iLy~}_NG%MhZOY9B6!ryYJ}YEtK?*l|H3JFCveCY9+*r73 z;^uygM~|jf4H9XgB14PCNOZRSu8Hn;8YyanJ7Z+4Nv3a=6zrbk9amj7I_p3gHcNuc zzN!||F*q>2&$6r|+XsLY4|B=r0rrD_?lr~1am8^kH@W(aN%(O_JgmTV$Pi?9c!n{Y z8Amd8q;Q-OnHi8PI)1&s&Tr#vsIOlli|xZxB1#y&aAew>goehm3)D}!@tYGLD|Vgv zec2)W1kEmMWkz{%c`43yQl{vM&Z0ieDy6{cw8^AgdBnNhIP$<5nzGPw%n{x2!dO5r zE!Bt(6_6w=b)JINsZGYMvc%NrSVwKxmM~YOn9~8-x=zZiu~^pgDWN0GwbA}N zR%o`ub=dc?&H~q1QKtLIm-jvPn(Djh5JF3#hdmHLY19IoJr;2jH|h6^pj*+tXYQBD zBf{xDo)gEeaK@7%9przrJJOxEYW$?)S*m7U{X&9@{a9iU1U zDzC1PP`yB(YSdH|BTU0_Q^i&9kTSH2h@kVX!Q96BxTWGOCg({16sQGSD3mVsy0!YM!XQgG4_hdl2Bj08Q)rvLIX%PpV4N#>O|>{e^G@rabeSW0 zH_H&Gk%8bQj5i{LgG0xL)Y1}APDf?0J>KV{FpwP86fyMq2*j*#YU`~$)Zn@ItN8YE z^4tzXh4$A7DzRdmuGJWhU~|^@L$*Zh6;HEIy0h0*c@8aD=CT#D?KQ_R+M*-3&fh>z zO38|fsb+-I@>PSyN~~B;rq}Yi4w}jI-(SF;-Uq=+KbR}zAUg$`q|LV|(MQ@$wevr? z?p)ga(}P|n3YU03Qh*X3F9A}XPuGb z*Gm|MRK<@avJGExFCZx=ikvET@ z$A(H{arLreB#wt4a`eLRl=hy%Sp3{D8m8~4@0Zp0qT@VxIxqz{;V>YPR8I30hQpE- zmfum;QMa>n!DEnan(O%WtLW)Au8qr1UGd4kwHK^+EXCsow?X0>zbu?4u_#j{39~TZ zA@A(`H>Gr&D)H^H@K5Ar<^4m+#`cdvS{&nxonmABFl1eLTB%SOs@;ki*R|wB&D_LZ z_;DDwjFxbTXU5so`ZPqqZHT>m%0;N6Ak$u>b7+fjvvAL|3VmX-dPCA$ZXhjNrmLicw71a5@-?3M5kQK`W`IG>Mf2O%s8aQZ6BP&KRSW;9SYfyHoxpD5d>LjZub2 zO%p0QH?;6=O9rwn^tpm>eg*so3(Z4!TqA?$pU(y zcI){^pC(*`K}omzCdYl9x`0C%Z|0vLzn`G>VXAvW4YgSwiRBq)AX&pDq{9xrfgA8d z?jYffxg!&fD`8C;OEU{MvpO~8d3dIB!}*jqDJhO=inz6$mRj9E!3mYCv8~NW0Fdx& zRqEm7TrA1l7S3#wPVwkX-CT6<;Z~8aGy*|x;p#`Ix6ao(i7pYR( zlUJijhdWoUw3*tPM-#pW>WhaOg9P5J)V0(bTUL!xGP$;f&QQkVQaY-+MS@PP!Uc}Z zwI#o`wi)KqYVtrcz-hw)&!2J54jN=^FBtF0)tVb@WLR0t3l7GjJBisC5H)A4IR74|V!w^S^I;|r;Yu+tY+dQF{#4r+G_VJ$ zmmwX8O?Pyin0XE-l)mIP+YcJf7aG%SvuFpXXzuDR(~Y`U=|k4T>>SBYN2dhHjx%Z> zelVeM1Jq=dTTU%Wvtk*mw;*(>)VuQnNNL7~snmNIgxpYUU~G30RF2Rl(+F?zWf|af zMkT5eS=}n>G7X44zA5NA_h`oF6}`|?5#=qFso0|3dN17`%fStMAf$RHzc@p9M%FBeDQ1S!KfVSNKfW}7rc#^{vZ4Ou?{lYE{SVh^@Mi`hN#{eU)? z^u&u#Iu!84*4zdo8OJZ>q*$BQq1*Uf*B?Sr%!K&0{AEe zsY1hI<_TB(k;7B)-nB+um>!Jai?ssYeV;b9yD?;kH9N?h5JZdK>q^J8?FnV;IRzQ5gTIdr{@S zDrndjZYR1;p!r8V`R(h}BR)vcbrYIFWNAxqNrT~RIJI~Q=1@?$#1Tvps&u)z2uo0i zqhG-eW0v@7X*gmQrF+#DgwX9G6+J8hYgV9Rq&ZfcUp`czxyj_p}=>StTZ>d{P=$myQVT<@Tz(eBx)q)~n zU#APPkx~Kiej1?Dz&-iSswYQzeA+KpJ2UZ{R@?%*P2VG@!C}=RmnSD~BknjRUlPJK zZXcaO3L#?BD3->0sg2Rlv`yd0@u|nu8;!{?Kn?rgDlPXCoK=q3E1u=pqiSf{D_#(u06tB4Y*E`LE2hzX=Yw) zX6q!uAXQ3-0t4@fvY*{&<|*D6iS2~?1+RoNG$UTS*o4rmmv(%n)qd`|6sc&T2n8BP z@-YU77xnu^i9S;P0AskU+zQhlEq0!&mHV;wk=KdDz3*4A^{ ze?d;@q-@~lgbl_*B7F|oH&-QM={zcIjOlROgEF^^A%E!Jfie$|xg@O7`m|AWZ%Ue( zPfjJ*6zqHBNg*a?4;3gd&?ZJo!WhMU9{)rgfHtrB8wd3Dvu}?;xU_3%vYxr@S8~fq z!o>BoXA~o`&o+3uF1H|-Vyk=&Tt|?cuPq+mA9i)hz$oNrwC6C%aqKC`h8<@BM2#g>SqnaPyP1z6$3MO{aTcSS4kSp#JmWyAqd&4;gl%MLY6kTo9-YF`>oh27V4Soz`pqDaSv>+^KOHLh?t*045 zC99QFY@WmpA9K2e%!Vvki>+6xz>cma2E&Lz*0HJ3!Q2&^HGzvRt>sl%OH3VXGmzsY z+IVJ_W~IFBZ|Lrqc26A}9iK(osYr+nSgJQ6rq-Q}lzHxWZdRA)oL$g3r!mZd@kr2% z>orQnNaB@PGWnaIx#}pRidPqaHdP4`M^V|tb-TBD!PXpySxRL$tb90M4xmQ5UBV}5 zZF{?!;~C#EAEO(zak_BeA+~i>;|BhIvZ=K$BCXSSSR=2HeB9ngxEnS$<<)sK(s}Np zL3&$Wyz$;zmX$apebek&Y95M$SMt=LF`$abh_WxyVynk7Ic6uB6q(STPuuXtYC=(p zS+yB9j0=*Pnwo;8DezK{i(@i+1vl7RPg7GKV`E=d7rXy@D!vUj2_u~~oYd>lK^e=- z=)mQPVG>yh&L_7GYfXMd5lsL5TLngMHyzbfzX&+emDE05lCn=PXjQj;m*5naJj z>uB4k&%H)7VUgui3i^T{i*WvZcj%W>RdE_J{OUE>G3vsg(F%3j8Jz+yyRvhpfT9bZ z_Ofa70=`P-xd&03bzMq<-!0O#uh>sac9zVcBM3skQf$HHDQ597XSj9&rXOTBag$F_ z7g!s*dtfw}Gi22)$Gt~NW+8Vp_5spP(G%{DTGZ&X&{6&_e7{2`rtJ=B3#V{*NB|SC0xeI=#pncDBn_OC}3%;mlm!W|aGhh^(dmW9 zQs(?;7=dojDyIuirf^i=#?&CoRd4@gzSA;=Ge}?KEkc~4U$umtRZ>?)#So0`ZbFR-38^7rK_@+`;B@Y-L$84W)U4r8U|w21Z)9zb}XOV zcac#V4Dga&s=}mS5Hv=?FOYJ8taP5Q<1E`+8_r>tyTtvZOv2@_#kb-2V=ye+M<7TCXjz+rfLv!I&Z-CDn?GXroj{l2r2&8W1bL z08;>>s424JkZFqowTe@@)WCBqbfpYU@~zDCm=Aql&!=+1*hnn5| za40;y7yFuRgSo!s5J;hOjYQEGPNBl(6XurJ8({_-mwe@pkp%e?BfLT9y4fT!yvNq? zaW99X6NN-ZYnMW7$lZ)k(4-+EScJ(&dCC|sqJ&oLPz0eQIkIapfZT-Nv;~ziP*U9L z>sN~^5hBI)RA^3R9walxPCwc^@hs;yqj!HOM!ArlReKu9wmHr3S&1P$`Jb?1{jI_} zBMsQxG%#2#ssMsGhjbP|Z9tBsaMUNLLomjfIBDiDtAj;Kbx87kC@%^ekS0TLp)=`rk?oB*5jup>U8C1>hx|hAs73irziNouf<2|kBd62 zCpY6D-bKnUZF>t<$e=8$bw>9-4V2%Z%NI!~*yw%t$?f%*t2OhX zAcr-(dqmK0wy)Exfhai}^)qq>iK`}YAx-9w|B9mM*x)qiT(q`QNMogr<34UNK9A29 zw=@|MGkRop)vA}R6T~Z!SG4Q**0>ra-Q~Xv(zWf-acEPLKKf}4TkSsk^tn$iWJj|D zx_9ffUWNeNT#zs~xJDy13peNOANR&T@_OXFfjz$qU^9XAKm12!6B~OwM*~L>Q9Enn zzb^KoRJ4>7px@+iVJWZ7EL%_ zZa^4iW#L^WG;|NQiLr13z~-B?SDI*^x7QljP$-{bU0bl1BUrG{#6534E9jOVupPDZ^3(FfS#0Xdv>vF`nk?F1KIyDay?Q)L z?p7YScby=&0Zr9ijiYrEy5M)=9ecIq+*09Lt=sk-pZTFXzpu3EnobKZ1u9X#T|TPl zBB$9kUqh3_y6>ct-MuWRUSq`SHX+t!#_om@F~ePelTp6tD}NAXpS=9Jh6$!IKM)TF znarYnR?kgGPrt<;l&6sx_n2CSN5jsG_BFL*X&H;M1Lx~!ipm!}^0C`V=EHOf?cO*U zyigVYlnD{V1yT5WG27Mhv8zQRq_+dqP=AF;ERK8t(O?QT1sw>Op8i1h=eiT)h3+2& z9S#{9q?_#W3dN-3nCe0*`ZxUED8pjJ$-2{(Mf(+Fs`546=5p6jyi-1SO@l{BuP1?3 z+txp)jYUv4?kw^BK0!q?4l2+n8hNF&}g zE5j#H@uR{C@&+#R1k9cb1Sw_fNufD$H5F9Kk zy+QI--&@BRF#E@iKwypA(Q^*_IuP14GY2>gzX3~C9t%T#cG zbh{JwQd}{@kf-^7<=v{mQhmXeKjUga{9gN0lIj%^OaTL*NalwpK`Mf{w9hDRZ1z)8 zY4+gwC&;ByKm9iCOdsCt&?$1K5$zqQJyWNVu_dL#YgDW*xp4dsPwsr0i?~c^kS@ch z^nwzFQD7S|3N^;!MpeEW#)!K49V{b5X%0e+&sjL;2KLDX#WS0;{iN4hP)`bj>|lc>DfS*(OXX!hd_UZM z!0ZFUqdA(KQRSrx0r3DEcoV>rOFDM|;cD8ImhH+KZYnM*t=qi5c!p+G;Us3>f@Tb% z>oz=enuSJ{xm;#ftj8TJ#)+TR&;#dN)6B8+slB~^ky3TgFKq7d2 z*N$QwW}m`6)U-?RolFS0O+6*F&*4bARPNwL4U)SAhrxurmS+?pFS6z0c=V)-Rm9{X z_l7cp@EpvfxZg4_LM&vwxWzBVnurX4a27zX9~4s}2Ct3-D<=1v35WVDSD@%5nB>{a z;lQyN7Lh-fibB~4sz@eR0#p9i>Yv|v<&k<|2820idUMRjLBx$%Nk;W;y1ZqNKJP2P zU17zM3;%?^yE6EZNJS{&3z?AszQ9$N`vB?a*TF;N`7t*3E=ZqFNc92z_ixovhMyDw z{7$yOoss`EUisrPTJ4WnxQ&7BU%6}2zgo7yJ;vk>_5Em3q;F-(HU^Z2A`Bz|0TRj= zkek}vQLqG!@xs_rwKt&s`**d$>)P{PP0jyhr{Yievri4SP_gY z^Bd&^K?F!L$Kk&Dk`e`pgb|h^mgdv9o(Z}n+bv=PM409di8{I9Jh7KyP+0XIb01$k{K2gMMg@A7Uc<~Ah^ zp7g}+8?jl7-uqY93ONeql`F0-HsBn!l(E`*@;U7%?k6_&3Q9eIiq^zC6(6m(bSC?| zckPsUXlQ|M^##5k+E{?__?cvd!!c>b=HD}_UU9p?vr3A^x)A|zWC+}lP;kidc1JzU zsyo+;D9fG22aY5sS@;*R8Wgj(;Gj7{9+Wo#FKc0RQMN^AIi;JL338uCW7N3M=sfYT9)b zc4TvHolTuprNc#=i8rf*K~F)1bL+uHZ%BAxMwm7nCwuLjW|3T~^v$1GyB|(65Rk%VptT2 zVWR(oZ~nsYpGi@|zfxwv$Ha&Y^3f;F907|3Fj-B5`+#x+MCG!e&jfK4pTp9l>Sexq zmvmTBRe2D$lz}6E=@ue1Wk-jxbqYnD@^n2|^)nm%W99&{^|_HL{8wF#jwnJq`UB0G zmiw^0=T2~z=V)xR6)vFHVIBoeN`@ZQEkAvQ^^f<*Q0u`&reuS*u2S4+PPZE@B7OnE*zr-jyUw0EC2^yzZ~! zeM*_ouSZH_l@wt*4m-yO)sgJaaf8YR2L6KvD=cStjNfx#6wA3ES`!6Nc+$5w8h8Nv z)|6Omby)eUol*^5-C2Cew^Pe!oTV-`QJ_AC^F%KjlE$T|ciIK)Av8MJ11}K2+%)&( zWdlKQ&^%SeJ{ebk`*FyXJiCYP0c%XnANMNH&(k9Ct_A6!k9e=39zI=eQjzioqv{aI zbaz6w7)yT1Wm^cv!^Wbm`p~PtB$obBGv0j{Y`ZHP?k@WATP0KtvX*t_tC00p)v{SB z)5)7PZzY!J#gwRbM)s7Ow zCUDjvxetO^`?^fv6Pc2Cp2rU{*N@OVX=Zy6a!F>u*wA30HRY`f52-=& zs3H5nm4JKnN3Cx1X(`kql0kX2l)AC|yP7N(c_or(Uiuqj%5}87=TssI-v?peN+i93 zdR9}Py%jc(@4)I>dpVnr5l`0Ps&2FAuY#^}|Ch+Ya6ia<9rhN2t)8+MdReCVC;kDGzM4{u4>28Xur!z&0>_nvOjPa`p%!=lBO^| zcS*Z<5`V|=zQ*L-w%Wq3!gz$A)uf)sZV7X_5p1O7VDtUQvDqg*@8~5U0Fr?KAovde zP&IMd~c%V zp%Z837Z;|#6UhG^Xu8eI&>u3VTgMDkQJwUDJ=cDJxkl+m2!K$&o=y{^`)aK|=Qz_} z6xaloZQwhaw0Rh&Z|>HJ6_ihtY++uJRy>TG0vM3Y1QCSD&K`co)!J#Z>6r9g2gEO3Yea8S6_X{05@3>J8EM@uuwdkrf+GQ zhGxHVj-AalrS97npb6yiG=h>tNN>ha&*SM6sv+d2dIHQ2DIhi#-qXkzhgFX!{LxRI z8F7~EVVg%bb5#iU=x9B^p9a{O|1g8tly4IV{@UKXCeyRuu}M~IrF8aDZ;$nO<8<1R zZ6w3fO(jD2R!Q{nPf(1Q-n@+fK~V+-#ed3g{{qGT(1H}szi6S(C2FDUzFg6&F;@6w z$4MAm0nrea%AZemhb7gSzxS-7Y3iNO2bt;#?6<;Bri3JGTWoM9x7)#*(^N+4YsgPG zkfy5vp-=eQG+x670|Vq3<#c?^sLduM_Xt8=+7=8PUe~GmDHUVl-co%<^2Hrk)1%J3 zw%0j5Ni5I$Gc&lU3^WTy3lHs-NY7O8!aM9i@%)AItN_r<`v88pANyt{6v$N9LMP}? zsfgx~56EQ2UNy#b4@|Qe z4Ikhwiio6@H%$-ze~i6Tm}XnHEt(m&%?#VNZQIPSZQHhO+jfS{4BL^x`>(3nXV+P` zzO(nkobO|fuGxC)t=FSt{e0eJ7jkiX>(weKHNhdFT_)!XS6V^>pMT-Jo$ZwoQV57- z`|Xf2ey#!n6Sr7`xZV{S{OoKy8Y!W*xa2SVD>(r?^14*r5zF6F3MI1=>a;R zup#^Hhl}9xcA}eRtC#LQ)>$Go5U_j>I#=K$L)iACZrHWDq(ed>UhHTB-nj-$&O;|| zi9bVK3&#E4ye)ST8rJVaQXDP*2-cYC%bJdV z1G`LCK4Vu!uoJXkGgIQr>sq=BCCCjKa0CXG2>~p<-6uhUxfH#g;%tQ(b+9HHfy?|k zP3${Q6~ql;CU#vU%c%S{^Lg-45%B0cF7{f#$P|33Y496)SiG2!bGiHi4UPe4b__AE<^4Ht(R&@^bM%;&L9y{caJ}uS>n*B}Mr%BG|&l1IW zSLnFn$P|cZLgogNJKebH1e)_|Df({j@TgDJwOI!H;3IBlj=EsRY0ZmNg?_9xXDklE ztNF5hym4`X#3~qtc{=fHp!8+*-@J%%A3`-~lPbvj(y|`U^#X73KA{O?r0y&EE&D?j zMNjlkcnZZ1w%BrYk~xx9#phWmH$mQy*>sqjCZOU-^`tm?H{eA%+~8if_@{#&#dI|BH<{I&58obWpW|vL-F0@EUio2g6LZl7aVSI%yzG0IR%A@<f5@J6A#jML85?pk~*SaCuw*kNPFgrCLUDsDZlVFGOxkQveb{rdXM2k zk}ve?AVrRR{RdcT@cY@wfS9IUIzvlPA7p5~!&3%zUK@w|a_N7{9*-xNCQCEn0u!dg zt-8LZ4KPOsm_-?lVDo@a8O9u8Ac=$RI^P}1HAR+dg69LIB-TgC%(F&;1an-os|Yd@ zb%HE)ge}sozy)i7;|~OZ+f-s*x1QnL{;UwDbbSz~*eABBd92w_Qfep)__x*_EjeVW zx^{_k2U2RdNfTtg`JePwX#rOW#;TmuLlN(HJ63Hv`1&~$>2DRePQI;=0B4Y_N4ovG z`8WFSUq(Btrcf0IFxDo(^Y`Dce?&rI6GtP5pN9V}S;O^cyTS_w1||e1>jLKD0tP1v z*7LB4l)AY8yI?9HVd|Y*6buwrCilI->7#1CYYOS3V7{wsk#e*Z#{ruxcVuNC$)G7uh24)%tzh8WC zynnhs=#Zg4Xo571)!&@&4WMwjjQ0OL$G?e2HLLw`MP5Pu97&+oz`{NNHG&Aw z$1on(PeEv1WpIw7kfjM-gaTj(QHKIZ$;>n6!W!!(B&P`pMN%C@ML#p02(0s2BaE}lw+29;Mj=CR8>AKwnVe35^e$Oe(KdimE zQNhbG2JF!}u;d2ZT2KEVn>V|Esrw6>tygB~b=_$qca~wilGSc!m;D4de$S|lZ2jO* zI@trvZMPJ?T*m{L-YGYRNDjQ2yK}(H^TwNwc9#%-*3)i05PkI`5=lESA9s%das}Sf zqsh{j6qT*xL7KAoOh;?UNjO#x%bsS5D4&*_9cvpI3ukqkkC7QGLB7%U2b!GpiG`%# z{f*C|-+VH|et37h8XK_Z>@vV@gN6tVTpuv zumx#B36V}wSe~2+sPs=|NhTCkNhx)EHUGGTjnfI}_?d#R8p;sPjBsoVe>q44-}cA} zFfK}xIgUITgip}H+a%5eiI_?cbxgUiu%@tt)$$X2pH{SN3dCwTim1x9ARN^NQAERL zgj;?=iBiw)1O)B)AcvQ_pkR|L^6X&+oQx^ad1cB?>|LYiWP_u}R*ZEMVE~amjXtG;tB66`lu8D`fd^UkA^!gvE%F$lrE^4Fr}&R0_)kGv9Gt zSk4qkNrgw_>Nb6?>nsE6LKduhnPOQFVoF7*;&yLbHziIZO50}| z%2yaEgsfogG1Cl`ht-ZwXx?ElD{3$@X4aOMoJa*Ikto~@B{@w~e49ONMJ4QL&~pZ? z58jr-ehvEIuD^Wl)0$Z)P~4p|Ff$bb-Re8cvlHj5ev>Raeeh$IxVHX`uqrDKI+9z7 zQRczDH!qM?2_HJ)KPIX;;XIs7msffyn~b!t-ThRMJhM~Bk@mH9yFZF}dYgz8JaL^f zcW62ZQP&end|yYQgSP;4Bg_Oj5S+;3 zDG4pPGIJ|&D^0WD_ol>f*pRZ0pyhWLo#+biPQjxT=Ocopu%E~!DYlBg7Ao2Wo_+TbszSi_v(xpVX zeRwb@Dl3W7dcBhFan;eJOJG|w9Qv)N%qv>LRdy_kqC{XZU|#pf5^KBClr&C}tLS*H z@8n$l5HB`49EmmQ3esWp3CNXf%OAj;Tn%v@XAhXP`h#IIU9vHDGO}Uvkf$~>eUfO8 z?lS3y`DSu4jE9K@U%P8&(?xl};^U6XmzuAyJt7-|bfA%SXgfrT32qNiw%Sd#d6yii zy~W0SZd|mz<)VC)q)xbnvjWEH@;1D>H-c~S4(Xe6 z`|VROl&hebA$j5bR&2JV2rHbT+>MjsfYgdo(zJz4B~wgke!GE<2+>#oQg@%We*U-7 zBd-h@p_H3gFgE1|?PX1R@@LE+uMdtB)&hhB)lpjV=6Ts|`5wu<^1|3MaM(|IF zx|N1(#Ng{V6_@F4*`A&t*`!HM3k|st&|2F zUX2d&zwBw79RAEzC7(*pg4IYNbero2Pd~_#P%f8Cp0;Da8$xeOAbmWvK+7for2r%> zaK$d&m7`hMP4~P$xwVb_cd08%gY&h_s{#W@T-xfPpzE=KA6mwgM^*QN%mROl5|S+n zna5@mO9Zl{)=z`Ao&#|k#q6G>C1x#0&Gc{lY`2GCTPlLHLOI%y7O@(QqwkewPZ)~A zRoPR`m|UK4>B`J8{XJMl06_pf0M{_c-|e4w0OaKuC-q@X0Wq3+f86|j*zFeC6&06C z(>8s_D7|K!?h(%o730&)T5pZsBklPZ6z#pG*_7~X#}(t?**Zfd>cUPW1=Lsuoi!Rz zud$fhKfr$jg9VgrHs{9asvQ}I+h;S-6!~em6HU4)M7^dIw?YB|J#%vbM^!6T)g`%E zOjE1#@S8_%mxKBDAAPVwG?0S^7)dv}5$Z!N@pb7Bn2Z1>^X=r&6I3ns*y_O1QSV+X!}_j zoTgz?t}c0Qk9JazcxVXp@+=$=5|f6FZuST&WkX#EX4Un*>@o^ZB4z$Y>*S?Sz>w#5t{vSSuu2wGJusdxE6 zP2*UVLcD~OH!ztaw7W;u$tf6*mcMc9@^3kF#8eHw#r>#tRu_<7Coaou$ftFuF_}zk zSzLmGYnzZ9U^36_zXM1kS!V`GY+9b$(w>1Ub3Is6Ta=e%pBDJUH5U?DD}2K6{7LK7 z;9GRBpS4eHTmuLuR$W=S*sNYyIA;$-K`Lw8W(r!@EwKb9r|xF@^igEH-A5$Z@|jAd z2|>>&;`52Er4yMQ2fy(;{1RLV^oNmXC$9w;Cc4pw-IjZ|Lr?-5$|++{z0&^dJYBFZ zD-*e!$lpYDN;4I^`A(I@T}z(C(Ue-UFOr#*;le9!i9g`o&Lx7xZC>Q4!-C@lN&AzN zJ#=Y-04lZTwftadP*0gSm7**)T(WlVsccO z+7t`Xr}^}a`kxP z@J%gfm9*jI5Z0Fhme-xl&ClNJ2fgdpndw^>q=_JJr}%5`_uJRry}i#|JHI!5bGTvk zSw5?GDRC0)LxJ$&R0#bB8MiC)a6(afx@1N+h8KL?LjzdY6@y*(b@m@+Z|`kxU-2-n zRp_BZf!uQ4di46i?NTvtRqWV!$q(>A??J{GH?@M_?0Tb&zH|RLXbXVf8)W1y&`0E@ zJO~OHc9Z|cM|@x;_+Ws!68;<;nJTBehv=pFo`urEU9qd=CSAo#D=HVJAUi?Tl zMW620#qtv=htf(;jO94qH1kj=*JqoG(i+|*k_ALt;2T>Bk{UieHRSXjAuEx|si~wCrmQwr}K zBdCnXh;9l(2Bcp@NzORwI9irhldNaBAQYKqq9$pf(i_d*ctZ85e?RrD6mx@X6SH(6 zc39^d@l-CDasbY3W9pD+;*@pX0$zmIO6^CfCciLHrr8HFfYI080_ z6gQ^4G7aGU&PNSc#Eo$yuiR6an`C#hzqrT!cI#@ zo}{ZVZ`l|R30Q(fNr$Khm%$OY=atShRyB1F2y60w_v%jN5}DFrkhpo5CVisx?pP|! z#N4299Dvnjr639mYR3DuS-z97A-`+GGB(k19@&4Yf%d~-p9%dtFb`#=6Evz|a1|@T%Ak;Y8zV~HnCRaRW3RG0Qk)XChTxnh zqvcx35o!mdsJVkojJ&n`&@TlM1WuK1$Tn)XBw2~{wuV906IkOx>~)SIb8*Nq1gLr= zYR24^`;}uAFM!R|JvIB-FQnL8ZbP=rGM9OEg%P%U8;m`L`<*X%T8q-je*Oy?Go;7_ z>%@zeMMwml=tF`?Xwlb8irOwy&Gqz2x8A6HeefjOUb^L^o3}&*9_p=HeENrl{9zyJ z!`KW{ZfSWv5yv;k22X5x)C+ls3p` z;H6R8s?)cHI*qQmcxF&)*DH)VYi`=J#vY9lZ=}tk)`qWm#FXvcxwoOM5m}T{W`7vz z^oF9GoX8F)4UHYwH~v506p9AqT~qD&Oe{!s0cnY4Mm6c1q14D+1Jf$~fF$v8JFMG)x$lquk&0rLC!C9+BAS*-DLv6Y4AtBfX z-Z|o}$IQkpd3pY5`$B;_k|YA7<8AuE$Nr!Jw%KV!E8JR^%6bI^axZ~Oe)|WWqf_CY zi?jW>&CS)5bE4V!a;*tx+F;Z`(g(S90cZdvt7a=!*rX|BsHbzAe#H~H!THyoMb>pw z@?z1#rQLnEhjjiZXzAH_fj@@;({^7*S6)f`_LSjR3#RD^R_F~mXH5>vVmmRjkgip+ zf$EB7TE|@K51kZKO-?1_TbO#X7#H5@uA4t(tW&gx76+~RC3^BSH(m5=u2CU)J}+P| zG;noMVat;WG@}>m?^{!?GUNvkX{a2a6pUayS4!lbK%Zh9$Ae4n)%hS{2ct+=IuWcr z?368qTO$TLuJ#_|lx{*s z5D2A=^J#$%L=A+Y6@_t=vVGV1!DoZQJSzoQ)9)9(nA49YlX>N z@kG%({-9*(B%!^kpxdkF{uWM`kvE{~90$uehuGJASnXS~3SY7JcHNUVG=&#i*?{Vq zAnoWUS--;SUM9g3kQoZB=pGYoX8j%kVPOr_2Et~jz8Q{l{^w{xi}F~{97m)&h+&Fw zdh+bdA&n=1<9#}xH?-X-ZS)T`=cd_IFQFMUbJ2fN$MIf16H? z2HLd^cQ8r)op>F0XmLF0l@@D6q&IuuA%`|nCB*!+0VDv7k1Y@wP@qOC3=<9)spqdF z3?0$$Q@I#E4nQUQ89?K7N;~Bm-45&gemNrOVaf4Ou8w94EIZD@L?7a z>yCD2TTF=;0yb8kZiX=CIDVHzxE0qS%bzdGU3+WNk9VM#U9B?A5tYP4LE<6%M2Jtx z7B+$YWXu7~82@R{w1ZXjlvs>Wp^_srZ z?2zHDYdF$a3$U&hK5h%l}c<8ZCb&|@^=Y8!&LFo_V>%%9R8G#@y>AaY^*hp`+ zHRI*o+5Y}uFE5Jc3C4VJUUpi>gh6%H61aLV+$WF!>Tg76C@1>FW*Up+I3mxT3Zh5f z#F?(J#SqAPV-}Fln3U5Nor;XOc^@t%?tCKG&UNIke2lVK&<=yyr>{#D;XgSjk1+pw zjChL>NpJBiA+v_~i(F;v!fEA%_3E8HErO~%he;{s094N&$^BGDhc79|k*J`ZkLefx zg79|{WKK<(Xe&gR<|--5WjPVK6%?xb&?3&A(-?d4t@$$hsfHxdJBKExq%v)jJK2*e zghJN`pk+^yD~fOib2>$sUHw28rd!ws)L}4aEs8)H)h$$yS^ZewgyY@>=${UFOT-q~ zT*fRJovYGg5=@Ka-hW%IAsuI)Kn>_jgd_g{`=0**djEAD|7=cVtDUMXs-k>}fH5M6 z2B64qa<-_38erO2q7F?I7=kzXsW-Ju8{;8N5vL6YUsdZ|^!S`}e4t;T?Pg6n| z?g{`sdG}Bl!Nn9saR-g2M^#tff9Pbi0;RDtZiCXa*Bb#WaC0lu$Go%{*+W8y&@jYCi?+&5W~Q+!mMqDdh}Og zM}8-#W5~OwE(jc(s-RdHt35)j@G}qUvn;3FuyxUBSW#t2Pu1N}?0UyYkR#k`V)?5I%V1R9MNY}K`46P|8;t!MYt#gk1g zAA=Rkieq_)bwPr%NU_y~Y33yp<*>qL4~xhNt}^0;3bH^QdYMVoa#y!m^j)Y9 zce+=4B-vnNdh(_UO{4p%Y#90{l0o&AN|p2lSW58iNWx9jEcd0wRBoZwtRC_-OBf`4 zg@O2Le+hQ%f)+PURh5+lqZpe;?f7qxi9&}5Z%*9eMaO3$Wj;%)I+Y>t5iR{~@g)x5 zAWMblz$&-~u^kyVOEMCctaBQ;wTw_yDsJ8QuMa);*~8F{y^uyrU#Me@P9hJmN=S%> zLh>)6IemVC)8p(R`g+N(c|1W*Aoj%Fn&9Z|+2deFNu8{Z6ct(PouuW}i{hJ8kG(Dt z*z)FQLW*T)a-9)3v{Yo8AshA*GoP`qJTXH#x(2XT_d7r?Nt9`vviA(T+Gh<>K%Umcfx5(^iK16)^$xR-JR3iohI4I_eNU=oki~gQ z#ZUbsAZXTn@iMKHlmh?>QATH9f{&kI0W6<+CI4{HTRoDCwJA}^>EJrOXrUHN_6i6Sd)0RHNz;`zExW$pDaupBm$sodERF>kTzg!Gqz+-9HXPqR>13@X9g}h( zJ){;SvLjy?p^ErUN8xY^%mRP7><;t$Vca0WEnp5#vI}Z!s~0xL%#dzUM@HyimUTMvPBR*0(~xsuFoNYGfP5dwe*xSILtS|!-YYE z?uM3Sxg?X=P?X-2o{`kCpl2OY8gPe#19 zz!y7^WCMeBAtzSGp!K)Pt}9C9$UK#+e~i6gqZ?^vtMg9r0b`x40}m{%O7H%N4NfT2 z#zxq*h?fm@zlpbo!|s`N33#R-T)=7*w7J$C&^`!3Az^m2Alw69z#)6}8A`KC^?HVD zAtUKP&|>Gt-3uzsOCGK$V~3p-s0)DF+0hjIyYM0j8XVFPh=AN9WNkDKury7Tbg0~N zM)P1kTl{RFF~^;IEwCuQrAlh=x^kbS4tLkuz^DObt%ywglmch*Es*D_?($gANm}9o zq#+m)WJE~hHmIHha~e?oK!12;s>^}UtwZri5jb)I@LRpa-@U|jCBRjVLxb&xU8zsp zB4Qkig@k3RV9GEn<+kjLFg73(ovQSfwe*&H?%H3gLse`HT1aZL?d=L!ttVev`zzL) z$gNHNLB>Tos>4;Z0mN-FgWGaQ_JRuMFMOz2Ki@6lx!(~DMDU5 zDVEcU>lP(wcw5}s+cF~&3f|L<9D?c`Yg=Ri?5coa;+CMX9P&rfsP4wkz3#i93fq0n zw2)le>;(V1cO^gPh* zNdFU3^{<0T|8#UR0dPqEMIchyP+X8l(J5UFDT!A_>B=uC5LDP8q|}X%)UWqb6dw5% z8i&UqEuO87^FeLq#E<{}jc>yKdSO*LZwXxXiC4q3+FR<+pYu2PZzNTx^zj*#QAg>TldSq7MLBT>c3PhJd5||z{P{vfP)M$e@u;;Z{*l;>ds~2e&G?;iYKTa6O z=Yh6RH{gjGATdl#v+SjJQXh^4x$5)z2$HnqethVYI92+ef;N!aefr^;72CQ$z4g^} zQvQ;r=|N!M;Na)?egBm(amymD8(>&}uT0kL3LYgPh+G1g=WvCxDLB7(I zJx9d<=_kD9q2Jp~lh_P}sAy8v{ekRq$X7_%epdp}vh0fOrr3dRRUtu?9*p`1V$+&y zwLy`jY#JUb!Yc_>%Jri>e97ZP!(rxV%?yjK#x@;a8khrzVJ?tbs}TziJ8iHlgbZv# zo&E*|6*$t0#$c_FiF>8aFfT#{n68eR{-u@&5#w}|8Ot<^XF>xNXJLz)8C(uud}AM^ zBcvUpfseKBZNoQ{=RBtJD_s}H^hIwU*y<4BwMrTIz0AgB=kKXM zvI{S;Hf!y}Y$zh!O4EGn2oe%H=QNc)$iek<>g2-OtCGN$bbOV{b8Q-ia)^)a+xX+F zGte_1rQ=6AO0X5T=$_FU#c8xHC`h-G#PQ{)5NJh)?iDHi6>^i%c-oo@0x6i+_pCJyn)Z;TFLPL67nYNqa!b#K3jnjdx*OtNzQ|P&) zm3^Gd_-2hKyA)+|P-@EE>z#2ym%0ifsQ1`;JjWSNdg;%PPs6pJZU66(LtDw``Io$N zB0#hE??m5!m9~F{oPRoGvWlhLf;@)LjH>FgGjKn4L;w`j<2>vQCkU!Y=sj2v2omz- zh3WW3f^OFb%9o!W^RFR^#i75HoO?e2I&+{YuXlrI|IIyFLS$}XbNE;(hJCANm$|spFJVMn=eQ!xep9qB84MJVT5les-1~C-dxd32MiAUnVD15L=ae z%GqJ=&fFGG_E$yrxZYZ4%VJITVVBu+S#;)3z|1Y{yyjptsyvmE%g3c?_XV%e@8zQKpa2Y;}coR&kzw^^Y4K3NXzB1rm_$rVNe7EWjcHT2=033n={g_L>!e`!?H)N@Ciqe?=IYRW zbGYB4~5vDlZj5n6HA z@Aq4v^m6BlO?j?hq95M>je`UZ$gCU$`CnuJqyQ3t6#Si% z`%nLMwo&`(Wd2VF4vtrl0un$N{jyvy*3dv(6vE&UM{Ihq0zm`|NIp>!maBw4#yi%% zxP%M38kb&o{!Te?2_`h zcsjqX2&IH3(4jwElta0R;3w&fTt_{uaT?ZTkxVoJ)!Y4I$L{IG582DG8t0({6*RnN z>|9ekAkR%so_z4^69eJYks(?cje*D%9UTiQwe}iDP z`$SeUgMvWeNWBLZj78=RZ85rny5UgWS42S_gDF*3p+Txt8Sqf$5n^w_Z z#Y@h5rKBw26LSMT@qZ4H|5%Fi&oAt(&@cPf4jkxU!E!%x!U$11F!s3<6#zxbP>^0> zu)CUyw!d1V#U~k^F3s%*_?`T~YSLf4ZE7Rk``&c>YW8}C%})u3bIf4WKR6^%huQjK zZMF56;g}u-#RG{@%N8bs`o~E;lQNj#oxwYj-QzB}QpF;e!ik(%4-%;!3e5+#Da^D$ z(a1J2DS_OuqQl`9iQSAmo}>4$Sw2#&rf|Yu*_K8z9YYzJluC%MXEGTPO^)yhc0oFW zv;&s03!Me;!UuT@r@iCg?xt8h)SqVh$&~qQ59F_DSA)Xcf~bgSV00EM2Il27{jv-+ z+q21fS8QoF@z-h=w15YLWgRlOYNJ=c$js%bBemdquwgu7Y#icIN3K4;(^y}Anp}i) z5_t!Ozg=KQ`fZ#(YNoQ;$fV$f6@lu>Onf@g+o#;Mu|#d$*)Ml4gQdUsJC%KM8XN%^ zkp#F1>i<+l0!H8L!9o!9 za}g_)I*mRwp-*KC%xnhsYM0plOAw)c`Nv{3w%aDUDcox+K?@)H-HOrZrZ3DBz~Vzj zzkG+{W_sM=zkskiV5U1#hU6z{E2ZruOO8m?SmV5Isd7St3^6j8`#tusr5n~|n9kml z84-4R2U8QWOV5zI8)*I2Ppv+A=~Hiq&UK47(VM?;u zxSDu6gTZ)ZKZv)R!$$h+0yut;GpbpTAsGlKUVYfghaCBat@;bW8}o&tITv=)$p8K| zPTlYY^dv0+C$fGI*%s`+PDSyZgu0J+oUkJOC2b~asV$Z-=}}lit}%UHR7zbIYq>6A ziG2))y?JvXmN44(GP^1)a4D!+bXWkn9TGUnWZanl7Ww}!G#-xk(f$A~t_3iw_P@S7 z#((_?{GYi?S}V1(Vm|@lIG|!sO7!GRatDQ`Bw>i~SLP-n+=h#N-LQ8=WFLPzZu5f2 z1aq$^+ZVn?rj3ft0OJO;nJF*N8CP1S9bcbMD18j7M{{9GF_;g|vv^g)!XdvH0T_|^ zVP}#MmZ%dD-0H!!5Ns%WrBRwF%d|QA@wtY{X=8=9dBkD&Jv5y51Bng8ld-iKQ-2;PP;pVn$gxWx60Y5*S?kg8y3jh-e@XI! z(j{kD93vJYY#nxWUw$r1*C7ntY{X^6q`{Mw*D+}p@Io&CoWLh-Wo@j?A*z-cIInEE zMgfT@lx`ZZ7T+UBgjVfu(ixzEt~Ex7l{Q%K6B&YK-fQv4++?srZv?wCkR9yu2c@=X zv)%RQ)EE#7d1?$`oQt7K3W@lb!JE*%z#mPHrctAHU&U;aKtmBpL@lK_T3Ks7-$@4PK&aw6lbvm#h62yTHpor0(dp6CNE zYVqcK_&OuuByesX!$o0q5@(2Q*=#BJqx!B2W?I`OV6}i~z+h1$Mab0^Z#E9sTFjmCNyWkNs~;5kLW^>xPPB3`hH6kDcbHm&uy6IV33>@2?i1Xa zUwH!?PPwuS22k*9hd)^1pQ>7<;u}skQaWux1$|-zBo|Q$2Ca4?E^HFTbavdQg}4xa z*MbZxT@*$z^t*FZP1g4EAzpfyj%#RV@`82vT(Yy%`jWpS+-K$O68JMoGi#Qna~}H{ zwI|OpIu(9&!KqAX1p2>)8$24o}5Uuz{qRP1A z)#P5lq+Bm3$Y$m0Wc6Bu56())j!FZkG1=e_xnh@1E11E$bPO2d=}z{OS%DJ5ljIGy z{ArR>7t!4Gp(;sUFeEP%Xqv{|D-+UOnNH&y8>-MY_?B`b+nTzMHAip+FJ^t7>POd^ z`{-RP*qaB}E-WJ}s+;4*`Q1ZqE>$4KB})4M<032zhE(ha!Y)|1l+d>cNS#5H60zSZ z#)(-j0aM>m$9y={@;Fub2VqRV2k(*EkUX(o5l>w0{7lZ?8GS9I7^hjm)WT&QAr0RZ4lMjK{v%sgg{#K8doNM> z^-WFu2gr?xwIH8#mt-Lix9D8aMV_e6q{Qqa)SR(*cKLF)X}pv3Zv-z8nx)Q43J)no(QXh?~{ z@ccprH;cl;A>l`P#l&`+uZ~yV!2OJ@#7+z`3{eat>B*B980C_wnpxo4Qb9UM9!8dv zl9^Q~?=}CZ;}U`#ub-R+%x&?BLvF9~QVR0@5|ueKEZJ0^agYrOpT?lVocSbss36lp zl0`m0GE`s^Z(GMW6eft)U2d;>K{hljt*DydQW3YV(PeD5+Gi4Uvb9Vtx7_M;`KrOC z`P~>*9};GFm&*~P5Qxyu?0B1L2#>psef^E=X7?Vq?)=AZbe0446%NE|@b^KsIZLf@ zjX+kIIiqMbP^-KhAaHBT`+pmG|I5ON1sob90H3!5@chqZgp#d;(|_AnaMWM+g(7^s zvRd)O4XPeH(DJzk1ReCbmn11DZH(>Kj+Wam6e$y#JxBN30JA9v;4uHYGyV5)U9_T%Ei$04 z-L`7DWX&f?x>f`VN@dK z%KJJDm{9lr@JtoVubhW#h-~xO$HQ|uV_Dx}mVk?cPEELHK~>hhtwqP%ew+@Wz)6y7 zkN=Ffr)ri2TUR&G%%&AeIvY>IR`hfMJ1-tnA}Wnp)QP#mp$F+0tZVL?b>=Z~o4bnr zBbH;V9i8wzSTAnvTE8#C$7BD5P9HjVtP1W>)JBsP$o92BT{V@E!!}XP>N#24Cbxde zk4}nOTkLteT^KOEf5*2F$pg>kak-n&i9TI#thVAJ*lP2Jo!Je zz--=|Lo^WtE#|%aR3%q)j%uHOBX@eXB&IF^lD!$A@BBX} z`@anRzhLv^BrT-{dB9IT8BLLlk_{RNsPN%@NwB4q>0+3H;JgH~ z7;nT*Kl%uC;1v7oS*XLNjM1TDJ?}#nk7rBo*Hum;KpHKz_FF_-<&S7XB*>|;wiH2_ z6{V9tSj+~5+hjwBoW z3V-XDl=BnIn&ZsvF8;HnhE63G?m<@`|DL;++mSioorXs~A1J9B4Xv0x@Ei*I4dyZ@ z&D$J}N;lPH&|`FndEEwcR{{MW8`@;8vY^zRbP`34Rvbqbb&Wqgn%cO=o^KV=h&6Q_W#BSPibt=UUlhqVjFZEtVBJ zr&~dHAB$gwVI#G*DJg$%*F_~j&!mq%a(l9|5#e`;1R69OwO@?t6HY|RM46szUEoIG zP^eh_wKvkR84K=f^#0YXu)Nt6~3xnB2I~)xp#&e>qCPGi{cig2K1scDe2%6r>#66oL@^eSv zGW-RG7=)V)VCE`n@uHy#GOHsAyyL8rk2=T}=CBDZF;dNqo6&z8n38_s*1Mie`3haw z3vlsk59ng-;G5!<+QTr8gmVZKX_xT`eyNOe2|7EVrHi6rYWJ(mBY0)SFAGJO(x|*a zQ0TGqYr$M&V_h251cRkEe#t0FxDsxv#gj;#Y3^5|*yD?AHi@paqMtlt-bvWKLa=Xr zE6or7*^o>oRd7J5&j@5`u%`S;fP@_?ZgU~DCUyp_Y!l5ccui{4-K{h?=#F)7aDEC2 zj~V`N;uL@7fG#yBHyuE%R04F9sQy!`wXt;qh!Yt73kLu!z;*sF3UsuJr4o_>ijOV= z`mzj)?dmW+6{7q^m$GU`iN;>>kLg${+BVV7sRk#&Ow}~X%x`JFJp3i6nFgdW**}L{ zuCpAo_gUDJwL5%1KyA@Hm#3*gi{X|*+!%vnW2IP3_+vu@R z<^sa0It48ABkLEeb>pjzUZcYWa+vW{m*%O80IvC6Bp8eCv{+!WDWQx2X%GKZgQF3Do4)uBL~VFP9P(=clPb3rtiUPe-g zW@=gnX5CaL?6qBw28BJ=TnlY7CUlU)L~2@zD=Fe&z1b;KAkaC^rX#K+d-S0{8pB-J zO37~vA}-ufs8V^6uzo_L(c-X~C7Y|JtvkywFMw)Q-VQPq73QEINCs33gUsaGs{G6) zRJTBusx90ebi<8ew-Z0{MzSA9OVQaeMRZRkia%EjG)qlZ07wF~w!Tmw-4?_q%TmI8 z=j*7g*|+G>`nzwI>-}9X=>=`DE=B61T;>@U;hFNJ$uv7cT2w2Y!kcb;wK{usxibTZ z;<2&)a{=8pMh%x*4T1I%tBEzs*RoEA`KBWzJG(Gyw(M2GC|&>30J*n$!2`klFSXDo zKO00{C=W>l=14@&+W8GUk(X0USsWo^#hpDV;@-ipCI1l|b?|Hj&QL_c0-FL%5~(V< zL6)fRGnbt1!H%5*g1j9IK<$hR55{`*x3HgBoIT7hT)1y#gXN1x+Oq!aq}pEV!{8Xc zXgIb&;8^;aEbw*L)GsMy>`P;td7R$b{g6POqbF0uazB2Nq?HjU2jZL-1cqD6pQsK7 zV|BPDvIKomI&*br6i*z{hr5f}*Ug+!f>CTqNOOdjV6W#wj&9*|3BXG{naU!pN#PaR z1`fR`vB1R5>>e3MuKq~=PK|VkbTX1Kas7@E{j^!F=5Hyz+ zmRrSycR-{=`Cx^t=N4nT9G>y^x1O()vOw)$Vi9`)odCN3(Mti#*#6f1RoalnWHpFdAG~RaKXF-=2q#}GR}>7TtiRJ1-JB2(9xb;JHv+}I zpqExRpbnO$UQunrsK|`H%?%E3df(gSs;RkEdInW~g=3PImBp4+dq+1B1##tC4 zDE#N{{Vj(2eP3|qAnly{EQ7!~@gI=}r3YCf(nu@MZ)?;?cyZHaYEKNVCeUlfZ|&n~ z^+_VC`1~zV=JC1CvXYrO_f1}bNGc`@T0j#1KU=^80 zM=byEg11;nM{bcHg{M(Vvvtu#1LYQ4K+QyJbpkp=UmC{HP|?i}l8zU4Yi*05ndLI+ zWR?+8#_I1NE&tp#}2s8UP(Fx+*>pMx}r(Oiq#k?s_~>LN|8m z1MN`$;L6>`@8QBZ0X2Ari9#5rM4Q;4G_f)Y=a8u(Jad zfh=uK@1XO2bqd=ZlW+UR0&9GoSql~)VWYrb%(XC=^A}DV-surM@f3oc5v7t37%5*4 z;JquenO{_+juFC*UtB>F!;4Fpf7A=eEa#DHn6X|9zG0m%GYeW{!9}P3Yze3Q=&L%% z4Q#I*Eo;Mj3pg7cXp-%g0EOr7hk2A`$Q1#0WY*0$MQ})db=SsL;w@FcSG?bpEAt9r z$Zv>@9xXBxX5(YTSvXw-szKfhYKy=QewNv!tlLl*PBfJnD4~Cq{{JX@$LLDitXnv! zIH}mSZC7mDwkx)6+qO}$?WAJcHczUb?tV}A>2G{*kFocUJ@&urp7)w-t!u6|`Ek(_ zv;VcBoXr>(0P>X}ul?6Z`g>QoP(k9)UXl+MJA<7x606*4`J5jkhY*v|4b%|<(ycADrqDcSTOMo6;Uim23@;CX4_d0Yl09oAMxRvKqY13lEfxf_)!clSb^G65D#pW z3sEDNJO+m~DBTh*vpngR9hGRk8dugJ;b{Mg>tT5F3mMCGj2=zB*Jh#}!EkD>5?-JE zDHnXtyI!te)H+#&KV76pEv4hn`)ohU%qs5X zV$Av_x>~b*kl?E9JZR|Xa1Gq6PBzq%m#(mI4t3fs^R39!(P^p(X>d>UPyu+-g7rfD z@Zh|mnwMmf2$P|Jp{tiq(Cc1@RW+H<%pOBs^O4ILnVE2wg(D%Aqrl`7$8}{Nr<2-+ z>9jzpSEHRKxgy*Y=QTz;lU-=yA){=$kC@a+_{!;9fUJDs`N=2O`C8FeWOY!pDg>?G zM)*C(m3v~P#pjS&QZz&|O3ou$F7`EfYc{{RHAgDMt#2(6iQ})J%8ct$YrQ~rlnxC3 zZ{;x$zH)x);k^G=blpw`F#f^R(SMC8#=m+ug$jSIq)u;Pv6D=1lKtARX9gL$J{TF} zLe9@$C@NY6OLPJyqhS(nX=J%40g@dk$hYGQyOj@D@3hjea{#Wv*_@fm%~=2Xx9G&N zRH_I1h@{4xYcSF8S%GPav80>Axy@Hki@=+7DUTiqO{t9pyS_`6P>N}yN2dSyZ0McL zCnLgOc0tG1fmjx2r_^Z?(( zgJ?gu7gCH-Pq+sT){QEKr{z4-S9DUPRch_Q5T4C`%{MCYWlnA%ySunlG=#4NHi&P8RNY&0n^If%>B<`Wd3Q=`7d_j+g==$9AKKh^v|{^?~3Ml*!xXlNoz^&4sh=SW~^7dzcVib#*(E+AbuR?(a1=i4Uf&*eR**1|K@|f$L)!N8c zbHWcKF3HRUbf7r?-dEXIp@jF}7>^Rl!WG~PQ=k7erkMW1RHfqo#Hkb(tK1*1i3p|! z&31(NG(w^!=0pY40vc}Hvz2XPO$-)$A|Sj_p?>|oxZTnG<11o_(so3au7|aZ^|uq_ zFOS*TT>uTW3IkX;r$!U}ATm@HyQQH)p(fCc5;#n5nxJMxXe_OI^N%$0#E7)wi3qX9 zy@C$~Q;6sk)$y1Y42p5S5ty9N7f8u{ir9vKA{C`rP&N97&E%E}UHJioe=TYjVoYF_ z;tt-s3rU`V7fOtADdr0o+ji{yjjWj|60~m3=1Ge?V6?%Px?^XVSsRYV;yA$CP)7 zWWP^ae*wsyG%QT3_)Fc9*tL<(K~ZsBAg9zj2FC5y;gWezNFJJ1P7?#Np_n!@dcl81 zo(`dGzO>bbs;x=7Jzsh1(k_&gE?5ENEDPn#ndINPF6Xy%Is6lJp&Ts#))6 z$z(qqckawsy<5D*!lDl&j^mhN!H5(4{DUoxO<=D zic8JjlOsal4P#u62b?m*dVU45P45{8Ww5fOcOlf=IGFKW5XxKA76KP} zEki-=ArCJ?0sVe6#1hV#x`NZR*HJd`yt|hgjM-9k$zj@0Vmm?(GzfKnCb*rn3aRX4 z^CTl|0oHZ?u^Q3PG|AXR^=w2CE0k$fZ0=1Gv4k963)ETBBxu*L$He6mm-OBkWTo{y zKOSRp-s3@r|79U+rhp~sm{)h!J6FEC+zYrt;Wja_69cOix>;;x@LNZB#Hp6gFHF=w z*;G_0Ee3~BxtJ_o4^w4Sl8NjP);Z{fZkBAAX|R)!*8N&_iHAQuQO$jiNLU`88ktWr zk+^!d7J>GB0`wzU-dBx*3)^u11*@b2Vvbb7>l8yzW5q4x6Wo7=l~*O{{U2EU_sqxg z59a&Jf2&B#>HN!{E-WkzPw1G&;TY-*R{kk5iZ}sRJ99OeO#%yQ^{9EUCpP~~%uSjC z`P;2_tq;}?G8i}6O%7h8t2Y4}YUFypU6|FG_Vvd_zN$9KHrMphIrjFsi4gHo=@c`_ zLqnaDT|5t^#+Bllh=(qDbF6IY)6I2Co?t?6RA*6$8>xV5w!P3YG$x-CEa*iOvGaVH z%SFLII@3i8fEsX~fKwDuCoYX?V~0NZ;079|nu!3y!n#s5@-SgwZ~>!bXk}V+?uii$ z*J)!Zdd82|I&XX<5Q$ZF8Kz5h@3I;rLPi>&rjk8KeawOD@%PHD$_j>$cqa=7zLq@M zF-QHu@)z}$;6)&mx=jhKM021hV>4}Wlyp1kZio3(EKvQyS>f)GDR7^$-KFOSvI(T) zXB|iR%nQB>_h)-GbY$;x>Gap4N?+00^{g=c89mjPzfm6)Pv6*I)R*{&`Xa0)nZKwn zg0G=Qw0gB*QM>H--QTFsDpx5`;EVb+$mU=r+cwBk+ML4TPHSn&yvMajzg(zTe4JAV zPWEn?%u|THB9r)%P6ZEb4N`6(>^wyW?0IwV&SUg4C7f>B{T45DZ`7Y5y*W%;YhhZ*;E*A<2A`+ zpJakxHK2_blFba_dtQGl45Xfo##pF)3ROKoY7udq#S#q-LHDeDv-1X<<1(ac+KtNL z2P*B?{x}gO0(&DP81sM&=Hl23oqy>zHNAq?waq$qScR8S;7f|U=3~Z@XMdPXmqj9z zhk8UehP-U{m1N}Wfv%(<<+`PTg6BGm{{8!w&aW2tP>jr}kf!Pbad?5AcY8hw8(G+n zLh16?@QdA0Z<;^J-wQrly2vjVneXbh$4?L|-B-FEf5(-#qSmzOdq{bf_l8Q)!P0W+ zLzQH|uV}qitFf7m1DdioqwmbB!B@0;_I|vM25Am2{b&o?PPD6oe?yGOi$r$YB!*!t2>h!1GEOu7ew`NoiBu6M!M%<_C1TaUF41av()d%kQ6M|X zrs#&hBpu*YK*_V=7K7)x9tkP3b)glO2L?HN6^b;du)&TS9FP~uw(0DUC4}xA*T^hc zYa?9al1xn?_f6vNv*dhL%Kkl1*R14my z$%nKC1{vV!Z%pMqX~+U4!Gv&rz|y3=hMn^sh(P?;d&U*GX6X&UB9VZ#DkLMTcA4s&o-~{q~1Q?x~jjK>wy=ovSh z`57PcPholj;rM6FCOyev$nWlCs4CZ6Nw*2022X3Jgq&Q(@s3#gM$EWIhALSJDAcFb zR!CbJKedYDy){@S3)6W;9#y@^bMrB7Q0&kbIo5m!4o zH%D2b8oaUjmr&YjhEVH;0Yck|yIK&}U^>FySqcY)Fx({~NysV~PmW%hY1N=oEuEtZ zj+*|+kKmXOR}$@Qh!9DMg-gChlOZB9948<*_%4I)Ml&84@!f%89@X`pAq&5M`ub9H zE-h<9O|!Q>0_kh4!X6#UrHAgxyHf0Tc225>=019`aKkqSTKUfrJwWRCZI*RlcsKie z;z$R+a3~(3p{yplgwyAZV!7iBavlLklS=5>Fk{l^qFw1Di&hwD6*D$*`R=Hec&big zYuR0A0}9CVDTqLu2GzJ z&H`84(1L6aA7xDv^0rfesvPtkXY5>$Ant@7iK(v`oJD(eo*#h^zY(0h4XhZbjL-+0 zaG9t7y7fqPoTv!Q?(P3}LRjYZDBBU9cJ8mkX+6r~Fw3Wn%1=2e))e0ue+D^1^WvNj z%Y8>JPv=_$RUP=&X6op#jH5V{d`2<=Ib6%N*W>{o?0&AxlZ~cU=kTjQ78s1LpX|Ag zgglyTtUBPaJ1lDb z%?J!tP{8uK!^-uDO14L(%nR;O1k9IP&*O(&)S)IzIvkK#5uLkt2KS-;WXEGh`rdEv z&o`(o(C=<^0Y)&3H3;3w811ThBj#}E6?XMF-9bUt9upJB02&y6PeGVzT(i?dLD9?s zYJ}sxHq6jloYtl{9YJI=d0aEh{i@W1@m4T)S^c#mUUh(bKrw)OApGduw8`R4v8)AR za|8NvX}2Kjbp^yZ`*T4?5(qOy85?uiMj~>GE6JeW%9`BWq$8 ziQz$+Ok)vJD2dq>)|iF*KN~eGdW(%ikjJZ$3am#Wv^e14G=M(L{3A@hwG-xJ0(Cyi zN4?z@N9Ji#T-r$3OKsA`5XI3L-S-ArV{kbK@VGDL^ z%^$islQLmWt1Ct#*CbKOg-SF_qrsbs2EI$F<_?ldb(oz^S4@T2vj`E!6fsk-@w6rq@hSoWqFYiS<}{oK+h9Ti>7+iVC3T>MTr( zj+ZMMDz-yIALR^aw>y08Y&x62%=0*|K^ zeMFGsM-aewOM|!3@h|!FnJqiX_OX8JzQg4ws|o)uX;Zh}*}eBn(jE`S!1`#p9#@o( zh3(q%ZVQL~1Qnsyu%mj}1$`hCNPTLI%`#?i2TeB^S@)GfXn z04#xKY!0W`gz!-=WPu&+NQq?WyN_}994YT_6i~$AE25~ab*_L*5W(J8AT4i-IXiR0 zEB14M7dzjNYC?!AF{22G7jZz0&3Fd^QF_#f%l=U!jgEH9kaD7?wcRv=;mj9nMzI*z7YNZsG4#>PZydn+kX<1i4XY z?k5ooF7MC2$}A~0Sg?24UTjsrX=`jyO@7``KX50%uXdXmevV}Le7t4gU5lJ5S&I%8 zLnfRa=;zf;(19Ry+;+gPq{H#ZT_J{6;1%hDs8Y!7IKQ1fdZInL(<{cceJPn6%HZ)@ zd;h;2=>FU(Ph>DVqx{j}e0~3;eCuEClocFoY;BDU`CXOljeh<=@-2FquNjNL&2B(I zKDfr7QEBS66f}&;z>?4def*#AKPy`HmO9SP(cjgSNl^aC%*e*Rgu){#MSb|-+zsLYUYipzKv%|Qq)@TK31{nBr(q3s9MYV#hc zy5aCgbVw;Mb9$#<*(OibibK5yOk=FB4V;Lh)?{`W1VcR&t(xWuv34hapHGw7UI4vF!Wm-jU=%9&T;yV8Ss)ELpAc3QYB7~I$asf)di zutceVx%ofU=AWq*7s?Z2!LO5s{VEOc{zLv|Ps?X%`8S2!Upbni+?X^FJrZ}IZ!EkZ zjvofAb%g#-KXX7ooL1!Ex8BYlzyq}c9N4(o`=kAVxLYFVHbY=?`ssIB?ia_uI*wOg z$0&Ui&RmA|$AtQX;_)|Q#nWg6-sw_qIWK}WrQWrNcUwG}3~k+J1nClhOZ%06aw52O zi{R7$#>2R^9d2xRMm_$aX;7H@id){9b zZX08;^zIE5$PX&1b|Rjy<^E!6Xj9S<;5`NDUp`1( z&y$XmQ@oqr0ICD;=t#9#`WTD+RNHPon1I#{32Q%$8%d!jqH5n=*k)%3oC+Fi)ZXM% z4L|QS{1#TiOqQF5H1_T_5uW_EKZ?8hP>ErJS{3OxZ_cufsr?1s;=u*6jI>DcWA;#6pX7)KLC$6P%UK9ne~&#a}%D z!4KSMEz%ZNDeYnJo{@_aU*bIAw$uT*zn^IBhwMn@bFsOVaz^}6-utVc5dO|a zdjyaqr^EO%V#Srj*k z9JDCZE}o;&rmcj*u$ec*wL#cRXWq!01KcRPX32bUDIY(oDll5hzjowUAHOv+Y#Zbh zr0pPBm5y{aYj4YVJVMf!>b(5zg6kAmU0uMjQGE?q`pU#ZhHEqbL=tIZOre1t6%=og za`Ltc3l;^sLg;(+<8@FJFZRfMV`^_14JuVqX|+$To|SptX7CZ@g%GWD83ziK;1&3~ z=I)$N<|kc-uK6-fIBWy1wC_)MF679xYr)qbQ7V^$LpNw@mHEe#YZ{VE_+tjCvE3;q z?(~t+ZKnLzwUKg-1>MfhXP0R#=^%rdfWc-ur85{)7!JoQoY-mvd zDc_%h=26^f!`V zNu^zz;>~vQ#EQa@kH3D&OYzKtu<-HZI-u@4dtA;^hNG|R@B{ryf0=f}F_{zUn|DAz zNd}>Ve}CWzucjdqVY!`9t(lS}(h@8R7#F0&xnQ-@az?E_^}t_cCD%7&R{EYICd6Vb zte5^_EMZk@$Tr)_ogu0}+UV+E9)3XEq=Xm&15+GVBx(fHXKDgs5F3In>EtiW1_zO? zxUz~BJ+$+remWJ1pCoI%l3jkwM>FcLYWfNyEkSc0S_C<^lHZNuXJyqtB08whV+g&v zl!CL49+|O(KJjsc?c?;DeJW->Jt8W|4CsI=BT^d|;jBmUeu&BaZLvz4HNX%Wx z1Ou|3p*e_XLI5gTmQZOUW)U`kmq&UMNf#+{ttuV0lY2sot0;8tI)Sq3W=C*^5e#CL z{)#HoNL~}?nDV{uTEkHPI%^yF*%>di@D6_5PvcxvcG_e+E~q8Z!u{NYO_LK(-e7KS zd)o1CEQWl)`FO>j^GI=d1hHAeOkHH=3RE@gGx@cIJKNSB5o|GFIc$K&FhdCXo1`qb zxPugA)QIgV7hb#oVOu%{arp;!N3yVNBC_qu#)V4=MZdA3NWq*3;#9wpw!n(8CiOB< zr&`;=p7D`b(ZLSvknB-PfbLu^r_5*Lj5c45*-f>^=y-#ZDwlwr2?s`u#tOMRp>RVt zYK-mI3o81E3i%9UHXqPlp{}fOC0DAQ)@+rDfeh=BrLZFPY{v=SxvUTZ_MSW<>`{H@ znX1w7n=-D;0%+Ctr;#q+bD{2Af1CFGVdzO`N`i1PKZFK}Mb9WU1l*N2f5u(NkeDm^ z(8F{nzbuALwa&3$wfDVhB-=eDf;Q&$4a=~|o{TE2l z*0*ZPK|GQvKZz*XSbg%jI=?1w2qA5i?r%;YF}K8(r~O8)5goOPTp{&@3q0jlAo~=6 zX46(ktVdvX0%S~mx$bz7Q$}Ah8D)RqH5*$vkj%nrQ!Iv9V07Cmx z>Y8HE;OCki5w^VRm>#((^gD`7dY2TNIW}uszj#n?$>JC|qsyEgavt+(!n+c_XtC=E zq$#oM79<(5Yjn3Xvp~s55FxP6eqAbLh-Xk>5vgofE;vbH=_h@;Io6Dm=m7uD9L^#8 z?THZn=4<-MXiN`38H_i+POV)|=+1cF0L@|-9@1FjCVbrjBAQ>n%-{6L-2XG^N&Kz^r>j8>q>kYt8Y#_LgD z0d0gkh}- z&`9?ld|0U?!2-wzoGrcY%|ct<Vjdkj-O1kSt)9J z>W80M)HoxNJ78Gkg2oR2Xa6IniTWZ@Z>uT9F-}cmTjK}6*vfo`m3(sW0cQA8@^U;e zm*jmarTaolstw4q%9X@zmtm(;I{X+kJ1oR4X#?M5N6AJutXPw|`Gce?!2_F#8wakS zwmLBQ4Nu~I1{13V;_M|+75SF;KmlS(kuRMzNff80Tvig|iPGL6P@6^~V*tFX&A4pe zaQj(dApL|G@A#QKpNlsY)=A2$JdatKz*^)kTGM7}N|DL>r{<*! z^K*Vn>vvFuj*}prtcMxV0H_m|_aDp#elmC@B3A)i=*q!}Y>PKHQMo0)Sp^57{8Ty6Myeq+5l~4v&UKEOJRY$Gs z-bsY06Gi&if1*M$=fx*G)ERsr9}y(>@f;Jl>nC2A@WTc*af??@P2v>oTCG8xJXBsK zUu&=McLKjfD|2|%EWJ=+MARIFEJtXQ?+V5wF7SxLo z+UELft4oBqn}$WHLju=fX}eWIyNMjY2$@;Fd5(U7ItRBEOqN_(Lu>un1yZ?%gInRu zmggzeFv~2LIjBP^CxFCBrS5{Hgwi_SsbWWBtCCip;CU`aLb_=F1XE;_EO)2WkSU?n z& z`}3mc*$#25wqu@FTu~-l4<8=Tdl#b8#(AODY1Dzm#)#Q@xiW-x#a)|~Q$_p1*c?f@ z)}BT=$M3})>G8ol(#2O&B~AIXl}Th#m0yI)v3GJ8Gg|yWhRceIg6y>1l+z z!m@Hmk&}eMBn)tp2DzwY*i|oTYo9>I5Sca^8h+(7T~3htSbh}7a6=Ac6{Y5MfkR3W zrXTYkILAES#ys1{Bo61tS-o0V0hc#hc_*N>AG;x|Ghl4=ztH33DptLGx= z7t2DW>{B;3)F5H51q>3D`}We3ZeuYsg8!xnwNQr)Su62aL@o6b#`}O`^4HFLzGKjm zs%{zA|3!Fp!{wX23goTqDHHx)K|OS+_{nZ!k0XEKQv#x^J~g9XgdIL5hbhnuW2!lD z$I|%N)D1$@Bd5mk^BVP+@hgQEpUGC|B!vfcjuXfPD^dICvwNn41RX;sN| zY%$zXq$_dkP4YccG^JblRRFm9x_Q#1UbexxWA|&5s%8{cFBx|FXD#VYu~{AYV_Rbt zN^uICieIu>U07h|Q=7nzikMl@QlRayv|T9QqunpPpPsq7+pMAob_00y4LTsN5zo+$ z=)#|9l@*20cN6dJ%HPxnC)Ff#v_ve_3a_?k>gjxM_&we6O=bBMM9MFyR8q@=k;H|k6qwC=(PgZ&C}(~vVoU#*ks$?{ z+eT5Vw2XwmNrV#*pW|*rd9~ENQ}hguOI;JRjFHT640P6^Xv#UyoX0zhj#(t-FX%KW zo&0Lx(0#QvoB=}E0+!ZQJ_Qf7_AFqVh=-~>$w$Quub{FaGaa2(hwipcxF%x72??#G zG%QQ0?@c6N8u5{p7)}o;TuOSDmuySY%V`#M3}HgUWE|WuS@sP&SXm1!{0c+IKX7k& z&wj(0)J@@6`)({~BdoGwSynH*Srq6Dk>9fw&tp7CLQH$v6Er|U<(=2h;EW5kA(}dO zkTx9NPG@BUScSHSt~Pxj7@L-GuINUvRk4kFv_?g6n*8eUZW|0WuDyCeR2b{Ktn{gPdV> zlV75J0_3IX99c(D#!h51=xAEQ+>yOqZ@Q>5k5{DB z&!FJ82JzkTtt;G1CiJkANOea{Vjge#3ic?Nat|%d*E95bFVx+1LwDCRI z0ql1TC#8+;5(`;!%J*jPkgn`$8LM2DrHZ0aVuQ!$UNhp&^E}Sqxtza?GzfTamhM`u z+!WNigf_xx0j&ez*Xy@8L~uHB)!n**}@=y{$E|~KYdo-VO&X(uPz_qSD*DiZ3nWa{j0(Ek1p$s^w)eWcVLfU z4tSKW7a;$R{tjjU7z9b$0Giy!m}U(f%dC~~J7u<{$KO`hoEO2iE|GK`X1Tk$t$KNM zb^x;tcKQ;ib5LPh1>MMgBfz0g(J~pqZ8^Wy)rZT3#;;qnip?UK zbXjP=_$#*9hQiFYn3ensL&-kD){Ruz$=?;VgoTxS z0-?FLI*-un9>?>r>q^QpGQXrk$4V^QjzYZDaguH1kOYY9vT-fNv1WGZ9_YeoV8@u z$lSi0C7IEb;e#~v?>4)in{6;Pq_$bVYBP|O-H#zHM)q$u`%P{mOrSnVCZt0*(Gm~) z%`9eGSTm-Fp|EH@$99@iRA;ym;7YEl@-&qyuGRQp96MpzAyqX^=Vr7ZP> zec_CrQPkyj|Lv5ib#E(#z7&y-U$@Tu|FNC@&vX6TDgU`!_`kZ^!Zttu`TyU~y-?ZA z9Z?C%%Z76zK<@}aT@ghpaEU3fh>RviK2e+=Elpg!vF^yhEnYfxe4aBtX(wt7%o~OW z7HNKHzn*t=$liuOt+Ij3Yj`}>ev|!>`*bhc+xr!<+w83YmKM)si>^x4Oj-K|ROVHzRQi9(zd!bd8Ur~zEetSo-@IA7-B|>F52XCUV?U|i*yPK^3*PY=%N;f^K;!d z84d@o0lN4#){yo>axi3-Isd+BI}HaYHVCVTW_NBhVO*ao3~TiwcEWaD~l^WzyC zm9@B*%yg-7$aFLtwa@BDPue+sMr_$<0jmn^O5!jYwv>AeWH+f;R$vG=tF+Zh{8c*z zSTMvQoM;6uArIk|4n>uC74{@C+Ih-_R1I#F0lnAa-$H`=3&YqpOYKJIfvw$yjequ` zHdkNS4(LoeFd>td3k1z@ujZDjH*1=t{$!A1|1LD}-7~Gse`FylVL99u-(y*buoB%S zhp~&`4Mt6onZHz7fRnHMcPx4P)(cDItEM~4Y!)tu&`^`%&$;=S`jgb~@kw}8{;>KB2q3_juoj-SiSw} zE?<;GASg7{8Va+P%j9fXkuP&f?q>Gd!pE5eK8VQolS#Yko1Uiaii7rAn9OUHgfaxe zW4N6JxCJ9xG05`Cf*@!-2aD9&04hi4{B>ez^>rlli3Y~)Y3No_)TQKF-{U-Z=no3X zHyDMYmaP%S^I;QggH}a>~T(0QkE@S&+I*m)DV0+!|R@R%~%+ z(_Gl7>NdCE7#t7Ff+xWe!o$M&l8H(K56 zI8a(Msb;&V+tOapc(k$iWqT**ko4|tg^za+DoD}f$Qg}Y3v}`B(i9;&z2l5R43Lbu zW6ZptewQ^r!&g1oBXlT~<`#4|7j*|eM>V=ecCC`FcbMqw#(Fv0T!E|74`?7ag^cY- z%PELw6LKnKlE!LHOdwIlAW2wL63DE|-wAL_G>k;+Qr`6l+FQH^6^lDoYh`SGENq&t z4-`FtzoQnsq%0{wlN*8xi&OiuaObACM2J(ip4j3ROnfb!2M&7#Y|yE#hVt%f$$rH? z&_DYzg?prRR@Hh+No5|O_hnJ|(o84o60t;x^(NtZG6e9j=yF%)V-s^gg1nuyLnsg> z*KJ}aytBuO7J2j z8|nE{i3#_6>kd(EW7|@c-e1CByO`?MmwNhMhi6?;X(->o<_qIc^Vxp|$~nA){p+o7 zXojZg*;kP6g8={_{{IisfAL?X%BlvU3fw0)LS2nzqU|jZ8JRh_ZcSwqqv(xWB}$+c<4KHGWS^Up}1_=AxJwO z|6mC?Jbo22N=`^gF9e_g5P@dN&xvaUNxacuF+hyPX`%kBJaAwVTq;02Km`JG+jekL z_RNEFlc%$U5c3R_t2m!zbn_sjxs$NbB3Gg+v#^YCoZ4%q`#LzBkP}M+K$5o5g4#s62PxG$P`D657ls2#4(cR^8jvLQ z%EwyOtWN=N#2MwiKM{2F)O^q#O|8HQaYJ1p=2}A{zo3cj ztTtbLlTmm}0;{{oNN$XN8cbznCA3?op6XK_7vTdwMiKS>7i0WM+fmene=Cx{KNEd5+~UDpH0X(UH!Uh23?%`_B4Q0e zlr){pdf-!sN}7IqWzuaZ5AtnF59)199;RK5pvbWR=?i;i(A}~^!*1*_v=_1BU}YM^ zW{GHF^7D4w*=t!6gN2CrtDv=T!ZwI&n&X>mxx7ib2HS?Fr=*RZ@V59>qPHfPR?U-S zt?egvLATm!EBVyY%JWZRvJHY*v2ACn!>Ve^L3`QePa((3cCqd$MmeZGRmPv*f5GkCW*UI;0Uy|fFL<#2uwSAdo9AWMbZp@=h zao7FKxRUHn$msz7G}e3&8cWhi8@MBONUS^7b>SW?%@5ZWkptN$LM|_FpkA!77ftNO z31`{yqdl9OPkuR+heS!=kIcnL%F@Z4FYZ|< zeCZdbR1>>T+Q=qYTt--q@a~ItuMrN0#IhnA(!CtciDN&67+~dom11pt8+{==-@gkm z`{fTAq-I$xM%<^Rcy3p1Pg+Cb+t>z431wrjPNi(u>V=Z!c%i|1`A#2w66-oIOKma6 zLR3>r?#n>{F+Zg@SFL8$DrwZpuVI|TGN=UP92w`Fso$jsHpiEvUJ?RUDj8Uy6t0a$ zP*P6bLJHR)L0T-3IAap59sqw=EJ0ex9*l}y(b@nG?81Qlfs@B&g~K_t9J<~{R*Qor z=60(~M_But2)9m!C$Lg*%yjTG#0vj}xYf$yn)iR`;*TVYzX?NW`m1Wn{gSBsr={`s zv|l;9k+s9W3R42(v}6$Zkb*YNP?KpWQ3CYk;B&`wP4lYT!wQsAwZ*puBx}N1rBZ)Wu;YzG&e~Gn)E1o}ts_{r0UU*cb$50c(6~18c!dgsQZd1kt_?L}9ro!_R=1v=`e`QA#}Uan zu{%;3u9Wq;COV5~{@ zr+%@~<;mId{AIay)viifr7u^aHd%gFu>jLx0^{YQf6eNoVNsAIs_KglkzTfo1i35F zev!1pie1*z3ET8rU~M0>59=MnO&=Rf-iAfu{ccqx7>(t4Ye|mvZf-dB{4@XD1z!$_ z{9O~HERT}4lrhXRO|Em+ZyE}jZwplix9cRQMv)OlGHRAIPT+!#Wrg+UqgcpncawIG z5eU59%Nx&-weK*6v?POtMkwcun#GP2D?MB&Y_w6X*8I&w2uV-}?vrU|mmVT&y5Afk zULks9U>clolz-fp1tF6}Up?@?QO`rY`7YaQD!;t>$mC}CM!MUT7mj0P*P9l5B zK#3JLv&I@Z^mf!RO-gxIO$ujNkBQsI7QPoROgG*xE_JlB8xij6IScg4&bK|j(hu`| zf`*-l!4xYhp?0tEs!mxT-Sf>E55@(viim2N`sL4lYE)4YUR=+_oaYaW&hEnXE5AmE z9~Uwmy;&#YWxJTAcV5swMPZQR-3kySf2gQ|KvL)`?M&ggiYh93+SXw6o5&F_;TP{vgBN))10 z+9E-Nn|t+WexK5q_{4(Pf^V{mHr-NmZP;DXFQ{Xhz*QETkTp(jdlKwzV=O|3cC(vn z8eMA%U_(W)4#uS0BG!cz#@Yt=UPv}cm%4||f{b=4z4s1+M0$J(s7aHJ#nuID1m3T< z^r;?vy1?EBM(O4a-2U5=5dik4p_4B>P<$!Q{}(ahpHtda7KnUsUQNyiv!~`&jq}Oo zk<8|9X7*vY)I#8p{1t_XUQYIE@i2#3YZ5)##6*x@aQ6n@igpia>IOM{?YqX-hx>X5 zshPX+Uz2KF!uB}CYs~uVA?`F-^O|cto?x(8Tn@4(WVoRvBtlCjs^+l$vET%`?mefI zKZ2GOK&{_6Cg(Yc5rc#|rQLe)7Ac_OG%ZrU6;H|nVv)3H!?sxU-zM(Rh$)#Gz|;XS(iD%?r=fuLmAbf zlJdjg&rjK73)_`BTqcgc*e&*e21kPq8EI~(1dr7MOv?3843RXM($#b5UVRv+n{u$G zw#<1g&;;qL;@Ov1=h2{}r_C93x|r_QI|P~Bf3^da%<{7_%`i|+F^&Tigl6y~YBliL z-zja$%@e$z&n%O4oUsb)ejI??e=L9}eS$oY)@i5`sO6b{tx$>E8~9}CSQORCu37W> zCBs_#g1JuNk;O}Ng|7#z=Q&ttZ`fRN2&Qy*3+rG5xsI8y(V}!`i)m3{rT$8x42iYE zj5J02uZ;5UX8B$6s}=h2zeCI4=dU9bH*FC3;66}lNEgcoR`ii8m-4uC&H$yFsUtc}0aj>ZR0#@=sl57aGe32CZ`uG~qd& zVlbQ}9j)P_RtRbgA1MKUrM)Xt%TT9BPG?ejJX&iKfM;}ou32I~^2;ROgaSx-0VP*%Ob>J1m_ZV9 zN$uDU2R-@ZqbNLZ45cT~YghrozCl648i8ws1nwkA=^)qm3da=?3PtP$L{?v7#fK)o%F=E-i6-Ft2}`mAPLe>9qeUhI0r3 z0Eqs-3gUleIDgf{g{lxPno7tYHVmoBuC8in1rjR_Qt>n+k}G2A2}wjCvoK+1B~oNX z;0&3rV%nUk5RCCOEppC1AaaV`*u(@OR)y5W;&S9ITVXq4;3YX{;gtN`hn=i88&o4i zX_sSdkAJqDeX3osA5K2%w4GW5Pzn`;X1Y*Kojlv?o zi3Wo49wcX9U1U={p-00~Jh4Z2ZB4-@ZY4h{L3l-OUhOtRdKK%F;2gko9S#w`Jpo_3 zDfSpp9BkWxcq`Ip5Al|&hVb4-ks@)G=HYmg_vl0;;Oz>tmqOEg>l>-Hmj2rzmj==}u8v zKtNKYlt#KG1SJLOE|C%e0Z9QB^qXtFck#k|@Bf{(j@gn zH~dgRp#E8b?F8A7^q4!<*q{}v)aj6Zg3XkaEMc4yB)M}RTY@Mki7!)Rx|zh(IB*&T z98O6I_BXaX43j0uq7WjzM_A|FA$lWDy$i9TZK3T>slZq_R{eK?r;5dU6KGnEwz7J+YxL*VPGD;LAs+9x!_ z9|oBaJ+-}6)Xu$9rjWs3@%~b%_&n zs`M@1^OsF6EQPl6vDOznR76%YS6Pz-YWNw9Z$-r6qTGHU6xa5?y=+)RmE$91{5*u- zm;;UXq5lwh`8BeLb9)!8t&){+m2#1jRLHV98)>PH*YGzK{rRZxxkq=JE>B;%*>;tZ zt-_G(Zkw|uL&|}xVU^T)ruv}7IJNHfrjh8iGq~ba#BO)4TdI*(42;INzgZ&Hs-t?y zV5+3g#)RXfIrCzX=zbjJEbAzVQNokZeEPaHN%c9~0@6Ek$#@7VJUzB;zE?HiV#Ts%ihsM>?`6@2_Oy_c&vgjB}pQ$riECaF4 z^EHWB%d5ODgzDs_iC7PZ=C#hKCo5E%_DFqIll;ozv67~N0P3BIR#NF0u&0YK&fmK` zsMmVtBFm&bd!uu!vF{lztcOWfLb|C!s6+IL98Pg&T2flqZO}QeG@H`Q987qns-e zapys>4f2Ho@h7`d(k7xQ7FS-F^M2H6Z0CGNI?3gYKsIDg(Z*?T$0js)K!U4E{axZ~ z?63}3@?g7Je1;sHOKj@mET7L_Tu^+#=o}nWxYTdY(MG4BP8AWINrBEkJ^Uo{348i% z#(n~gS;%;3LPiJ?n>N-qrz*ocD`Q_B8Kwzb{qu@LA(BKzZK7!Fjb2>O9+9RScIB+{ z%hHsu*d$L`_{D2kU~VWsEb7ej|HRl3%EVnX+u65mXA2<+!z-1*k#A*JR@xEXs{%KPr6tg_h2?nj~*dAP47@13Jn5zu|EV2IJ?TxPsZhbT4? z+|aiARrvX{17WwbVifs!`mq^YF1BW8oRt?NVjfKe3qP(-WonBn%BzyFZ^WExaT@{M8j8|*c$P0Fi*(-@|@ zK74xbhFM)*+qJp_0<-WGAHl$qX!p}!9?u~p+9T?1nuUO)Pp2flWsITl%;shYeNk=M zvVLnL(JZw%jwhi_ZeE~BvAI3R#OWkk|4dCTsSsbiVL06sE#}L#)E9+o(@Grg!z?gX z_{A8kJ8rUE;rGga`ibCOyLtD>J8{BV?}QD*Gap9j9SVoCdNL~=wC73OX&qc+Zodh1 z!?A12l@%NYw}L(`i{J6j3b~ zWl!8nsTT$+@ZRzIuUlMv$sA^a<czUtVJS26!L7FUmd1&#=x#A`h;qLP z$^Kw1&|9{;x~;bRc&edvPh95 z4r8duA(~FlEr+?dmoBYZxJSE}RlIZH-1~B&b8B9wG%m*PdGL$Mdug@7Wlec(7DAoM zyPSg)@0(i+amzbQ7#4Jt`66CY$9gHCX+=FuaJ!Ovx%jH$v|;*G?+wz_Rq@%szr`J}#V6TQ?l17=tci-aMX|=5K5m|QwcC}EOTSb@?zM1O zZ`Q&iGyRp`c@(W|vKU%)i;thH<4KzdYe?QwTNTuh7B#

`<^K9KoSHVVg)Dv&XRG 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 literal 0 HcmV?d00001 diff --git a/src/delombok/lombok/delombok/Comment.java b/src/delombok/lombok/delombok/Comment.java index 6f6910b4..c264733f 100644 --- a/src/delombok/lombok/delombok/Comment.java +++ b/src/delombok/lombok/delombok/Comment.java @@ -21,11 +21,11 @@ */ package lombok.delombok; -class Comment { +public final class Comment { final int pos; final String content; - Comment(int pos, String content) { + public Comment(int pos, String content) { this.pos = pos; this.content = content; } diff --git a/src/delombok/lombok/delombok/CommentCollectingScanner.java b/src/delombok/lombok/delombok/CommentCollectingScanner.java new file mode 100644 index 00000000..6f593c7f --- /dev/null +++ b/src/delombok/lombok/delombok/CommentCollectingScanner.java @@ -0,0 +1,85 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.delombok; + +import java.nio.CharBuffer; + +import lombok.delombok.CommentPreservingParser.Comments; + +import com.sun.tools.javac.parser.Scanner; +import com.sun.tools.javac.util.Context; + +public class CommentCollectingScanner extends Scanner { + + private final Comments comments; + + /** A factory for creating scanners. */ + public static class Factory extends Scanner.Factory { + + private final Context context; + + public static void preRegister(final Context context) { + context.put(scannerFactoryKey, new Context.Factory() { + public CommentCollectingScanner.Factory make() { + return new Factory(context); + } + }); + } + + /** Create a new scanner factory. */ + protected Factory(Context context) { + super(context); + this.context = context; + } + + @Override + public Scanner newScanner(CharSequence input) { + if (input instanceof CharBuffer) { + return new CommentCollectingScanner(this, (CharBuffer)input, context.get(Comments.class)); + } + char[] array = input.toString().toCharArray(); + return newScanner(array, array.length); + } + + @Override + public Scanner newScanner(char[] input, int inputLength) { + return new CommentCollectingScanner(this, input, inputLength, context.get(Comments.class)); + } + } + + + public CommentCollectingScanner(CommentCollectingScanner.Factory factory, CharBuffer charBuffer, Comments comments) { + super(factory, charBuffer); + this.comments = comments; + } + + + public CommentCollectingScanner(CommentCollectingScanner.Factory factory, char[] input, int inputLength, Comments comments) { + super(factory, input, inputLength); + this.comments = comments; + } + + @Override + protected void processComment(CommentStyle style) { + comments.add(pos(), new String(getRawCharacters(pos(), endPos()))); + } +} \ No newline at end of file diff --git a/src/delombok/lombok/delombok/CommentPreservingParser.java b/src/delombok/lombok/delombok/CommentPreservingParser.java new file mode 100644 index 00000000..c85124b5 --- /dev/null +++ b/src/delombok/lombok/delombok/CommentPreservingParser.java @@ -0,0 +1,77 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.delombok; + +import java.io.IOException; +import java.io.Writer; + +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.List; + +public class CommentPreservingParser { + private final JavaCompiler compiler; + private final Context context; + + public CommentPreservingParser(Context context) { + this.context = context; + CommentCollectingScanner.Factory.preRegister(context); + compiler = new JavaCompiler(context) { + @Override + protected boolean keepComments() { + return true; + } + }; + compiler.genEndPos = true; + } + + public ParseResult parseFile(String fileName) throws IOException { + Comments comments = new Comments(); + context.put(Comments.class, comments); + @SuppressWarnings("deprecation") + JCCompilationUnit cu = compiler.parse(fileName); + return new ParseResult(comments.comments, cu); + } + + static class Comments { + List comments = List.nil(); + + void add(int pos, String content) { + comments = comments.append(new Comment(pos, content)); + } + } + + public static class ParseResult { + private final List comments; + private final JCCompilationUnit compilationUnit; + + private ParseResult(List comments, JCCompilationUnit compilationUnit) { + this.comments = comments; + this.compilationUnit = compilationUnit; + } + + public void print(Writer out) { + compilationUnit.accept(new PrettyCommentsPrinter(out, compilationUnit, comments)); + } + } +} \ No newline at end of file diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index aa42f2b5..c6b58a31 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -112,17 +112,16 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { private static final Method GET_TAG_METHOD; private static final Field TAG_FIELD; + static { Method m = null; Field f = null; try { m = JCTree.class.getDeclaredMethod("getTag"); - System.out.println("Using getTag method"); } catch (NoSuchMethodException e) { try { f = JCTree.class.getDeclaredField("tag"); - System.out.println("Using tag field"); } catch (NoSuchFieldException e1) { e1.printStackTrace(); @@ -152,12 +151,11 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { } } - private List comments; private final JCCompilationUnit cu; private boolean newLine = true; - public PrettyCommentsPrinter(Writer out, List comments, JCCompilationUnit cu) { + public PrettyCommentsPrinter(Writer out, JCCompilationUnit cu, List comments) { this.out = out; this.comments = comments; this.cu = cu; diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java deleted file mode 100644 index caea38c9..00000000 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package lombok.delombok; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.StringWriter; -import java.nio.CharBuffer; - -import com.sun.source.tree.Tree; -import com.sun.source.tree.Tree.Kind; -import com.sun.source.util.SimpleTreeVisitor; -import com.sun.source.util.TreeScanner; -import com.sun.tools.javac.main.JavaCompiler; -import com.sun.tools.javac.main.OptionName; -import com.sun.tools.javac.parser.Scanner; -import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; -import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.List; -import com.sun.tools.javac.util.Options; - -public class PrettyPrinter { - - private final Context context = new Context(); - private final JavaCompiler compiler; - - public static void main(String[] args) throws Exception { - if (args.length == 0) { -// System.out.println("Usage: java %s ..."); - args = new String[] {"tests/foo/WithComments.java"}; - } - PrettyPrinter prettyPrinter = new PrettyPrinter(); - for (String fileName : args) { - prettyPrinter.print(fileName); - } - } - - public PrettyPrinter() { - Options.instance(context).put(OptionName.ENCODING, "utf-8"); - PrettyDocCommentScanner.Factory.preRegister(context); - compiler = new JavaCompiler(context) { - @Override - protected boolean keepComments() { - return true; - } - }; - compiler.genEndPos = true; - } - - public static class Comments { -// private static Key commentsKey = new Key(); - - private List comments = List.nil(); - - void add(int pos, String content) { - comments = comments.append(new Comment(pos, content)); - } - } - - private void print(String fileName) throws Exception { - - Comments comments = new Comments(); - context.put(Comments.class, comments); - - @SuppressWarnings("deprecation") - final JCCompilationUnit cu = compiler.parse(fileName); - - StringWriter writer = new StringWriter(); - cu.accept(new PrettyCommentsPrinter(writer, comments.comments, cu)); - System.out.printf("####### Original source of %s #######\n", fileName); - BufferedReader reader = new BufferedReader(new FileReader(fileName)); - String line = null; - while ((line = reader.readLine()) != null) { - System.out.println(line); - } - reader.close(); - - System.out.printf("####### Generated source of %s #######\n", fileName); - System.out.println(writer); - - printNodes(fileName, cu); - System.out.printf("####### Comments of %s #######\n", fileName); - for (Comment comment : comments.comments) { - System.out.println(comment.summary()); - } - System.out.printf("####### End of %s #######\n\n", fileName); - } - - private void printNodes(String fileName, final JCCompilationUnit cu) { - System.out.printf("####### Nodes of %s #######\n", fileName); - cu.accept(new TreeScanner(){ - @Override - public Void scan(Tree node, Void p) { - if (node == null) { - return null; - } - node.accept(new SimpleTreeVisitor(){ - @SuppressWarnings("incomplete-switch") - @Override - protected Void defaultAction(Tree treeNode, Void r) { - if (treeNode == null) { - return null; - } - JCTree tree = (JCTree)treeNode; - Kind kind = tree.getKind(); - System.out.print(kind.toString() + " " + tree.pos + " - " + tree.getEndPosition(cu.endPositions)); - switch (kind) { - case IDENTIFIER: - case PRIMITIVE_TYPE: - case MODIFIERS: - System.out.print("[" + tree.toString() + "]"); - break; - } - System.out.println(); - return null; - } - }, null); - return super.scan(node, p); - } - }, null); - } - - public static class PrettyDocCommentScanner extends Scanner { - - private final Comments comments; - - /** A factory for creating scanners. */ - public static class Factory extends Scanner.Factory { - - private final Context context; - - public static void preRegister(final Context context) { - context.put(scannerFactoryKey, new Context.Factory() { - public Factory make() { - return new Factory(context); - } - }); - } - - /** Create a new scanner factory. */ - protected Factory(Context context) { - super(context); - this.context = context; - } - - @Override - public Scanner newScanner(CharSequence input) { - if (input instanceof CharBuffer) { - return new PrettyDocCommentScanner(this, (CharBuffer)input, context.get(Comments.class)); - } - char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); - } - - @Override - public Scanner newScanner(char[] input, int inputLength) { - return new PrettyDocCommentScanner(this, input, inputLength, context.get(Comments.class)); - } - } - - - public PrettyDocCommentScanner(PrettyPrinter.PrettyDocCommentScanner.Factory factory, CharBuffer charBuffer, Comments comments) { - super(factory, charBuffer); - this.comments = comments; - } - - - public PrettyDocCommentScanner(PrettyPrinter.PrettyDocCommentScanner.Factory factory, char[] input, int inputLength, Comments comments) { - super(factory, input, inputLength); - this.comments = comments; - } - - @Override - protected void processComment(CommentStyle style) { - comments.add(pos(), new String(getRawCharacters(pos(), endPos()))); - } - } -} diff --git a/test/delombok/resource/after/WithComments.java b/test/delombok/resource/after/WithComments.java new file mode 100644 index 00000000..0f9ddb9f --- /dev/null +++ b/test/delombok/resource/after/WithComments.java @@ -0,0 +1,5 @@ +// Cool Comments + +public class WithComments { + // Also inside the body +} \ No newline at end of file diff --git a/test/delombok/resource/before/WithComments.java b/test/delombok/resource/before/WithComments.java new file mode 100644 index 00000000..22d044b3 --- /dev/null +++ b/test/delombok/resource/before/WithComments.java @@ -0,0 +1,4 @@ +// Cool Comments +public class WithComments { + // Also inside the body +} diff --git a/test/delombok/src/lombok/delombok/TestSourceFiles.java b/test/delombok/src/lombok/delombok/TestSourceFiles.java new file mode 100644 index 00000000..90c9b543 --- /dev/null +++ b/test/delombok/src/lombok/delombok/TestSourceFiles.java @@ -0,0 +1,97 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.delombok; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringWriter; + +import lombok.delombok.CommentPreservingParser.ParseResult; + +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +import com.sun.tools.javac.main.OptionName; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Options; + +public class TestSourceFiles { + + private static CommentPreservingParser parser; + + private static final File BEFORE_FOLDER = new File("test/delombok/resource/before"); + private static final File AFTER_FOLDER = new File("test/delombok/resource/after"); + + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + @BeforeClass + public static void init() { + Context c = new Context(); + Options.instance(c).put(OptionName.ENCODING, "utf-8"); + parser = new CommentPreservingParser(c); + } + + @Test + public void testSources() throws Exception { + File[] listFiles = BEFORE_FOLDER.listFiles(); + for (File file : listFiles) { + ParseResult parseResult = parser.parseFile(file.toString()); + StringWriter writer = new StringWriter(); + parseResult.print(writer); + compare(file.getName(), readAfter(file), writer.toString()); + } + } + + private void compare(String name, String expectedFile, String actualFile) { + String[] expectedLines = expectedFile.split("(\\r?\\n)"); + String[] actualLines = actualFile.split("(\\r?\\n)"); + int size = Math.min(expectedLines.length, actualLines.length); + for (int i = 0; i < size; i++) { + String expected = expectedLines[i]; + String actual = actualLines[i]; + if (!expected.equals(actual)) { + fail(String.format("Difference in line %s(%d):\n`%s`\n`%s`\n", name, i, expected, actual)); + } + } + if (expectedLines.length > actualLines.length) { + fail(String.format("Missing line %s(%d): %s\n", name, size, expectedLines[size])); + } + if (expectedLines.length < actualLines.length) { + fail(String.format("Extra line %s(%d): %s\n", name, size, actualLines[size])); + } + } + + private String readAfter(File file) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader(new File(AFTER_FOLDER, file.getName()))); + StringBuilder result = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + result.append(line); + result.append(LINE_SEPARATOR); + } + reader.close(); + return result.toString(); + } +} From f22021ca7808af2cd0ba03b7c34b8fd3758ff44b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Nov 2009 17:12:41 +0100 Subject: [PATCH 04/14] Minor refactoring + added testcase for for-loop --- .../delombok/CommentPreservingParser.java | 30 ++++++++++++++----- .../delombok/PrettyCommentsPrinter.java | 10 ++----- test/delombok/resource/after/ForLoop.java | 13 ++++++++ .../delombok/resource/after/WithComments.java | 2 +- test/delombok/resource/before/ForLoop.java | 12 ++++++++ .../src/lombok/delombok/TestSourceFiles.java | 11 ++----- 6 files changed, 54 insertions(+), 24 deletions(-) create mode 100644 test/delombok/resource/after/ForLoop.java create mode 100644 test/delombok/resource/before/ForLoop.java diff --git a/src/delombok/lombok/delombok/CommentPreservingParser.java b/src/delombok/lombok/delombok/CommentPreservingParser.java index c85124b5..19219d93 100644 --- a/src/delombok/lombok/delombok/CommentPreservingParser.java +++ b/src/delombok/lombok/delombok/CommentPreservingParser.java @@ -25,29 +25,43 @@ import java.io.IOException; import java.io.Writer; import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.main.OptionName; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Options; public class CommentPreservingParser { - private final JavaCompiler compiler; - private final Context context; - public CommentPreservingParser(Context context) { - this.context = context; + private final String encoding; + + public CommentPreservingParser() { + this("utf-8"); + } + + public CommentPreservingParser(String encoding) { + this.encoding = encoding; + } + + public ParseResult parseFile(String fileName) throws IOException { + Context context = new Context(); + + Options.instance(context).put(OptionName.ENCODING, encoding); + CommentCollectingScanner.Factory.preRegister(context); - compiler = new JavaCompiler(context) { + + JavaCompiler compiler = new JavaCompiler(context) { @Override protected boolean keepComments() { return true; } }; compiler.genEndPos = true; - } - - public ParseResult parseFile(String fileName) throws IOException { + Comments comments = new Comments(); context.put(Comments.class, comments); + + comments.comments = List.nil(); @SuppressWarnings("deprecation") JCCompilationUnit cu = compiler.parse(fileName); return new ParseResult(comments.comments, cu); diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index c6b58a31..2fb62e53 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -184,10 +184,6 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { */ Writer out; - /** Indentation width (can be reassigned from outside). - */ - public int width = 4; - /** The current left margin. */ int lmargin = 0; @@ -205,19 +201,19 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { */ void align() throws IOException { newLine = false; - for (int i = 0; i < lmargin; i++) out.write(" "); + for (int i = 0; i < lmargin; i++) out.write("\t"); } /** Increase left margin by indentation width. */ void indent() { - lmargin = lmargin + width; + lmargin++; } /** Decrease left margin by indentation width. */ void undent() { - lmargin = lmargin - width; + lmargin--; } /** Enter a new precedence level. Emit a `(' if new precedence level diff --git a/test/delombok/resource/after/ForLoop.java b/test/delombok/resource/after/ForLoop.java new file mode 100644 index 00000000..609549b7 --- /dev/null +++ b/test/delombok/resource/after/ForLoop.java @@ -0,0 +1,13 @@ + +public class ForLoop { + + public static void main(String[] args) { + // before loop + for (int i = 0; i < 10; i++) { + // start of block + System.out.println(i); + // end of block + } + // after loop + } +} diff --git a/test/delombok/resource/after/WithComments.java b/test/delombok/resource/after/WithComments.java index 0f9ddb9f..59cc97c4 100644 --- a/test/delombok/resource/after/WithComments.java +++ b/test/delombok/resource/after/WithComments.java @@ -1,5 +1,5 @@ // Cool Comments public class WithComments { - // Also inside the body + // Also inside the body } \ No newline at end of file diff --git a/test/delombok/resource/before/ForLoop.java b/test/delombok/resource/before/ForLoop.java new file mode 100644 index 00000000..2bed7f9b --- /dev/null +++ b/test/delombok/resource/before/ForLoop.java @@ -0,0 +1,12 @@ +public class ForLoop { + + public static void main(String[] args) { + // before loop + for (int i = 0; i < 10; i++) { + // start of block + System.out.println(i); + // end of block + } + // after loop + } +} diff --git a/test/delombok/src/lombok/delombok/TestSourceFiles.java b/test/delombok/src/lombok/delombok/TestSourceFiles.java index 90c9b543..374eeb8b 100644 --- a/test/delombok/src/lombok/delombok/TestSourceFiles.java +++ b/test/delombok/src/lombok/delombok/TestSourceFiles.java @@ -21,6 +21,8 @@ */ package lombok.delombok; +import static org.junit.Assert.fail; + import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -31,11 +33,6 @@ import lombok.delombok.CommentPreservingParser.ParseResult; import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assert.*; - -import com.sun.tools.javac.main.OptionName; -import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Options; public class TestSourceFiles { @@ -48,9 +45,7 @@ public class TestSourceFiles { @BeforeClass public static void init() { - Context c = new Context(); - Options.instance(c).put(OptionName.ENCODING, "utf-8"); - parser = new CommentPreservingParser(c); + parser = new CommentPreservingParser(); } @Test From e5d248c3ccf64211fd8a301f584bde82dd426601 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 27 Nov 2009 00:38:58 +0100 Subject: [PATCH 05/14] delombok now calls lombok. wahey! --- src/core/lombok/javac/JavacAST.java | 5 +- src/core/lombok/javac/JavacTransformer.java | 98 +++++++++++++++++++ src/core/lombok/javac/apt/Processor.java | 67 +------------ .../delombok/CommentPreservingParser.java | 32 +++++- .../src/lombok/delombok/TestLombokFiles.java | 95 ++++++++++++++++++ .../src/lombok/delombok/TestSourceFiles.java | 21 +++- .../resource/after/CommentsInterspersed.java | 26 +++++ .../resource/before/CommentsInterspersed.java | 14 +++ 8 files changed, 285 insertions(+), 73 deletions(-) create mode 100644 src/core/lombok/javac/JavacTransformer.java create mode 100644 test/delombok/src/lombok/delombok/TestLombokFiles.java create mode 100644 test/lombok/resource/after/CommentsInterspersed.java create mode 100644 test/lombok/resource/before/CommentsInterspersed.java diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index f2c83fb8..77c63cfe 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -32,7 +32,6 @@ import javax.tools.JavaFileObject; import lombok.core.AST; -import com.sun.source.util.Trees; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; @@ -66,13 +65,11 @@ public class JavacAST extends AST { /** * Creates a new JavacAST of the provided Compilation Unit. * - * @param trees The trees instance to use to inspect the compilation unit. Generate via: - * {@code Trees.getInstance(env)} * @param messager A Messager for warning and error reporting. * @param context A Context object for interfacing with the compiler. * @param top The compilation unit, which serves as the top level node in the tree to be built. */ - public JavacAST(Trees trees, Messager messager, Context context, JCCompilationUnit top) { + public JavacAST(Messager messager, Context context, JCCompilationUnit top) { super(top.sourcefile == null ? null : top.sourcefile.toString()); setTop(buildCompilationUnit(top)); this.context = context; diff --git a/src/core/lombok/javac/JavacTransformer.java b/src/core/lombok/javac/JavacTransformer.java new file mode 100644 index 00000000..d004414d --- /dev/null +++ b/src/core/lombok/javac/JavacTransformer.java @@ -0,0 +1,98 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.processing.Messager; + +import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.util.Context; + +public class JavacTransformer { + private final HandlerLibrary handlers; + private final Messager messager; + + public JavacTransformer(Messager messager) { + this.messager = messager; + this.handlers = HandlerLibrary.load(messager); + } + + public void transform(Context context, Iterable compilationUnits) { + List asts = new ArrayList(); + + for (JCCompilationUnit unit : compilationUnits) asts.add(new JavacAST(messager, context, unit)); + + handlers.skipPrintAST(); + for (JavacAST ast : asts) { + ast.traverse(new AnnotationVisitor()); + handlers.callASTVisitors(ast); + } + + handlers.skipAllButPrintAST(); + for (JavacAST ast : asts) { + ast.traverse(new AnnotationVisitor()); + } + } + + private class AnnotationVisitor extends JavacASTAdapter { + @Override public void visitAnnotationOnType(JCClassDecl type, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + + @Override public void visitAnnotationOnField(JCVariableDecl field, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + + @Override public void visitAnnotationOnMethod(JCMethodDecl method, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + + @Override public void visitAnnotationOnMethodArgument(JCVariableDecl argument, JCMethodDecl method, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + + @Override public void visitAnnotationOnLocal(JCVariableDecl local, JavacNode annotationNode, JCAnnotation annotation) { + if (annotationNode.isHandled()) return; + JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); + boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); + if (handled) annotationNode.setHandled(); + } + } +} diff --git a/src/core/lombok/javac/apt/Processor.java b/src/core/lombok/javac/apt/Processor.java index 9c851762..b779a680 100644 --- a/src/core/lombok/javac/apt/Processor.java +++ b/src/core/lombok/javac/apt/Processor.java @@ -21,9 +21,7 @@ */ package lombok.javac.apt; -import java.util.ArrayList; import java.util.IdentityHashMap; -import java.util.List; import java.util.Set; import javax.annotation.processing.AbstractProcessor; @@ -36,19 +34,12 @@ import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic.Kind; -import lombok.javac.HandlerLibrary; -import lombok.javac.JavacAST; -import lombok.javac.JavacASTAdapter; -import lombok.javac.JavacNode; +import lombok.javac.JavacTransformer; import com.sun.source.util.TreePath; import com.sun.source.util.Trees; import com.sun.tools.javac.processing.JavacProcessingEnvironment; -import com.sun.tools.javac.tree.JCTree.JCAnnotation; -import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; -import com.sun.tools.javac.tree.JCTree.JCMethodDecl; -import com.sun.tools.javac.tree.JCTree.JCVariableDecl; /** @@ -66,7 +57,7 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl; public class Processor extends AbstractProcessor { private ProcessingEnvironment rawProcessingEnv; private JavacProcessingEnvironment processingEnv; - private HandlerLibrary handlers; + private JavacTransformer transformer; private Trees trees; private String errorToShow; @@ -86,7 +77,7 @@ public class Processor extends AbstractProcessor { this.errorToShow = null; } else { this.processingEnv = (JavacProcessingEnvironment) procEnv; - handlers = HandlerLibrary.load(procEnv.getMessager()); + transformer = new JavacTransformer(procEnv.getMessager()); trees = Trees.instance(procEnv); this.errorToShow = null; } @@ -111,61 +102,11 @@ public class Processor extends AbstractProcessor { if (unit != null) units.put(unit, null); } - List asts = new ArrayList(); + transformer.transform(processingEnv.getContext(), units.keySet()); - for (JCCompilationUnit unit : units.keySet()) asts.add( - new JavacAST(trees, processingEnv.getMessager(), processingEnv.getContext(), unit)); - - handlers.skipPrintAST(); - for (JavacAST ast : asts) { - ast.traverse(new AnnotationVisitor()); - handlers.callASTVisitors(ast); - } - - handlers.skipAllButPrintAST(); - for (JavacAST ast : asts) { - ast.traverse(new AnnotationVisitor()); - } return false; } - private class AnnotationVisitor extends JavacASTAdapter { - @Override public void visitAnnotationOnType(JCClassDecl type, JavacNode annotationNode, JCAnnotation annotation) { - if (annotationNode.isHandled()) return; - JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); - boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); - } - - @Override public void visitAnnotationOnField(JCVariableDecl field, JavacNode annotationNode, JCAnnotation annotation) { - if (annotationNode.isHandled()) return; - JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); - boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); - } - - @Override public void visitAnnotationOnMethod(JCMethodDecl method, JavacNode annotationNode, JCAnnotation annotation) { - if (annotationNode.isHandled()) return; - JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); - boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); - } - - @Override public void visitAnnotationOnMethodArgument(JCVariableDecl argument, JCMethodDecl method, JavacNode annotationNode, JCAnnotation annotation) { - if (annotationNode.isHandled()) return; - JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); - boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); - } - - @Override public void visitAnnotationOnLocal(JCVariableDecl local, JavacNode annotationNode, JCAnnotation annotation) { - if (annotationNode.isHandled()) return; - JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get(); - boolean handled = handlers.handleAnnotation(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); - } - } - private JCCompilationUnit toUnit(Element element) { TreePath path = trees == null ? null : trees.getPath(element); if (path == null) return null; diff --git a/src/delombok/lombok/delombok/CommentPreservingParser.java b/src/delombok/lombok/delombok/CommentPreservingParser.java index 19219d93..51df5ed1 100644 --- a/src/delombok/lombok/delombok/CommentPreservingParser.java +++ b/src/delombok/lombok/delombok/CommentPreservingParser.java @@ -23,6 +23,15 @@ package lombok.delombok; import java.io.IOException; import java.io.Writer; +import java.util.Collections; + +import javax.annotation.processing.Messager; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.tools.Diagnostic.Kind; + +import lombok.javac.JavacTransformer; import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.main.OptionName; @@ -64,9 +73,30 @@ public class CommentPreservingParser { comments.comments = List.nil(); @SuppressWarnings("deprecation") JCCompilationUnit cu = compiler.parse(fileName); + + new JavacTransformer(messager).transform(context, Collections.singleton(cu)); + return new ParseResult(comments.comments, cu); } - + + private static final Messager messager = new Messager() { + @Override public void printMessage(Kind kind, CharSequence msg) { + System.out.printf("M: %s: %s\n", kind, msg); + } + + @Override public void printMessage(Kind kind, CharSequence msg, Element e) { + System.out.printf("E: %s: %s\n", kind, msg); + } + + @Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a) { + System.out.printf("A: %s: %s\n", kind, msg); + } + + @Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v) { + System.out.printf("V: %s: %s\n", kind, msg); + } + }; + static class Comments { List comments = List.nil(); diff --git a/test/delombok/src/lombok/delombok/TestLombokFiles.java b/test/delombok/src/lombok/delombok/TestLombokFiles.java new file mode 100644 index 00000000..10782830 --- /dev/null +++ b/test/delombok/src/lombok/delombok/TestLombokFiles.java @@ -0,0 +1,95 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.delombok; + +import static org.junit.Assert.fail; +import static lombok.delombok.TestSourceFiles.removeBlanks; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringWriter; + +import lombok.delombok.CommentPreservingParser.ParseResult; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class TestLombokFiles { + private static CommentPreservingParser parser; + + private static final File BEFORE_FOLDER = new File("test/lombok/resource/before"); + private static final File AFTER_FOLDER = new File("test/lombok/resource/after"); + + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + @BeforeClass + public static void init() { + parser = new CommentPreservingParser(); + } + + @Test + public void testSources() throws Exception { + File[] listFiles = BEFORE_FOLDER.listFiles(); + for (File file : listFiles) { + ParseResult parseResult = parser.parseFile(file.toString()); + StringWriter writer = new StringWriter(); + parseResult.print(writer); + System.out.println(writer); + compare(file.getName(), readAfter(file), writer.toString()); + } + } + + private void compare(String name, String expectedFile, String actualFile) { + String[] expectedLines = expectedFile.split("(\\r?\\n)"); + String[] actualLines = actualFile.split("(\\r?\\n)"); + expectedLines = removeBlanks(expectedLines); + actualLines = removeBlanks(actualLines); + int size = Math.min(expectedLines.length, actualLines.length); + for (int i = 0; i < size; i++) { + String expected = expectedLines[i]; + String actual = actualLines[i]; + if (!expected.equals(actual)) { + fail(String.format("Difference in line %s(%d):\n`%s`\n`%s`\n", name, i, expected, actual)); + } + } + if (expectedLines.length > actualLines.length) { + fail(String.format("Missing line %s(%d): %s\n", name, size, expectedLines[size])); + } + if (expectedLines.length < actualLines.length) { + fail(String.format("Extra line %s(%d): %s\n", name, size, actualLines[size])); + } + } + + private String readAfter(File file) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader(new File(AFTER_FOLDER, file.getName()))); + StringBuilder result = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + result.append(line); + result.append(LINE_SEPARATOR); + } + reader.close(); + return result.toString(); + } +} diff --git a/test/delombok/src/lombok/delombok/TestSourceFiles.java b/test/delombok/src/lombok/delombok/TestSourceFiles.java index 374eeb8b..b662651d 100644 --- a/test/delombok/src/lombok/delombok/TestSourceFiles.java +++ b/test/delombok/src/lombok/delombok/TestSourceFiles.java @@ -28,6 +28,8 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; import lombok.delombok.CommentPreservingParser.ParseResult; @@ -35,14 +37,13 @@ import org.junit.BeforeClass; import org.junit.Test; public class TestSourceFiles { - private static CommentPreservingParser parser; private static final File BEFORE_FOLDER = new File("test/delombok/resource/before"); private static final File AFTER_FOLDER = new File("test/delombok/resource/after"); - - private static final String LINE_SEPARATOR = System.getProperty("line.separator"); - + + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + @BeforeClass public static void init() { parser = new CommentPreservingParser(); @@ -59,9 +60,19 @@ public class TestSourceFiles { } } + static String[] removeBlanks(String[] in) { + List out = new ArrayList(); + for (String s : in) { + if (!s.trim().isEmpty()) out.add(s); + } + return out.toArray(new String[0]); + } + private void compare(String name, String expectedFile, String actualFile) { String[] expectedLines = expectedFile.split("(\\r?\\n)"); String[] actualLines = actualFile.split("(\\r?\\n)"); + expectedLines = removeBlanks(expectedLines); + actualLines = removeBlanks(actualLines); int size = Math.min(expectedLines.length, actualLines.length); for (int i = 0; i < size; i++) { String expected = expectedLines[i]; @@ -77,7 +88,7 @@ public class TestSourceFiles { fail(String.format("Extra line %s(%d): %s\n", name, size, actualLines[size])); } } - + private String readAfter(File file) throws IOException { BufferedReader reader = new BufferedReader(new FileReader(new File(AFTER_FOLDER, file.getName()))); StringBuilder result = new StringBuilder(); diff --git a/test/lombok/resource/after/CommentsInterspersed.java b/test/lombok/resource/after/CommentsInterspersed.java new file mode 100644 index 00000000..ec5374c0 --- /dev/null +++ b/test/lombok/resource/after/CommentsInterspersed.java @@ -0,0 +1,26 @@ +import lombok.Getter; + +/*bla */ +public class CommentsInterspersed { + /** javadoc for field */ + private int x; + + /* bla2 */ + @Getter() + private String test = "foo"; + //$NON-NLS-1$ + + /** Javadoc on method */ + public native void gwtTest(); + /*-{ + javascript; + }-*/ + + public CommentsInterspersed() { + } + + public String getTest() { + return this.test; + } +} +//haha! diff --git a/test/lombok/resource/before/CommentsInterspersed.java b/test/lombok/resource/before/CommentsInterspersed.java new file mode 100644 index 00000000..2a32d309 --- /dev/null +++ b/test/lombok/resource/before/CommentsInterspersed.java @@ -0,0 +1,14 @@ +import lombok.Getter; + +public /*bla */ class CommentsInterspersed { + /** javadoc for field */ + private int x; + + private /* bla2 */ @Getter String test = "foo"; //$NON-NLS-1$ + + /** Javadoc on method */ + public native void gwtTest(); /*-{ + javascript; + }-*/ +} //haha! + From 86ac271a45e1152272f44fcd81f0c90914853013 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 27 Nov 2009 02:38:55 +0100 Subject: [PATCH 06/14] We encountered a strange NPE here. Can't reproduce, nevertheless added null-checks --- src/eclipseAgent/lombok/eclipse/agent/PatchFixes.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchFixes.java b/src/eclipseAgent/lombok/eclipse/agent/PatchFixes.java index 5d54692e..1430ca8c 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchFixes.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchFixes.java @@ -26,6 +26,7 @@ public class PatchFixes { public static void setIsGeneratedFlag(org.eclipse.jdt.core.dom.ASTNode domNode, org.eclipse.jdt.internal.compiler.ast.ASTNode internalNode) throws Exception { + if (internalNode == null || domNode == null) return; boolean isGenerated = internalNode.getClass().getField("$generatedBy").get(internalNode) != null; if (isGenerated) { domNode.getClass().getField("$isGenerated").set(domNode, true); From c91e3701b9f5cf85a09f998d305895d4d1617206 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 27 Nov 2009 02:44:46 +0100 Subject: [PATCH 07/14] Added another test --- test/delombok/resource/after/Cast.java | 7 +++++++ test/delombok/resource/before/Cast.java | 6 ++++++ 2 files changed, 13 insertions(+) create mode 100644 test/delombok/resource/after/Cast.java create mode 100644 test/delombok/resource/before/Cast.java diff --git a/test/delombok/resource/after/Cast.java b/test/delombok/resource/after/Cast.java new file mode 100644 index 00000000..a1b455f0 --- /dev/null +++ b/test/delombok/resource/after/Cast.java @@ -0,0 +1,7 @@ +import java.util.*; +public class Cast { + public void test(List list) { + RandomAccess r = (/*before*/ + RandomAccess /*after*/)list; + } +} \ No newline at end of file diff --git a/test/delombok/resource/before/Cast.java b/test/delombok/resource/before/Cast.java new file mode 100644 index 00000000..95237b0f --- /dev/null +++ b/test/delombok/resource/before/Cast.java @@ -0,0 +1,6 @@ +import java.util.*; +public class Cast { + public void test(List list) { + RandomAccess r = (/*before*/ RandomAccess /*after*/)list; + } +} \ No newline at end of file From e54c3f36e3122dfe34a119178cfcca2dcdbad998 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 27 Nov 2009 03:10:03 +0100 Subject: [PATCH 08/14] Added change tracking so that 1 AST instance can tell you if any processor changed anything. --- src/core/lombok/core/AST.java | 13 +++++++++++++ src/core/lombok/core/LombokNode.java | 6 ++++++ src/core/lombok/eclipse/EclipseAST.java | 3 +++ src/core/lombok/javac/JavacAST.java | 1 + 4 files changed, 23 insertions(+) diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java index 6d786d1e..e769ce34 100644 --- a/src/core/lombok/core/AST.java +++ b/src/core/lombok/core/AST.java @@ -54,11 +54,24 @@ public abstract class AST, L extends LombokNode, private final String fileName; Map identityDetector = new IdentityHashMap(); private Map nodeMap = new IdentityHashMap(); + private boolean changed = false; protected AST(String fileName) { this.fileName = fileName == null ? "(unknown).java" : fileName; } + protected void setChanged() { + this.changed = true; + } + + protected void clearChanged() { + this.changed = false; + } + + public boolean isChanged() { + return changed; + } + /** Set the node object that wraps the internal Compilation Unit node. */ protected void setTop(L top) { this.top = top; diff --git a/src/core/lombok/core/LombokNode.java b/src/core/lombok/core/LombokNode.java index c8ee4c00..95c5a0cb 100644 --- a/src/core/lombok/core/LombokNode.java +++ b/src/core/lombok/core/LombokNode.java @@ -126,6 +126,7 @@ public abstract class LombokNode, L extends LombokNode, L extends LombokNode, L extends LombokNode, L extends LombokNode, L extends LombokNode { this.compilationUnitDeclaration = ast; setTop(buildCompilationUnit(ast)); this.completeParse = isComplete(ast); + clearChanged(); } /** {@inheritDoc} */ @@ -201,12 +202,14 @@ public class EclipseAST extends AST { public void reparse() { propagateProblems(); if (completeParse) return; + boolean changed = isChanged(); boolean newCompleteParse = isComplete(compilationUnitDeclaration); if (!newCompleteParse) return; top().rebuild(); this.completeParse = true; + if (!changed) clearChanged(); } private static boolean isComplete(CompilationUnitDeclaration unit) { diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 77c63cfe..93e3f3dc 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -78,6 +78,7 @@ public class JavacAST extends AST { this.nameTable = Name.Table.instance(context); this.treeMaker = TreeMaker.instance(context); this.symtab = Symtab.instance(context); + clearChanged(); } public Context getContext() { From 391db3dcecdd0d94eb76b656e655346891b02bb4 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 27 Nov 2009 04:18:28 +0100 Subject: [PATCH 09/14] Thorough work on inserting comments in the proper place for delombok; should now work fine with GWT native methods! NON-NLS-1 is still theoretically problematic, but that'll be a fix for another day. Also added ability to recognize that nothing has changed, which will copy the original file instead of reparsing it. --- .classpath | 2 +- src/core/lombok/javac/JavacTransformer.java | 7 ++- .../lombok/javac/handlers/HandleCleanup.java | 2 + .../lombok/javac/handlers/HandleData.java | 1 + .../handlers/HandleEqualsAndHashCode.java | 1 + .../lombok/javac/handlers/HandleGetter.java | 2 + .../lombok/javac/handlers/HandleSetter.java | 2 + .../javac/handlers/HandleSneakyThrows.java | 2 + .../javac/handlers/HandleSynchronized.java | 3 ++ .../lombok/javac/handlers/HandleToString.java | 2 + .../javac/handlers/JavacHandlerUtil.java | 51 +++++++++++++++++++ src/delombok/lombok/delombok/Comment.java | 12 ++++- .../delombok/CommentCollectingScanner.java | 16 +++++- .../delombok/CommentPreservingParser.java | 29 ++++++++--- .../delombok/PrettyCommentsPrinter.java | 37 ++++++++++++-- .../src/lombok/delombok/TestLombokFiles.java | 6 ++- .../src/lombok/delombok/TestSourceFiles.java | 7 ++- .../resource/after/CommentsInterspersed.java | 20 +++----- .../resource/before/CommentsInterspersed.java | 2 +- 19 files changed, 169 insertions(+), 35 deletions(-) diff --git a/.classpath b/.classpath index 3390740d..0d702795 100644 --- a/.classpath +++ b/.classpath @@ -14,7 +14,7 @@ - + diff --git a/src/core/lombok/javac/JavacTransformer.java b/src/core/lombok/javac/JavacTransformer.java index d004414d..5f145460 100644 --- a/src/core/lombok/javac/JavacTransformer.java +++ b/src/core/lombok/javac/JavacTransformer.java @@ -42,7 +42,7 @@ public class JavacTransformer { this.handlers = HandlerLibrary.load(messager); } - public void transform(Context context, Iterable compilationUnits) { + public boolean transform(Context context, Iterable compilationUnits) { List asts = new ArrayList(); for (JCCompilationUnit unit : compilationUnits) asts.add(new JavacAST(messager, context, unit)); @@ -57,6 +57,11 @@ public class JavacTransformer { for (JavacAST ast : asts) { ast.traverse(new AnnotationVisitor()); } + + for (JavacAST ast : asts) { + if (ast.isChanged()) return true; + } + return false; } private class AnnotationVisitor extends JavacASTAdapter { diff --git a/src/core/lombok/javac/handlers/HandleCleanup.java b/src/core/lombok/javac/handlers/HandleCleanup.java index 88a8e1d7..2c89d9ad 100644 --- a/src/core/lombok/javac/handlers/HandleCleanup.java +++ b/src/core/lombok/javac/handlers/HandleCleanup.java @@ -21,6 +21,7 @@ */ package lombok.javac.handlers; +import static lombok.javac.handlers.JavacHandlerUtil.markAnnotationAsProcessed; import lombok.Cleanup; import lombok.core.AnnotationValues; import lombok.core.AST.Kind; @@ -53,6 +54,7 @@ import com.sun.tools.javac.util.Name; @ProviderFor(JavacAnnotationHandler.class) public class HandleCleanup implements JavacAnnotationHandler { @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Cleanup.class); String cleanupName = annotation.getInstance().value(); if (cleanupName.length() == 0) { annotationNode.addError("cleanupName cannot be the empty string."); diff --git a/src/core/lombok/javac/handlers/HandleData.java b/src/core/lombok/javac/handlers/HandleData.java index eef7f78d..a0315d08 100644 --- a/src/core/lombok/javac/handlers/HandleData.java +++ b/src/core/lombok/javac/handlers/HandleData.java @@ -59,6 +59,7 @@ import com.sun.tools.javac.util.List; @ProviderFor(JavacAnnotationHandler.class) public class HandleData implements JavacAnnotationHandler { @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Data.class); JavacNode typeNode = annotationNode.up(); JCClassDecl typeDecl = null; if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl)typeNode.get(); diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 61a4ef63..f388336d 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -72,6 +72,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, EqualsAndHashCode.class); EqualsAndHashCode ann = annotation.getInstance(); List excludes = List.from(ann.exclude()); List includes = List.from(ann.of()); diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index e60e426d..b0343eaf 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -80,8 +80,10 @@ public class HandleGetter implements JavacAnnotationHandler { } @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Getter.class); JavacNode fieldNode = annotationNode.up(); AccessLevel level = annotation.getInstance().value(); + if (level == AccessLevel.NONE) return true; return createGetterForField(level, fieldNode, annotationNode, true); diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 84032e9c..1d029f33 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -82,8 +82,10 @@ public class HandleSetter implements JavacAnnotationHandler { } @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Setter.class); JavacNode fieldNode = annotationNode.up(); AccessLevel level = annotation.getInstance().value(); + if (level == AccessLevel.NONE) return true; return createSetterForField(level, fieldNode, annotationNode, true); diff --git a/src/core/lombok/javac/handlers/HandleSneakyThrows.java b/src/core/lombok/javac/handlers/HandleSneakyThrows.java index e7879dd1..8a185e87 100644 --- a/src/core/lombok/javac/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/javac/handlers/HandleSneakyThrows.java @@ -22,6 +22,7 @@ package lombok.javac.handlers; import static lombok.javac.handlers.JavacHandlerUtil.chainDots; +import static lombok.javac.handlers.JavacHandlerUtil.markAnnotationAsProcessed; import java.util.ArrayList; import java.util.Collection; @@ -49,6 +50,7 @@ import com.sun.tools.javac.util.List; @ProviderFor(JavacAnnotationHandler.class) public class HandleSneakyThrows implements JavacAnnotationHandler { @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, SneakyThrows.class); Collection exceptionNames = annotation.getRawExpressions("value"); List memberValuePairs = ast.getArguments(); diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index c86d99c6..eaa0ad6d 100644 --- a/src/core/lombok/javac/handlers/HandleSynchronized.java +++ b/src/core/lombok/javac/handlers/HandleSynchronized.java @@ -51,10 +51,12 @@ public class HandleSynchronized implements JavacAnnotationHandler private static final String STATIC_LOCK_NAME = "$LOCK"; @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, Synchronized.class); JavacNode methodNode = annotationNode.up(); if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof JCMethodDecl)) { annotationNode.addError("@Synchronized is legal only on methods."); + return true; } @@ -62,6 +64,7 @@ public class HandleSynchronized implements JavacAnnotationHandler if ((method.mods.flags & Flags.ABSTRACT) != 0) { annotationNode.addError("@Synchronized is legal only on concrete methods."); + return true; } boolean isStatic = (method.mods.flags & Flags.STATIC) != 0; diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index f7251ab8..dd3df620 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -68,6 +68,8 @@ public class HandleToString implements JavacAnnotationHandler { } @Override public boolean handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + markAnnotationAsProcessed(annotationNode, ToString.class); + ToString ann = annotation.getInstance(); List excludes = List.from(ann.exclude()); List includes = List.from(ann.of()); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 34d8b849..caa8a998 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -21,6 +21,7 @@ */ package lombok.javac.handlers; +import java.lang.annotation.Annotation; import java.util.regex.Pattern; import lombok.AccessLevel; @@ -34,7 +35,9 @@ import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCImport; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; @@ -57,6 +60,54 @@ public class JavacHandlerUtil { return TransformationsUtil.PRIMITIVE_TYPE_NAME_PATTERN.matcher(typeName).matches(); } + /** + * Removes the annotation from javac's AST, then removes it from lombok's AST, + * then removes any import statement that imports this exact annotation (not star imports). + */ + public static void markAnnotationAsProcessed(JavacNode annotation, Class annotationType) { + JavacNode parentNode = annotation.directUp(); + switch (parentNode.getKind()) { + case FIELD: + case ARGUMENT: + case LOCAL: + JCVariableDecl variable = (JCVariableDecl) parentNode.get(); + variable.mods.annotations = filterList(variable.mods.annotations, annotation.get()); + break; + case METHOD: + JCMethodDecl method = (JCMethodDecl) parentNode.get(); + method.mods.annotations = filterList(method.mods.annotations, annotation.get()); + break; + default: + throw new IllegalStateException("Don't know how to remove annotations from: " + parentNode.getKind()); + } + parentNode.removeChild(annotation); + + JCCompilationUnit unit = (JCCompilationUnit) annotation.top().get(); + deleteImportFromCompilationUnit(unit, annotationType.getName()); + } + + private static void deleteImportFromCompilationUnit(JCCompilationUnit unit, String name) { + List newDefs = List.nil(); + + for (JCTree def : unit.defs) { + boolean delete = false; + if (def instanceof JCImport) { + JCImport imp0rt = (JCImport)def; + delete = (!imp0rt.staticImport && imp0rt.qualid.toString().equals(name)); + } + if (!delete) newDefs = newDefs.append(def); + } + unit.defs = newDefs; + } + + private static List filterList(List annotations, JCTree jcTree) { + List newAnnotations = List.nil(); + for (JCAnnotation ann : annotations) { + if (jcTree != ann) newAnnotations = newAnnotations.append(ann); + } + return newAnnotations; + } + /** * Translates the given field into all possible getter names. * Convenient wrapper around {@link TransformationsUtil#toAllGetterNames(CharSequence, boolean)}. diff --git a/src/delombok/lombok/delombok/Comment.java b/src/delombok/lombok/delombok/Comment.java index c264733f..55a5c46d 100644 --- a/src/delombok/lombok/delombok/Comment.java +++ b/src/delombok/lombok/delombok/Comment.java @@ -23,11 +23,21 @@ package lombok.delombok; public final class Comment { final int pos; + final int prevEndPos; final String content; + final int endPos; + final boolean newLine; - public Comment(int pos, String content) { + public Comment(int prevEndPos, int pos, int endPos, String content, boolean newLine) { this.pos = pos; + this.prevEndPos = prevEndPos; + this.endPos = endPos; this.content = content; + this.newLine = newLine; + } + + public boolean isConnected() { + return !newLine && prevEndPos == pos; } public String summary() { diff --git a/src/delombok/lombok/delombok/CommentCollectingScanner.java b/src/delombok/lombok/delombok/CommentCollectingScanner.java index 6f593c7f..c38aef24 100644 --- a/src/delombok/lombok/delombok/CommentCollectingScanner.java +++ b/src/delombok/lombok/delombok/CommentCollectingScanner.java @@ -80,6 +80,20 @@ public class CommentCollectingScanner extends Scanner { @Override protected void processComment(CommentStyle style) { - comments.add(pos(), new String(getRawCharacters(pos(), endPos()))); + int prevEndPos = prevEndPos(); + int pos = pos(); + boolean newLine = containsNewLine(prevEndPos, pos); + String content = new String(getRawCharacters(pos, endPos())); + comments.add(prevEndPos, pos, endPos(), content, newLine); + } + + + private boolean containsNewLine(int from, int to) { + for (char c : getRawCharacters(from, to)) { + if (c == '\n' || c == '\r') { + return true; + } + } + return false; } } \ No newline at end of file diff --git a/src/delombok/lombok/delombok/CommentPreservingParser.java b/src/delombok/lombok/delombok/CommentPreservingParser.java index 51df5ed1..9fd8778c 100644 --- a/src/delombok/lombok/delombok/CommentPreservingParser.java +++ b/src/delombok/lombok/delombok/CommentPreservingParser.java @@ -24,11 +24,13 @@ package lombok.delombok; import java.io.IOException; import java.io.Writer; import java.util.Collections; +import java.util.Date; import javax.annotation.processing.Messager; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; +import javax.tools.JavaFileObject; import javax.tools.Diagnostic.Kind; import lombok.javac.JavacTransformer; @@ -52,7 +54,7 @@ public class CommentPreservingParser { this.encoding = encoding; } - public ParseResult parseFile(String fileName) throws IOException { + public ParseResult parse(String fileName, boolean forceProcessing) throws IOException { Context context = new Context(); Options.instance(context).put(OptionName.ENCODING, encoding); @@ -74,9 +76,8 @@ public class CommentPreservingParser { @SuppressWarnings("deprecation") JCCompilationUnit cu = compiler.parse(fileName); - new JavacTransformer(messager).transform(context, Collections.singleton(cu)); - - return new ParseResult(comments.comments, cu); + boolean changed = new JavacTransformer(messager).transform(context, Collections.singleton(cu)); + return new ParseResult(comments.comments, cu, forceProcessing || changed); } private static final Messager messager = new Messager() { @@ -100,21 +101,33 @@ public class CommentPreservingParser { static class Comments { List comments = List.nil(); - void add(int pos, String content) { - comments = comments.append(new Comment(pos, content)); + void add(int prevEndPos, int pos, int endPos, String content, boolean newLine) { + comments = comments.append(new Comment(prevEndPos, pos, endPos, content, newLine)); } } public static class ParseResult { private final List comments; private final JCCompilationUnit compilationUnit; + private final boolean changed; - private ParseResult(List comments, JCCompilationUnit compilationUnit) { + private ParseResult(List comments, JCCompilationUnit compilationUnit, boolean changed) { this.comments = comments; this.compilationUnit = compilationUnit; + this.changed = changed; } - public void print(Writer out) { + public void print(Writer out) throws IOException { + if (!changed) { + JavaFileObject sourceFile = compilationUnit.getSourceFile(); + if (sourceFile != null) { + out.write(sourceFile.getCharContent(true).toString()); + System.out.println(out.toString()); + return; + } + } + + out.write("// Generated by delombok at " + new Date() + "\n"); compilationUnit.accept(new PrettyCommentsPrinter(out, compilationUnit, comments)); } } diff --git a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java index 2fb62e53..611dd417 100644 --- a/src/delombok/lombok/delombok/PrettyCommentsPrinter.java +++ b/src/delombok/lombok/delombok/PrettyCommentsPrinter.java @@ -179,7 +179,32 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { align(); } } - + + private void consumeTrailingComments(int from) throws IOException { + boolean shouldIndent = !newLine; + Comment head = comments.head; + while (comments.nonEmpty() && head.prevEndPos == from) { + from = head.endPos; + if (!head.isConnected()) { + if (head.newLine) { + if (!newLine) { + println(); + align(); + } + } + else { + print(" "); + } + } + print(head.content); + comments = comments.tail; + head = comments.head; + } + if (newLine && shouldIndent) { + align(); + } + } + /** The output stream on which trees are printed. */ Writer out; @@ -277,15 +302,17 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { if (tree == null) print("/*missing*/"); else { consumeComments(tree.pos); - tree.accept(this); - consumeComments(endPos(tree)); + tree.accept(this); + int endPos = endPos(tree); + consumeTrailingComments(endPos); + consumeComments(endPos); } } catch (UncheckedIOException ex) { IOException e = new IOException(ex.getMessage()); e.initCause(ex); throw e; } finally { - this.prec = prevPrec; + this.prec = prevPrec; } } @@ -301,7 +328,7 @@ public class PrettyCommentsPrinter extends JCTree.Visitor { public void printStat(JCTree tree) throws IOException { printExpr(tree, TreeInfo.notExpression); } - + /** Derived visitor method: print list of expression trees, separated by given string. * @param sep the separator string */ diff --git a/test/delombok/src/lombok/delombok/TestLombokFiles.java b/test/delombok/src/lombok/delombok/TestLombokFiles.java index 10782830..f04a0a34 100644 --- a/test/delombok/src/lombok/delombok/TestLombokFiles.java +++ b/test/delombok/src/lombok/delombok/TestLombokFiles.java @@ -52,10 +52,9 @@ public class TestLombokFiles { public void testSources() throws Exception { File[] listFiles = BEFORE_FOLDER.listFiles(); for (File file : listFiles) { - ParseResult parseResult = parser.parseFile(file.toString()); + ParseResult parseResult = parser.parse(file.toString(), true); StringWriter writer = new StringWriter(); parseResult.print(writer); - System.out.println(writer); compare(file.getName(), readAfter(file), writer.toString()); } } @@ -63,6 +62,9 @@ public class TestLombokFiles { private void compare(String name, String expectedFile, String actualFile) { String[] expectedLines = expectedFile.split("(\\r?\\n)"); String[] actualLines = actualFile.split("(\\r?\\n)"); + if (actualLines[0].startsWith("// Generated by delombok at ")) { + actualLines[0] = ""; + } expectedLines = removeBlanks(expectedLines); actualLines = removeBlanks(actualLines); int size = Math.min(expectedLines.length, actualLines.length); diff --git a/test/delombok/src/lombok/delombok/TestSourceFiles.java b/test/delombok/src/lombok/delombok/TestSourceFiles.java index b662651d..91ace773 100644 --- a/test/delombok/src/lombok/delombok/TestSourceFiles.java +++ b/test/delombok/src/lombok/delombok/TestSourceFiles.java @@ -53,7 +53,7 @@ public class TestSourceFiles { public void testSources() throws Exception { File[] listFiles = BEFORE_FOLDER.listFiles(); for (File file : listFiles) { - ParseResult parseResult = parser.parseFile(file.toString()); + ParseResult parseResult = parser.parse(file.toString(), true); StringWriter writer = new StringWriter(); parseResult.print(writer); compare(file.getName(), readAfter(file), writer.toString()); @@ -71,6 +71,9 @@ public class TestSourceFiles { private void compare(String name, String expectedFile, String actualFile) { String[] expectedLines = expectedFile.split("(\\r?\\n)"); String[] actualLines = actualFile.split("(\\r?\\n)"); + if (actualLines[0].startsWith("// Generated by delombok at ")) { + actualLines[0] = ""; + } expectedLines = removeBlanks(expectedLines); actualLines = removeBlanks(actualLines); int size = Math.min(expectedLines.length, actualLines.length); @@ -78,7 +81,7 @@ public class TestSourceFiles { String expected = expectedLines[i]; String actual = actualLines[i]; if (!expected.equals(actual)) { - fail(String.format("Difference in line %s(%d):\n`%s`\n`%s`\n", name, i, expected, actual)); + fail(String.format("Difference in line %s(%d):\nExpected `%s`\nGot `%s`\n", name, i, expected, actual)); } } if (expectedLines.length > actualLines.length) { diff --git a/test/lombok/resource/after/CommentsInterspersed.java b/test/lombok/resource/after/CommentsInterspersed.java index ec5374c0..f3841606 100644 --- a/test/lombok/resource/after/CommentsInterspersed.java +++ b/test/lombok/resource/after/CommentsInterspersed.java @@ -1,26 +1,20 @@ -import lombok.Getter; - +/* cmt */ +/* cmt2 */ +/* cmt3 */ /*bla */ public class CommentsInterspersed { /** javadoc for field */ private int x; /* bla2 */ - @Getter() - private String test = "foo"; - //$NON-NLS-1$ + private String test = "foo"; //$NON-NLS-1$ /** Javadoc on method */ - public native void gwtTest(); - /*-{ + public native void gwtTest(); /*-{ javascript; }-*/ - public CommentsInterspersed() { - } - public String getTest() { - return this.test; + return test; } -} -//haha! +} //haha! diff --git a/test/lombok/resource/before/CommentsInterspersed.java b/test/lombok/resource/before/CommentsInterspersed.java index 2a32d309..455c680d 100644 --- a/test/lombok/resource/before/CommentsInterspersed.java +++ b/test/lombok/resource/before/CommentsInterspersed.java @@ -1,4 +1,4 @@ -import lombok.Getter; +import /* cmt */ lombok./* cmt2 */Getter /* cmt3 */ ; public /*bla */ class CommentsInterspersed { /** javadoc for field */ From 4316e77e1eb6654eec18d04780a6da78c22fb644 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 27 Nov 2009 07:18:48 +0100 Subject: [PATCH 10/14] Added a class that is easier to use than the parser itself for delombok, as well as code to process entire directories at a time. Also removed duplication from the testcases. --- .classpath | 1 + src/delombok/lombok/delombok/Delombok.java | 155 ++++++++++++++++++ test/core/src/lombok/TestViaDelombok.java | 97 +++++++++++ .../src/lombok/delombok/TestLombokFiles.java | 67 +------- .../src/lombok/delombok/TestSourceFiles.java | 76 +-------- 5 files changed, 261 insertions(+), 135 deletions(-) create mode 100644 src/delombok/lombok/delombok/Delombok.java create mode 100644 test/core/src/lombok/TestViaDelombok.java diff --git a/.classpath b/.classpath index 0d702795..a33a68d9 100644 --- a/.classpath +++ b/.classpath @@ -6,6 +6,7 @@ + diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java new file mode 100644 index 00000000..c6f9ecf9 --- /dev/null +++ b/src/delombok/lombok/delombok/Delombok.java @@ -0,0 +1,155 @@ +package lombok.delombok; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintStream; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; + +import lombok.delombok.CommentPreservingParser.ParseResult; + +public class Delombok { + private Charset charset = Charset.defaultCharset(); + private CommentPreservingParser parser = new CommentPreservingParser(); + private PrintStream feedback = System.err; + private boolean verbose; + private boolean force = false; + + /** If null, output to standard out. */ + private File output = null; + + public void setCharset(String charsetName) throws UnsupportedCharsetException { + charset = Charset.forName(charsetName); + } + + public void setForceProcess(boolean force) { + this.force = force; + } + + public void setFeedback(PrintStream feedback) { + this.feedback = feedback; + } + + public void setVerbose(boolean verbose) { + this.verbose = verbose; + } + + public void setOutput(File dir) { + if (dir.isFile()) throw new IllegalArgumentException( + "DELOMBOK: delombok will only write to a directory. " + + "If you want to delombok a single file, use -p to output to standard output, then redirect this to a file:\n" + + "delombok MyJavaFile.java -p >MyJavaFileDelombok.java"); + output = dir; + } + + public void setOutputToStandardOut() { + this.output = null; + } + + public void delombok(File base) throws IOException { + delombok0(base, "", 0); + } + + private void delombok0(File base, String suffix, int loop) throws IOException { + File dir = suffix.isEmpty() ? base : new File(base, suffix); + String name = suffix + File.separator + dir.getName(); + + if (dir.isDirectory()) { + if (loop >= 100) { + feedback.printf("Over 100 subdirectories? I'm guessing there's a loop in your directory structure. Skipping: %s\n", suffix); + } else { + dir.mkdir(); + delombok0(base, name, loop + 1); + } + } else if (dir.isFile()) { + String extension = getExtension(dir); + if (extension.equals(".java")) delombok(base, name); + else if (extension.equals(".class")) skipClass(name); + else copy(base, name); + } else { + feedback.printf("Skipping %s because it is a special file type.\n", canonical(dir)); + } + } + + private void skipClass(String fileName) { + if (verbose) feedback.printf("Skipping class file: %s\n", fileName); + } + + private void copy(File base, String fileName) throws IOException { + if (output == null) { + feedback.printf("Skipping resource file: %s\n", fileName); + return; + } + if (verbose) feedback.printf("Copying resource file: %s\n", fileName); + byte[] b = new byte[65536]; + FileInputStream in = new FileInputStream(new File(base, fileName)); + try { + FileOutputStream out = new FileOutputStream(new File(output, fileName)); + try { + while (true) { + int r = in.read(b); + if (r == -1) break; + out.write(b, 0, r); + } + } finally { + out.close(); + } + } finally { + in.close(); + } + } + + public void delombok(String file, Writer writer) throws IOException { + ParseResult result = parser.parse(file, force); + + result.print(writer); + } + + public void delombok(File base, String fileName) throws IOException { + if (output != null && canonical(base).equals(canonical(output))) throw new IOException( + "DELOMBOK: Output file and input file refer to the same filesystem location. Specify a separate path for output."); + + ParseResult result = parser.parse(new File(base, fileName).getAbsolutePath(), force); + + if (verbose) feedback.printf("File: %s [%s]\n", fileName, result.isChanged() ? "delombok-ed" : "unchanged"); + + Writer rawWriter = output == null ? createStandardOutWriter() : createFileWriter(output, fileName); + BufferedWriter writer = new BufferedWriter(rawWriter); + + try { + result.print(writer); + } finally { + writer.close(); + } + } + + private static String canonical(File dir) { + try { + return dir.getCanonicalPath(); + } catch (Exception e) { + return dir.getAbsolutePath(); + } + } + + private static String getExtension(File dir) { + String name = dir.getName(); + int idx = name.lastIndexOf('.'); + return idx == -1 ? "" : name.substring(idx+1); + } + + private Writer createFileWriter(File base, String fileName) throws IOException { + File outFile = new File(base, fileName); + outFile.getParentFile().mkdirs(); + FileOutputStream out = new FileOutputStream(outFile); + return new OutputStreamWriter(out, charset); + } + + private Writer createStandardOutWriter() { + return new OutputStreamWriter(System.out, charset); + } +} diff --git a/test/core/src/lombok/TestViaDelombok.java b/test/core/src/lombok/TestViaDelombok.java new file mode 100644 index 00000000..e8070723 --- /dev/null +++ b/test/core/src/lombok/TestViaDelombok.java @@ -0,0 +1,97 @@ +/* + * Copyright © 2009 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok; + +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +import lombok.delombok.Delombok; + +public class TestViaDelombok { + private static Delombok delombok = new Delombok(); + + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + public static void runComparison(File beforeDir, File afterDir) throws IOException { + File[] listFiles = beforeDir.listFiles(); + + for (File file : listFiles) { + delombok.setVerbose(false); + delombok.setForceProcess(true); + delombok.setCharset("UTF-8"); + StringWriter writer = new StringWriter(); + delombok.delombok(file.getAbsolutePath(), writer); + compare(file.getName(), readAfter(afterDir, file), writer.toString()); + } + } + + private static void compare(String name, String expectedFile, String actualFile) { + String[] expectedLines = expectedFile.split("(\\r?\\n)"); + String[] actualLines = actualFile.split("(\\r?\\n)"); + if (actualLines[0].startsWith("// Generated by delombok at ")) { + actualLines[0] = ""; + } + expectedLines = removeBlanks(expectedLines); + actualLines = removeBlanks(actualLines); + int size = Math.min(expectedLines.length, actualLines.length); + for (int i = 0; i < size; i++) { + String expected = expectedLines[i]; + String actual = actualLines[i]; + if (!expected.equals(actual)) { + fail(String.format("Difference in line %s(%d):\n`%s`\n`%s`\n", name, i, expected, actual)); + } + } + if (expectedLines.length > actualLines.length) { + fail(String.format("Missing line %s(%d): %s\n", name, size, expectedLines[size])); + } + if (expectedLines.length < actualLines.length) { + fail(String.format("Extra line %s(%d): %s\n", name, size, actualLines[size])); + } + } + + private static String readAfter(File afterDir, File file) throws IOException { + BufferedReader reader = new BufferedReader(new FileReader(new File(afterDir, file.getName()))); + StringBuilder result = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + result.append(line); + result.append(LINE_SEPARATOR); + } + reader.close(); + return result.toString(); + } + + private static String[] removeBlanks(String[] in) { + List out = new ArrayList(); + for (String s : in) { + if (!s.trim().isEmpty()) out.add(s); + } + return out.toArray(new String[0]); + } +} diff --git a/test/delombok/src/lombok/delombok/TestLombokFiles.java b/test/delombok/src/lombok/delombok/TestLombokFiles.java index f04a0a34..1d93a4b2 100644 --- a/test/delombok/src/lombok/delombok/TestLombokFiles.java +++ b/test/delombok/src/lombok/delombok/TestLombokFiles.java @@ -21,77 +21,18 @@ */ package lombok.delombok; -import static org.junit.Assert.fail; -import static lombok.delombok.TestSourceFiles.removeBlanks; - -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.StringWriter; -import lombok.delombok.CommentPreservingParser.ParseResult; +import lombok.TestViaDelombok; -import org.junit.BeforeClass; import org.junit.Test; public class TestLombokFiles { - private static CommentPreservingParser parser; - - private static final File BEFORE_FOLDER = new File("test/lombok/resource/before"); - private static final File AFTER_FOLDER = new File("test/lombok/resource/after"); - - private static final String LINE_SEPARATOR = System.getProperty("line.separator"); - - @BeforeClass - public static void init() { - parser = new CommentPreservingParser(); - } + private static final File BEFORE_DIR = new File("test/lombok/resource/before"); + private static final File AFTER_DIR = new File("test/lombok/resource/after"); @Test public void testSources() throws Exception { - File[] listFiles = BEFORE_FOLDER.listFiles(); - for (File file : listFiles) { - ParseResult parseResult = parser.parse(file.toString(), true); - StringWriter writer = new StringWriter(); - parseResult.print(writer); - compare(file.getName(), readAfter(file), writer.toString()); - } - } - - private void compare(String name, String expectedFile, String actualFile) { - String[] expectedLines = expectedFile.split("(\\r?\\n)"); - String[] actualLines = actualFile.split("(\\r?\\n)"); - if (actualLines[0].startsWith("// Generated by delombok at ")) { - actualLines[0] = ""; - } - expectedLines = removeBlanks(expectedLines); - actualLines = removeBlanks(actualLines); - int size = Math.min(expectedLines.length, actualLines.length); - for (int i = 0; i < size; i++) { - String expected = expectedLines[i]; - String actual = actualLines[i]; - if (!expected.equals(actual)) { - fail(String.format("Difference in line %s(%d):\n`%s`\n`%s`\n", name, i, expected, actual)); - } - } - if (expectedLines.length > actualLines.length) { - fail(String.format("Missing line %s(%d): %s\n", name, size, expectedLines[size])); - } - if (expectedLines.length < actualLines.length) { - fail(String.format("Extra line %s(%d): %s\n", name, size, actualLines[size])); - } - } - - private String readAfter(File file) throws IOException { - BufferedReader reader = new BufferedReader(new FileReader(new File(AFTER_FOLDER, file.getName()))); - StringBuilder result = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - result.append(line); - result.append(LINE_SEPARATOR); - } - reader.close(); - return result.toString(); + TestViaDelombok.runComparison(BEFORE_DIR, AFTER_DIR); } } diff --git a/test/delombok/src/lombok/delombok/TestSourceFiles.java b/test/delombok/src/lombok/delombok/TestSourceFiles.java index 91ace773..a5df5197 100644 --- a/test/delombok/src/lombok/delombok/TestSourceFiles.java +++ b/test/delombok/src/lombok/delombok/TestSourceFiles.java @@ -21,86 +21,18 @@ */ package lombok.delombok; -import static org.junit.Assert.fail; - -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; -import lombok.delombok.CommentPreservingParser.ParseResult; +import lombok.TestViaDelombok; -import org.junit.BeforeClass; import org.junit.Test; public class TestSourceFiles { - private static CommentPreservingParser parser; - - private static final File BEFORE_FOLDER = new File("test/delombok/resource/before"); - private static final File AFTER_FOLDER = new File("test/delombok/resource/after"); - - private static final String LINE_SEPARATOR = System.getProperty("line.separator"); - - @BeforeClass - public static void init() { - parser = new CommentPreservingParser(); - } + private static final File BEFORE_DIR = new File("test/delombok/resource/before"); + private static final File AFTER_DIR = new File("test/delombok/resource/after"); @Test public void testSources() throws Exception { - File[] listFiles = BEFORE_FOLDER.listFiles(); - for (File file : listFiles) { - ParseResult parseResult = parser.parse(file.toString(), true); - StringWriter writer = new StringWriter(); - parseResult.print(writer); - compare(file.getName(), readAfter(file), writer.toString()); - } - } - - static String[] removeBlanks(String[] in) { - List out = new ArrayList(); - for (String s : in) { - if (!s.trim().isEmpty()) out.add(s); - } - return out.toArray(new String[0]); - } - - private void compare(String name, String expectedFile, String actualFile) { - String[] expectedLines = expectedFile.split("(\\r?\\n)"); - String[] actualLines = actualFile.split("(\\r?\\n)"); - if (actualLines[0].startsWith("// Generated by delombok at ")) { - actualLines[0] = ""; - } - expectedLines = removeBlanks(expectedLines); - actualLines = removeBlanks(actualLines); - int size = Math.min(expectedLines.length, actualLines.length); - for (int i = 0; i < size; i++) { - String expected = expectedLines[i]; - String actual = actualLines[i]; - if (!expected.equals(actual)) { - fail(String.format("Difference in line %s(%d):\nExpected `%s`\nGot `%s`\n", name, i, expected, actual)); - } - } - if (expectedLines.length > actualLines.length) { - fail(String.format("Missing line %s(%d): %s\n", name, size, expectedLines[size])); - } - if (expectedLines.length < actualLines.length) { - fail(String.format("Extra line %s(%d): %s\n", name, size, actualLines[size])); - } - } - - private String readAfter(File file) throws IOException { - BufferedReader reader = new BufferedReader(new FileReader(new File(AFTER_FOLDER, file.getName()))); - StringBuilder result = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - result.append(line); - result.append(LINE_SEPARATOR); - } - reader.close(); - return result.toString(); + TestViaDelombok.runComparison(BEFORE_DIR, AFTER_DIR); } } From 9ac004b385f5fdc1a113a7b6fc38098c86e8ac8a Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 27 Nov 2009 07:19:38 +0100 Subject: [PATCH 11/14] Fixed whitespace to project standards. --- .../delombok/CommentCollectingScanner.java | 60 +++++++++---------- .../delombok/CommentPreservingParser.java | 10 +++- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/delombok/lombok/delombok/CommentCollectingScanner.java b/src/delombok/lombok/delombok/CommentCollectingScanner.java index c38aef24..361d975c 100644 --- a/src/delombok/lombok/delombok/CommentCollectingScanner.java +++ b/src/delombok/lombok/delombok/CommentCollectingScanner.java @@ -29,55 +29,52 @@ import com.sun.tools.javac.parser.Scanner; import com.sun.tools.javac.util.Context; public class CommentCollectingScanner extends Scanner { - - private final Comments comments; + private final Comments comments; /** A factory for creating scanners. */ - public static class Factory extends Scanner.Factory { - - private final Context context; - + public static class Factory extends Scanner.Factory { + private final Context context; + public static void preRegister(final Context context) { - context.put(scannerFactoryKey, new Context.Factory() { + context.put(scannerFactoryKey, new Context.Factory() { public CommentCollectingScanner.Factory make() { - return new Factory(context); + return new Factory(context); } - }); + }); } - + /** Create a new scanner factory. */ protected Factory(Context context) { - super(context); + super(context); this.context = context; } - - @Override - public Scanner newScanner(CharSequence input) { - if (input instanceof CharBuffer) { - return new CommentCollectingScanner(this, (CharBuffer)input, context.get(Comments.class)); - } - char[] array = input.toString().toCharArray(); - return newScanner(array, array.length); - } + + @Override + public Scanner newScanner(CharSequence input) { + if (input instanceof CharBuffer) { + return new CommentCollectingScanner(this, (CharBuffer)input, context.get(Comments.class)); + } + char[] array = input.toString().toCharArray(); + return newScanner(array, array.length); + } + + @Override + public Scanner newScanner(char[] input, int inputLength) { + return new CommentCollectingScanner(this, input, inputLength, context.get(Comments.class)); + } + } - @Override - public Scanner newScanner(char[] input, int inputLength) { - return new CommentCollectingScanner(this, input, inputLength, context.get(Comments.class)); - } - } - public CommentCollectingScanner(CommentCollectingScanner.Factory factory, CharBuffer charBuffer, Comments comments) { super(factory, charBuffer); this.comments = comments; } - - + public CommentCollectingScanner(CommentCollectingScanner.Factory factory, char[] input, int inputLength, Comments comments) { super(factory, input, inputLength); this.comments = comments; } - + @Override protected void processComment(CommentStyle style) { int prevEndPos = prevEndPos(); @@ -86,8 +83,7 @@ public class CommentCollectingScanner extends Scanner { String content = new String(getRawCharacters(pos, endPos())); comments.add(prevEndPos, pos, endPos(), content, newLine); } - - + private boolean containsNewLine(int from, int to) { for (char c : getRawCharacters(from, to)) { if (c == '\n' || c == '\r') { @@ -96,4 +92,4 @@ public class CommentCollectingScanner extends Scanner { } return false; } -} \ No newline at end of file +} diff --git a/src/delombok/lombok/delombok/CommentPreservingParser.java b/src/delombok/lombok/delombok/CommentPreservingParser.java index 9fd8778c..d353a9a6 100644 --- a/src/delombok/lombok/delombok/CommentPreservingParser.java +++ b/src/delombok/lombok/delombok/CommentPreservingParser.java @@ -43,9 +43,8 @@ import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Options; public class CommentPreservingParser { - private final String encoding; - + public CommentPreservingParser() { this("utf-8"); } @@ -73,6 +72,7 @@ public class CommentPreservingParser { context.put(Comments.class, comments); comments.comments = List.nil(); + @SuppressWarnings("deprecation") JCCompilationUnit cu = compiler.parse(fileName); @@ -130,5 +130,9 @@ public class CommentPreservingParser { out.write("// Generated by delombok at " + new Date() + "\n"); compilationUnit.accept(new PrettyCommentsPrinter(out, compilationUnit, comments)); } + + public boolean isChanged() { + return changed; + } } -} \ No newline at end of file +} From 1a3bd818bd956c297fffd0ebd9d11290272f3294 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 27 Nov 2009 09:49:04 +0100 Subject: [PATCH 12/14] Added cmdreader dependency, as delombok uses it to have a nice command line. --- .classpath | 1 + lib/lombok/com.zwitserloot.cmdreader.jar | Bin 0 -> 19426 bytes 2 files changed, 1 insertion(+) create mode 100644 lib/lombok/com.zwitserloot.cmdreader.jar diff --git a/.classpath b/.classpath index a33a68d9..a4aa40ee 100644 --- a/.classpath +++ b/.classpath @@ -17,5 +17,6 @@ + diff --git a/lib/lombok/com.zwitserloot.cmdreader.jar b/lib/lombok/com.zwitserloot.cmdreader.jar new file mode 100644 index 0000000000000000000000000000000000000000..411f2a1fdb13a85f1617cfbc1a8ecb3326c3b61d GIT binary patch literal 19426 zcma&Mb9iULwk;alwr$(L*fu-1ZQHhOJL%X-$LZL%)yeC9_CDv`bKkrB-1V(lRey|H zYks3<&060YQ&9#K3M&Uj)*>5MJ(@JzAC zzU`X~e!~&d{a&ceLP(mVn8AcvDQlEoEE7#q%;q4kM4{+TzHDh`H8N|nt!je;M^~jH zN>B%H?9xW69V<)A19UDI_uk_$_PngquAXG(PG6f*5}$Y+{@9K`@!dH&ceTCqRADfTQq{@pR4Z%*MawKEgh=FTz%&OX)c4VECi^HXlE9M&2iQ@!F z~Wc-T2Q_Gb3U|2Qf3AdVu03V~_MLbt%@FUwJUhlwkDiM48L zmMO3l$>u~WH>?EVRi{UcGn@9=IZMtmu1>Sdk~g5pZ&f9)*7k)&n^Kp+WAC@-w2aJC zd_-`5&JZf90cga$^+}k=S7LLZI67r*%`-OG;>QBsE`{BPAtBfS&Tg=9C7dor+ZHEe zV*Dm%)HNFt>;QbmLvyu@1eWUR%aTl`N2!qok85baWr>i-pb}n|G-+6&HlXXr22Er) z=f1?4@3j$(p-OG&NGLij?!w~5g{7=BQDV*ylefn%E*k2}LFPTpEM|kz!uj=g?urT` zq?E-V?QA6lTu(L$=q6{7JKu7a^Pu8P2w`bcC#&Pv2Ft6}87(nF(t7l<7B+~r0#~RO zwJjzV<2xElYdvm>$w!g2cGy^gVym-)cN5`e59&^mss%w7$_8#l0Xv=)Susj$m$_Ed z8e%ofg}k7$^m=`tK{`!rS54z>`qY$L=q{O$m>9ctmmjjOPG%fYgwn6b`Y8>d1}V2h zeMCl-&oG->(2vAZ${26HNfjNNjCBjpoPwj)DEec# zN_0{k0nsRaLHRJ7&4Gtfuh=*KsP!;>9nW9L!7MeV;nO~O0e3R{C(65Z>`>4p<~@D5nVu$1Sq*vs4hcd1|J0mQBX9DkK(=p&6vf{YFn4J-un}<|dToT=yhr z>Mk28SA&B=eUjOX#Z-IvJ+!|F&{SLBYV)LL>Y~)Lol}!YOD@}OxUF!iY-Z;J!|alJ z!`;b05&Fw}z;hX~x~w+Tc(w=81M6ZnvT%})Cfl#k@8(q4$7#pTK6}rKftN`tA~@Hp zhCVJUd{d z;=^IP1mrdBTDAHwNAa5Z^hX+DcrPkb=0$k|ltT1jy^trpXb}?QDie4dqPN63svhDz7g5`eif2>^m2d=|^o>(pgKx*rB zR)H+3M3QU8QzQkJaNu%IXTcRTHi2(1xsxUBr$U zvOrFLMVTRQ5}|CwMO5l97iSUm{Tsaw0k2Us;VW>XoG8zUle#`)g@j#~vn%WL)G(%K=N3X22 z#M92&A6~E|Chv|R!*D)&@~4Ma5jl=iBXJ04rj?9SyHbrEUXLcSGPD5a=HTLQWCmRveOfb_;o6D zM$7B=7CEC!ajOSr_JEn=heRF*CR`}7G(hc&-SFbO1Qb@pn6Z&Y0#m7m{gT8ikIW3w zZd8jZI{HH%4zJBOa}W5pXIcN+bD&~tRiFdSrLAX-gsClPqG||d30$ox^6a7S%b@C1Rnu1L>?xE08(7^l@ZKxN%RLhju=xY zHl|L7ohkw3SzqXBD9_0x){Pk94Lae?3{MXy=&k(cjfddJ_kedHLA?Z&mk?+lV zOSrm5T{&^IITO{akv3m6`5oRDh5l`1{$1pW&;Fvo-5$+;y6-;W`>_2oazDDzXM@6L zF^eNHBr@j0`tV}wKW<9FJdbbf;SH;ZWWRFFck4#g$A#teTxkv{EnrX}P{h5&k34Z>mHG)}&V(;3Jg)lV!UVRo??n^P&JFi5iSCpe$zN1@H zk|&sLjQYJMkKFA%&RfRD5dY}tAJraic&um^K% z$CDx{XCTXeNbOc+XtgjSQ)^&7U03v^Y*%paGCo@KNvi31r7`;VzgVH(S%LfDJ~99E z`{AD_J5R`R#t0@55HK4M5cU7v$^OqHeMAe^M|C;#yU%kgbAmkNC(w|yP(p%C z(g09WR)_=%mZDKcCo$=SY(^$fp=PT{?YdR9uP{AHQDPOk7)S<)_C@iEo2_;GM!4Pb zx@-H^R$qJTM$`ArCT~1ha)RB<%f_c)=gX#Z-$U-rAFhXUgM5A&(e!&6g8PO19#u)g z@zXhdzOM}#|H6JROS0TCJmb+RI@0V>w>Jli%f}>nLW|3L1hvK*s(A7V0l!s-mpS%kYj|4X*QedE+v(Fbz}wk9-m~}A1*|@_+S#Gh z;D(&X+V#m3)vdllAfHk&+G9l8A193JupxAF@0U{5udF#ZH;?LUZ5BB$&2YlRZuBh8 z)`I*}|H(`+p_;>{Txnrr?Ub1aM_F`L=@DcpdKFuUU--MWaBb!Ha&4iB6LE4maThy= zv@020*}U&6COZd14M+lO7R!2)tQdum1kE~6H%FGNk)?2crC95p$HwIrZ*gTwqDAbO zO7oCyVhC~+R^;z$KxBy$s47e)=Wi5+5^a%2C?>=?VHHfPvHRs-bBv>f6%^@^L2A-Q zhw*SrDdX;hu@X+zdcD3Lzs2_~(^%TfjxbA2SH3ja&>xkqg)0a{2x9|5)=F#`a%#-6 zG-s4;nHL#&%XbmPAri*oz7iW4r1Mzo3sIT->mFQ7T?{D^lkMzhlC7cx$B)8Lb#~D; zYQ>>Nk@{Rb8;c&&;Xy>T9R7lnGw8%S81`mebcoh~lG}B$*i`Op4cpFnsB#Q-c$fVh zkv0GrB6r&KrM=zkam73iur>DySnB6tFZK16=U>&AB?eT~nu^GX!dmxs=TRhAn6j&t^DM!Dt zO5WzidtXuNd#9PttQr}WCFa~i2lrD~*R*tgeb&XXE|;wYB|`Pg*{PhUwV|_BV5v-( z7BQlK=P(t2UVTxT_)(9RM_Xs+il+}}K^XF0I=TE9hsQy&DA`h-U>$-_q*K`mwuU}< zdTrZiSb1LYVqtitWa2vHi^>_WBm(0|Ylf*kC?eHENCH8lx5RkC(RAV)7&|Zb zPSgbU*(SLEP{~k^;AP(`p{G$hsJRiAjMrV9l-gl8aHt$-9bk0JUYmdS0Pp& zpz7OGNV=(PUZTC97=r`E$qrdITEkvMtc8nI(Ym|_LkS%oYr=v_l@VT+wT6%a3-Sv~ z+J;@Z^L7#9gji)SHG{>8yxl!yI9A4aQOvbRjRR)1M`;~*7RaP(ybrh3ZK9niK;w`g zU)~HfK>di4ozcbb9w0rv$k2I+g4RL~s0z3rM%`erVVp3)JYwar2lS94bEu1!HqcHN zZq_}x@sv0RCG%{F63(9i`z+8u8kI$d39%zBjP2HG zEu>SR6v{V~QJ>2c%~D_g@(7>h^-Q15?a?_vyyywH$9Zg#9mcp9EV`TF*%@p<|5WOe zJL&CFIElZz!tvKV;eD0Qy(w~c`2yRC)MOV5Sba&z&W&4S<;ndSEJ%Bse=s*B49ep#oUp+GVQM8PzG{38;r!1z#y&( zJO2JB`P@; z2T>EnKoklPCkiwyVBJO*l3AO_fxeV2xQ8b@u!SlyWJR(P2ZJinj`s9tR{bDhf>!t)&sJ=}c}eX5iitoV&>9%Sn^3~)68bv*KC zw(25RuEa~RDiF53GtueDhK8BIJVNI%)vS4nEY1yfUeiD_vO`JYlV~POJ&@GDiF8l7 ziscin$Ҫ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 Z%|)$_0=!w-Kw1TXFpZUgA Date: Fri, 27 Nov 2009 09:49:21 +0100 Subject: [PATCH 13/14] Added delombok to the build scripts. --- buildScripts/compile.ant.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/buildScripts/compile.ant.xml b/buildScripts/compile.ant.xml index cafc59b9..043b67c0 100644 --- a/buildScripts/compile.ant.xml +++ b/buildScripts/compile.ant.xml @@ -83,6 +83,7 @@ lombok code including the various agents. + @@ -111,6 +112,7 @@ lombok code including the various agents. + @@ -119,6 +121,7 @@ lombok code including the various agents. + @@ -133,6 +136,9 @@ lombok code including the various agents. + + + From 2b61c2534b22f07a13d8cb4c97c2ad323c6c4597 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 27 Nov 2009 09:49:48 +0100 Subject: [PATCH 14/14] Delombok now works from the command line as: java -jar lombok.jar delombok (args) --- .../delombok/CommentPreservingParser.java | 9 +- src/delombok/lombok/delombok/Delombok.java | 132 +++++++++++++++++- src/installer/lombok/installer/Installer.java | 7 + 3 files changed, 136 insertions(+), 12 deletions(-) diff --git a/src/delombok/lombok/delombok/CommentPreservingParser.java b/src/delombok/lombok/delombok/CommentPreservingParser.java index d353a9a6..c776a224 100644 --- a/src/delombok/lombok/delombok/CommentPreservingParser.java +++ b/src/delombok/lombok/delombok/CommentPreservingParser.java @@ -82,19 +82,19 @@ public class CommentPreservingParser { private static final Messager messager = new Messager() { @Override public void printMessage(Kind kind, CharSequence msg) { - System.out.printf("M: %s: %s\n", kind, msg); + System.out.printf("%s: %s\n", kind, msg); } @Override public void printMessage(Kind kind, CharSequence msg, Element e) { - System.out.printf("E: %s: %s\n", kind, msg); + System.out.printf("%s: %s\n", kind, msg); } @Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a) { - System.out.printf("A: %s: %s\n", kind, msg); + System.out.printf("%s: %s\n", kind, msg); } @Override public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v) { - System.out.printf("V: %s: %s\n", kind, msg); + System.out.printf("%s: %s\n", kind, msg); } }; @@ -122,7 +122,6 @@ public class CommentPreservingParser { JavaFileObject sourceFile = compilationUnit.getSourceFile(); if (sourceFile != null) { out.write(sourceFile.getCharContent(true).toString()); - System.out.println(out.toString()); return; } } diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index c6f9ecf9..e05f4982 100644 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -5,14 +5,26 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.Writer; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; +import java.util.ArrayList; +import java.util.List; import lombok.delombok.CommentPreservingParser.ParseResult; +import com.zwitserloot.cmdreader.CmdReader; +import com.zwitserloot.cmdreader.Description; +import com.zwitserloot.cmdreader.Excludes; +import com.zwitserloot.cmdreader.InvalidCommandLineException; +import com.zwitserloot.cmdreader.Mandatory; +import com.zwitserloot.cmdreader.Parameterized; +import com.zwitserloot.cmdreader.Sequential; +import com.zwitserloot.cmdreader.Shorthand; + public class Delombok { private Charset charset = Charset.defaultCharset(); private CommentPreservingParser parser = new CommentPreservingParser(); @@ -23,6 +35,107 @@ public class Delombok { /** If null, output to standard out. */ private File output = null; + private static class CmdArgs { + @Shorthand("v") + @Description("Print the name of each file as it is being delombok-ed.") + @Excludes("quiet") + private boolean verbose; + + @Shorthand("q") + @Description("No warnings or errors will be emitted to standard error") + @Excludes("verbose") + private boolean quiet; + + @Shorthand("e") + @Description("Sets the encoding of your source files. Defaults to the system default charset. Example: \"UTF-8\"") + @Parameterized + private String encoding; + + @Shorthand("p") + @Description("Print delombok-ed code to standard output instead of saving it in target directory") + private boolean print; + + @Shorthand("d") + @Description("Directory to save delomboked files to") + @Mandatory(onlyIfNot="print") + @Parameterized + private String target; + + @Description("Files to delombok. Provide either a file, or a directory. If you use a directory, all files in it (recursive) are delombok-ed") + @Sequential + @Parameterized + private List input = new ArrayList(); + + private boolean help; + } + + public static void main(String[] rawArgs) { + CmdReader reader = CmdReader.of(CmdArgs.class); + CmdArgs args; + try { + args = reader.make(rawArgs); + } catch (InvalidCommandLineException e) { + System.err.println("ERROR: " + e.getMessage()); + System.err.println(reader.generateCommandLineHelp("delombok")); + System.exit(1); + return; + } + + if (args.help || args.input.isEmpty()) { + if (args.input.isEmpty()) System.err.println("ERROR: no files or directories to delombok specified."); + System.err.println(reader.generateCommandLineHelp("delombok")); + System.exit(args.input.isEmpty() ? 1 : 0); + return; + } + + Delombok delombok = new Delombok(); + + if (args.quiet) delombok.setFeedback(new PrintStream(new OutputStream() { + @Override public void write(int b) throws IOException { + //dummy - do nothing. + } + })); + + if (args.encoding != null) { + try { + delombok.setCharset(args.encoding); + } catch (UnsupportedCharsetException e) { + System.err.println("ERROR: Not a known charset: " + args.encoding); + System.exit(1); + return; + } + } + + if (args.verbose) delombok.setVerbose(true); + if (args.print) delombok.setOutputToStandardOut(); + else delombok.setOutput(new File(args.target)); + + for (String in : args.input) { + try { + File f = new File(in); + if (f.isFile()) { + delombok.delombok(f.getParentFile(), f.getName()); + } else if (f.isDirectory()) { + delombok.delombok(f); + } else if (!f.exists()) { + if (!args.quiet) System.err.println("WARNING: does not exist - skipping: " + f); + } else { + if (!args.quiet) System.err.println("WARNING: not a standard file or directory - skipping: " + f); + } + } catch (Exception e) { + if (!args.quiet) { + String msg = e.getMessage(); + if (msg != null && msg.startsWith("DELOMBOK: ")) System.err.println(msg.substring("DELOMBOK: ".length())); + else { + e.printStackTrace(); + } + System.exit(1); + return; + } + } + } + } + public void setCharset(String charsetName) throws UnsupportedCharsetException { charset = Charset.forName(charsetName); } @@ -40,7 +153,7 @@ public class Delombok { } public void setOutput(File dir) { - if (dir.isFile()) throw new IllegalArgumentException( + if (dir.isFile() || (!dir.isDirectory() && dir.getName().endsWith(".java"))) throw new IllegalArgumentException( "DELOMBOK: delombok will only write to a directory. " + "If you want to delombok a single file, use -p to output to standard output, then redirect this to a file:\n" + "delombok MyJavaFile.java -p >MyJavaFileDelombok.java"); @@ -57,20 +170,23 @@ public class Delombok { private void delombok0(File base, String suffix, int loop) throws IOException { File dir = suffix.isEmpty() ? base : new File(base, suffix); - String name = suffix + File.separator + dir.getName(); + String name = suffix; if (dir.isDirectory()) { if (loop >= 100) { feedback.printf("Over 100 subdirectories? I'm guessing there's a loop in your directory structure. Skipping: %s\n", suffix); } else { - dir.mkdir(); - delombok0(base, name, loop + 1); + for (File f : dir.listFiles()) { + delombok0(base, suffix + (suffix.isEmpty() ? "" : File.separator) + f.getName(), loop + 1); + } } } else if (dir.isFile()) { String extension = getExtension(dir); - if (extension.equals(".java")) delombok(base, name); - else if (extension.equals(".class")) skipClass(name); + if (extension.equals("java")) delombok(base, name); + else if (extension.equals("class")) skipClass(name); else copy(base, name); + } else if (!dir.exists()) { + feedback.printf("Skipping %s because it does not exist.\n", canonical(dir)); } else { feedback.printf("Skipping %s because it is a special file type.\n", canonical(dir)); } @@ -87,7 +203,9 @@ public class Delombok { } if (verbose) feedback.printf("Copying resource file: %s\n", fileName); byte[] b = new byte[65536]; - FileInputStream in = new FileInputStream(new File(base, fileName)); + File outFile = new File(base, fileName); + outFile.getParentFile().mkdirs(); + FileInputStream in = new FileInputStream(outFile); try { FileOutputStream out = new FileOutputStream(new File(output, fileName)); try { diff --git a/src/installer/lombok/installer/Installer.java b/src/installer/lombok/installer/Installer.java index e1da5d31..a823dd69 100644 --- a/src/installer/lombok/installer/Installer.java +++ b/src/installer/lombok/installer/Installer.java @@ -64,6 +64,7 @@ import javax.swing.UIManager; import javax.swing.filechooser.FileFilter; import lombok.core.Version; +import lombok.delombok.Delombok; import lombok.installer.EclipseFinder.OS; import lombok.installer.EclipseLocation.InstallException; import lombok.installer.EclipseLocation.NotAnEclipseException; @@ -95,6 +96,12 @@ public class Installer { private JButton installButton; public static void main(String[] args) { + if (args.length > 0 && args[0].equals("delombok")) { + String[] newArgs = new String[args.length-1]; + System.arraycopy(args, 1, newArgs, 0, newArgs.length); + Delombok.main(newArgs); + return; + } if (args.length > 0 && (args[0].equals("install") || args[0].equals("uninstall"))) { boolean uninstall = args[0].equals("uninstall"); if (args.length < 3 || !args[1].equals("eclipse")) {