From 84e5ca16e6497affd0a9602a5d93487c3f933e2c Mon Sep 17 00:00:00 2001 From: Akarshit Wal Date: Thu, 1 Oct 2015 22:29:10 +0530 Subject: [PATCH 001/375] Core libraries added to the count of updates --- app/src/processing/app/contrib/ContributionListing.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/processing/app/contrib/ContributionListing.java b/app/src/processing/app/contrib/ContributionListing.java index cf35ff628c..bd3460d645 100644 --- a/app/src/processing/app/contrib/ContributionListing.java +++ b/app/src/processing/app/contrib/ContributionListing.java @@ -580,6 +580,11 @@ public int countUpdates(Base base) { count++; } } + for (Library lib : base.getActiveEditor().getMode().coreLibraries) { + if (hasUpdates(lib)) { + count++; + } + } for (ToolContribution tc : base.getToolContribs()) { if (hasUpdates(tc)) { count++; From 0eb5ba518ac40343a68cef09a13ecf9c9e5ce0fe Mon Sep 17 00:00:00 2001 From: Jeremy Laviole Date: Tue, 24 Nov 2015 17:55:40 +0100 Subject: [PATCH 002/375] Support of embedded images in SVGs, linked images are supported but should not be avoided if possible. Support of Text in SVGs (partial). Multiline text are also displayed. Text limitations : Inline styles are not supported. Not all fonts are supported (depending on your OS). Tested only on Inkscape SVGs. --- core/src/processing/core/PShape.java | 111 +++++++++++-- core/src/processing/core/PShapeSVG.java | 199 +++++++++++++++++++++++- 2 files changed, 291 insertions(+), 19 deletions(-) diff --git a/core/src/processing/core/PShape.java b/core/src/processing/core/PShape.java index 44ff15115c..03de66203f 100644 --- a/core/src/processing/core/PShape.java +++ b/core/src/processing/core/PShape.java @@ -22,8 +22,23 @@ package processing.core; +import java.awt.Image; +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; +import java.util.Base64.Decoder; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.nio.charset.StandardCharsets; +import javax.swing.ImageIcon; +import javax.xml.bind.DatatypeConverter; + + import processing.core.PApplet; @@ -106,6 +121,7 @@ public class PShape implements PConstants { /** Texture or image data associated with this shape. */ protected PImage image; + protected String imagePath = null; public static final String OUTSIDE_BEGIN_END_ERROR = "%1$s can only be called between beginShape() and endShape()"; @@ -1645,6 +1661,10 @@ protected void drawPrimitive(PGraphics g) { params[6], params[7]); } else if (kind == RECT) { + + if (imagePath != null){ + loadImage(g); + } if (image != null) { int oldMode = g.imageMode; g.imageMode(CORNER); @@ -1879,6 +1899,63 @@ protected void drawPath(PGraphics g) { g.endShape(close ? CLOSE : OPEN); } + private void loadImage(PGraphics g){ + + if(this.imagePath.startsWith("data:image")){ + loadBase64Image(); + } + + if(this.imagePath.startsWith("file://")){ + loadFileSystemImage(g); + } + this.imagePath = null; + } + + private void loadFileSystemImage(PGraphics g){ + imagePath = imagePath.substring(7); + PImage loadedImage = g.parent.loadImage(imagePath); + if(loadedImage == null){ + System.err.println("Error loading image file: " + imagePath); + }else{ + setTexture(loadedImage); + } + } + + private void loadBase64Image(){ + String[] parts = this.imagePath.split(";base64,"); + String extension = parts[0].substring(11); + String encodedData = parts[1]; + + byte[] decodedBytes = DatatypeConverter.parseBase64Binary(encodedData); + + if(decodedBytes == null){ + System.err.println("Decode Error on image: " + imagePath.substring(0, 20)); + return; + } + + Image awtImage = new ImageIcon(decodedBytes).getImage(); + + if (awtImage instanceof BufferedImage) { + BufferedImage buffImage = (BufferedImage) awtImage; + int space = buffImage.getColorModel().getColorSpace().getType(); + if (space == ColorSpace.TYPE_CMYK) { + return; + } + } + + PImage loadedImage = new PImage(awtImage); + if (loadedImage.width == -1) { + // error... + } + + // if it's a .gif image, test to see if it has transparency + if (extension.equals("gif") || extension.equals("png") || + extension.equals("unknown")) { + loadedImage.checkAlpha(); + } + + setTexture(loadedImage); + } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -2387,14 +2464,14 @@ public void setFill(boolean fill) { /** * ( begin auto-generated from PShape_setFill.xml ) * - * The setFill() method defines the fill color of a PShape. - * This method is used after shapes are created or when a shape is defined explicitly - * (e.g. createShape(RECT, 20, 20, 80, 80)) as shown in the above example. - * When a shape is created with beginShape() and endShape(), its - * attributes may be changed with fill() and stroke() within - * beginShape() and endShape(). However, after the shape is - * created, only the setFill() method can define a new fill value for - * the PShape. + * The setFill() method defines the fill color of a PShape. + * This method is used after shapes are created or when a shape is defined explicitly + * (e.g. createShape(RECT, 20, 20, 80, 80)) as shown in the above example. + * When a shape is created with beginShape() and endShape(), its + * attributes may be changed with fill() and stroke() within + * beginShape() and endShape(). However, after the shape is + * created, only the setFill() method can define a new fill value for + * the PShape. * * ( end auto-generated ) * @@ -2543,14 +2620,14 @@ public void setStroke(boolean stroke) { /** * ( begin auto-generated from PShape_setStroke.xml ) * - * The setStroke() method defines the outline color of a PShape. - * This method is used after shapes are created or when a shape is defined - * explicitly (e.g. createShape(RECT, 20, 20, 80, 80)) as shown in - * the above example. When a shape is created with beginShape() and - * endShape(), its attributes may be changed with fill() and - * stroke() within beginShape() and endShape(). - * However, after the shape is created, only the setStroke() method - * can define a new stroke value for the PShape. + * The setStroke() method defines the outline color of a PShape. + * This method is used after shapes are created or when a shape is defined + * explicitly (e.g. createShape(RECT, 20, 20, 80, 80)) as shown in + * the above example. When a shape is created with beginShape() and + * endShape(), its attributes may be changed with fill() and + * stroke() within beginShape() and endShape(). + * However, after the shape is created, only the setStroke() method + * can define a new stroke value for the PShape. * * ( end auto-generated ) * @@ -3442,4 +3519,4 @@ protected void colorCalcARGB(int argb, float alpha) { calcAlpha = (calcAi != 255); } -} \ No newline at end of file +} diff --git a/core/src/processing/core/PShapeSVG.java b/core/src/processing/core/PShapeSVG.java index bf5cdc2f1f..adc1763bb0 100644 --- a/core/src/processing/core/PShapeSVG.java +++ b/core/src/processing/core/PShapeSVG.java @@ -24,6 +24,9 @@ package processing.core; +import static java.awt.Font.BOLD; +import static java.awt.Font.ITALIC; +import static java.awt.Font.PLAIN; import processing.data.*; // TODO replace these with PMatrix2D @@ -329,6 +332,10 @@ protected PShape parseChild(XML elem) { } else if (name.equals("rect")) { shape = createShape(this, elem, true); shape.parseRect(); + + } else if (name.equals("image")) { + shape = createShape(this, elem, true); + shape.parseImage(); } else if (name.equals("polygon")) { shape = createShape(this, elem, true); @@ -358,8 +365,10 @@ protected PShape parseChild(XML elem) { // return new FontGlyph(this, elem); } else if (name.equals("text")) { // || name.equals("font")) { - PGraphics.showWarning("Text and fonts in SVG files are " + - "not currently supported, convert text to outlines instead."); + return new Text(this, elem); + + } else if (name.equals("tspan")) { + return new LineOfText(this, elem); } else if (name.equals("filter")) { PGraphics.showWarning("Filters are not supported."); @@ -439,8 +448,23 @@ protected void parseRect() { getFloatWithUnit(element, "height", svgHeight) }; } + + + protected void parseImage() { + kind = RECT; + textureMode = NORMAL; + family = PRIMITIVE; + params = new float[] { + getFloatWithUnit(element, "x", svgWidth), + getFloatWithUnit(element, "y", svgHeight), + getFloatWithUnit(element, "width", svgWidth), + getFloatWithUnit(element, "height", svgHeight) + }; + this.imagePath = element.getString("xlink:href"); + } + /** * Parse a polyline or polygon from an SVG file. * Syntax defined at http://www.w3.org/TR/SVG/shapes.html#PointsBNF @@ -1557,8 +1581,179 @@ public RadialGradient(PShapeSVG parent, XML properties) { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + public static float TEXT_QUALITY = 1; + protected PFont parseFont(XML properties) { + +// FontFace fontFace = new FontFace(this, properties); + String fontFamily = null; + float size = 10; + int weight = PLAIN; // 0 + int italic = 0; + + if (properties.hasAttribute("style")) { + String styleText = properties.getString("style"); + String[] styleTokens = PApplet.splitTokens(styleText, ";"); + + //PApplet.println(styleTokens); + for (int i = 0; i < styleTokens.length; i++) { + + String[] tokens = PApplet.splitTokens(styleTokens[i], ":"); + //PApplet.println(tokens); + + tokens[0] = PApplet.trim(tokens[0]); + + if (tokens[0].equals("font-style")) { + // PApplet.println("font-style: " + tokens[1]); + if (tokens[1].contains("italic")) { + italic = ITALIC; + } + } else if (tokens[0].equals("font-variant")) { + // PApplet.println("font-variant: " + tokens[1]); + // setFillOpacity(tokens[1]); + + } else if (tokens[0].equals("font-weight")) { + // PApplet.println("font-weight: " + tokens[1]); + + if (tokens[1].contains("bold")) { + weight = BOLD; + // PApplet.println("Bold weight ! "); + } + + + } else if (tokens[0].equals("font-stretch")) { + // not supported. + + } else if (tokens[0].equals("font-size")) { + // PApplet.println("font-size: " + tokens[1]); + size = Float.parseFloat(tokens[1].split("px")[0]); + // PApplet.println("font-size-parsed: " + size); + } else if (tokens[0].equals("line-height")) { + // not supported + + } else if (tokens[0].equals("font-family")) { + // PApplet.println("Font-family: " + tokens[1]); + fontFamily = tokens[1]; + + } else if (tokens[0].equals("text-align")) { + // not supported + + } else if (tokens[0].equals("letter-spacing")) { + // not supported + + } else if (tokens[0].equals("word-spacing")) { + // not supported + + } else if (tokens[0].equals("writing-mode")) { + // not supported + + } else if (tokens[0].equals("text-anchor")) { + // not supported + + } else { + // Other attributes are not yet implemented + } + } + } + if (fontFamily == null) { + return null; + } + size = size * TEXT_QUALITY; + + return createFont(fontFamily, weight | italic, size, true); + } + + protected PFont createFont(String name, int weight, float size, boolean smooth) { + +// System.out.println("Try to create a font of " + name + " family, " + weight); + java.awt.Font baseFont = new java.awt.Font(name, weight, (int) size); // PFont.findFont(name);ç + +// System.out.println("Resulting family : " + baseFont.getFamily() + " " + baseFont.getStyle()); + PFont outputPFont = new PFont(baseFont.deriveFont(size), smooth, null); + +// System.out.println("Resulting PFont family : " + outputPFont.getName()); + return outputPFont; + } + + public static class Text extends PShapeSVG { + + protected PFont font; + + public Text(PShapeSVG parent, XML properties) { + super(parent, properties, true); + + // get location + float x = Float.parseFloat(properties.getString("x")); + float y = Float.parseFloat(properties.getString("y")); + + if (matrix == null) { + matrix = new PMatrix2D(); + } + matrix.translate(x, y); + + family = GROUP; + + font = parseFont(properties); + } + +// @Override +// public void drawImpl(PGraphics g){ +// } + } + + public static class LineOfText extends PShapeSVG { + String textToDisplay; + PFont font; + + public LineOfText(PShapeSVG parent, XML properties) { + + // TODO: child should ideally be parsed too... + // for inline content. + super(parent, properties, false); + +// // get location + float x = Float.parseFloat(properties.getString("x")); + float y = Float.parseFloat(properties.getString("y")); + + float parentX = Float.parseFloat(parent.element.getString("x")); + float parentY = Float.parseFloat(parent.element.getString("y")); + + if (matrix == null) matrix = new PMatrix2D(); + matrix.translate(x - parentX, (y - parentY) / 2f); + + // get the first properties + parseColors(properties); + font = parseFont(properties); + + // It is a line.. + boolean isALine = properties.getString("role") == "line"; + // NO inline content yet. + if (this.childCount > 0) { + } + + String text = properties.getContent(); + textToDisplay = text; + } + + @Override + public void drawImpl(PGraphics g) { + if (font == null) { + font = ((Text) parent).font; + if (font == null) { + return; + } + } + + pre(g); + g.textFont(font, font.size / TEXT_QUALITY); + g.text(textToDisplay, 0, 0); + post(g); + } + + } + public static class Font extends PShapeSVG { public FontFace face; From 8effb5d600deef46b26fe486d5f0336aab7188b4 Mon Sep 17 00:00:00 2001 From: Paco Date: Tue, 20 Jun 2017 20:28:42 -0300 Subject: [PATCH 003/375] make "loadXML(String)" handle "file not found" when file is not found, a null pointer exception crashes processing i guess is because this line --- core/src/processing/core/PApplet.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index a743839108..1b899361a5 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -5921,7 +5921,9 @@ public XML loadXML(String filename) { */ public XML loadXML(String filename, String options) { try { - return new XML(createReader(filename), options); + BufferedReader br = createReader(filename); + if (br != null) return new XML(br, options); + else br = null; // can't use catch-all exception, since it might catch the // RuntimeException about the incorrect case sensitivity From 1798e9074d9c6b4c06b69a85bbbfc3f91bbc6daf Mon Sep 17 00:00:00 2001 From: Paco Date: Tue, 20 Jun 2017 20:41:50 -0300 Subject: [PATCH 004/375] styling fix just read how to style correctly --- core/src/processing/core/PApplet.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 1b899361a5..f046d50cf8 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -5922,8 +5922,11 @@ public XML loadXML(String filename) { public XML loadXML(String filename, String options) { try { BufferedReader br = createReader(filename); - if (br != null) return new XML(br, options); - else br = null; + if (br != null) { + return new XML(br, options); + } else { + br = null; + } // can't use catch-all exception, since it might catch the // RuntimeException about the incorrect case sensitivity From 17d0ce6b2a232b32be4eddcb719309a43eb0fa67 Mon Sep 17 00:00:00 2001 From: Kenichi Ito Date: Sun, 17 Sep 2017 13:26:57 +0900 Subject: [PATCH 005/375] Update Japanese translation --- build/shared/lib/languages/PDE_ja.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/shared/lib/languages/PDE_ja.properties b/build/shared/lib/languages/PDE_ja.properties index bd59345f86..e831c9bcc0 100644 --- a/build/shared/lib/languages/PDE_ja.properties +++ b/build/shared/lib/languages/PDE_ja.properties @@ -166,6 +166,8 @@ preferences.editor_and_console_font = エディタとコンソールのフォン preferences.editor_and_console_font.tip = Select the font used in the Editor and the Console.
Only monospaced (fixed-width) fonts may be used,
though the list may be imperfect. preferences.editor_font_size = エディタフォントサイズ preferences.console_font_size = コンソールフォントサイズ +preferences.zoom = インターフェース拡大率 +preferences.zoom.auto = 自動 preferences.background_color = プレゼンテーションの背景色 preferences.background_color.tip = Select the background color used when using Present.
Present is used to present a sketch in full-screen,
accessible from the Sketch menu. preferences.use_smooth_text = エディタウィンドウでスムーズテキストを使う @@ -312,6 +314,7 @@ editor.header.delete.warning.title = いや、うん。 editor.header.delete.warning.text = 開いただけのスケッチのメインタブは削除できません。 # PopUp menu +editor.popup.jump_to_declaration = 宣言に移動 editor.popup.show_usage = 用法の表示... editor.popup.rename = 名前の変更... From 13b094473fb6d1280f916e40878db2b363365e32 Mon Sep 17 00:00:00 2001 From: Kenichi Ito Date: Mon, 18 Sep 2017 00:54:32 +0900 Subject: [PATCH 006/375] Update Japanese translation --- build/shared/lib/languages/PDE_ja.properties | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build/shared/lib/languages/PDE_ja.properties b/build/shared/lib/languages/PDE_ja.properties index e831c9bcc0..a767f02810 100644 --- a/build/shared/lib/languages/PDE_ja.properties +++ b/build/shared/lib/languages/PDE_ja.properties @@ -56,7 +56,7 @@ menu.sketch.stop = 停止 # --- menu.library = ライブラリをインポート... menu.library.add_library = ライブラリを追加... -menu.library.contributed = 貢献 +menu.library.contributed = Contributed menu.library.no_core_libraries = モードにコアライブラリがありません # --- menu.sketch = スケッチ @@ -486,10 +486,10 @@ contrib.errors.no_internet_connection = You do not seem to be connected to the I contrib.status.downloading_list = Downloading contribution list... contrib.status.connecting = Connecting... contrib.status.done = Done. -#contrib.all = すぺて -#contrib.undo = 元に戻す -#contrib.remove = 削除 -#contrib.install = インストール +contrib.all = すべて +contrib.undo = 元に戻す +contrib.remove = 削除 +contrib.install = インストール contrib.progress.installing = Installing contrib.progress.starting = Starting contrib.progress.downloading = Downloading @@ -546,8 +546,8 @@ update_check.updates_available.contributions = There are updates available for s # --------------------------------------- # Color Chooser -color_chooser = Color Selector -color_chooser.select = Select +color_chooser = カラーセレクター +color_chooser.select = 選択 # --------------------------------------- # Movie Maker From 34a0944db29005ae704427cd8c5f9a89edf6c152 Mon Sep 17 00:00:00 2001 From: Kenichi Ito Date: Thu, 21 Sep 2017 01:02:37 +0900 Subject: [PATCH 007/375] Update Japanese translation --- build/shared/lib/languages/PDE_ja.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/shared/lib/languages/PDE_ja.properties b/build/shared/lib/languages/PDE_ja.properties index a767f02810..3d9db512e1 100644 --- a/build/shared/lib/languages/PDE_ja.properties +++ b/build/shared/lib/languages/PDE_ja.properties @@ -257,7 +257,7 @@ create_font.character_selector = 文字選択 create_font.character_selector.label = Default characters will include most bitmaps for Mac OS\nand Windows Latin scripts. Including all characters may\nrequire large amounts of memory for all of the bitmaps.\nFor greater control, you can select specific Unicode blocks. create_font.default_characters = デフォルトの文字 create_font.all_characters = すべての文字 -create_font.specific_unicode = Specific Unicode Blocks +create_font.specific_unicode = 特定のUnicodeブロック create_font.filename = ファイル名 # Color Selector (Frame) @@ -490,9 +490,9 @@ contrib.all = すべて contrib.undo = 元に戻す contrib.remove = 削除 contrib.install = インストール -contrib.progress.installing = Installing -contrib.progress.starting = Starting -contrib.progress.downloading = Downloading +contrib.progress.installing = インストール中 +contrib.progress.starting = 開始中 +contrib.progress.downloading = ダウンロード中 contrib.download_error = An error occured while downloading the contribution. contrib.unsupported_operating_system = Your operating system does not appear to be supported. You should visit the %s\'s library for more info. contrib.category.3d = 3D From 8fd8f2108f1e841424f0d6bf676ffdf5d4f90cf2 Mon Sep 17 00:00:00 2001 From: Kenichi Ito Date: Thu, 21 Sep 2017 22:33:25 +0900 Subject: [PATCH 008/375] Update Japanese translation --- build/shared/lib/languages/PDE_ja.properties | 46 ++++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/build/shared/lib/languages/PDE_ja.properties b/build/shared/lib/languages/PDE_ja.properties index 3d9db512e1..a2d1e21860 100644 --- a/build/shared/lib/languages/PDE_ja.properties +++ b/build/shared/lib/languages/PDE_ja.properties @@ -158,7 +158,7 @@ close.unsaved_changes = %s への変更を保存しますか? # Preferences (Frame) preferences = 設定 preferences.button.width = 120 -preferences.requires_restart = Processing の再起動が必要です +preferences.requires_restart = Processingの再起動が必要です preferences.sketchbook_location = スケッチブックの場所 preferences.sketchbook_location.popup = スケッチブックの場所 preferences.language = 言語 @@ -181,7 +181,7 @@ preferences.cmd_space = space preferences.suggest_imports = import 宣言をサジェストする preferences.increase_max_memory = 有効な最大メモリを増やす preferences.delete_previous_folder_on_export = エクスポート時に以前のフォルダーを削除する -preferences.check_for_updates_on_startup = 起動時にアップデートをチェックする +preferences.check_for_updates_on_startup = 起動時に更新をチェックする preferences.run_sketches_on_display = スケッチを実行するディスプレイ preferences.run_sketches_on_display.tip = スケッチが最初に置かれるディスプレイをセットして下さい。
通常、スケッチウィンドウを動かすと、同じ位置に再び開かれますが、
プレゼンテーション(フルスクリーン)モードで実行している場合、
このディスプレイが常に使用されます。 preferences.automatically_associate_pde_files = 自動的に .pde ファイルを Processing に関連付ける @@ -341,7 +341,7 @@ editor.status.printing = 印刷しています... editor.status.printing.done = 印刷が完了しました。 editor.status.printing.error = 印刷中にエラーが発生しました。 editor.status.printing.canceled = 印刷がキャンセルされました。 -editor.status.copy_as_html = Code formatted as HTML has been copied to the clipboard. +editor.status.copy_as_html = HTMLとしてフォーマットされたコードがクリップボードにコピーされました。 editor.status.debug.busy = Debugger busy... editor.status.debug.halt = Debugger halted. editor.status.archiver.create = アーカイブ "%s" を作成しました。 @@ -402,7 +402,7 @@ name.messages.new_sketch_exists.description = A file named "%s" already exists a name.messages.new_folder_exists = 名前を変更できません name.messages.new_folder_exists.description = Sorry, a sketch (or folder) named "%s" already exists. name.messages.error = エラー -name.messages.no_rename_folder.description = Could not rename the sketch folder. +name.messages.no_rename_folder.description = スケッチフォルダー名を変更できませんでした。 name.messages.no_rename_file.description = Could not rename "%s" to "%s" name.messages.no_create_file.description = Could not create the file "%s"\nin "%s" @@ -478,13 +478,13 @@ contrib.errors.malformed_url = The link fetched from Processing.org is not valid contrib.errors.needs_repackage = %s needs to be repackaged according to the %s guidelines. contrib.errors.no_contribution_found = Could not find a %s in the downloaded file. contrib.errors.overwriting_properties = Error overwriting .properties file. -contrib.errors.install_failed = Install failed. +contrib.errors.install_failed = インストールに失敗しました。 contrib.errors.update_on_restart_failed = Update on restart of %s failed. -contrib.errors.temporary_directory = Could not write to temporary directory. -contrib.errors.contrib_download.timeout = Connection timed out while downloading %s. -contrib.errors.no_internet_connection = You do not seem to be connected to the Internet. +contrib.errors.temporary_directory = 一時ディレクトリに書き込めませんでした。 +contrib.errors.contrib_download.timeout = %sをダウンロード中に接続がタイムアウトしました。 +contrib.errors.no_internet_connection = インターネットに接続されていないようです。 contrib.status.downloading_list = Downloading contribution list... -contrib.status.connecting = Connecting... +contrib.status.connecting = 接続しています... contrib.status.done = Done. contrib.all = すべて contrib.undo = 元に戻す @@ -519,18 +519,18 @@ contrib.startup.errors.new_marker = The unupdated contribution marker seems to n contrib.import.dialog.title = Missing Libraries Available contrib.import.dialog.primary_text = The following imported libraries are available for download, but have not been installed. contrib.import.dialog.secondary_text = Would you like to install them now? -contrib.import.progress.download = Downloading %s... -contrib.import.progress.install = Installing %s... -contrib.import.progress.done = %s has been installed. +contrib.import.progress.download = %sをダウンロードしています... +contrib.import.progress.install = %sをインストールしています... +contrib.import.progress.done = %sがインストールされました。 contrib.import.progress.final_list = The following libraries have been installed: contrib.import.errors.link = Error: The library %s has a strange looking download link. # --------------------------------------- # Warnings -warn.delete = Delete -warn.delete.sketch = Are you sure you want to delete this sketch? -warn.delete.file = Are you sure you want to delete "%s"? +warn.delete = 削除 +warn.delete.sketch = このスケッチを削除してもよろしいですか? +warn.delete.file = "%s"を削除してもよろしいですか? warn.cannot_change_mode.title = モード変更失敗 warn.cannot_change_mode.body = 互換性がないため、"%s"モードに切り替えられません。 @@ -538,8 +538,8 @@ warn.cannot_change_mode.body = 互換性がないため、"%s"モードに切り # --------------------------------------- # Update Check -update_check = Update -update_check.updates_available.core = A new version of Processing is available,\nwould you like to visit the Processing download page? +update_check = 更新 +update_check.updates_available.core = 新しいバージョンのProcessingが利用可能です。\nProcessingのダウンロードページにアクセスしますか? update_check.updates_available.contributions = There are updates available for some of the installed contributions,\nwould you like to open the the Contribution Manager now? @@ -557,20 +557,20 @@ movie_maker.title = QuickTime ムービーメーカー movie_maker.blurb = This tool creates a QuickTime movie from a sequence of images.

To avoid artifacts caused by re-compressing images as video,
use TIFF, TGA (from Processing), or PNG images as the source.

TIFF and TGA images will write more quickly, but require more disk:
saveFrame("frames/####.tif");
saveFrame("frames/####.tga");

PNG images are smaller, but your sketch will run more slowly:
saveFrame("frames/####.png");

This code is based on QuickTime Movie Maker 1.5.1 2011-01-17.
Copyright © 2010-2011 Werner Randelshofer. All rights reserved.
movie_maker.image_folder_help_label = Drag a folder with image files into the field below: movie_maker.choose_button = 選択... -movie_maker.select_image_folder = Select image folder... +movie_maker.select_image_folder = 画像フォルダーを選択... movie_maker.sound_file_help_label = Drag a sound file into the field below (.au, .aiff, .wav, .mp3): -movie_maker.select_sound_file = Select sound file... +movie_maker.select_sound_file = 音声ファイルを選択... -movie_maker.create_movie_button = Create movie... +movie_maker.create_movie_button = 動画を作成... movie_maker.save_dialog_prompt = Save movie as... movie_maker.width = 幅: movie_maker.height = 高さ: -movie_maker.compression = Compression: +movie_maker.compression = 圧縮: movie_maker.compression.animation = Animation movie_maker.compression.jpeg = JPEG movie_maker.compression.png = PNG -movie_maker.framerate = Framerate: -movie_maker.orig_size_button = Same size as originals +movie_maker.framerate = フレームレート: +movie_maker.orig_size_button = オリジナルと同じサイズ movie_maker.orig_size_tooltip = Check this box if the folder contains already encoded video frames in the desired size. movie_maker.error.avoid_tiff = Try TGA or PNG images instead of TIFF. From 44732e5f2c151b24f554f4accda00c0d5152b3ec Mon Sep 17 00:00:00 2001 From: Kenichi Ito Date: Fri, 22 Sep 2017 23:08:14 +0900 Subject: [PATCH 009/375] Update Japanese translation --- build/shared/lib/languages/PDE_ja.properties | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build/shared/lib/languages/PDE_ja.properties b/build/shared/lib/languages/PDE_ja.properties index a2d1e21860..87c79ed526 100644 --- a/build/shared/lib/languages/PDE_ja.properties +++ b/build/shared/lib/languages/PDE_ja.properties @@ -330,10 +330,10 @@ editor.sketch.rename.description = スケッチの新しい名前 editor.status.autoformat.no_changes = No changes necessary for Auto Format. editor.status.autoformat.finished = 自動フォーマットが完了しました。 editor.status.find_reference.select_word_first = First select a word to find in the reference. -editor.status.find_reference.not_available = No reference available for "%s". -editor.status.drag_and_drop.files_added.0 = No files were added to the sketch. -editor.status.drag_and_drop.files_added.1 = One file added to the sketch. -editor.status.drag_and_drop.files_added.n = %d files added to the sketch. +editor.status.find_reference.not_available = "%s" のリファレンスは利用できません。 +editor.status.drag_and_drop.files_added.0 = スケッチに追加されたファイルはありませんでした。 +editor.status.drag_and_drop.files_added.1 = 1 個のファイルがスケッチに追加されました。 +editor.status.drag_and_drop.files_added.n = %d 個のファイルがスケッチに追加されました。 editor.status.saving = 保存しています... editor.status.saving.done = 保存が完了しました。 editor.status.saving.canceled = 保存がキャンセルされました。 @@ -359,10 +359,10 @@ editor.status.missing.left_paren = Missing left parenthesis "(" editor.status.missing.right_paren = Missing right parenthesis ")" editor.status.missing.left_curly_bracket = Missing left curly bracket "{" editor.status.missing.right_curly_bracket = Missing right curly bracket "}" -editor.status.missing.add = Consider adding "%s" +editor.status.missing.add = "%s" の追加を考えてください editor.status.reserved_words = "color" and "int" are reserved words & cannot be used as variable names editor.status.undefined_method = 関数 "%s(%s)" は存在しません -editor.status.undefined_constructor = The constructor "%s(%s)" does not exist +editor.status.undefined_constructor = コンストラクター "%s(%s)" は存在しません editor.status.empty_param = The function "%s()" does not expect any parameters editor.status.wrong_param = The function "%s()" expects parameters like: "%s(%s)" editor.status.undef_global_var = グローバル変数 "%s" は存在しません @@ -370,7 +370,7 @@ editor.status.undef_class = クラス "%s" は存在しません editor.status.undef_var = 変数 "%s" は存在しません editor.status.undef_name = The name "%s" cannot be recognized editor.status.type_mismatch = Type mismatch, "%s" does not match with "%s" -editor.status.unused_variable = The value of the local variable "%s" is not used +editor.status.unused_variable = ローカル変数 "%s" の値は使われていません editor.status.uninitialized_variable = The local variable "%s" may not have been initialized editor.status.no_effect_assignment = The assignment to variable "%s" has no effect @@ -408,7 +408,7 @@ name.messages.no_create_file.description = Could not create the file "%s"\nin "% # Delete handler delete.messages.cannot_delete = 削除できません -delete.messages.cannot_delete.description = You cannot delete a sketch that has not been saved. +delete.messages.cannot_delete.description = 保存されていないスケッチを削除することはできません。 delete.messages.cannot_delete.file = Could not do it delete.messages.cannot_delete.file.description = 削除できませんでした delete.messages.is_read_only = スケッチが読込み専用です From 8a62026120982241e58e3b38c2976787ad54f700 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Sun, 29 Oct 2017 17:32:19 -0400 Subject: [PATCH 010/375] remove unhelpful deprecation, other notes and todo items --- core/src/processing/awt/PGraphicsJava2D.java | 3 +-- core/src/processing/core/PImage.java | 1 - core/todo.txt | 3 +++ todo.txt | 2 ++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/processing/awt/PGraphicsJava2D.java b/core/src/processing/awt/PGraphicsJava2D.java index e34303aadd..1fc3beb208 100644 --- a/core/src/processing/awt/PGraphicsJava2D.java +++ b/core/src/processing/awt/PGraphicsJava2D.java @@ -1916,7 +1916,7 @@ protected void handleTextSize(float size) { if (font != null) { if (font.getSize2D() != size) { Map map = - new HashMap(); + new HashMap<>(); map.put(TextAttribute.SIZE, size); map.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); @@ -2932,7 +2932,6 @@ protected void setImpl(PImage sourceImage, @Override - @SuppressWarnings("deprecation") public void mask(int[] alpha) { if (primaryGraphics) { showWarning(MASK_WARNING); diff --git a/core/src/processing/core/PImage.java b/core/src/processing/core/PImage.java index cc1105322f..4fdd8cd49f 100644 --- a/core/src/processing/core/PImage.java +++ b/core/src/processing/core/PImage.java @@ -936,7 +936,6 @@ protected void setImpl(PImage sourceImage, // ALPHA CHANNEL - @Deprecated /** * @param maskArray array of integers used as the alpha channel, needs to be * the same length as the image's pixel array. diff --git a/core/todo.txt b/core/todo.txt index a33849f7dd..3a0bf412ee 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,6 +1,9 @@ 0264 (3.3.7 or 3.4) X fix exception due to version parsing in Java 9 X https://github.com/processing/processing/issues/5275 +X remove useless deprecation on PImage.mask(int[]) +_ add circle() and square() +_ add push() and pop() data X added setIndex() method to IntDict, FloatDict, StringDict diff --git a/todo.txt b/todo.txt index 209b52c2d3..14b01f1557 100755 --- a/todo.txt +++ b/todo.txt @@ -2,6 +2,8 @@ X downloading the jre broken again X https://github.com/processing/processing/issues/5284 X the old 144 link must have been removed +_ update to launch4j 3.11? +_ http://launch4j.sourceforge.net/changelog.html jakub X Fix scrub comments for empty block comment /**/ From 35bc7f0bfec6d5ddc4d65bd87800d6d96cc93efa Mon Sep 17 00:00:00 2001 From: gohai Date: Mon, 30 Oct 2017 21:12:08 +0100 Subject: [PATCH 011/375] Fix 3D on Raspberry Pi with Mesa drivers We need to use a special shader to workaround register allocation issues with the new driver, see: https://github.com/anholt/mesa/issues/63 --- core/src/processing/opengl/PGraphicsOpenGL.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index a86290a1be..88c8356608 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -6893,7 +6893,7 @@ protected void getGLParameters() { // overwrite the default shaders with vendor specific versions // if needed if (OPENGL_RENDERER.equals("VideoCore IV HW") || // Broadcom's binary driver for Raspberry Pi - OPENGL_RENDERER.equals("Gallium 0.4 on VC4")) { // Mesa driver for same hardware + OPENGL_RENDERER.contains("VC4")) { // Mesa driver for same hardware defLightShaderVertURL = PGraphicsOpenGL.class.getResource("/processing/opengl/shaders/LightVert-vc4.glsl"); defTexlightShaderVertURL = From 9c67d17b91f9096390e12b3284e6c7fa099776f9 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Thu, 9 Nov 2017 12:23:51 -0500 Subject: [PATCH 012/375] Fix error checker crash when className contains [ or ] --- java/src/processing/mode/java/pdex/PDEX.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/src/processing/mode/java/pdex/PDEX.java b/java/src/processing/mode/java/pdex/PDEX.java index 9f84ccbcff..52280c0e49 100644 --- a/java/src/processing/mode/java/pdex/PDEX.java +++ b/java/src/processing/mode/java/pdex/PDEX.java @@ -1290,6 +1290,7 @@ static private List checkForMissingBraces(PreprocessedSketch ps) { static public String[] getImportSuggestions(ClassPath cp, String className) { + className = className.replace("[", "\\[").replace("]", "\\]"); RegExpResourceFilter regf = new RegExpResourceFilter( Pattern.compile(".*"), Pattern.compile("(.*\\$)?" + className + "\\.class", From e83ae2054a3d3c52b1663385673fdfb26abcc96b Mon Sep 17 00:00:00 2001 From: REAS Date: Fri, 10 Nov 2017 14:41:32 -0800 Subject: [PATCH 013/375] Small parameter changes for Reference --- core/src/processing/core/PApplet.java | 5 +++-- core/src/processing/core/PImage.java | 14 ++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index cccf598398..9d183b437f 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -5258,7 +5258,6 @@ public void noiseDetail(int lod) { /** * @see #noiseDetail(int) - * @param lod number of octaves to be used by the noise * @param falloff falloff factor for each octave */ public void noiseDetail(int lod, float falloff) { @@ -5994,7 +5993,9 @@ public JSONObject loadJSONObject(String filename) { return new JSONObject(createReader(filename)); } - + /** + * @nowebref + */ static public JSONObject loadJSONObject(File file) { return new JSONObject(createReader(file)); } diff --git a/core/src/processing/core/PImage.java b/core/src/processing/core/PImage.java index 4fdd8cd49f..049d198f44 100644 --- a/core/src/processing/core/PImage.java +++ b/core/src/processing/core/PImage.java @@ -3328,15 +3328,13 @@ private IIOMetadata imageioDPI(ImageWriter writer, ImageWriteParam param, double /** * ( begin auto-generated from PImage_save.xml ) * - * Saves the image into a file. Images are saved in TIFF, TARGA, JPEG, and - * PNG format depending on the extension within the filename - * parameter. For example, "image.tif" will have a TIFF image and - * "image.png" will save a PNG image. If no extension is included in the - * filename, the image will save in TIFF format and .tif will be - * added to the name. These files are saved to the sketch's folder, which + * Saves the image into a file. Append a file extension to the name of + * the file, to indicate the file format to be used: either TIFF (.tif), + * TARGA (.tga), JPEG (.jpg), or PNG (.png). If no extension is included + * in the filename, the image will save in TIFF format and .tif will be + * added to the name. These files are saved to the sketch's folder, which * may be opened by selecting "Show sketch folder" from the "Sketch" menu. - * It is not possible to use save() while running the program in a - * web browser.

To save an image created within the code, rather + *

To save an image created within the code, rather * than through loading, it's necessary to make the image with the * createImage() function so it is aware of the location of the * program and can therefore save the file to the right place. See the From 8059a4edb1339c6da1dccde18c242622fbd9408c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 20 Nov 2017 16:06:21 -0500 Subject: [PATCH 014/375] set colorModeDefault to true by default --- core/src/processing/core/PGraphics.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index ede34ca38d..3bc19fef5a 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -334,8 +334,11 @@ public class PGraphics extends PImage implements PConstants { /** True if colors are not in the range 0..1 */ boolean colorModeScale; // = true; - /** True if colorMode(RGB, 255) */ - boolean colorModeDefault; // = true; + /** + * True if colorMode(RGB, 255). Defaults to true so that color() + * used as part of a field declaration will properly assign values. + */ + boolean colorModeDefault = true; // ........................................................ From 74868eec1d87ba2b348a10f5889cd540831fb3d1 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 20 Nov 2017 16:06:48 -0500 Subject: [PATCH 015/375] couple of todo notes from recent github issues --- core/todo.txt | 1 + todo.txt | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 3a0bf412ee..70d5da204d 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -2,6 +2,7 @@ X fix exception due to version parsing in Java 9 X https://github.com/processing/processing/issues/5275 X remove useless deprecation on PImage.mask(int[]) +X set colorModeDefault to true by default _ add circle() and square() _ add push() and pop() diff --git a/todo.txt b/todo.txt index 14b01f1557..d291d0d343 100755 --- a/todo.txt +++ b/todo.txt @@ -2,13 +2,20 @@ X downloading the jre broken again X https://github.com/processing/processing/issues/5284 X the old 144 link must have been removed +_ Contributions manager fails to complete install of PythonMode when no windows open +_ https://github.com/processing/processing/issues/5309 _ update to launch4j 3.11? _ http://launch4j.sourceforge.net/changelog.html +_ add a note about temp dir to the bug on windows temp dirs +_ move away from using a temp dir at all for sketches +_ -Djava.io.tmpdir=Z:\temp jakub X Fix scrub comments for empty block comment /**/ X https://github.com/processing/processing/pull/5265 X https://github.com/processing/processing/issues/5219 +X Fix error checker crash when className contains [ or ] +X https://github.com/processing/processing/pull/5304 contrib X detect errors from curved quotation marks From fd7c5a0d8f21651ee6bdc854551b5a66533fb8fc Mon Sep 17 00:00:00 2001 From: codeanticode Date: Fri, 8 Dec 2017 15:28:18 +0900 Subject: [PATCH 016/375] texture wrap can be set multiple times in a sketch, fixes #5322 --- .../processing/opengl/PGraphicsOpenGL.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index a86290a1be..458d5aadc4 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -617,7 +617,7 @@ public void setPrimary(boolean primary) { format = ARGB; if (primary) { fbStack = new FrameBuffer[FB_STACK_DEPTH]; - fontMap = new WeakHashMap(); + fontMap = new WeakHashMap<>(); tessellator = new Tessellator(); } else { tessellator = getPrimaryPG().tessellator; @@ -1993,6 +1993,9 @@ protected void endShape(int[] indices) { @Override public void textureWrap(int wrap) { + if (this.textureWrap != wrap) { + flush(); + } this.textureWrap = wrap; } @@ -7142,7 +7145,7 @@ static protected AttributeMap newAttributeMap() { static protected class AttributeMap extends HashMap { - public ArrayList names = new ArrayList(); + public ArrayList names = new ArrayList<>(); public int numComp = 0; // number of components for a single vertex @Override @@ -7668,9 +7671,9 @@ void allocate() { shininess = new float[PGL.DEFAULT_IN_VERTICES]; edges = new int[PGL.DEFAULT_IN_EDGES][3]; - fattribs = new HashMap(); - iattribs = new HashMap(); - battribs = new HashMap(); + fattribs = new HashMap<>(); + iattribs = new HashMap<>(); + battribs = new HashMap<>(); clear(); } @@ -9105,7 +9108,7 @@ static protected class TessGeometry { FloatBuffer polyShininessBuffer; // Generic attributes - HashMap polyAttribBuffers = new HashMap(); + HashMap polyAttribBuffers = new HashMap<>(); int polyIndexCount; int firstPolyIndex; @@ -9160,9 +9163,9 @@ static protected class TessGeometry { float[] pointOffsets; short[] pointIndices; - HashMap fpolyAttribs = new HashMap(); - HashMap ipolyAttribs = new HashMap(); - HashMap bpolyAttribs = new HashMap(); + HashMap fpolyAttribs = new HashMap<>(); + HashMap ipolyAttribs = new HashMap<>(); + HashMap bpolyAttribs = new HashMap<>(); TessGeometry(PGraphicsOpenGL pg, AttributeMap attr, int mode) { this.pg = pg; From 151003fb4358addb0501ba2690bf67a234d754bb Mon Sep 17 00:00:00 2001 From: Alexander Hurst <34695105+alexanderghurst@users.noreply.github.com> Date: Wed, 20 Dec 2017 15:09:16 -0500 Subject: [PATCH 017/375] cursor() sets the cursor visible, fixes #5330 --- core/src/processing/opengl/PSurfaceJOGL.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index bde0f52303..dd7a1d7674 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -1280,6 +1280,7 @@ public void setCursor(PImage image, int hotspotX, int hotspotY) { display.getEDTUtil().invoke(false, new Runnable() { @Override public void run() { + window.setPointerVisible(true); window.setPointerIcon(pi); } }); From 77c000fa27f0032b80dc6c1456aff65e4b9e430a Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 5 Jan 2018 14:45:38 -0500 Subject: [PATCH 018/375] fix for NPE in deleteFlagged() (fixes #5342) --- .../processing/app/contrib/ContributionManager.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/processing/app/contrib/ContributionManager.java b/app/src/processing/app/contrib/ContributionManager.java index e2e8297ef6..c2d4883155 100644 --- a/app/src/processing/app/contrib/ContributionManager.java +++ b/app/src/processing/app/contrib/ContributionManager.java @@ -361,7 +361,7 @@ static public void downloadAndInstallOnImport(final Base base, editor.getTextArea().setEditable(false); // base.getActiveEditor().getConsole().clear(); - List installedLibList = new ArrayList(); + List installedLibList = new ArrayList<>(); // boolean variable to check if previous lib was installed successfully, // to give the user an idea about progress being made. @@ -590,8 +590,10 @@ public boolean accept(File folder) { LocalContribution.isDeletionFlagged(folder)); } }); - for (File folder : markedForDeletion) { - Util.removeDir(folder); + if (markedForDeletion != null) { + for (File folder : markedForDeletion) { + Util.removeDir(folder); + } } } @@ -632,8 +634,8 @@ public boolean accept(File folder) { } }); - ArrayList updateContribsNames = new ArrayList(); - LinkedList updateContribsList = new LinkedList(); + List updateContribsNames = new ArrayList<>(); + List updateContribsList = new LinkedList<>(); String type = root.getName().substring(root.getName().lastIndexOf('/') + 1); String propFileName = null; From 54f7cb9b6e81a6d4a18dfd5c41609dae08cad916 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 5 Jan 2018 15:03:12 -0500 Subject: [PATCH 019/375] ack, some ugly code here --- app/src/processing/app/contrib/ContributionManager.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/processing/app/contrib/ContributionManager.java b/app/src/processing/app/contrib/ContributionManager.java index c2d4883155..857c5fb174 100644 --- a/app/src/processing/app/contrib/ContributionManager.java +++ b/app/src/processing/app/contrib/ContributionManager.java @@ -637,6 +637,12 @@ public boolean accept(File folder) { List updateContribsNames = new ArrayList<>(); List updateContribsList = new LinkedList<>(); + // TODO This is bad code... This root.getName() stuff to get the folder + // type, plus "libraries.properties" (not the correct file name), + // and I have no idea what "putting this here, in just in case" means. + // Not sure the function here so I'm not fixing it at the moment, + // but this whole function could use some cleaning. [fry 180105] + String type = root.getName().substring(root.getName().lastIndexOf('/') + 1); String propFileName = null; From e5490f5f02261346e56821e3ef7b21a3a96742ff Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 5 Jan 2018 15:55:30 -0500 Subject: [PATCH 020/375] a couple todo item updates --- core/todo.txt | 8 ++++++++ todo.txt | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 70d5da204d..0a21daa19e 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -15,12 +15,19 @@ contrib X minor bezierPoint() rewrite for performance X https://github.com/processing/processing/pull/5251 +andres +X textureWrap() not updating when changed during draw() +X https://github.com/processing/processing/issues/5322 + _ make setting the window icon automatic, based on files in local dirs X https://github.com/processing/processing/issues/5123 X https://github.com/processing/processing/pull/5202 _ need to make this work behind the scenes instead _ create icon.png or have an 'icons' folder with multiple sizes +_ many shift- keys not working properly in FX2D (added a test sketch) +_ https://github.com/processing/processing/issues/5317 + _ Switch to getModifiersEx() and fix the AWT modifiers used in PSurfaceAWT _ this is an easy fix, but need to check impact elsewhere _ does anything else rely on these modifiers? @@ -48,6 +55,7 @@ _ Sketches on Windows don't take UI sizing into account _ https://github.com/processing/processing/issues/4894 _ Sketches on Linux don't take UI scaling into account _ https://github.com/processing/processing/issues/4895 +_ gohai says "xrdb -query" or "xdpyinfo" might work _ TRIANGLE_STRIP not working correctly with createShape() and default renderer _ https://github.com/processing/processing/issues/4678 diff --git a/todo.txt b/todo.txt index d291d0d343..dde8c8d08c 100755 --- a/todo.txt +++ b/todo.txt @@ -2,6 +2,10 @@ X downloading the jre broken again X https://github.com/processing/processing/issues/5284 X the old 144 link must have been removed +X NullPointerException in ContributionManager.deleteFlagged() +X https://github.com/processing/processing/issues/5342 +_ change up the newline handling +_ https://github.com/processing/processing/issues/5327 _ Contributions manager fails to complete install of PythonMode when no windows open _ https://github.com/processing/processing/issues/5309 _ update to launch4j 3.11? @@ -9,6 +13,11 @@ _ http://launch4j.sourceforge.net/changelog.html _ add a note about temp dir to the bug on windows temp dirs _ move away from using a temp dir at all for sketches _ -Djava.io.tmpdir=Z:\temp +_ add pyde as a supported extension? +_ https://github.com/jdf/processing.py/issues/284 + +_ an incompatible Mode prevents the PDE from quitting after the last window is closed +_ https://github.com/processing/processing/issues/5112 jakub X Fix scrub comments for empty block comment /**/ @@ -34,6 +43,8 @@ _ https://github.com/processing/processing/issues/5272 _ add select/copy to the status bar _ https://github.com/processing/processing/issues/5271 +_ possible fix (just copies on click) +_ https://github.com/processing/processing/pull/5345 _ untitled folders are stored in temp folder _ clean up /tmp folders used during build From f479824c976fa94ee4899092e7a35e5c76ecec5f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sat, 6 Jan 2018 16:47:22 +0100 Subject: [PATCH 021/375] Fix line join triangles Fixes #5353 --- core/src/processing/opengl/shaders/LineVert.glsl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/processing/opengl/shaders/LineVert.glsl b/core/src/processing/opengl/shaders/LineVert.glsl index 7dc290b78a..50946ba5ae 100644 --- a/core/src/processing/opengl/shaders/LineVert.glsl +++ b/core/src/processing/opengl/shaders/LineVert.glsl @@ -71,7 +71,10 @@ void main() { // and corrects for aspect ratio, see https://github.com/processing/processing/issues/5181) // t = +- normalize( (q.xy*p.w - p.xy*q.w) * viewport.zw ) - vec2 tangent = normalize((q.xy*p.w - p.xy*q.w) * viewport.zw); + vec2 tangent = (q.xy*p.w - p.xy*q.w) * viewport.zw; + + // don't normalize zero vector (line join triangles and lines perpendicular to the eye plane) + tangent = length(tangent) == 0.0 ? vec2(0.0, 0.0) : normalize(tangent); // flip tangent to normal (it's already normalized) vec2 normal = vec2(-tangent.y, tangent.x); From 1aa37c0d791d1d7d495ed6b748a30853071c8616 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 10 Jan 2018 22:04:42 -0500 Subject: [PATCH 022/375] minor tweaks for warnings --- java/src/processing/mode/java/JavaEditor.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 562efca8a6..10c825027f 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -311,17 +311,17 @@ public void actionPerformed(ActionEvent e) { @Override public void menuSelected(MenuEvent e) { - boolean isCoreLibMenuItemAdded = false; - boolean isContribLibMenuItemAdded = false; - // Adding this in case references are included in a core library, - // or other core libraries are incuded in future - isCoreLibMenuItemAdded = addLibReferencesToSubMenu(mode.coreLibraries, libRefSubmenu); + // or other core libraries are included in the future + boolean isCoreLibMenuItemAdded = + addLibReferencesToSubMenu(mode.coreLibraries, libRefSubmenu); - if (isCoreLibMenuItemAdded && !mode.contribLibraries.isEmpty()) + if (isCoreLibMenuItemAdded && !mode.contribLibraries.isEmpty()) { libRefSubmenu.addSeparator(); + } - isContribLibMenuItemAdded = addLibReferencesToSubMenu(mode.contribLibraries, libRefSubmenu); + boolean isContribLibMenuItemAdded = + addLibReferencesToSubMenu(mode.contribLibraries, libRefSubmenu); if (!isContribLibMenuItemAdded && !isCoreLibMenuItemAdded) { JMenuItem emptyMenuItem = new JMenuItem(Language.text("menu.help.empty")); @@ -329,8 +329,8 @@ public void menuSelected(MenuEvent e) { emptyMenuItem.setFocusable(false); emptyMenuItem.setFocusPainted(false); libRefSubmenu.add(emptyMenuItem); - } - else if (!isContribLibMenuItemAdded && !mode.coreLibraries.isEmpty()) { + + } else if (!isContribLibMenuItemAdded && !mode.coreLibraries.isEmpty()) { //re-populate the menu to get rid of terminal separator libRefSubmenu.removeAll(); addLibReferencesToSubMenu(mode.coreLibraries, libRefSubmenu); From 6dfcc5ab9f941c66051beec9116ea4abfcce3c44 Mon Sep 17 00:00:00 2001 From: Gottfried Haider Date: Thu, 11 Jan 2018 16:53:05 +0100 Subject: [PATCH 023/375] Fix mistake in Italian translation Fixes #5365 --- build/shared/lib/languages/PDE_it.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/shared/lib/languages/PDE_it.properties b/build/shared/lib/languages/PDE_it.properties index 20e6113ba9..8c8f32898f 100644 --- a/build/shared/lib/languages/PDE_it.properties +++ b/build/shared/lib/languages/PDE_it.properties @@ -201,7 +201,7 @@ sketchbook.tree = Cartella degli Sketch examples.title = %s Esempi examples.add_examples = Aggiungi Esempi... examples.libraries = Librerie di terze parti -examples.core_libraries = Librarie +examples.core_libraries = Librerie examples.contributed = Esempi di terze parti # Export (Frame) From 4aa30ed85792c3e600eb4fdb5c321195849edd78 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Sat, 13 Jan 2018 14:16:02 -0500 Subject: [PATCH 024/375] some additions to the PLG.Tessellator interface --- core/src/processing/opengl/PGL.java | 8 ++++++- core/src/processing/opengl/PJOGL.java | 32 ++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index 4620e9cf22..cbb2d2f9db 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -2674,12 +2674,17 @@ protected static void fillFloatBuffer(FloatBuffer buf, int i0, int i1, protected interface Tessellator { + public void setCallback(int flag); + public void setWindingRule(int rule); + public void setProperty(int property, int value); + public void beginPolygon(); + public void beginPolygon(Object data); public void endPolygon(); - public void setWindingRule(int rule); public void beginContour(); public void endContour(); public void addVertex(double[] v); + public void addVertex(double[] v, int n, Object data); } @@ -2791,6 +2796,7 @@ protected interface FontOutline { public static int TESS_WINDING_NONZERO; public static int TESS_WINDING_ODD; + public static int TESS_EDGE_FLAG; public static int GENERATE_MIPMAP_HINT; public static int FASTEST; diff --git a/core/src/processing/opengl/PJOGL.java b/core/src/processing/opengl/PJOGL.java index 7b67fe0d9d..58f7618d9d 100644 --- a/core/src/processing/opengl/PJOGL.java +++ b/core/src/processing/opengl/PJOGL.java @@ -600,19 +600,33 @@ public Tessellator(TessellatorCallback callback) { GLU.gluTessCallback(tess, GLU.GLU_TESS_ERROR, gluCallback); } + @Override + public void setCallback(int flag) { + GLU.gluTessCallback(tess, flag, gluCallback); + } + + @Override + public void setWindingRule(int rule) { + setProperty(GLU.GLU_TESS_WINDING_RULE, rule); + } + + public void setProperty(int property, int value) { + GLU.gluTessProperty(tess, property, value); + } + @Override public void beginPolygon() { - GLU.gluTessBeginPolygon(tess, null); + beginPolygon(null); } @Override - public void endPolygon() { - GLU.gluTessEndPolygon(tess); + public void beginPolygon(Object data) { + GLU.gluTessBeginPolygon(tess, data); } @Override - public void setWindingRule(int rule) { - GLU.gluTessProperty(tess, GLU.GLU_TESS_WINDING_RULE, rule); + public void endPolygon() { + GLU.gluTessEndPolygon(tess); } @Override @@ -627,7 +641,12 @@ public void endContour() { @Override public void addVertex(double[] v) { - GLU.gluTessVertex(tess, v, 0, v); + addVertex(v, 0, v); + } + + @Override + public void addVertex(double[] v, int n, Object data) { + GLU.gluTessVertex(tess, v, n, data); } protected class GLUCallback extends GLUtessellatorCallbackAdapter { @@ -752,6 +771,7 @@ public void next() { TESS_WINDING_NONZERO = GLU.GLU_TESS_WINDING_NONZERO; TESS_WINDING_ODD = GLU.GLU_TESS_WINDING_ODD; + TESS_EDGE_FLAG = GLU.GLU_TESS_EDGE_FLAG; GENERATE_MIPMAP_HINT = GL.GL_GENERATE_MIPMAP_HINT; FASTEST = GL.GL_FASTEST; From dfca4e4adeb4377f561c4d328347376f509fb248 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 17 Jan 2018 18:33:54 -0500 Subject: [PATCH 025/375] move to Java 8u162, additional todo updates --- build/build.xml | 6 +++--- core/todo.txt | 12 ++++++++++++ todo.txt | 9 ++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/build/build.xml b/build/build.xml index db4738915c..839ec6f169 100644 --- a/build/build.xml +++ b/build/build.xml @@ -70,11 +70,11 @@ value="../../processing-docs/content/examples" /> - - + + - + diff --git a/core/todo.txt b/core/todo.txt index 0a21daa19e..6b72fee7e7 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -14,11 +14,23 @@ X fix entries() Iterator in IntDict, FloatDict, StringDict contrib X minor bezierPoint() rewrite for performance X https://github.com/processing/processing/pull/5251 +X void cursor() don't work after void noCursor() in P2D and P3D +X https://github.com/processing/processing/issues/5330 +X https://github.com/processing/processing/pull/5340 andres X textureWrap() not updating when changed during draw() X https://github.com/processing/processing/issues/5322 +gohai +X ARM tweaks for shaders on the RPi +X https://github.com/processing/processing/pull/5297 + +jakub +X fix line joins on triangles +X https://github.com/processing/processing/issues/5353 +X https://github.com/processing/processing/pull/5354 + _ make setting the window icon automatic, based on files in local dirs X https://github.com/processing/processing/issues/5123 X https://github.com/processing/processing/pull/5202 diff --git a/todo.txt b/todo.txt index dde8c8d08c..2fb9a19b50 100755 --- a/todo.txt +++ b/todo.txt @@ -4,6 +4,9 @@ X https://github.com/processing/processing/issues/5284 X the old 144 link must have been removed X NullPointerException in ContributionManager.deleteFlagged() X https://github.com/processing/processing/issues/5342 +X move to Java 8u162 +_ Rename dialog is unusable on high density screen +_ https://github.com/processing/processing/issues/5368 _ change up the newline handling _ https://github.com/processing/processing/issues/5327 _ Contributions manager fails to complete install of PythonMode when no windows open @@ -16,8 +19,10 @@ _ -Djava.io.tmpdir=Z:\temp _ add pyde as a supported extension? _ https://github.com/jdf/processing.py/issues/284 -_ an incompatible Mode prevents the PDE from quitting after the last window is closed +_ an incompatible Mode prevents the PDE from quitting after last window is closed _ https://github.com/processing/processing/issues/5112 +_ processing.net.client not working properly after a few hours +_ https://github.com/processing/processing/issues/5360 jakub X Fix scrub comments for empty block comment /**/ @@ -34,6 +39,8 @@ X Refactor to use a few Java 8 features X https://github.com/processing/processing/pull/5134 X Remove "Pipe Organ" from exec javadoc X https://github.com/processing/processing/pull/5282 +X typo in Italian translation +X https://github.com/processing/processing/issues/5365 _ Welcome dialog rewritten in Swing _ https://github.com/processing/processing/pull/5210 From 5a27deee6379a9c08451d22c9d5fb1736f9338ae Mon Sep 17 00:00:00 2001 From: codeanticode Date: Thu, 18 Jan 2018 10:15:29 -0500 Subject: [PATCH 026/375] reset correct clear variable --- core/src/processing/opengl/PGL.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index cbb2d2f9db..73e519871a 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -704,7 +704,7 @@ protected void beginRender() { clearColor = false; pclearDepth = clearDepth; - clearColor = false; + clearDepth = false; pclearStencil = clearStencil; clearStencil = false; From c9eab5c86df6aaa1068dac9c7191f5c1e3ed47b4 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 21 Jan 2018 16:40:47 +0100 Subject: [PATCH 027/375] Net-client: use final field for lock --- .../libraries/net/src/processing/net/Client.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index 11287c59ef..04b3de1ad9 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -57,6 +57,8 @@ public class Client implements Runnable { public InputStream input; public OutputStream output; + final Object bufferLock = new Object[0]; + byte buffer[] = new byte[32768]; int bufferIndex; int bufferLast; @@ -230,7 +232,7 @@ public void run() { return; } - synchronized (buffer) { + synchronized (bufferLock) { // todo: at some point buffer should stop increasing in size, // otherwise it could use up all the memory. if (bufferLast == buffer.length) { @@ -341,7 +343,7 @@ public void clear() { public int read() { if (bufferIndex == bufferLast) return -1; - synchronized (buffer) { + synchronized (bufferLock) { int outgoing = buffer[bufferIndex++] & 0xff; if (bufferIndex == bufferLast) { // rewind bufferIndex = 0; @@ -394,7 +396,7 @@ public char readChar() { public byte[] readBytes() { if (bufferIndex == bufferLast) return null; - synchronized (buffer) { + synchronized (bufferLock) { int length = bufferLast - bufferIndex; byte outgoing[] = new byte[length]; System.arraycopy(buffer, bufferIndex, outgoing, 0, length); @@ -419,7 +421,7 @@ public byte[] readBytes() { public byte[] readBytes(int max) { if (bufferIndex == bufferLast) return null; - synchronized (buffer) { + synchronized (bufferLock) { int length = bufferLast - bufferIndex; if (length > max) length = max; byte outgoing[] = new byte[length]; @@ -451,7 +453,7 @@ public byte[] readBytes(int max) { public int readBytes(byte bytebuffer[]) { if (bufferIndex == bufferLast) return 0; - synchronized (buffer) { + synchronized (bufferLock) { int length = bufferLast - bufferIndex; if (length > bytebuffer.length) length = bytebuffer.length; System.arraycopy(buffer, bufferIndex, bytebuffer, 0, length); @@ -490,7 +492,7 @@ public byte[] readBytesUntil(int interesting) { if (bufferIndex == bufferLast) return null; byte what = (byte)interesting; - synchronized (buffer) { + synchronized (bufferLock) { int found = -1; for (int k = bufferIndex; k < bufferLast; k++) { if (buffer[k] == what) { @@ -531,7 +533,7 @@ public int readBytesUntil(int interesting, byte byteBuffer[]) { if (bufferIndex == bufferLast) return 0; byte what = (byte)interesting; - synchronized (buffer) { + synchronized (bufferLock) { int found = -1; for (int k = bufferIndex; k < bufferLast; k++) { if (buffer[k] == what) { From bae41fa4a404813209ef4ddb46e2bf8ecdd85db8 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 21 Jan 2018 16:42:45 +0100 Subject: [PATCH 028/375] Net-client: synchronize access to all concurrently modified fields --- .../net/src/processing/net/Client.java | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index 04b3de1ad9..4eda3b8244 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -49,7 +49,7 @@ public class Client implements Runnable { Method clientEventMethod; Method disconnectEventMethod; - Thread thread; + volatile Thread thread; Socket socket; int port; String host; @@ -308,7 +308,9 @@ public String ip() { * @brief Returns the number of bytes in the buffer waiting to be read */ public int available() { - return (bufferLast - bufferIndex); + synchronized (bufferLock) { + return (bufferLast - bufferIndex); + } } @@ -323,8 +325,10 @@ public int available() { * @brief Clears the buffer */ public void clear() { - bufferLast = 0; - bufferIndex = 0; + synchronized (bufferLock) { + bufferLast = 0; + bufferIndex = 0; + } } @@ -341,9 +345,9 @@ public void clear() { * @brief Returns a value from the buffer */ public int read() { - if (bufferIndex == bufferLast) return -1; - synchronized (bufferLock) { + if (bufferIndex == bufferLast) return -1; + int outgoing = buffer[bufferIndex++] & 0xff; if (bufferIndex == bufferLast) { // rewind bufferIndex = 0; @@ -366,8 +370,10 @@ public int read() { * @brief Returns the next byte in the buffer as a char */ public char readChar() { - if (bufferIndex == bufferLast) return (char)(-1); - return (char) read(); + synchronized (bufferLock) { + if (bufferIndex == bufferLast) return (char) (-1); + return (char) read(); + } } @@ -394,9 +400,9 @@ public char readChar() { * @brief Reads everything in the buffer */ public byte[] readBytes() { - if (bufferIndex == bufferLast) return null; - synchronized (bufferLock) { + if (bufferIndex == bufferLast) return null; + int length = bufferLast - bufferIndex; byte outgoing[] = new byte[length]; System.arraycopy(buffer, bufferIndex, outgoing, 0, length); @@ -419,9 +425,9 @@ public byte[] readBytes() { * @param max the maximum number of bytes to read */ public byte[] readBytes(int max) { - if (bufferIndex == bufferLast) return null; - synchronized (bufferLock) { + if (bufferIndex == bufferLast) return null; + int length = bufferLast - bufferIndex; if (length > max) length = max; byte outgoing[] = new byte[length]; @@ -451,9 +457,9 @@ public byte[] readBytes(int max) { * @param bytebuffer passed in byte array to be altered */ public int readBytes(byte bytebuffer[]) { - if (bufferIndex == bufferLast) return 0; - synchronized (bufferLock) { + if (bufferIndex == bufferLast) return 0; + int length = bufferLast - bufferIndex; if (length > bytebuffer.length) length = bytebuffer.length; System.arraycopy(buffer, bufferIndex, bytebuffer, 0, length); @@ -489,10 +495,11 @@ public int readBytes(byte bytebuffer[]) { * @param interesting character designated to mark the end of the data */ public byte[] readBytesUntil(int interesting) { - if (bufferIndex == bufferLast) return null; byte what = (byte)interesting; synchronized (bufferLock) { + if (bufferIndex == bufferLast) return null; + int found = -1; for (int k = bufferIndex; k < bufferLast; k++) { if (buffer[k] == what) { @@ -530,10 +537,11 @@ public byte[] readBytesUntil(int interesting) { * @param byteBuffer passed in byte array to be altered */ public int readBytesUntil(int interesting, byte byteBuffer[]) { - if (bufferIndex == bufferLast) return 0; byte what = (byte)interesting; synchronized (bufferLock) { + if (bufferIndex == bufferLast) return 0; + int found = -1; for (int k = bufferIndex; k < bufferLast; k++) { if (buffer[k] == what) { @@ -578,8 +586,10 @@ public int readBytesUntil(int interesting, byte byteBuffer[]) { * @brief Returns the buffer as a String */ public String readString() { - if (bufferIndex == bufferLast) return null; - return new String(readBytes()); + synchronized (bufferLock) { + if (bufferIndex == bufferLast) return null; + return new String(readBytes()); + } } From 0c749325be032632f053bd3e1466f00c04b7c87f Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 21 Jan 2018 17:03:55 +0100 Subject: [PATCH 029/375] Net-client: compact the buffer if possible instead of resizing --- java/libraries/net/src/processing/net/Client.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index 4eda3b8244..da37e503b3 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -236,9 +236,18 @@ public void run() { // todo: at some point buffer should stop increasing in size, // otherwise it could use up all the memory. if (bufferLast == buffer.length) { - byte temp[] = new byte[bufferLast << 1]; - System.arraycopy(buffer, 0, temp, 0, bufferLast); - buffer = temp; + if (bufferIndex > 0) { + // compact the buffer + int bufferLength = bufferLast - bufferIndex; + System.arraycopy(buffer, bufferIndex, buffer, 0, bufferLength); + bufferLast -= bufferIndex; + bufferIndex = 0; + } else { + // resize the buffer + byte temp[] = new byte[bufferLast << 1]; + System.arraycopy(buffer, 0, temp, 0, bufferLast); + buffer = temp; + } } buffer[bufferLast++] = (byte)value; } From 4ca967fa44a647c36efcd5cec4386e3cf9f8f63e Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 21 Jan 2018 21:52:57 +0100 Subject: [PATCH 030/375] Net-client: read bytes to a read buffer instead of one by one --- .../net/src/processing/net/Client.java | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index da37e503b3..866d1b9695 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -209,15 +209,16 @@ public void dispose() { public void run() { + byte[] readBuffer = new byte[2048]; // Ethernet MTU = 1500 B while (Thread.currentThread() == thread) { try { while (input != null) { - int value; + int readCount; // try to read a byte using a blocking read. // An exception will occur when the sketch is exits. try { - value = input.read(); + readCount = input.read(readBuffer, 0, readBuffer.length); } catch (SocketException e) { System.err.println("Client SocketException: " + e.getMessage()); // the socket had a problem reading so don't try to read from it again. @@ -226,7 +227,7 @@ public void run() { } // read returns -1 if end-of-stream occurs (for example if the host disappears) - if (value == -1) { + if (readCount == -1) { System.err.println("Client got end-of-stream."); stop(); return; @@ -235,31 +236,36 @@ public void run() { synchronized (bufferLock) { // todo: at some point buffer should stop increasing in size, // otherwise it could use up all the memory. - if (bufferLast == buffer.length) { - if (bufferIndex > 0) { - // compact the buffer - int bufferLength = bufferLast - bufferIndex; - System.arraycopy(buffer, bufferIndex, buffer, 0, bufferLength); - bufferLast -= bufferIndex; - bufferIndex = 0; - } else { - // resize the buffer - byte temp[] = new byte[bufferLast << 1]; - System.arraycopy(buffer, 0, temp, 0, bufferLast); - buffer = temp; + int freeBack = buffer.length - bufferLast; + if (readCount > freeBack) { + // not enough space at the back + int bufferLength = bufferLast - bufferIndex; + byte[] targetBuffer = buffer; + if (bufferLength + readCount > buffer.length) { + // can't fit even after compacting, resize the buffer + // find the next power of two which can fit everything in + int newSize = Integer.highestOneBit(bufferLength + readCount - 1) << 1; + targetBuffer = new byte[newSize]; } + // compact the buffer (either in-place or into the new bigger buffer) + System.arraycopy(buffer, bufferIndex, targetBuffer, 0, bufferLength); + bufferLast -= bufferIndex; + bufferIndex = 0; + buffer = targetBuffer; } - buffer[bufferLast++] = (byte)value; + // copy all newly read bytes into the buffer + System.arraycopy(readBuffer, 0, buffer, bufferLast, readCount); + bufferLast += readCount; } // now post an event if (clientEventMethod != null) { try { clientEventMethod.invoke(parent, new Object[] { this }); - } catch (Exception e) { - System.err.println("error, disabling clientEvent() for " + host); - e.printStackTrace(); - clientEventMethod = null; + } catch (Exception e) { + System.err.println("error, disabling clientEvent() for " + host); + e.printStackTrace(); + clientEventMethod = null; } } } From a5bbd2a20180bf8f1474d6a1ebe1215487b5b16b Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 21 Jan 2018 21:55:24 +0100 Subject: [PATCH 031/375] Net-client: set max buffer size --- java/libraries/net/src/processing/net/Client.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index 866d1b9695..0970e130df 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -45,6 +45,9 @@ * @see_external LIB_net/clientEvent */ public class Client implements Runnable { + + protected static final int MAX_BUFFER_SIZE = 2 << 27; // 128 MB + PApplet parent; Method clientEventMethod; Method disconnectEventMethod; @@ -234,8 +237,6 @@ public void run() { } synchronized (bufferLock) { - // todo: at some point buffer should stop increasing in size, - // otherwise it could use up all the memory. int freeBack = buffer.length - bufferLast; if (readCount > freeBack) { // not enough space at the back @@ -245,6 +246,13 @@ public void run() { // can't fit even after compacting, resize the buffer // find the next power of two which can fit everything in int newSize = Integer.highestOneBit(bufferLength + readCount - 1) << 1; + if (newSize > MAX_BUFFER_SIZE) { + // buffer is full because client is not reading (fast enough) + System.err.println("Client: can't receive more data, buffer is full. " + + "Make sure you read the data from the client."); + stop(); + return; + } targetBuffer = new byte[newSize]; } // compact the buffer (either in-place or into the new bigger buffer) From 74e7f2a9d469c4e7cbd2519f8cc3038954f3a3f2 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 21 Jan 2018 21:58:48 +0100 Subject: [PATCH 032/375] Net-client: remove unnecessary array creation --- java/libraries/net/src/processing/net/Client.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index 0970e130df..cf103c39b4 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -95,16 +95,14 @@ public Client(PApplet parent, String host, int port) { // which would be called each time an event comes in try { clientEventMethod = - parent.getClass().getMethod("clientEvent", - new Class[] { Client.class }); + parent.getClass().getMethod("clientEvent", Client.class); } catch (Exception e) { // no such method, or an error.. which is fine, just ignore } // do the same for disconnectEvent(Client c); try { disconnectEventMethod = - parent.getClass().getMethod("disconnectEvent", - new Class[] { Client.class }); + parent.getClass().getMethod("disconnectEvent", Client.class); } catch (Exception e) { // no such method, or an error.. which is fine, just ignore } @@ -138,8 +136,7 @@ public Client(PApplet parent, Socket socket) throws IOException { // public void disconnectEvent(processing.net.Client) try { disconnectEventMethod = - parent.getClass().getMethod("disconnectEvent", - new Class[] { Client.class }); + parent.getClass().getMethod("disconnectEvent", Client.class); } catch (Exception e) { // no such method, or an error.. which is fine, just ignore } @@ -160,7 +157,7 @@ public Client(PApplet parent, Socket socket) throws IOException { public void stop() { if (disconnectEventMethod != null && thread != null){ try { - disconnectEventMethod.invoke(parent, new Object[] { this }); + disconnectEventMethod.invoke(parent, this); } catch (Exception e) { e.printStackTrace(); disconnectEventMethod = null; @@ -211,6 +208,7 @@ public void dispose() { } + @Override public void run() { byte[] readBuffer = new byte[2048]; // Ethernet MTU = 1500 B while (Thread.currentThread() == thread) { @@ -269,7 +267,7 @@ public void run() { // now post an event if (clientEventMethod != null) { try { - clientEventMethod.invoke(parent, new Object[] { this }); + clientEventMethod.invoke(parent, this); } catch (Exception e) { System.err.println("error, disabling clientEvent() for " + host); e.printStackTrace(); From 38a91f1a27c30d0c90eb568b2eee067f92b2ee69 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 21 Jan 2018 22:01:42 +0100 Subject: [PATCH 033/375] Net-client: remove extra catch block Handled by IOException block (it's a superclass of ConnectException and does the same thing). --- java/libraries/net/src/processing/net/Client.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index cf103c39b4..f179b6d2ee 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -107,10 +107,6 @@ public Client(PApplet parent, String host, int port) { // no such method, or an error.. which is fine, just ignore } - } catch (ConnectException ce) { - ce.printStackTrace(); - dispose(); - } catch (IOException e) { e.printStackTrace(); dispose(); From 44b336a163c80980886d09424d8ba0fe0c95a7ad Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 21 Jan 2018 22:23:53 +0100 Subject: [PATCH 034/375] Net-server: properly synchronize clients array --- .../net/src/processing/net/Server.java | 99 +++++++++++-------- 1 file changed, 57 insertions(+), 42 deletions(-) diff --git a/java/libraries/net/src/processing/net/Server.java b/java/libraries/net/src/processing/net/Server.java index bf4abced2d..d0ef757849 100644 --- a/java/libraries/net/src/processing/net/Server.java +++ b/java/libraries/net/src/processing/net/Server.java @@ -52,10 +52,11 @@ public class Server implements Runnable { PApplet parent; Method serverEventMethod; - Thread thread; + volatile Thread thread; ServerSocket server; int port; - + + protected final Object clientsLock = new Object[0]; /** Number of clients currently connected. */ public int clientCount; /** Array of client objects, useful length is determined by clientCount. */ @@ -127,26 +128,30 @@ public Server(PApplet parent, int port, String host) { */ public void disconnect(Client client) { client.stop(); - int index = clientIndex(client); - if (index != -1) { - removeIndex(index); + synchronized (clientsLock) { + int index = clientIndex(client); + if (index != -1) { + removeIndex(index); + } } } protected void removeIndex(int index) { - clientCount--; - // shift down the remaining clients - for (int i = index; i < clientCount; i++) { - clients[i] = clients[i+1]; + synchronized (clientsLock) { + clientCount--; + // shift down the remaining clients + for (int i = index; i < clientCount; i++) { + clients[i] = clients[i + 1]; + } + // mark last empty var for garbage collection + clients[clientCount] = null; } - // mark last empty var for garbage collection - clients[clientCount] = null; } protected void disconnectAll() { - synchronized (clients) { + synchronized (clientsLock) { for (int i = 0; i < clientCount; i++) { try { clients[i].stop(); @@ -161,20 +166,24 @@ protected void disconnectAll() { protected void addClient(Client client) { - if (clientCount == clients.length) { - clients = (Client[]) PApplet.expand(clients); + synchronized (clientsLock) { + if (clientCount == clients.length) { + clients = (Client[]) PApplet.expand(clients); + } + clients[clientCount++] = client; } - clients[clientCount++] = client; } protected int clientIndex(Client client) { - for (int i = 0; i < clientCount; i++) { - if (clients[i] == client) { - return i; + synchronized (clientsLock) { + for (int i = 0; i < clientCount; i++) { + if (clients[i] == client) { + return i; + } } + return -1; } - return -1; } @@ -219,7 +228,7 @@ static public String ip() { * @usage application */ public Client available() { - synchronized (clients) { + synchronized (clientsLock) { int index = lastAvailable + 1; if (index >= clientCount) index = 0; @@ -293,7 +302,7 @@ public void run() { try { Socket socket = server.accept(); Client client = new Client(parent, socket); - synchronized (clients) { + synchronized (clientsLock) { addClient(client); if (serverEventMethod != null) { try { @@ -333,39 +342,45 @@ public void run() { * @param data data to write */ public void write(int data) { // will also cover char - int index = 0; - while (index < clientCount) { - if (clients[index].active()) { - clients[index].write(data); - index++; - } else { - removeIndex(index); + synchronized (clientsLock) { + int index = 0; + while (index < clientCount) { + if (clients[index].active()) { + clients[index].write(data); + index++; + } else { + removeIndex(index); + } } } } public void write(byte data[]) { - int index = 0; - while (index < clientCount) { - if (clients[index].active()) { - clients[index].write(data); - index++; - } else { - removeIndex(index); + synchronized (clientsLock) { + int index = 0; + while (index < clientCount) { + if (clients[index].active()) { + clients[index].write(data); + index++; + } else { + removeIndex(index); + } } } } public void write(String data) { - int index = 0; - while (index < clientCount) { - if (clients[index].active()) { - clients[index].write(data); - index++; - } else { - removeIndex(index); + synchronized (clientsLock) { + int index = 0; + while (index < clientCount) { + if (clients[index].active()) { + clients[index].write(data); + index++; + } else { + removeIndex(index); + } } } } From b8f3e42b6d58e980acdd341eb053b62b167f3649 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 21 Jan 2018 22:32:16 +0100 Subject: [PATCH 035/375] Net-server: remove extra array creation --- java/libraries/net/src/processing/net/Server.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/java/libraries/net/src/processing/net/Server.java b/java/libraries/net/src/processing/net/Server.java index d0ef757849..74345800ca 100644 --- a/java/libraries/net/src/processing/net/Server.java +++ b/java/libraries/net/src/processing/net/Server.java @@ -100,9 +100,7 @@ public Server(PApplet parent, int port, String host) { // which is called when a new guy connects try { serverEventMethod = - parent.getClass().getMethod("serverEvent", - new Class[] { Server.class, - Client.class }); + parent.getClass().getMethod("serverEvent", Server.class, Client.class); } catch (Exception e) { // no such method, or an error.. which is fine, just ignore } @@ -297,6 +295,7 @@ public void dispose() { } + @Override public void run() { while (Thread.currentThread() == thread) { try { @@ -306,7 +305,7 @@ public void run() { addClient(client); if (serverEventMethod != null) { try { - serverEventMethod.invoke(parent, new Object[] { this, client }); + serverEventMethod.invoke(parent, this, client); } catch (Exception e) { System.err.println("Disabling serverEvent() for port " + port); e.printStackTrace(); From bbfcbb322532753c4ba9e3dc36b8654aadca8152 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 22 Jan 2018 13:44:43 +0100 Subject: [PATCH 036/375] Net: unwrap the exception if it came from the user code --- java/libraries/net/src/processing/net/Client.java | 14 ++++++++++++-- java/libraries/net/src/processing/net/Server.java | 7 ++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index f179b6d2ee..2a779f96c7 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -155,7 +155,12 @@ public void stop() { try { disconnectEventMethod.invoke(parent, this); } catch (Exception e) { - e.printStackTrace(); + Throwable cause = e; + // unwrap the exception if it came from the user code + if (e instanceof InvocationTargetException && e.getCause() != null) { + cause = e.getCause(); + } + cause.printStackTrace(); disconnectEventMethod = null; } } @@ -266,7 +271,12 @@ public void run() { clientEventMethod.invoke(parent, this); } catch (Exception e) { System.err.println("error, disabling clientEvent() for " + host); - e.printStackTrace(); + Throwable cause = e; + // unwrap the exception if it came from the user code + if (e instanceof InvocationTargetException && e.getCause() != null) { + cause = e.getCause(); + } + cause.printStackTrace(); clientEventMethod = null; } } diff --git a/java/libraries/net/src/processing/net/Server.java b/java/libraries/net/src/processing/net/Server.java index 74345800ca..f77b2e0c8f 100644 --- a/java/libraries/net/src/processing/net/Server.java +++ b/java/libraries/net/src/processing/net/Server.java @@ -308,7 +308,12 @@ public void run() { serverEventMethod.invoke(parent, this, client); } catch (Exception e) { System.err.println("Disabling serverEvent() for port " + port); - e.printStackTrace(); + Throwable cause = e; + // unwrap the exception if it came from the user code + if (e instanceof InvocationTargetException && e.getCause() != null) { + cause = e.getCause(); + } + cause.printStackTrace(); serverEventMethod = null; } } From b5dd3b4328b3d87864fc8ddac1a699e6fb634b51 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 22 Jan 2018 19:34:21 +0100 Subject: [PATCH 037/375] Net-server: call clientEvent() of the sketch when received data from a client --- java/libraries/net/src/processing/net/Client.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index 2a779f96c7..dd03a0439d 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -129,7 +129,15 @@ public Client(PApplet parent, Socket socket) throws IOException { thread.start(); // reflection to check whether host sketch has a call for - // public void disconnectEvent(processing.net.Client) + // public void clientEvent(processing.net.Client) + // which would be called each time an event comes in + try { + clientEventMethod = + parent.getClass().getMethod("clientEvent", Client.class); + } catch (Exception e) { + // no such method, or an error.. which is fine, just ignore + } + // do the same for disconnectEvent(Client c); try { disconnectEventMethod = parent.getClass().getMethod("disconnectEvent", Client.class); From 1ca9c6283283cd38b325c578ef92b062b37ac37b Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 22 Jan 2018 19:50:06 +0100 Subject: [PATCH 038/375] Net-server: remove suspicious sleep --- java/libraries/net/src/processing/net/Server.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/java/libraries/net/src/processing/net/Server.java b/java/libraries/net/src/processing/net/Server.java index f77b2e0c8f..e027142fa9 100644 --- a/java/libraries/net/src/processing/net/Server.java +++ b/java/libraries/net/src/processing/net/Server.java @@ -327,9 +327,6 @@ public void run() { e.printStackTrace(); thread = null; } - try { - Thread.sleep(8); - } catch (InterruptedException ex) { } } } From 2c4d7839fdb2472f04beda561863f165ea126faf Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 22 Jan 2018 19:50:48 +0100 Subject: [PATCH 039/375] Net-client: remove unneeded synchronization block --- java/libraries/net/src/processing/net/Client.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index dd03a0439d..fffa2391b1 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -621,10 +621,9 @@ public int readBytesUntil(int interesting, byte byteBuffer[]) { * @brief Returns the buffer as a String */ public String readString() { - synchronized (bufferLock) { - if (bufferIndex == bufferLast) return null; - return new String(readBytes()); - } + byte b[] = readBytes(); + if (b == null) return null; + return new String(b); } From 759408e637151541644a147d9590348b3f33aed3 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 22 Jan 2018 20:28:09 +0100 Subject: [PATCH 040/375] Net-client: perf tuning - make read buf the size of socket receive buf --- java/libraries/net/src/processing/net/Client.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index fffa2391b1..61bdfa9bea 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -219,7 +219,15 @@ public void dispose() { @Override public void run() { - byte[] readBuffer = new byte[2048]; // Ethernet MTU = 1500 B + byte[] readBuffer; + { // make the read buffer same size as socket receive buffer so that + // we don't waste cycles calling listeners when there is more data waiting + int readBufferSize = 2 << 16; // 64 KB (default socket receive buffer size) + try { + readBufferSize = socket.getReceiveBufferSize(); + } catch (SocketException ignore) { } + readBuffer = new byte[readBufferSize]; + } while (Thread.currentThread() == thread) { try { while (input != null) { From e90cf63622a8a2ab9923343863e386933f04b979 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Mon, 22 Jan 2018 21:10:05 +0100 Subject: [PATCH 041/375] Make un/registering methods in PApplet thread-safe --- core/src/processing/core/PApplet.java | 69 ++++++++++++++++----------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 9d183b437f..3feb82b725 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -1384,6 +1384,9 @@ public void resume() { } HashMap registerMap = new HashMap<>(); + /** Lock when un/registering from multiple threads */ + private final Object registerLock = new Object[0]; + class RegisteredMethods { int count; @@ -1525,16 +1528,17 @@ public void registerMethod(String methodName, Object target) { private void registerNoArgs(String name, Object o) { - RegisteredMethods meth = registerMap.get(name); - if (meth == null) { - meth = new RegisteredMethods(); - registerMap.put(name, meth); - } Class c = o.getClass(); try { - Method method = c.getMethod(name, new Class[] {}); - meth.add(o, method); - + Method method = c.getMethod(name); + synchronized (registerLock) { + RegisteredMethods meth = registerMap.get(name); + if (meth == null) { + meth = new RegisteredMethods(); + registerMap.put(name, meth); + } + meth.add(o, method); + } } catch (NoSuchMethodException nsme) { die("There is no public " + name + "() method in the class " + o.getClass().getName()); @@ -1546,16 +1550,17 @@ private void registerNoArgs(String name, Object o) { private void registerWithArgs(String name, Object o, Class cargs[]) { - RegisteredMethods meth = registerMap.get(name); - if (meth == null) { - meth = new RegisteredMethods(); - registerMap.put(name, meth); - } Class c = o.getClass(); try { Method method = c.getMethod(name, cargs); - meth.add(o, method); - + synchronized (registerLock) { + RegisteredMethods meth = registerMap.get(name); + if (meth == null) { + meth = new RegisteredMethods(); + registerMap.put(name, meth); + } + meth.add(o, method); + } } catch (NoSuchMethodException nsme) { die("There is no public " + name + "() method in the class " + o.getClass().getName()); @@ -1572,32 +1577,38 @@ private void registerWithArgs(String name, Object o, Class cargs[]) { public void unregisterMethod(String name, Object target) { - RegisteredMethods meth = registerMap.get(name); - if (meth == null) { - die("No registered methods with the name " + name + "() were found."); - } - try { + synchronized (registerLock) { + RegisteredMethods meth = registerMap.get(name); + if (meth == null) { + die("No registered methods with the name " + name + "() were found."); + } + try { // Method method = o.getClass().getMethod(name, new Class[] {}); // meth.remove(o, method); - meth.remove(target); - } catch (Exception e) { - die("Could not unregister " + name + "() for " + target, e); + meth.remove(target); + } catch (Exception e) { + die("Could not unregister " + name + "() for " + target, e); + } } } protected void handleMethods(String methodName) { - RegisteredMethods meth = registerMap.get(methodName); - if (meth != null) { - meth.handle(); + synchronized (registerLock) { + RegisteredMethods meth = registerMap.get(methodName); + if (meth != null) { + meth.handle(); + } } } protected void handleMethods(String methodName, Object[] args) { - RegisteredMethods meth = registerMap.get(methodName); - if (meth != null) { - meth.handle(args); + synchronized (registerLock) { + RegisteredMethods meth = registerMap.get(methodName); + if (meth != null) { + meth.handle(args); + } } } From ac041b960673741a8c5666f2ae930752122fc056 Mon Sep 17 00:00:00 2001 From: Miles Fogle Date: Sat, 27 Jan 2018 15:22:54 -0600 Subject: [PATCH 042/375] fix NPE when closing sketch window on Mac (#5214) This fixes the first error mentioned in the issue, but not the other one mentioned by @christianbender. Tested on macOS High Sierra (10.13.2) --- core/src/processing/core/PApplet.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 3feb82b725..0f22490346 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -3703,8 +3703,7 @@ public void dispose() { if (platform == MACOSX) { try { final String td = "processing.core.ThinkDifferent"; - final Class thinkDifferent = - Thread.currentThread().getContextClassLoader().loadClass(td); + final Class thinkDifferent = getClass().getClassLoader().loadClass(td); thinkDifferent.getMethod("cleanup").invoke(null); } catch (Exception e) { e.printStackTrace(); From cf9b6ff3e944ef3c8770fc7e4c9db0200adc70a5 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Fri, 2 Feb 2018 17:14:56 +0100 Subject: [PATCH 043/375] Fix Net library buffer sizes Because I don't know how to count... --- java/libraries/net/src/processing/net/Client.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/libraries/net/src/processing/net/Client.java b/java/libraries/net/src/processing/net/Client.java index 61bdfa9bea..6e343f2c7a 100644 --- a/java/libraries/net/src/processing/net/Client.java +++ b/java/libraries/net/src/processing/net/Client.java @@ -46,7 +46,7 @@ */ public class Client implements Runnable { - protected static final int MAX_BUFFER_SIZE = 2 << 27; // 128 MB + protected static final int MAX_BUFFER_SIZE = 1 << 27; // 128 MB PApplet parent; Method clientEventMethod; @@ -222,7 +222,7 @@ public void run() { byte[] readBuffer; { // make the read buffer same size as socket receive buffer so that // we don't waste cycles calling listeners when there is more data waiting - int readBufferSize = 2 << 16; // 64 KB (default socket receive buffer size) + int readBufferSize = 1 << 16; // 64 KB (default socket receive buffer size) try { readBufferSize = socket.getReceiveBufferSize(); } catch (SocketException ignore) { } From f54ee983562d1059d9efcaaa2cbc48ca83c2e22d Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 5 Feb 2018 17:01:26 -0500 Subject: [PATCH 044/375] notes for recent updates --- core/todo.txt | 5 +++++ todo.txt | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 6b72fee7e7..81df909316 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -17,6 +17,9 @@ X https://github.com/processing/processing/pull/5251 X void cursor() don't work after void noCursor() in P2D and P3D X https://github.com/processing/processing/issues/5330 X https://github.com/processing/processing/pull/5340 +_ nullPointer on close button with P3D and noLoop +_ https://github.com/processing/processing/issues/5214 +_ https://github.com/processing/processing/pull/5384 andres X textureWrap() not updating when changed during draw() @@ -30,6 +33,8 @@ jakub X fix line joins on triangles X https://github.com/processing/processing/issues/5353 X https://github.com/processing/processing/pull/5354 +X Make un/registering methods in PApplet thread-saf +X https://github.com/processing/processing/pull/5379 _ make setting the window icon automatic, based on files in local dirs X https://github.com/processing/processing/issues/5123 diff --git a/todo.txt b/todo.txt index 2fb9a19b50..62f96905eb 100755 --- a/todo.txt +++ b/todo.txt @@ -30,6 +30,12 @@ X https://github.com/processing/processing/pull/5265 X https://github.com/processing/processing/issues/5219 X Fix error checker crash when className contains [ or ] X https://github.com/processing/processing/pull/5304 +X major fixes for the net library +X https://github.com/processing/processing/pull/5378 +X https://github.com/processing/processing/issues/4419 +X https://github.com/processing/processing/issues/5360 +X https://github.com/processing/processing/issues/3970 +X https://github.com/processing/processing/pull/5389 contrib X detect errors from curved quotation marks From 8ff6fb6b5c1909859ee140bc37f4a73e8ccf2802 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Tue, 13 Feb 2018 02:13:45 -0500 Subject: [PATCH 045/375] cap framerate at 1000 in OpenGL --- core/src/processing/opengl/PSurfaceJOGL.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index dd7a1d7674..17d2d916eb 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -815,8 +815,15 @@ public void setSmooth(int level) { public void setFrameRate(float fps) { if (fps < 1) { - PGraphics.showWarning("The OpenGL renderers cannot have a frame rate lower than 1.\nYour sketch will run at 1 frame per second."); + PGraphics.showWarning( + "The OpenGL renderer cannot have a frame rate lower than 1.\n" + + "Your sketch will run at 1 frame per second."); fps = 1; + } else if (fps > 1000) { + PGraphics.showWarning( + "The OpenGL renderer cannot have a frame rate higher than 1000.\n" + + "Your sketch will run at 1000 frames per second."); + fps = 1000; } if (animator != null) { animator.stop(); @@ -1220,7 +1227,7 @@ void set() { } static Map cursors = new HashMap<>(); - static Map cursorNames = new HashMap(); + static Map cursorNames = new HashMap<>(); static { cursorNames.put(PConstants.ARROW, "arrow"); cursorNames.put(PConstants.CROSS, "cross"); From f588ea88efe02dc7c9c3173450449169369092e2 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 14 Feb 2018 21:47:21 -0500 Subject: [PATCH 046/375] deal with quirk in extension parsing when no extension found (fixes #5326) --- core/src/processing/core/PApplet.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 3feb82b725..d8bcf61ab6 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -5381,14 +5381,16 @@ public PImage loadImage(String filename, String extension) { //, Object params) int dot = filename.lastIndexOf('.'); if (dot == -1) { extension = "unknown"; // no extension found - } - extension = lower.substring(dot + 1); - // check for, and strip any parameters on the url, i.e. - // filename.jpg?blah=blah&something=that - int question = extension.indexOf('?'); - if (question != -1) { - extension = extension.substring(0, question); + } else { + extension = lower.substring(dot + 1); + + // check for, and strip any parameters on the url, i.e. + // filename.jpg?blah=blah&something=that + int question = extension.indexOf('?'); + if (question != -1) { + extension = extension.substring(0, question); + } } } From cbcf5a7a2369a1aaf176c48a1031b63af853b0a9 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Wed, 14 Feb 2018 21:50:21 -0500 Subject: [PATCH 047/375] note about fix from andres for frameRate(1001+) --- core/todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/todo.txt b/core/todo.txt index 81df909316..3272eb5301 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -24,6 +24,8 @@ _ https://github.com/processing/processing/pull/5384 andres X textureWrap() not updating when changed during draw() X https://github.com/processing/processing/issues/5322 +X cap frameRate() to 1000 in OpenGL +X https://github.com/processing/processing/issues/5404 gohai X ARM tweaks for shaders on the RPi From 7d3c1140cefce914094591a0a655c0556ff3959e Mon Sep 17 00:00:00 2001 From: Tobias Pristupin Date: Tue, 20 Feb 2018 08:30:45 -0500 Subject: [PATCH 048/375] Updated comment Comment said function throws RunnerException, but function throws SketchException which isn't related to RunnerException --- java/src/processing/mode/java/Compiler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/src/processing/mode/java/Compiler.java b/java/src/processing/mode/java/Compiler.java index 27c5c1f8cd..b68e6df738 100644 --- a/java/src/processing/mode/java/Compiler.java +++ b/java/src/processing/mode/java/Compiler.java @@ -54,7 +54,7 @@ public class Compiler { * @param sketch Sketch object to be compiled, used for placing exceptions * @param buildPath Where the temporary files live and will be built from. * @return true if successful. - * @throws RunnerException Only if there's a problem. Only then. + * @throws SketchException Only if there's a problem. Only then. */ static public boolean compile(JavaBuild build) throws SketchException { From 8a6b6f204b909839844d0affebe244a040ad3288 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Thu, 22 Feb 2018 11:37:40 -0500 Subject: [PATCH 049/375] notes from recent bug reports --- core/todo.txt | 3 +++ todo.txt | 35 +++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index 3272eb5301..3fecc039f5 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -6,6 +6,9 @@ X set colorModeDefault to true by default _ add circle() and square() _ add push() and pop() +_ Table.insertRow insert duplicates and cause ArrayIndexOutOfBoundsException (with fix) +_ https://github.com/processing/processing/issues/5406 + data X added setIndex() method to IntDict, FloatDict, StringDict X added resize() to IntDict, FloatDict, StringDict diff --git a/todo.txt b/todo.txt index 62f96905eb..a4dcbd9745 100755 --- a/todo.txt +++ b/todo.txt @@ -5,6 +5,22 @@ X the old 144 link must have been removed X NullPointerException in ContributionManager.deleteFlagged() X https://github.com/processing/processing/issues/5342 X move to Java 8u162 + + +welcome +_ just remove the welcome dialog; but what should the default behavior be? +_ Welcome dialog rewritten in Swing +_ https://github.com/processing/processing/pull/5210 +_ Welcome screen doesn't size properly for HiDPI screens +_ https://github.com/processing/processing/issues/4896 +_ click "show this welcome" text to check/uncheck the box +_ https://github.com/processing/processing/issues/3912 +_ submit the form (as if 'get started' clicked) when closing the window +_ whether hitting ESC or the close box on the window +_ https://github.com/processing/processing/issues/3911 + +_ windows defender blocks processing 3.3.6 +_ https://github.com/processing/processing/issues/5329 _ Rename dialog is unusable on high density screen _ https://github.com/processing/processing/issues/5368 _ change up the newline handling @@ -18,11 +34,11 @@ _ move away from using a temp dir at all for sketches _ -Djava.io.tmpdir=Z:\temp _ add pyde as a supported extension? _ https://github.com/jdf/processing.py/issues/284 - +_ “could not move the contribution to the backup folder” message while updating libraries +_ problem is that any sketch that uses a library, the lib is stuck as "in use" +_ https://github.com/processing/processing/issues/4973 _ an incompatible Mode prevents the PDE from quitting after last window is closed _ https://github.com/processing/processing/issues/5112 -_ processing.net.client not working properly after a few hours -_ https://github.com/processing/processing/issues/5360 jakub X Fix scrub comments for empty block comment /**/ @@ -47,8 +63,6 @@ X Remove "Pipe Organ" from exec javadoc X https://github.com/processing/processing/pull/5282 X typo in Italian translation X https://github.com/processing/processing/issues/5365 -_ Welcome dialog rewritten in Swing -_ https://github.com/processing/processing/pull/5210 high _ menu bars broken in High Sierra @@ -121,9 +135,6 @@ _ already reported? _ swap font smoothing for tab size? _ implement simple table for prefs? -_ Welcome screen doesn't size properly for HiDPI screens -_ https://github.com/processing/processing/issues/4896 - _ "Sketch disappeared" infinite pop up dialogs _ https://github.com/processing/processing/pull/4808 _ https://github.com/processing/processing/issues/4805 @@ -286,14 +297,6 @@ _ rather than post-compile _ https://github.com/processing/processing/issues/136 -welcome -_ click "show this welcome" text to check/uncheck the box -_ https://github.com/processing/processing/issues/3912 -_ submit the form (as if 'get started' clicked) when closing the window -_ whether hitting ESC or the close box on the window -_ https://github.com/processing/processing/issues/3911 - - fonts _ fonts are still really ugly (on non-retina) _ may need to drop use of Source Sans From 5729c6b78f7eef6b18c6de83cb7bf9a66e4b0b63 Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 2 Mar 2018 11:13:48 -0800 Subject: [PATCH 050/375] Fix 3D on contemporary versions of Linux (fixes #5308) Compiled from https://github.com/gohai/jogl/tree/processing at 0bd5acc. --- core/library/jogl-all.jar | Bin 3400609 -> 3400637 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/core/library/jogl-all.jar b/core/library/jogl-all.jar index 970a7dead98b6a4821358b6146904bea5f8bf4bf..8925b007a3494384d816ad38a0d5936a6fd05eb5 100644 GIT binary patch delta 90630 zcmYJaby$?$_dU!EFhhrQmvlEsNq3iYcM1Xz2#iRBG%}<#(jna-os!Za(xK9g@7#Xg z@AdnGYq8H+XYGCV+56o0%mw*F-$0#+9}+E9WE2b}Bs4T6^;gzv@Aqh$BS1(MP+Tda>+5N_$kZbnc=y?>-e z+Yyn!_Gx!dH!r!6RKMwO8|`aZ2ia5Cll?crr4=8sA)IXwyd=VfW6SiSe%CJogo&sf zk14DsKpm8g2Q<=boGtiRZY?4|yq_?H-|McVh3ylS=&e#}l^DHoM~6RxQ=N$|UczFi zcgprP^E19>+4q7N_qJL(iUS6ILH*8u+OH+MP3GrJ1mA*OEhTa4+g|)lnJ!*~vwJM@ z=U2M%cw7`!1m~I>HosPzZLDhifHyX>BVui4X4CLO9a~4Whm_nm8qR#JrzB?c;E@O! z3mE01B{Iw%6Z{Pp`fuDsVEjMSK`Z>*!L~ch|93uMkNN@7TM)>jUK%+VjDQ|gdcgV# zVFN52^hOLU4+2%iekHa6BqXHZ6uLN?lwSk~h`B{VG=TDhm=KD9E2{rc5#Yg~hlY(< zK&-GO#)XW8bPIvM_61R=&{E^pKeEds19M&L$ZZi|BqSo#l%y=`dN=MaK!<~m9|ZxH zLhJy1c)@~3#$Onic#!zHEpZ!v_EJ z2iNN2#j0P_lLev3A}X++#^4(mANVbJ-9Nzt!7E1i7fk6j=Bej43IX8&Q{yLW!54_( zMb!UE{ORE(fNys5qSap;KY{hR(}7-vmv7Z!deuq z{JM#t1*4`+5m5h&3U1QNi(PL3I|2iQa_k(v7DQrkLGW+!AZmDZFE4pY#QQ$P)>J}k zfRnfjn*`D`5@`aYfHC?H!XS>>0;XD=Sa)fRfJK{W z3sAzdKK%3A)e}j+iSSDOzig${WD%uke>z1lWOI!GVou%|aHvkD?SREtE(d5iSK0$G zUA+Q8Rb2`R0;ET-f%6ib^aPmY-xg4SZTT^MK1W8R`NRLeE!t6DRJiCEFH!yA91cL7 zpFaXbdKXLoDX$cxBP_ffTEHvs@eDAC@>>N6UGq$w8069X0S%N2K_DG2=mSEaxf&1D zhH%{ML~UgHFd70?X+VvD4Wa|_0`vTgpc24dW&%ASTYWDeMWEJ54| zgwxuA+7RZ79q0&HHsk~v1TfwW^c@Jx&KETCulPNE573Sf6%qQcF*uuD13+Ma=n(|c z0{r*DKubn}N^}sq_W`mBt9q3j*OZ&xC`>0M>B?2>$Ox*@eDF?4ckb z`C+E?N>Ib6mU!u#r=me;K!| zM9)CYz`D~55C@P^>U$6|uukv^1QcpBBM5v0@Trl(nn0NDQ1A<2z6=BWFB5lI;0|EE z83*i#sI+EoCU7~xTV?|nBf^Eh;{*32OnH8A7%)644CVyzMhpy;X|shS*a*PZmtZ2m z{Wk@$6=3r!gIxjqqzbnASF8FDB12QpkdQ<<;Yp!j8o1^zFA4lCEc>uToK=pTEVSpDN3bqG$$C2PlAX6Dh z;86(B9y?Rn=1k6$vR43(gBdsNwzLrD#Up0qX-QMu*^apk_tR!K=Ul5M6>l0xA`^U>G8{ zMt0<7AVdfh83Ul>VatpwtibsA0@O%@ICjlM#WMoIcu1-ZR0_JtIk-@;} z7!)H%N+EE48#xrP#riC@i5w>E+EWDdsKH|Tdp3c zk3c-muTg^mJn%xj1KN1|J?a>c_S!^LJ2nIox1;g_^U58l1OS?KqQ(HS``xG)fW6j> z+Vt;{jDEk5-AjOk6wU_+eTR_3c_4ha@Wf73)aLO%)ENQ1#{zaJnKT!kzDPnG_()pqxA<^Q)L4P2m&7?c1=|JdpC#bx@$^ZO= zdLfR$MNUXP;zZ#egdyVyFcN{BBSzIlA#8y9e=i`!049h*fahlOt~kUM9Z23MQDI^x z#7!#*hHGPylft#I`RJQ76d=3+YfKTM3Z#KVACe2i+-wLb|JRsNFyW#w#Dz|b3Qugt zBZXVy@?kY68${%N~JrH@ME5rn_f4W2L091Yr`33Mq zydkJSvL$mMIY4Gs^C7$cE~|QLzI$n6B%}!rpbALS3LvO(w`Y8K%?~9IHJ~b$J0TN* z0!cRn1}MUNA!dY#BwWrzZV>S6J7fhhI=TR{0cwH+ctuos^ogot&GC(tfnTb1b0C!n<| z@S$;loG2mmIe_NG(2IX3=}6wA#Ep<80mDzzDX8Fo$)MP9V=}&H%~_<-7YIf8cQWWb zV#N$O^b6o1oDymXJOtMGp)!C?D+qN1jyzrjdIH#iFQCT&I*CJT0VJ1%o&kvc5{d(O zrj&su15I9|3f%xOK_99KTn^Y$qr=KEiGefR5n;#h_@Lv?G9xgj7ccf4x9P z3h!}(LYu2&plU!7+{2-N0QKVxr~{y`mkpIewEpLe5-1QJj(M3t0-QKA6B-}j#h3?80@y;jG#V=u*g_}OyRJ*bWpD|C<5?iQ zyi`HMYra=PqX1$dQ9;`R)b9+@fcO4pe`7Rt1_TZTp)~;s3XVi;CPkcsP#)SP!sN(D zJ3uV^Ok9Wtq>ZEzEgev)Z9@AE#Fp2FM*puHmZ`g)iV)p^h6?9(eMSiHX+y(@FR=09 zH=}l<)c}qfyU`5)UDso1Bftf>FonkUZz*%&qPQqxDJBXWgo#cJ*8(9LiDwq=-^)PA zJemrydVB#*jU0hwXK2rX03^@RssTK?Kw|}vfH zE{cXDk9gg`p5<~uN4S$if!C3u(>I$Fpp%3D&CI<6=>e~3M5zB}V0>IQu2$aOL3&2I zvs#2t?wIJQ?;5oTL3U*`sH|UDRE?aCICR7CBdh{34|4F7QYO`7&it}p2hNkd9D)X2 zE0*n*j7R0EGw+Q_h;B%XJ3vU5y3Rc3Ygn+O7|737k_@OH;oJ-BD0=xYl;81ac82R`#>GKMPqDk zot@wPW;-*WIMb(MmG|U0piB#w)1drH9Cept=!}FcA{m<@c3_TLR=1baJHmu<><72Y zM`SMFOXMtZEA2wBw&b#zq~HPvw>92+6R6_qA6CWt_!^3#tN@rG8qSM=66=V3pCLY~ zwHowgs}rXBU#BhF1Zl9$HRA8lcHSxQ^9Wadzmz(qC3-P;b<)6zWS@bjLu<8Xr4RZ; zwPxSE#?^n(wAm5Wlkf7>a ziZN%s$*seb5=#KXW@mAH_3^_KL|0vn$5DRhM}g(hr=f$*f`zx%EgSz~Vf8KOR%X8l z7~oT>ersCMwdwm2Gh$Lo>^C*Wwff^`07dE$56eKEdB8vpABpL9&RM{LPT(b(*1&}F z%%Ds1OC7fD>XFC4go()^!g5y$S}*$D`@UDHtT!n;4Xv2!!8mHFZ~nV=elVVB&6XDT zm&d+b-qocjf~@hh>@hM8Ieia}6YP5Zk%tl854E}V*C|D~<-4veoWwM|c!gqHq_2yN z$?^O3xYJaM!t!hRpS6vJ@qLT=_bd;(yu)T5_s~8|6&?`WvQij@i;Nu!6N#B1vA|sji-WxK{1_~gXP<_>S+$zBYl99d~QrI579Nz z;jwh>4^rP63{PUu*m%yhiE;k2uo_nO+;6fUf5(3z_5yL=}xiTcnh$MFFA?d!hG6)#)s0b*Z~0Z&aSp7V*@lg}{Swu!{d zOM~d+9}%24m&0a1o;bY+@|9*1Q2O%B1F(gE`r`Mhm$Et5?L(fPDP`v#srG33b^0-uK50!Qe#jxbtPAf8OK_lX?8`w zv31_Gz1r*`|0V&CYttO4aO^}`=An|aR#D=z3Rn;U>bqxf4=kdNifBSY{{{$-Qym6PR7kxrq= zm&tN`x$sfs;glO|O|K$22Tb`d9c6xHVFS4$nDq>KM|Z_?=hW@_=;!7n4p{8m0-*yb zQx+ZWCG(f(eP-JpVS2-`%*s?6`cpKgfC*~)*3j|!?YUt%3z0&%jCKTum==>RpNq&P zng^rSl1u>KqkOVk=R+OxB%f=(AK&@!1<&2nVH_{qs2UC21IE%}D;T-Ya$S7!BD1wS zNtr{bW};Ru{bxzp?mJ4G!*5gb7M{|NMDT;R#*b97hcu-r-Re*Acgzat_mX_vJj0}K zqY0GQS*CP)Nrx%#DUP{|jxge{w=3qZqu07Hx1Gq9;N2ltmK#wz|1p`ROO9E1z} zY8F(0glUb0WVwI@57D9_fNK$;W5a3q_#p6abm*k8(q{s+&uCu?JWtm`(KAg(HArzC zXClPBGS8K$3&E(fltq`;tGz$&ysoY>T7N4^v@PZEYb{e9?e~56U&V~Kzf<`gCbM7I z`9CE@(jdR9Q;5NYIDgjh%A`nXOwHEFb!fTeJ5dV|i%qUyzhW=>hDxoj4!vlaIE3pQ`3>I9lV8 z6C0W{K3Lj~Xm6w_9gMs1PoaPiq-L%0tVVcYG9F>MbyA!)n4oXF>G?AGcr(%Yi7`^3 zeT9^_B_;c+{L0(bQ2E8z*nZF&o&1)i6`p+00&C4phB^*sp$~>eTqTydz3wAC@oN5_ z?^e7uN$8e!Ra@rvd5Ag$;z1pj&fGJO76tC+LJfwc%N2S*1?h*5+zo0vt(-k(hSW>0(p2A?yd9cbFK+ss zu?)Mvc<7mveB(mnMAP1=*`Qfg|4r@0TlfBbPoT137hhvdwE2dX;YQ}NU&)mO(bK@( zle06dkPRl>2-EtGTXMw!x*x%gZOBzW$<@2zR(Vn%;T9PEt3}hDx$IGL)n0bO*SMy4 z>!o|&H+Pi|E~VG72)B&bESXZHtIbF(nS!ZXZK8!MN3)0Lu&<^TZGOPO%!-zbDp4vf z;+9@=jSQKUZr@h0WYnxTj%?e5XY7-TbDm+Xm8bNv-A=Zy4tV$${ zj$1<)QQQ+`Ev0*`*|H%gh?}?lQWr~jK>8vxwlfOsv}Y8rP^(_y2U%@)BfAC-X~Kga+hv)nqgXp|d)7R3k=A^hFi9* zbxmb9;5uGpjBs7AaMmZ=7EUyx0OxzgoPrMe2rGvnK3u~G{S_>!+5l>FCEn2@=}t9#5d zprI?Sf%J)IAf@ELQ9@0EFbB2MO4d*O1G(y_9dzcj0o_VSM`-hK7XPJi|C*_l3cWw% zj5QQn*w~v}s!F5l{R*W$wckzju9_$!PvcEG*w+iG*FS&5Ww}i}ljQ3kf|b~lZxP(x z%@MM=ITa5bZOvkM0p>an9v{iMck}U7{qqB3|I_oV4eC2i^)Iq5lW?R zDVATPum%eaNI6wM*~P%Jwn$_jpr>LkcpslsJVf13vu<*d%@8O5T<+#XXn;n~C4sd! z70ZHAxY%CBO2tWKEful@%P4u1G2=E$sB2tuY%{8-dnIU>$vUf^VKu5&K9Acw$`LSD zQY01gp3+hUHwa6hSY}U5cX#UAa*I@IMjuByE9wJlWaf-2W1m`UF6*^0BP*VN9&2RQ z8LjMY+mi3L+c-TH{dws;YRNca?wOI}Xi^EK-SBh?rOjxa`&9#sGBSE?+wzXmW0YQ2 zgJ*{>)u)s-R$X*DHD&*ZM^{5ZCI=KY{Uen>Jo#C+mFRrxteR+!g09L47Cf8Pp_P|a z);>)!{YOLEt4`WcI^LB<#ItUT;AZ*|dcsYP0$EF2>CXrk&8+-IXd+#f`jYkN#}ZS!(fJZno6!_?{}@(H!5ya(Q`HF#;T^II@!3>| zj5AkV`cHc^c;95ZQubz7P+8W`WK<@FcjQYt()qaQyy!tNZowV9l8)6>!%f#=sf;rf zUGs1P_8Ntc%r(3_jU^qEsS8B%sJr{ucZ4VVM40~GjT|9 z8CxkEgdAEjFrK8YN{{5EuG)>ZmwjbY8SYNpwiv$OKM&TGd}-~EtiEg?;8J)DW%Z9r z=5%DVi)3wvJ&VanbuHYsYT)(~V@%MJxssJs@IYMj%2U*uR;t?s7q`!YBzMv@#~gIF z>(4~lZumPTH0z(hL0w9@+)0YBCzgev7Qpnr$_cvugzcTZu1}1Cc@%_jcWd>x`-=37v!MPUt1+~d?lIG z`_jVAEsu=-{;))_=F|7>>*=8nFE+eThDS+lt-N8#A?!v6m~*#jkVEi<3+eX9Ts+fX z6&{pCt{1`_H5B@pmCFJa6Btrg$#os>8oIS5MNLg3G#C??oK@%iEF3lH-xIv@IBHx@ zxvzykz?_|(9C7CE6&Vc_X?M@sZl5BSX>nFNJE}1(9@XW-$M+TeJ&9)eNM!c8%1;t| zjm?E;H^e`;mQ~VCedsgpr`5Mxvh4wni@%r79OaNr=DZfJ(p$<rZ4=Z`?S{04acjGJD)^N0J-3D_SJ2UEv zSZ>>PEI(UP(%bOr){P_Q!fq0nn@l$rU07&XO(5KgeZ9NZ_+;0W*0y`g_)+O$nQ4RV z?Rwi5?;0z6g-4~Vr$LMR#|^`=JWX1?wV8%-!=E*M@kuOkA@fgd2VM3S2Pzh3m^dKz zOIV!kB%09tJzk__Qg*8gdELr*W?BgoOxF97&4NK)n?OiG4Q`W6HKvSTiI*aMsX||} zr1R4An2Zhgdp0RIp0A|P>9Ts8gF}D6`@#%mDTUw|iE)T^B(~Xn$PRYbZW>eNYrO^X zlr|NM-;9oYU%yrQ6^SVbkdB|2Y2MR2&B2ViJslK>F4LmROUN$eh%^{g$j)e{dD%<) zTG=z-S5Ss9(keH6zu|iLIgVTR4YbB0W?eBAleW9OSq>>5dO1eLn;Vi&Tq*zlniE&x zhTZrOewRggQlN>ESF35yBiif`tUfA+qd-s=E9smb1%Llxnh%mh%EYHsCe5~J9Sfgh zN5_XLcl`jT~N z$4Bh?oZ!!b1;(+11@jM{K8BDJ+Q>QL&G4}HIG=Hr{1zLx z}QDQk*lKH;JfkP-_1{dbEH5$qc3}T3q<#d}?&m z+GNuusJ2(g1xL%IU6Vs~bjJ$%r!?*5Y;=CK#23e{cUt+`k<#MM*-WsRA91 zA)zR$GEjF>1{I`VHi!7baTfprKilJa<+Fj&>BFPk(Grm@Z2PfQ`i3F%zYCfgQx}Uuxm178g7w5!uMGc1)x6xR> zRdyi{ybQ@av;5PaHfZ$JrZDpr%IKZYX3%f0xII&JRqdX3rqZ7LpZPCIb>o@%q+tLDVrzkd03caXt>Sy*zCvPV?hG=;Uaz2Fkon6 zvPM}d`Z|u!iqWSc&;@Vq>))icgGup%K}8pSJXFqn!ySgrMK>avjhNnn`*=0KrzfmR z3Rj)#eK|YhtF<>RhBq?&B?ik+E2XA0pF6QXM=SD8FG3CP^cCE~G~ax&hM@#WU7)xb z&hoyg4^(fgn8L5t3Fcu_KMVg!ltBPlR9gNITV-oS(+z!Yo^5ahE9_ZISpReOjCfh! z*4{)K`a%?$XofYP2peKq2DPg9Jz-xU$#uqA=u}r4uULQ699D;= zyL3G>fjVAhMr0DH_eNM^rrC$nNA>Sqp9?S2DREFcc4%3M`A`3G`%jo%q^|MUa>Bsh z49QmXXi!5~Aijjw%MqsGZq%>thK3S7;RasD5Mf-1M<1Ot?Ea5--~T=K9!X@#2Rhoz zHRJ=g)MZTJMwdOCvhzPfEz>shJy*Yxpq`qzKo#zd3@49dVBX{G+Ie!?ftT^Ysp8qJo=~1T0Kw)GqOQAEZW4MQ1 z(`U7Drt92l=wlB%oxLTCcoOr83m{Hg~PS{FLZ+T8GOYN~e zgBy!f##yC{eO=?m8%oJ_*2Qu)|*)j4o)Yy}xx8CgdQh^24dBn?T+YV-* z4S#TE9}8|DrMVAlVy`v4f&Xf{AYA+UWpjoA?M+B?iNB!GzU=5Og#^)rA}D#?++^^f ztG~l-#ED)kj;79i^jAp9Q2!nX3NWGoaw6m9$LtcSJE-p zHqv%JO;A33`cPlxaIloNp1TgwO8N1YW_)_+8SE}VX=iIJIv7?6hlII~zd2l8vDf;X7}dO;h|da3p**}^2@zL*5(Pt?GhO-j_J(57QBM}B zejzy$-01HiYyJ;JhkZ*JgXTHHf^-5EdKnBbqPlX<+EHj*}56% zVJL@$;6d8rst-Iqu4GrPG2xW!#m7;<-Ph+;0_f2 zH4HhtO-j>_Wg8oKCA1ME{XY>eJNj4U;jqsuMqh5m9vF|i-}=Vq&kaw<6ek>-?G%>z z4s@J(dHmNRqBzUOzMDoZ;ioLWv&uNTtFQmjU|fHTrv}b5L_7Y+lFgGx-(~?ut^1y|PYK^mxL^8z#~k6gP>e}v zV3nNtbdofR&3}=UCaFT>cB*)5lO`GQkRki_M=h1snrUoAmy2tfK(4q~zinmH_{@+` zX#BGMuW8@GiDi*z38;47pC@$cQ=^?&2HU9-A9ZGMzYm!N;0FlYq3B%xd>xZo0Q)nz zpHx1>pz?WwGw0U?qxsp3>|N~q66$xA7as=fpU{5W3hl>A+pd|Pa*;ZQiSNt1k8I>kO+IK_^A zn^yddZsCNbGbW@$2v0|qAgab_(-B*>=KCHWY0_N%h2Sz~J_uG?+0|9NbcF_!`o3os ziqfG{Uc$5)p4Qd&rdoI*(Zl#I@TqbDRv5xPm7vfJtEsAZU~bI2r1Q`WF5+&ukiWCO z;JR9#T(27NzyAPpcY-=X3&1D7A!}k-oc4K;94cGSArX@Yrr`Qwno#dv*i=H}#ZO0r zwEZE5@AtLpANW2Onpu=Dyb6GE;+S6_jkQhMC%=YIa%F@PY)8BEew;5DrfZrE;Z(J# zuHo5UNu!?9dt zS7D#2osN_y@Vb-^hx!Li5Q^@rZ%;tsR-uXOt_PfVDuE0p^)Vg$+f*>URIZ*M#aeiY zCKQhDIPtX?^DoZ!NA6f7g3F6@6$*`1M-J}DB7#ebbLE|1ADb&1N;DT?+{UF^?Dy|l z78=S!N!<;8nrwhQg7WAVx90{aMZZ=w%q_Lq9qefx--&G?@Juiw_*1b(o`vH+iP7D_ z9b;N>S#UfP{Hg|0Nb!x9ylN==YN zp<~?Yk%%h0mPv&192?HTI@qJIbHhxBb&vJCoQ;h z-T8Fw0XG)b+pPy0G{0j&4Yll=T?x=_FYwY}WtH>bk`FQ`gc%DZFWPP^#Z1TRQ@i;^ zLTd|*TwScgudz!TFghARA6k@0+AurV8QyHI52OVb1{1XDNFd2^XV5Fl<5F-vs~p$9 zE$uCQW5~;VIu7bI`XYP!ebDG`qGNr=V_JK!nt8J2WAaLrj|X!aRiav1JZBZP%K?Rw zijdBP?<0r?Wmu6 zk4to<&c?9Hm2DLC^~BDklSR&FHOTZf``@?eq#XMi9#iM!Bs!IR^odk?m}v8rIR7j^ ze2PV;3L(=Ca2A9Puyf=c7HQ-SDs)U8S*%6zRhr_4k-7LJH9P6_Jv(w`Wk{11GSML>2 zh(nD!k@?&S`K(c%;q?8;07I$3g7w0AZ13w>L{D)#g&^8B996nFeyS2Gv3Z$a%;%~xaQmYN!<(PJRfLNYL%}@Fmq&S?;4X!DV^oaOtw?BeCb!_v<&?RO zsAc4L7)yVgqa15neZw<1w!v-*BvPuln-2c?^1M2lX%{vo(bj^k93~S~JaA|OWvs|3kn^tuAx5#+VTUyn~l@F4Q&Xg(IgA>_md{SZP)SQN*_ETP-+bk9s~(#CIs#T$HF z<*v175?+#caTIros#-K0WbI*#RN>zu9GnOmWw%^DMAw8EaFx`q6mWSey4a9j44sY6 z9Ksmo!e0DMR=79-vuVxb%EOHL1>waXbuaEHtBA0UjN-NSrv>H6xjvr=Ki|xC!oT!? zM3se2&sfmc9NSUpf33I+A0DlLq@(%nuMVTS980CW{|rWBVB-qDIi}p3^_kBUXF)rExte}AXs>P# zC>A{fOAt%!Fg2|3(rI+3YZdZjt9P*_-@4JCBawT2tofdB`*ZLE^$B)v4c$#x0HFb_ zjl9OMd}Cpo^Ezk$T7z-trH?gFP~^Vbc>Y_T^NRgJtDsJ7%k6Y}ENDD6|KQBV{Ad2* zc*_WXe6&c`%U>7%i(4Om)TtB~Vn0f#!g48(r0c5o^1XlMP@B%bGY{V|Ofc8=8_Nn# z-p$xKb%?Ug$7ZkM>an#KrTcLa7h=N!i?I!%zqH|-?I`T%cL>*x$%wIT)n`bYeBDPy zv@+$0)>L_MZ|oURM>|txE&;P2X*nojRT$8@3H=Z9br=^Lijna|N7T}{(I5?%XtcXM z6P!(K&2mNhVZ&9eLNoDjyfAITEcR_KScDb#^ z_}6?hlM9_*yW^E|(I9;2UF24ExJ;UJZAfcN*~-K0fS62lF#biIUMv z=5ZX{CdM=qI=%9^)FJsWhl7nH7_9E1`w+II`cg0+T;4svd8396IeL(stA{BvD<6Hn zY-~_=bZ_Y6VVh%`UHL&s^Arjhz~Fp@J}RoR7Z03{IdcEiF)n?G#^BGs%@4|99GlA! zRsEYGRQ(j)*l4t@rpi8xc&5UVoKM60vdDDVJ0}iHN=b(Hn1}4~FWb_SVKx^qlRNG? zDYt;5?z48zlUH{Sal{p{&mCrW?y4sFs2q>DcdIt)9A322bia_+{qx) z64N}KeZ}+P2Y7Ecl6qVIZr!P@&SVC8VapDFs%{Hs7RQsr<(zt%R4}9Q^X=Py{5oUe zSL@H3#2Kzn9BqXoQM0q~OJVDUVPz#^9b~*maTCFfGm*~hFLs&!etD7FuU-E*!T!GS z^$C&oc>s)7cqt>*R&mw4{XJHM0%Mi)0QD>mOkt31eqzi$est1-r-32@?KeptzT+7; zvxZjl${Zff(e2Z!c}?_TzXP_?@K^IS?I`LezJt}opg6%|QIWCk7izG%%GGTLtBGC9 zmYC+fpH_#K)bE>xMVwD&iFcmtCd%y+7z$*w_ewS#)BA>kvd;;vcw@S! z_bD;uEh;tEkU92$p-~Y0_9nHXafVACdyo=$gDldv(Cp9W6KM~f1F_d z5aU!5dVBs}+U?tW_c5n4RX^pjl?e$+JyZN_-N431ZIYn|e^WP(M82r@5eX;m$_^51 zws%(ooM>}GHMI`QBN;om92U|uVQTvLA37a!H7bs=Pt_{i2VjhT$v7t=`T-X;*%kz) zgROrUvg_`VhTQpI(}*{Ca&!5t^;~_wDpuS(iw%O)jiB1@d}(p9{*^wh*e^!DzLMqa z&TO-qJRMbOJm+-w4Le!x3J2v;0lbv6)I~6yqZa#gp>dPE2(*zTYNei-?{I#T=dLLic_FC@R zucQhs;sLu3%1`>?AjBt``bYX==N0BgcD(7N^Ph#q0(qT1SIx2m4yTuzQE9iN#|!72 zuJ=qkQLEd+V##D7l|_N-B;41J?-#A_sqg3`2@bH3LK$FBSy}dWYpYv))5z(+D_rOn zn!amVzxTE^$qxKd)7eF~{Pg$Q0WSc3)R(`H!q>NB-10*5kuB^jP{&hpR}dw!c+^pT zO44ylFAALmGO*gDA%elLo#Sg>IQQ~F-)&rnp8(yi{%1@d9oL!$LssFoKH>|UlHghA z8}p8fVY^^hRbBDYllF)HFXmvSd<$i^zKmC9t!irpha>$1_GI=o7RlLun= zwt_HR?*_{rW}KH_SCnUK8<@8h6?Ie=wN+Z%&)7Wgohtn^u#C)BadKZAa3hcSoMm8? zv--l%O@#N!S$!d($qyg$DJx42oe?!FKa+9wKh1T?XkQ*IVTG18-%zG}-XcO7yUXe6 z4XO{1p0J6l=_XHXf9T^D+DR=+On~WC18r6B?zYBnW%oPX|1vI`jd6ZGotbMQ>86_0 zFV`_2zHl~rPp;IWk$zF_MQEwF?pTL}&LzLIo*F)ZD> zW+rs~NFw!S>SvAO^V7lOKd?+byZZrdi!eibZKEaO-!sk_Vh+^xP(fwPt6Jvm@LYiM$W;y#^gc1ttlef|^o z^10ERah@doQ?jVvkL(#n#aSjBd)v72YMYgtO52J|0TRqnwh}|GQiJY22k!W3?zn!H z0~m&du3)$?_9X6ftG2X|VC4SZ4bPQtrQ5gfGoG`WNhbe_t87b`>=zI zU!}rx+xOu3OU#YaxVtNQ)jpqv$Q|lmc35|ctam2y`53|Es0Nc8eSUb1{Py1w&3?`= zp*J%bJNQhaI=(IJ(z}02x;Yms!YS6C@X_~%c;>d`A3C2c;~vcDt(t;h`rUWwu9J4bzAT+-bqRi*yUL7hVP*Gb4u0hZd=? zUkuK8Xb(MgO&=d5HSv$VU1si`i9T(I=_qrr@RGi(+`#*~8Gd8K;md<<0cY1%3Enih zT#2y*EvK2KF7OIBS z?{^;A!9PH`?}HzugM?2L1BAqOI48Y}&rNs44bKG+{rRNiB{cQFVcjiZU5e-A!ty^k zoYm{yE^q_e&o`3%3 z&|k0{LfUOG--^>+lW^-k@VlwSLqkeb=I;Y^?dj_to9C&?&5O!9>TV{aLKp=KpK$0g zQV>5Wn;>rxQaxGs#|SWZR%q%61XjDL@X&>>>i)BN<>jJUVxCppiN8tj$IosczfUfh zo+_`_eU*$_h$=a!m=oMW^zIbF#LmV$GWq)MAzgZ6amjDkCM<6$^1t~Go2E~Du-l&W z3@$CU{3Rys!4T>x>Ugj5XPf9aEQE^35p%n?Ba+sE;lnacD2aO{-76o*h-Mga1kszG z;G9~iE}tHd$&Z&{0ZLWeuR{K}CbaNm{Pc`wJng~jIVfSHW9^VMOl{#uBJ$>Y0$L)C zFf|eMh?fM%xOAkL6H1NVmd{o&7(Lm?->q2UxV{^x#gC8l{nJM^h35Cwxdqes2Xzb8 zub~>~rulz()De+4kg!kK%hay0BC^23-WBX%XwPq+u{d#W2U~k$kfFD?r8zTU1D*2g zQYx*e1P~R^Gn$|V98&pjIHXkaFxtsyJqA2^1llmtFG$hI2|b`crH97IX))qHB;6|q zdlu;fr~b=%LOhA&HjeazI(+fTp{!(@{CcTyUMoz>FQ_=hd-*1?yv5s3={&#D zCS+%4{g5>{B|S$ELh9YW2{EOxh;n#L8KhGV!0?|zH(x*hOJMm`cMAGRA^0tXdBzKZ5h%5?=S5j!h|5rg!$LV}VBg@(@_p*j)uqMua0 zeh@-l8so|u$wRjP;h>N)5m^5tzeK4HfL$?r*{)Nx4EAI&StME@gBsp%&EwPL9t*`4(r+2qw;A`Hi3%M}(*ct>9T z!^C#`H!T`0MDUNW2=)_>Loco;=ppLtp5V*%x8W~;bqF)S3U^#Ayf>Zgn=kEuNqead zq+eSR_dzYcyvF^aEF;vsB#i3hF9qwd`rJF*(BG7-;02Ql-)B1)u58PYax^3oRPx1C z{6bh}T34gTbu651U#&Y^NQn;Rbgii4o|V-=gycwRN3@D3-hUgy za*<~&UQUEF{>%;Mv2Lb!1u5rToUq4PEVm^7u5rW5So<3t3%CtmtRVV%Q2igebXC5j zcF^7Kil%Hs=+xvQ*gMC#wcO9ZYQctoUz)U5**K{;Wkzm28Hs`S(a{o4%!BSCkbRUQxW)WW6|cx5u6jYzy|TA5Fi3TIEQ0^h7`Zg_;^N$Nsxp9_8ZW=-%P5&Q1>qFh&$ z`j+bA4;9g4q;Fj5d7YeS1AaVIE7N_TT4=+4N}#&Zne1E1D?cya{(bHt&dTY8Id8_&uLjZ$)p5Rv#)i z@ptejpZr?Ba?__VZ!;a3e9fOqDC_?u^lIEvsFghk^Q*K{OO%w5l1oW9!bRy4L0U>dLb_8LY3Y)X=6BEi{PBI)yOwJ` z&di>@_w3md2RP^XXDj*%K9M9Y=7j?jO;j|ab#Wk|QMquBD7E5S_cAJ|4emb}U}h9V z|4NVEOhTsVWrwXkRmunz_5@bVvtMzKSU8F5*t1b5{e2uB9_x%g#0phPCh6!d1r3eF83j=C4v=a$Z|>QvTBRcwZkia2VD)9sB=MZco3tj6yLTbV5UWd9so~G$7m#<8& z1GdhgLZw;(KNti`v$5(0rm&ysE-A`K;J{#f)C#va#|_g0vBwa6x2 zA;^{6CWAucj{9D1Tkbo$O88(`fC_m`#YuLL(Fmz}M^)Dz`@b5A`8^HI9gQyJp5$wS z&7x;(^d?%e%*R-(J?q1z{&3pOj03u~Kmm#1f!xA2o`3Sve=?$~yy>DXC|Y2i_c^U7 zJ9iL3V#TKD_p$DfiW9Hnzsrwm*}PRhg<3mLgyHTy$=b$jKnXkWcA<;cQ-= zyQCMIyzC>(%Kh`Nh5N6YMedZSLm!vzC92JGel5!3ovUm5tLQnmo`-xd-unIOb9fj3 ziUZe3nTDc-tLe{LPrw6b(^lF0Z&ejbR(InUY;ci}X#(?(t*l)`l*>-OpE;H9%y4df-3Z=>4KhxxS2SF z2RI4gq1U1mUir!CVqqV|%RctQ6Onas6}8?$&~KM~|k1 zXX>wv{-s`KufGbtrwDz^&0_F@_Z?|6OJ6T60_i|E(|#d;QPktDE;-x1Zj<;f&(^!J zp#_VXsSjtXVLqW{o$K_x2vvt$oJL}Lwq|)VZY_PYjRz$>e^E4U$lL0#Pb==yW~Z6x zg-wE-wEL&AwsQ@(t*o7^C>wwGH0j!`ue-N6@{Mu)9OKZ!auX%~)atNfBmAtmP|8GU zn80j)ahWZ?=Teqb^WBmpt@2-D%C5^+i$)o>6}swAI2OXv>nm>eHN+Bf$-4WaP2vaG z?ekr~Z`#lp@3>qZMj_8R9!Y*a#wCj+Q|N7s986LFa9>;Hu2o(8ca?UJ19s$qQ$ZX) zlomYvJI>97RL8dXOZ;3W>qE*;3QtBYYRLA>G)ud@23zU|VW^TkM`D8L)ol2ln;0GS z;5l3|Tex0JY*yjBtYh4Tr2RCliyg;KdHoXiIqTdHttWkZA?nCqM0jisTN?E&z2g56 z+jQ5i_2qDWsSAyIo{YTL4Ow#q_dzW<@>mrd&ZKp_Ap}M90xktAL$i0+8Rx>PAB>Rb z);%OOfZeN3(au#BtbKA#s#ayq;;_4=E3T38)E)Qd?tw>2Wdu#^U}LM1g;BzI)vCB% z@$TBkFSm9kH3}Zc%Gj}xnaZiF=78^Ab8=dtDh~x&uz$lPIOARskgg%TL_(p6nRKmR z+Yx)AHnl1S%ELZv;vtFMo-`kL9Bx$!B){LIQ!o?du?maa8@8L9#)=!ec=nP&as+hm zxRy54IJ|bZh}6qRKynNu=6!FdcuRQQy!n@g1fM;a%RGl3X{g>~*ul+Y0`}!j2}Rc0 zPZi>1vY1^rDn9Q`Ow($jw?rMW9q@h(UDzmUvdam|-Zxmi$o6kxQ7$S!GWtx{9F)1$ zkg>HSB7M$vrQsv~M2ICj2gekvs1f4POT)UXtJVL-0+dDcCma|Jv0Mox9E0 zT;c7qBX4RadKX51FYU8Yza}MC$-39(D0t8iKR@NfYRCD8!i(hQ!kO2FLQVLLw!s`C zpyQ9jJ^HC)!F)LZA8GZesur4DBQ!GiT-4ilnETtWNbn7oE^!3`Nd(=%7473jZ1sO& z+fl~OSnJ^-JMqwBTNy={@*s32nYhtnx-SUj~JcSqNbeOE00xYla;M3eaD=0$YOXH zM`BLnH9vl$aoF-#wa_;>XFGt zc&Axt%*Bt{#kaF-3;6U}cMfu5{8{|QJJmiSzs8OA*KC`MG`+35C%qdmZd$9^q-{t078JNJz-JG8jJkDX+*)2T`(bN~rP@_H@Ob;sddacsE$z78X7jm}28wQ7HC%g8WW8(byX z3fPBC@YLkB6zE!{#Wgq|y|qlss~kYe@0>$#>>Y+ukM8}2EgliAvdJc0!*6E-#XGbY z4APc(9OF~6QhpI49o>xE)yeTP9}|6|0+o3R9FI9Yg)#-&X;|FdrM@Y}aV-AIATt;0 zrms(SLxP7b!Jx9XpYLym)cRNTrBV#~;dM4? zl%rC;)P0McO$j<%&<>m_5$A-M%iL{%K73@IQ(+x^(c@5fVG=LzPe_v_!b-q(v3~Y1 zj#CiJmsi^L(~vpcTO5OR(rBbrv_@w)0lRRWKvO)G4dF+lxSW`|-fByVS>gr}S$Z|8 zGDkI+gL;Ukg`%`|I5y=&kVP~l;n#N7&#*j;9Lg`B`R`QE^NudcENu+OTzHFc)m%k? zBs{!fxkWL`%?@X61qU~v=BlC_9o6`|^){8kWDd3$Kc_WWQ`l9li`0;|Q_=wg{paLv zwHY6X>iG5Wg!jyym|{3P4h>Q}vXg05o!@FbG&C-XKv{%-nH4);$1Cpf`!+AQVEtYS*1T>PLTGfq-P(Mr0 z?R1mn+!A}nq@?ZYLY&AZoVbf@%nKL6)oJ&9A$<vr7eBQm8u)=&$}2Q>FdgW37+AtKsxOw|H~a*?=$P@N?RA4wT( zYzbc*v}=j)$7$Otl1uClR%vPONN@;G9eAyT#{o&+ap4Q2WsJ3aq6C*P>bF6KL!Ev=)g}a`>U&zenE1x_2b^Sf)k4eew1N2cPnaBKWpzv3V~v$-XG-wwj344k=rD zF_n87uO7+uTkrN(0{JwH^iy_LqPp-Tn@-A=i1jS-h2xvFn3KMP271z~gMt1inlJrW z)Dx|zX*AyR&E2MbR-!Bfh(|&!W8e8tTr9EO+cbNv2}TgHK7G0gH9oZDUE83@FG*`7 zzZY?7O>|1T3*g^sa$%+2qmdUcl!^?s%}QAvT{w28`v14`ZoAV)+Z$$SOyxIqT1DzFA6r*FIFT0Lviair;O7_kPj%3e zxV)D#-KqV`%ll=BrI$57KeLu895saEFBNTA;dJtmsY}};1?B{(m8HJQ8I%dvLoVNY znnXXZGJZDs3seY}&Rl(%%`N!|ECyU!CzJW|Mhai2NN4U{?eEIlGp$c>=X zC7f^>{ER6q{L!&{Zh2S^)=`T2=3zXyAFn>=JMvt7f`Z*3mrs=-fMysn&Z|Z zZkPu{vf2#}!bH;^xstj?xoMMSb#+D(P2sxor9I@f_}X4j^3=HVPh{V;yesY2>b5~} zeS!(Alcio%+BC^BqE@5CDy_rkG^9S}2a}WCek93`Rb>Jh?9JbtWjblYxxTKb%QKj( zOcop6;u_LYz>I-znI)X7QQQ3>eyUS1O6AOcS=&F*E82|P^WaN|#&7n_<+`ZC^Ni(t zH}PI6&J;t38OuXg_J@*4y~Y+9Fwdc8N8gp*A?UWwOWkUjq%_M*M?$r+03KOaGqOzU znC@jJq3D-S%Pc)%8=+bK_^?P=&oA__XWcO4Odd%TSzevgAu?02Y_!XMnBiG^_Qf;! zEUZ@JDtn&Ge_S{!tGaaAZkPNp>a_k$*H`(f><6o-eR;&ZW$Kv%F@3Hdgiq|-1qdzm1z{E9NALMuZ0U>UJp*Iq06m9-t-qqg`=FQs5H3yb1VlIiSRNRea z3pq$9vQTY9+#r6<7is=oytBWRrAbZN1Xmg3DE*WZgxT zyzSS7miWR5ZT+`4#3hob?7=EygS`@1+}bAcYqI(W29xQ(Tf(3DDw0;T&Sn-jI2m{U z)hOXh5BpF`)v!lDzYg>1rlYR@nRu1n8bKuW_NdB+fJ1w0dARJOCA+u5+YB}AN7)in z)%rtPu!7pLNOAcWn;?ttdFJCOim|Urp5!(CS=1123r+5^RnAZmzkYnZ$dM5?@LI)9 z2RXh?J|e|geN!~Td%;Kfj$DO4zKXuy1~Djy++ZPSkre}n_Q~-+CJhZ<1E)R+lmBom z|BePfYSmwhF-$?04p*I@{&}CgK8MQB^VfpL54u{CUvthebhV0m^E$j=S(5fLWslen_*(!iH$~;kZ>e1GyDFIe z>U+i*|13jweWlKiD@8r={#3Fy{rW>z1R3q_EU@wAgDzTDdbj_w7EU)+ntHjW~tg$eUj5S94mlvOl*w8O~&^mZBe+l z{P>DlO+0kg;DPXzhO13sJHf1hd^XvIgyE1UB?=Yepc9mrJ<7Qv++Ag+MfmyqpWR{9 z9iO?3ozJyWbiVl}VFpT`d>zv6DLuuvNcw0&38wGjF1XeV&Xd91)Gdi}tGmkG@%Jei z(k$W~0;$(t*6U?PH+qAv3^GAHy)_5lC24;r+O;*WiB&ww?5dZ{%3$Gn>X$;==|mhb zz3;Nb>Shj-j)$JUSakWBLrHEPPdsG*IU~{%F)uJZM=IWeP@YNI@>UE^jbhVzgIsmA zJE9=%9jUFtGt$~7emY}k$s*xHWR$v2ZZwsP{-MR<3g@G}ZQEKeA_?a5VA@%b%F2qU zI9sUr`{z3X(}%OEaSD}Xh&!h`0a6#wYu|sAY>$=e(whVA@q&9TgfR!WIAN{=Vb37K8kJ*C~kUukGjLx|WF7wCuqrE|rb&n}^Q9X=}SK zg>!fQ^+_yRc(X`y>}xCb<9gqnsb~CUuYT#}By2srzbmm#WtGuZj6=lOrGBq85z|Edts?pwA(BZ0 zpP&sNN;G`m|9VpuI=#zVDIc+eY^~(LmGgboJ?-3M9kZ2|0W;y+2+-MV*EaMI4DI%) z`h>UZVm=q7++Ax*N^Hlrf|bq`%Q+sm$Hz9VlFN;Me&6MsFZYJYFkO@3iGSqN^LyyG z-xR)GfnpQQ+Fbt{i7NQ-mvHB-j}IOC)>3~oI+ucuhRJXekKp4t&^zY^`wvt0&G{K+J2r*isq-_jo#ul$e~@_{Kid)f@ubke zHRIE(X+vb;Sc3ZsQP%WeRR|J_lhpmDLYHuSRH}IQPT_9gAo-fK#;ly!qmQeLlu|RY zg^!xt;1&CxwLTW6{;khzKP6=}GFaH_EYLqak!<&kPf;*dzh#ck(-vX8BTlDj2jeyD z|2?RY^RBOS=UI?~-TgWDnV>wTuN&`jP{i2jft)(l0L#`Mm9dpOxTi2hC9 zrh<2Ufi>N|g}*!XDX)ptVA@DWE@GubTH;V?x)0{!#N&3dfzr^}5xdr>KZu`isQe_n za5$dgShW5D85~}3d3T}hg8XJmf*f6Mt+~Li*Oj5#8>aaA{2 zT$tWT!9k8GPS&>n*>f{|nXSGh3aLBITP#26ewgyjGPsbbWrY*Jxl`=yw>ld~c-(SM zUF=PZUq5IOVD(q1wCc`nD2u&c`lzU#^H;^k50f%b%;83|C0Hnx`)#49#%l zW$vk6!&E0VgY7RiwTiL=EqVi%_$t8|gftI&)TjvOb3Wn3qj>Ya(U{@!%dKe@9jd+8@Xb7`LAgxlv*=8-?< zHiz#*@)Czl*j}ve=LTm&a6(&wqx(C?POcoCX6v`PMgn|=13MX9)uMb7Mz)C1SAxsw zt%6gQZ%j2(rh2(~s$Rf1Q|~TvjGIE0_|`o(vD>uV%|lt}JbJB>?t)WeEL5Kzp6b9eheTj%ch1 zi#KK;lKrW@szy&{8FW_Xf<_bFsGqG`7c5|Z{m$4ya+t40%|PnJ{wzjLeKuc9Ol?Wn z0Cr+eU_w+_ExnlwPL0`gniAG-{@?YHbjdZJ8~F?p!jLNM;!2k`xbY?r6@t->piW)FNr+g=cbhw+t$U% zV(y8b+WF4Bam;Z%Tg~39ogFFmhe$2sj(t87pZc^c_~+5AD!~)-XQp~u|J+CXgsE_U zCrz~O)zB7QMvfV{cG`O0{#@>75&lB`dqrXjM`HTVGV!0DDdZh9(Qvye0;zjO(+ZBf zA{r6SkAhxX*KWjrVPSl2&za=t!EY($K3@JpN2BK`U*fHMt=#o(c3kI~bh^gat|(iQ z$~ za;E2mO596aSIa@#W__I>tmT>Or7QZ~OV?rlY2i6Tl)B`hz9hYtC&6r`Y~|FEVi=Rj z;rurdKlppE=-m=8L)k?nmM6qVbSy(@ETg8))$l?k^~$wZ%OR7TdG`4!ZpI^KW|QL7 z@uFY{LwMIGP3GLQXDVm>uXwz*M`Um|c^F@xxx0R6QOHS0#%O8^zkYFnpBfeJ;2Ltf zTNdKW{8%*1e$=Y_xFopEjh0hF?OJBd(N2@m=<0*NOWQ=y290E#Y-jFAzx#B2y)nGX z29tYcYCEPv;VLbm+wp|VK3)`1U4M}FJL~TDckqqGRk8r5?8$X zC1K5rZ$4gMBkf63kO2!1YPBUKQC4&KVq%@*yaZ`=^2(%!tI}c@;;E1CkoNUi^Sr6h zGerLq-Qv#|b^#`08S)RFFCNynIo59kttl?jsk;2QyDWtFpyAcnq5hdqJ}=e+me}K? zxLs@Ksp~I(528LWI<@kOCjGeA$(8iuolV;Gtmgo2@76TZjr9eoqvuk<7P-ari?wTGbOHtD;>7Y!{v!A!5v*ev$hc%I;RVNgSve!zf z1LB$3A0Lg?4yH;WqACd6zDVPVH)i|}hkFZElP^l)=P`3cWb z`GsCd){RhKhh5W+p0M_9Lh^=8Wet8sA93fzz4UpD7dsXT6&az{ND*REWh#+qcj@8o zMSt8zA4?k2I`dO7E1jp#CYFU+X@@k;0Vgyz}E1cem zuC>NC>5Q5JgUNN&>wPhu@BaF)fW8gXKb5vLX37#QODU(G?0ysTYVBXA$A#>Q&)eLQ zPkNLh8?R!hPc&8#*Y~V4ZgMM4k@NMs$jN&3Tl9C+=DT@?Df14*e!mdW;N9ab>$FR& z?D3kapY-ZQe;~HitHoQ5{OCRF zd|P~2dg-^~`;V#9Y)+3F>9JsWHGlp2FzIsoc5FIHwoBXiyrHrC9ywbx9fcJ1SWs%iU2!TfyL~DB_?aq4e=9$;0b^ykZ|C* z=Qo4edv6aJAfWM{@JEKqb;MlnX;d$8vSOTgdt9g_yQMOQ1M06wr9>H(_&V_2yW2pD zP(~g(>3Sszi_8fu|MT`i;evuUt+dRv(a1@ihU|%ah3dY8kYj~>1@+fW&^^aznd-JI zb902--_6UvH~jvVw!a%tGq3s}K9ZUwf$@3xp8T6&wjmue@~Ql`eDqt$CN46FqXo-zo1sKAHPBM6_z%ds zYGve;HTmy88Q#1k-tR9BNsoi&ZBp*#j#7Rh=fEbTzMD>hFGGzl#z~A-ADHGR{C#I!|39;z_!WZ=Q(XuAz6@DZP_v=Rz^* zi`#o6H(&5Brap|ZGY-j5&S>UZfY}9tKh)2)5LjW)WErz^{H}=6r!{wj%OkZ~sU6?(3 z%>O3J={_ZFa40|h>P7Ipp(0^J=uiKTs!IGW-JDU}NQ0s$=T#N@(Y|x|I7;<{#8jhF z@|I~C0lVy(udsHB^r~M5>+UnnxEmk`c!CWE+{*>6&O?R-^9eZ!o`k)Q4>S4eKnBT7 zmz`>)TKanU$}`_idHc;?Wc}EUO#K-64TsphW09n#p4lgwT;8z0L-T9{U&YA4&E8m4 zo?_ykS5F`GkQ{0`DPF!r8CRcVZi*R4SsQ27iP7fK`OUX^$~J&EJwgdyF*s}@SzBdr zw&5R`2(7)|tA#yL#tV+<5_F4-{wuhr&DH^|kCkl#DKk`mR2lA?_he{aZ*3ybFtt7~t(giQVOSMZZA z-^p&W-Ib66HQ#gk`baBTETZ(0`!5A#`R4((>`t1O?NCOjrJ{soKx$7K{-yxamj>5p zQT)Ct=MbqfKXnOrpGfqm0oeoXg{gi8pRlfiphRgawZyM=ecJjjTW9wTp2@DQdK0U#|4@ zNPOlIAdJ0p$jq9i))Pq)_H4L?$rJxZngANa%w6?Lr@Gt~Z!ceca`WI`u?Y9;@wG8t zh3^4{%fd6a5&OM!K90v$*zL&j;UTTFm(YXrq~*SyO%kc^oz5ba%?9tj$aUg?jzD@p zkKi$#xKz&*`JPmj^*1xE<2+3LzTYsALd)?>O_#F}Z*;f6$yPrP%=xonpatilUS@ge z&pMrBvEM|~|K!=kSiBQkjnAQxOm<3kT$R+`56ynsG}OpV*CYic-rdweCP91IoLJr( z$%echHxb*X9@n@~Qbk&`P5P(8dr8(r&A)*-X?msa7QzeID&ONz$xG6@iRZ3cSUlV+ z<{C&0|K5$~#qJn-yUL0dJ<%&T!I5 z=qtqz2-ApIrm)YVxdH_okZkF8eK}F3!@bk&r5{TtI=|K!G8z>+nxnsQ=o#!uG5dLb z$Z6d3Yg#pG+Lr6*-l%`i-h{Nxzn6AXI5QMGa*0E9%2>NNeOP@=v+M7q_n6E7W9vpqYteL;E}dIP&mzQL9#Zf^ZO zjvV;?ceS!k3TN6`^4E@;)XFs9kWAHr51rkb42qsX8ogzclQ<7zLkH=%j(a`ra*XzO=z7=ywr2YY&$k29K=N-^G1&=m*Pc zd3CNRovex8aNba74bra&oMZLZ9Ex4hWOYfLLvjvney;W@@tLu)pVj0BmLqh|sVYOt z;b~{$BR|vHkNkpPtWkFuUD+OTH!C%EIm77>_al?8gk3)_a1S0xwBz{~*7w)x)A^U% z9A0wDEWAuUyew5hUdh#*`O+f_CRcimGb58e;gnwtgny$e)<(bil;rop7alP>i5n4Fc>__^M2!r+p^ zrlxgHD)p}VqX}e}-fc_$0X+6^s6wXSro@sH6?6I`NqkPiZ+s)p;a6jt(|aUu+~SCn z(tJ<77nQxQz^nHqS)VL~ zhRYkTvfFIo^x%VAh2+f9;u>+7ONOxACk>+kl*-zf2JbmCDZVo+Nb)za!uc3)@?KRkN;FmrA;v@e{(I(bRSF`n%sV-!oU>vs0e>b>;?Kt z+TkmN_4JbilG?@-{qw*UHG6#vCtc9cEiX&EAu7nZ@bFh=Pf zwoRFtg?*bN?dFz61%4~8nA{SlRp%&}XW&@?))nVp4^nS&dZ7k9a-)pxH@a(z+?6I&k}?-Ntu09hUgx@qu+$C z2-hOnrGnbe^RI#-Nu*UCQnl+;-Wp2J0@#$XDSpMXyfm-){7yTUl&W1cmASLcSer~e z7fU!&xn5T-l*>|lj>WdvlNfuD?ypM|pL*uLiU$&O6Q!>tlc8298hDE@@%@>(x?SiI zqxJK~R77?vq7(m4zRvvUq>`0~`5MLJFVam#r**Prih@RLHODTG6oZ3#pU3UG_lEEw ztO`@oO8B~(1ZU~B-*iYVjl)>HADP|J6o$%{}(`<^U z)%^kFjl;WGp_s#0wJNPKi{xo75Rv-{2JW7a2Y83`$HKT73g}lM2Vw~3gR+k{t{!G@ z9%lc0uz~%37>n!mj4J8EqYn1P*M26qghZULyRKgl)Dhno+2s9@*QyC&w(|Uzp-sE0 zBfdeUSM`n*L>}8|5W{lL`IG0<6PmNjbhZ_JLu3WP@#J5#rw*#R*t7ovk2%A3FXck} z187h9N&3noVg2^H?EDHSz3RgCFO%h7B(r%Wzwnz@JMObm>}uUN4SVT|yVYKvz8|>J zd1o*oxnPwsESbQ1veiA)65CvnnA##N<^lR&hw?O5hr)EAK8xLhIDxf)7o;S|Gcbs= zCDQCIb!0~~gVDZtP(BU`&NqWUpsHp@Ra;HnKOIqr3t%5__Kowy;bw&mIQQ{mA;CMV zs98_{&5_{>NT|?g{;UHx;A5epN<$Gg@2t z#a%PXm%o-UcYfi;(L}{Uele4uSI5#q)Yz4kk4T zgS8-&SF&-isx`lv-a8iO=Gkju{2Wl^CqsjgH=QjHI=Yp^5-zoE|MpLCq7wWgqHzb> zR>eb0h}{e}QSae|^)qVb%oHC8Tg^GhLXFOO$F`t0wg(K>f0V!XnAA@_HTWd0Vf9Xu zyh^!rJNlU=i0b~3Mb&AfC1~rdLxo4B<W40N7OnaTq{+$U(fNOylNwl5@f3ya~{X`1qwu8Mq>Dk_1R zAiG9V)D-wA_;YkJEzB88r}0 zxP>Ncst+N=0%)SXM-Zw2yj0jpgpB|ZRC6++EE;Q53GD%vx|fB7I6$>i5#fI%k|l&& zQ~-e)tM<|Z0yNWD2+I5&8yqDojHaUM=pw|hXD)OTDq^UoVm4pB?LZ6Z;GittvB3Z- z$~xmd!eM|qife!nLn);_NSMeA@M_VG8!vhi-MOQ355>npjFAS_k=_zU0kl>hL7)<# zmkKc`9Kc}`&=a8h~FbLJ>p^3@=3)qz$xhJO+KkFo~gG#Jx~QGl@+Q{pX7YF+Tx{>kTpj!k-=vItPrU#DN%qZgmNuU7%c$ z3c3%-b$tNQ0J!=QgrVsoO$TWJWs?jL3^R_)BZ>R>(F7)7d>|V4P>Vijy0y$qkRmYp zl^hU;vQsM`L<~4<@)n?Ezz;MLINE`~_*@lA`BgZkhXYG3?GAPpLa7K2A~!R0|OiLEZc*s0mG-SC>vi zqz806CMCkqf67CM(t*J(P!jQDs2PQOSksND?%Zh*2PT0U6{(7*b5o`vvIUsRN`;9| zFhfkFi-9YmIXBBeCnu>_z{^K{3^~#^+LdUuU4;4_w3PYKz^An;5(0>I|_o#$O6f>gjl&jiEPBfoP z@_!@Z(Lj%=wwx%L6KzXvj>s5@N6`Wih9LH0naBYMuiXw&CNLfN`$XCR>K_uJfSfuw zBT@t8rLKsc0)%z(5aRb}YPmWl4&qgyA4rJUi4=|A3dEDZn6;INTe0qAwedhli5tn}TQ#x(OVVc{%|t>e_&x z7*%0_c2cH+Oa_Q9@&{Qj9F331$N<9Uy2uH#W*|cz&yocI?S1oP7y@JCB{FfK9<@e> zVba@JCmRFW8@I^30at`~$OwT9ll@DE;fk$1B_jdkn=i;N0l9{2GIv0Z_m+$VC`)63 zM*+G)a$>MKhGuYRtvpN_op9=e|B)G1SfFR)GZd_c){;UAo|k4x^T;3c#|>P61~Ci(a}C`~^_C^%a}~U|=m68!#PG2Mz&L68;2B0re{F;C;Xqkv=eH zSr-q39|OTZ83$_u%Uo#&%mcXMu>`&ZhVHrs-UQl>w!oMqNZSG50`+MJ;3Pnv=M?M- zB*iBpa!1Uj!$hI=%od$TztE(LzrdU*(%1adb#^4=u7LGvGI9)6vMhug3&TqsMu#;b zhdxb;iBYoL=&%R4g72ahjmdFQr1a#3bpe#*`hd67bmSOj=Y;#@4bN{f6F@KWL#xf>9ra$|BG44dh$(^*$1*_}H`niMi3Ogza^ z;&1p#>y$0XM}TvM(v|!XhMScwgt=eap8`%w|4?!P%!vQ7T=(&# z*Xkkm|33!j2y%kDy)g18z)Xlokdp%VD3V+ZrMo*V>Bm2Vn(H85D-Eb?bS zP~PQ`zXvEYsjA5_UfE85^2pkBxDKCWPJ{o=owCl^5HbS@ zJvK%Qp)tS|@&i~=(k~!?0IN(65LTdG!wG`91}r&4FvmHsDyCLmD>^B{PDR2wHgcj(ObpjDWXJE}Qs43>2^$Dx@6C*lRd*CRnL>BZpABWy0v|`ZQ zwr==PZX#gnX@}LPU!Zf;3>&zL-9yEXL(#0r^dk2G}FkY0;eCXxycPwg6bh z0R09e*b7!DhRD2^9r_gThn5SP{{WcD^;{`Y)G#}g1yvD`UK!V#Pz<9z{3)~uxGFTi zf<^#(9yvlWSG*o4Xe4IEU@<8&3!}Y(VgsD5|9OKNPDG!Io{9Xhx)c|v9MEsd6^fyY zH*tfO17#8qs24EFpZ1^{t;+yG4nG_SWn69M$;ggyW!IinZq4vAnG3!&76oP1HOh@ z1OAxf!JY$hb%d~dATGuvFlUT@GMFdkDP#Hp9#+@T%V*Hjje^sVfeG{Q~L(LjJ?&p|DSY-Rp4J z20+{VCmWUrv`6N`=79zKq7qgK^rxzUVNRgHI+!XT-}?IEF9$z#mQkl+Oa-e*wAeAoRY4#=T%Th86xM3?2={Eh-9*;e=j{g?9q-g$Z!X zWi9VL+z6Pz+f=wOAm^J7rw7Vu*>FQZ?lc#U3)Ej0z}Eo1ONH=50LO~pn5z=i7dR$v z_9bx4DPd9u7e%+DQp(|zXfdY>xDb#w`Hk>%AiXj>;cS4q?jATh5SF7sxCmg5V+{TW zkb^A32>|s}OK>c}Jk1LH9w0CL2d)Q%J9Zad3e-y;z(s+2k0W>#pcm^JUIwIN1qosi z=$}A_5C-&iLlKyJ<8K5)1t>F9BWM6rphvs|`t`6Pl7O-a7lH;z2On|79FTr`PZ6ZR zblMstssTA_TSPA)_va;o53o<^h-e4w%sU}eF?!t)#F!=9cd=RvLN8f2Jd~^=#Y0q+ z7lOFX*#kibcpK}5z>Eg{2Y;`DGBpxW58!wZBKE(l2+zBQCiKSYiGu=XAp}t^gXjae zDg-f%X)P6Q*_lJP7XLr3D3d{cg1YHY#5&+kYdAs}?Ox$oBm(gAJQ@)Oco&#}2nP_9 zf}jEFSyB<@CQz^rZrHBjHsi@+SVBmD?WE>904UILS?IDv@8+_Xl@;&XS=Zh`SoheZf3 z6wf4@fi!Ir9h>{Jh%-P1)o%pmXh~W^9028zRRm@`+ucQAmOJY{q6#?2Xa6B^f%e67 z1TTQ(R|rJ_pWh%#F%d{Itf>n@&z~^?DyIR#fjXE+Ke=Vj^5fS$ricTap249Q2YQs_ zQ^W#;lfFwK1Z1*12?Y-jn0zROD9}C+r_chBo04J-vke>D4}}S!pXO^pKxVL`z_=8+ zb&@m`kAU8x_bJE$=~PAv%=Wv-M1i@L1+r3<0akfADLjGpLT-vL7;V`!5!lh_c!#1d zt!Qm^5&RUN0C#u=De8a@8zK~sFbVmBDmyF(Js=nXDu4uSmQIv{pw3yGq85;1mZrea z(Z|YC@B+P?I;nUv+hLb#--j zP0x(ya&Dw`3(uoW&u{J7lg(PbljjU}uv6VUhlu_5*%Fa+??630#aH*#P~uZ8FDCZz zd@jJ5+PnXJ!i1!u+!vmawD~DIQs2wdlxx_R?kRkwWq;3s{5yZJ=NGQ=REDP)UmuP0 z?85ZAQ#>k&c6!?Kb?yJbXM_&h3XCW=5;HTu#L)AmB#!N9aJLRRB=&tVZJrIP{4JAyXqSM z9;;H-;Ol8G)qTEh^i>6Nx%>dt3;w+~ST%#MbxNwvus$A(x@Fa35~0uX@k9j^&+H&cdlPFZOHR6CDs}MoCvZ z0`>R0s>CSh-$S*4CrkUWDv^2coUD4o(cWT_stpV3n5CM|3cXvY>d1y@x<~Z~D|TkD zsxx18`&28qA(s!T&T^DraYi+s>EZb*W8P^+-cxP$$Mx1v)qkRwuB_;HwHg$ujyz9O zb=X`dwToVDq839l%}nhS4d%>P^->n%Us|2S*Yq-K;!3P4s6{%&qq4fbSeMciw{z<; z7Az>Rvbu_XOM+U@{N1XmMK3k4uI|X?_SRCL;;}R)NzG{(a%-wSgP-@Csw0`*zPVaX zd^(i#i`)ls158QR(btVKtzrYn#yZwU-@AqSxKO{w-3q0H!Lky&g{JBlY{=DSlx`hs zug`3y*0QuMt<~=Z>!m7_J_Mts1s1$b#p2K=Hc0<6SslwA=-*!LD!A&K_;sBHul;0X z;PNK5ZLA$-q^K8z)2D-4%-bb8LN0!*JFCUA@o5*eSgzQ1SGN#d+`8(rzg;m}X2BXm z)g|?Fd#OXX_51p$CyGIsmR+OYJt*XEE*R*XeXON^L|^qwR;b4SwMgh}`$OGH*tTBl z?av0Ir5ZB+ZlR_ehgf%g;!yP%5oZ?9`)6hvz(51&pf?+?9>ofdAE92r*MJQ5T)ytk zl&|$is}Ha~HsjU9c&v?|r50l_e4bh@HhLMQuJu2O;I-M7`d(H0(bf@aOFA12C5J6m zUt%w8xLhr=my1`bPf8qf`mAmrKZ61~tAi=P9gOp?s+V(}<*uu53PnSm`aB{idZSQL z5A;-xo9gwd!#VT+Gy7pC|8thV9nz^`ht7QFCNeMwZgA|}%F1*D#) zQ8P_pUDoT0v6l%mUpMvo$kz)NUfV^_4!L@8DO-E82{p3wiq#*n@e-DQvUq^b~;)18OUMm7|O-=H$gw}(-J zm3K*fr!QV&jeYQ&m$)mj?5EdXqLw2&Mwj1=HmdEYij{W=jTo)A(hoQB-otGvZROpH zrOvSN?j*RI)O9GE4XN|Y1-HJ0z4sYrc<1Q-iM#)Wv-b#g>F(~{$JyY~WxW@%pu9Nm zZXzF>Ki0zi4w88197U?^e6qK-KBc<%Pi{*}J#SOCROg1?x5aeV!DQ9&H5kAzEhy8} z%9qZE#G2{TntC7NDxzC@j}bb(sHC0FG4GDaFOi=5H?6%7us$1;y<4z;X6?PjmTq@P zZ?RfE+u6GT)4jWSFXSqB_wv@T(1(4z9l7)V9pY`yo%MN)_ZYs8nC^Xm&0dkb*RkBk z^S$?Q`K61z-TZ|kRVXuOoP&{3ny;J_&eX(OQLU(0XZ?q4@0r}c<4<{S;;dn*>)s*} z{Nbi|CRaV^p10V!*L~tWk9TMHO?=eM|JBK-A>Rk87wyx5Rof)_r0~_Dj87$2rG90f z68yVw6`yu|Jzw3Yu^1d(H+bh&gNZjd()rTxn-nQFP~W+>Pojt^KL$0~+6tMAu8y=# zWsSsMbst;(okX8Lyb5m6+$WNoHKe7FNH#Z5@ez~Sz79Tbxf?fh^Z7&A{Nd=6jcUSc zn%c@~q|7-!_WGorKApt4nPS>;Z2&j6C79)0<5^Jlrwuho_OzUzOw>C`+Y{Cw$x~ z?T4See#}E3Yc4nKtItR-XZORWJbP75Gv9{Xwt2R`lh|$nZob3V?u%8v2|RLc2l{T{ zJn^JTzB+ct#`gV!}qad!@VoFc@<+FseYwc2Yp%} z-x6HopXt66*m-=0`-)jMBg3~9OSnGT_YZDiqlvx;`M1+l-@VLtntVkB`Mkh4hc(Pz z?mJ2Ny@k5>tGe*$y(T;bB1t#Z*OksE#H#f(SNk?&|9i5=*TTACBOnK8ZZ1<|y=P<2Spr3C3?y|_NN057?YOFKWx#fEU z+$C=N?&OwSzw0Zus;Q5BRjldwx4sc<%WWTgTd`EzufFlTb*<;(*N*wuyZO2DqUK<% z-x|JlZQ|DfK1?S&_&vqXtsVWAvDQhQ{e)q5bn_E;zZ`n`o#(E&o8~78w^~rJ@nc0~ zC!JMvsGFZZCDg?LO6=#?L?kA6f65rx0%mbDA?E_WFxoo9&q{x1gx^3hEj_1@irave zMfc*s3J@khs`|V|A zhR^UD=*Ol#wP$zmAeeSVqCAey*NOGkM{V|-!1mph=O=PV$@zZ5G7~QQiBbCes$Vwe zgjT-x6Zt#y0>1zr%_V>M{mXstW#TV3_4UpCKZt<%@N(DwwV`%56Uq$0ctkDEv?wXo zOFzxdU!?f%+xusU76!Dw(ftWnr(w^)tWHg0gZ0N8{Y8@Kkh8zoE4+8}=cI@}%EMn| zCmdA%Ekt%9$bS#7KmAMl-(mbm8UGV}JzmaVY>01F@E5znH*x;HV)(@S`|&lhihnNi zy{_sn?y!BWF7x9-{`(?_zja^s*#&&ZQcdxt{T=jyb^JGQfwOh}@A7q1eSfhsn3d@N z0KX>;Nb<*j0R98@1CoLS*0OO>iYYH&dKuRbwWmgV?1eD&QOj7B{!6nUl_}o|&)EI^ zYPTxbh{hXJ6$@8au2AqeQNvz-mii{Gg8EiLmB$taS#j0*i{$Io#W-bw-*=Y;angFi z=i=c`9vi!c zZRzm|GH)Px(>z>7nR7!OX-TJ8EB*KRp{88D@#4_Be67DMv=?9ZtOyl(sL0i!S44#t zK_}*Kg@GO$$-|2)q*h%JRI9BE-G>rC*M%MxrtH*VZIu(KtPia4OEq%r8jH_2hh7x2 z+V5ZU?_O|pENr4s-h4~wd2ZsBZJ~<?Vik zLv2L+)@n~(GYUdByt$!$mijH(q256dn0G7miii*ne+5PStu``xU%GIG);!df`gD)A z(_jA@dXIZD+db?xw|=cUOfTV@Qa{Xx1L%lGVZsAGHV%suZ5*?F!fLjLmoeYwaHD%Y zW8J8G)38%)?QvGatItN?I9ijjEe1Y7FMaQ3VM|!FO{*|*nDY^ z;@Qz`PM9&{7Jr7d=4*$!VF_Zro*Z{HwhD|{a^CDvHKi{PbJyRT7bfocXcvU}!kwx9 z^04nHQg=mIKQ4OUudrTB4&NB|7C+US!Y(rT)#k7X+>Qa;!ww4D$4!56qYEU5-~9A@%7umcB zTf%eK+JZ1Kb^dr4R$92j^rXf+YPlL2B}lxF5hK)$a$LjB^eOMd+VS?`kY#vBp;AcY z53eoJ0SAz2)jAbnC9qo1)Io^ZF^;yr`q8%G-`M9e9KuCEFLn*@!^+sYhl_iT#_I6a zJjo>ch8y#(jdt2_FaAA53a`$52V=vl^3}L>xEssyC>tICoXS=V|H=_?uUpX0FeuXA z+=xacVII%ahFj^|#)ZeR2^YqPdx|c1emUpAQ!wEG3wgwxA0BQ)ud9Vy(d}W_yuV2Z zzbs5JTOZ=#0=^k$lzYeulMndx;1fIYz?$I}EH$i7_*&NGLcQ?1Y)GHR;SsE3ttR0j z-!!**xQ>6HXc0b-`P#J(&*Kh>=oa3I%TMnaF79hy=ocO&53Xe|X01dc@~n7p`RV-z zh37Ei-67%eEXaRY_)NZT9Ue}&Qtgr9-|(|WMtBMS*)uczU;J!0D%^>=(ng0r=4zXb z3vVDA-^kr&@;*7Rh!w7A{Mqs07r?Y^Lb$k9A%2C>Me2-$No6 zGM>IFVsL3(pWlcG2*=gNEb?_cuAiz!mJP!-rg!A1vOI&1t+F~ep0<5)^T3%xFFU$7 z9($&{e?_+C+A6Jz+|1Wkt0S8UMF;ubp~#(FdVfx&$SMsu99h7@tjozrag^%&xk!;f-gqf;zAflA?ncIQzm9tl zSy?Q;+O19-yBb!xVMG_&MSIYbmyvmFdaU_{XefF=dw{J zzKu-gu6q0_atKGJ_Ldqw(>-l86+|0e^t#n8RGRcqSv z?T1#8n)mpbsL^yot7vz$hP`q}jAlA>Rh2YZVoU|5p6WCmE6j>E^zKun4=tlubG=h( zjkpDxTVB&wtYzmP?7a0QOfjp_@aY;2#&HdeSf_NUscFWeeqUY9HCFHNkm1@lP_MD6 z+)D+7S#r~SjO26mG`#wwQw=ovP-1?f#(|Yt(@^u1ZM3GbrZxARNn4FbC_A**tQ1OS zf7s>I1{U9j7|RxqX^)r7-|L_e2cBAY)+`W~4cB+5Y=nWDi8Vn_cn6fU(ED`N_;9b5 z@1YT)YIskL*h-)7jl>w}9s6iRp8o70O@H=+Dx)=1cyV)fvgSMMls8Rtov*8AYPz!= zhd(v>e7#MY@!Y?iS8M)cIiJ^P#MJq8gGSu_({9p;lL!0t8dF|)N^*G^?FIEUGDAgEOOQ^0nvKsG8i& zZF8d1QGQL(+$bJv!3(1*uvOcwidxFWzpshqAW+iae|s?kKyvHi5B6JvYTp8<1((9_62y-n`_02@?|US zNfX>h-8`!Ts;ug%70HFU=~~g0i37A5?6g)H+Dn{?zqLS{ z%+ks)*8bq8mdlc*XRgp@fWCW`b~wW$)@VgGwc-Y?*taj=tQEJhRNJ&7kFaQmcD(TY zcDJwp8vw6vU_n`XwXx*82g-Ect&KG0C4c7@9XpfXHf?#zVET={+BlZ(xnKK2l#c1R zV?!)TzcLr4^;HgOYp_-m4r|9SqwO(mb1};`9+H2@3(JeP8jb@Vv~^dkk3Q?9Hj-Bs zXKreLa`&9MuiePkAx~j=9_qO!psz1ulj&-(50h^~ccW_NtF=!&*gqBnD6?W#xj<7-CE z=s>m2=wrQh!!9mit*`b6*G-xvEvi(BL^ zhvAW1{GK{CdOF{&@m>`DgUfp@jc&--o>|crjQ3p^?ak$;ZHx|Pt+#E8-pH||-Tr71 zj9(v!7K3%*(P&rBDNVW%?ZV!_`0r?u6{&JFx+Kf%emi;z(=8rE598mXA4S&@-SaUz zMD%v4J}2(HKrm0Wkt1)+nOGNn$uH60#P)3ekwv#SXWh9lE(^59&**QWE6cxKXY7JZ zn}-W6Pv`DB6C0{uVjSbkGtfS(n3G)7Sf3cNOYZC!Gn`v;-#_LETWVFwn2+3|C8c9p zvS$C4jS-e_QXys^hXu#FG2#Zm!^D`mypA8zAtsD1x}s}LYmTjxk-rf{YKu`0AG|jd?79TaC9m4*;;m zTmS^XUcYyF%y<@;urfv*6&<-cW-tFPw=TwlJ3c-;W*7hdus`NczD_*Wm=uy)Z3%ak@m84C2ox2|j7bLxQ>|@O9Py-3=p z3u1HZpHgY|McC{Hfjr|H&>-k{=aJg){bCfpjDI{cVfb4)YI$NIx8 ziT3p7Zy_k<00d2FIHysE09txLn0POf0vj`FPP@jgWOGn(st$tulgTA1`JfI1i}2K? zkICGoOqz48sUv0mlseODAu3@cdk=&aBIo;kj_s|L9t(12{|5`W&5|8Ox;X9G#cRi%y_MkyWi&7cpF}mEU-n z?<$W(O*%yjEHc1ZlG^0zyx2e1+b?Ol2MmsAuB2crJ(|0QHs|U>neq9fF;;xwX(^;C zTUu$1V01XF3uDIMMFkEMz*G`dE6335v4Sz}unsv9nsFHYw10vioj9xu0_g>lRFjxA zr{N@=A&-^pOiZvvIs&@&WI<1u>`ap{>+E^Beje8H^+^`_~wG&{+3bFxL=kOvwtJmz)Em|D5aR z?C8yDQTaENF&TK7$y7d1I9qZaNGJcEbK#nXR_BSHImo1)*FcJ+MSJD>B!AgppW3Kl z2%dgRP}I`)CKw|r?ToGjdxI+KO~l{0<=F_)QmbIZ%Iu7;GOSW?2J%b1nu8a})9c!W z?al7$-s%n7>VvZJigF*{fHRtwofYHd&{-6&`VUB2vdtIv^UntHI0l(b$1{ z=IctJq8SXhIT`>YF!O~S-Y~G-Nd|5^8QW6Z(~_M(+x=#lnGP;he4t zx3TT2^OZ~EIKUX^;(`1S<($*Sq3ZAFP(x*Zt|5%7ofmUq3N9w^1LRs`0*#$%^Le4p zegLK=LyYNujIlcvoEM?q_5z4!OUlG~q0q7J1;O2tfin>@Fekvzhi|%C(v}N4&j2Xb z;FRu-Is73N3PvgnIZ#tr!`BPKJOLLW=tztpMw0fvkUp4+ZAuAZFlAp97S3m4|1!oj ztBkQk{+9%2)Flw7#R*Oi>Uc>P$hK+YH0#zY+Qup$_KCLiI^)oOS0-}Y?zV1 zv8e1GzhR^ssL>U4>!?)jRxdh#9Ytnd5v!WL4741i1gz#=6$>w~s{l(5Ee2BWp~i+a z&M;=_IHCwk)(B%i`tnI9hltM)dpBDNSB*p~lyQGYhO&?+#a+`OCqa#_LFD#PMbMeo zbm0K985lpV2!OgA$Wo50-q(TN9dAJ4a@R!@=QHrfBm;n8JMRWayD_5_n!}tb-4Kx` zg@F&4Kn%c=8#*@NK?V{Q82~d%$-<&{`XXabQgn)udN8Wi} z7h0Ob_N5TAl%a0>#^Pn{ZVUSd-iAcetwqqvTTx%yZBgF{Mz!0EpwPya*51KPcKx=F z?`^(imTkNKUlzOF##WS~j}?oB4tKzKf6xEJ$g|%CMx75UQ5)LuTnzWfyKwXE_Y2)z zxb&<0#$J?pSExCi;X@CK!l&+vnd3eqntu={BojaKyC-iaT#gLy_6kdhWNaFP6y^62k3_jLL>bnT}9SuQz$Efm+_D+c1ZdqRcV_fS#Tk3z)jJ|7pMxcg|7%9xfv z(|J>pv55!eTol|37;rX~fy@UwYr1(~bVmUL9dPEGO9-IG*;sig@ce4W4K_Rnpo5ju z>S7xMKaL;J(g%?7+Ri|;rh5-`CD}hts=8f>#TH5r=Ll7_d%c6qp72nI^DdP95F&y~ z%Cz)Y6LV@`(!}l8Hef%aXCsuT1NC|)OdjwEXn&~)x>Yi9q4YDdfzmR|Hrf z1DhH6(9i&Q(vPR|>T>Da)75^WKVKr`S5xSy?!@fD)T)z7kT3#IWv8CLeE1LanT2L4 zm%&3Q>zOVQjd}YFb)D$Rh09Upm&kQso!;s>h*BC8OVX0(!Z!~w&1#^mRKh@$62D9x z@dCh-p)#;_jEN=P8fxN1zVc9;$Y?^Q0rjLAnI?GD_J!!CH;fJ*V?cdr(HbTxhS$8p zkZUpDWX=V1H5bM-w+yN*nQwyQ!1AVi8nZNBreuN3$>yZKAP+YzMwE8a$Qp{=W3pl{!2zk>t6R>IIzp_o8-s`OBe1VvH zKXW;&4~4QADE&_7&v8dLv0Cpk=*)VEx5_-j($7WMU%u1X(4u!D;%|8eVSYx`=)KO5 z00cuZ$A3WkjQ4CXt=>PvjZ>LsW+&6)?M$tSb_-kNFz`$*1KhJ-ZgTLSFkjti5OnXsHriFjdsd)&Tsl9h`C`S8! z1PJBAzc;0P&{bi*zZ%)qya3m0?pi!TJ*dmlqUiMpv3R%o54~pH%v21Pg#Uy&(m*pg z(wv*&K?%)FE$Mr6)4*SDdY#dOt&5kHY(2LWXJ8zJgepZhzF-1y)3(k}ucacmPH`iAE_?h41>~ zVS`8qcbfc37X`cR`2;15GN|B-&X@lEB*L)OXV7d%%d{G!P2H(NPsAV{1h=~L{#`mW z`v}dHJCPRSW&Y)#bv%V0Vi``;W!jg|Vzub|1+*SBWm?NGa$;h8vr)VJ&`0GE0-_Xc zEjL@{-2O%9&%OC!WR>XVsQWAGR`%v{dizCJ1-0tFqK2A_<#L&eO+Cr+i}1Hu4Afc0 zfDh$;6$9ih(=I$>nmcLptgOlVn*gG}!Klrin9_ySX71DpMDCRItGXeVCm0zmK?WK= zZuna{s>4sg>OmXj@;O|-&jd3rucD9Ngi-CjgJ?UmkXY@zAhu-Uj@5$bPgZJdSlP;P zmdzf`4#1hB_C`j2hKe|!w}5iL3(qUylHDGOlI~REhY(l(2Z%G@6cST^$h$|k(ucnq z!@|j!^KjtO@V9bQ$Df6)dw+;QbROkRmKxIqbIF6uehQiDpP+4blxYoq>O6VS)XRPF zj~7<%u@I{i+0IGkT<}v!+{&eQILovr&gNRmuZke3OPd=Y`Ix+QF#wKpJ4qs4l$QK( zMGi#Q$CwQ^=*n$h;wE#ScQbdKn=K(_JohAoEcKAdNyd0h%23-_7f2@`V<4No42YN) znD*LVrUe9;+t3S*B+^|cyPR)k2LF2p?+R7ad4ld6OJ(6%Y7-Q83X==xlrguXhGFIw zVix22QW@S=x(K}FlZYB88JJea0C-bk9`<@MFrwFu(c{D6@~gY!DFj8WTg%D(Z^u~U z9W|zsE4zP_Taz>9fb9_el}f5;mZ?zkl&R!nT)@A4D6E^gJvo}OnaI}+O0>rof%|o4 zUvn!OmLS_Hm65i64TvW>%)q?NPWZZvcKlAP9sVd;JfPp|XW)0Fq_4gf6qAU#9%k@0 zhq$Yw8CFpfbBXt--I?~+OqsS6G;Yjjx1*mwp&^UV(@F=jrt{_!N2VWKE^a^dwUB}- z-a5z__A_;mPF|m5~rfJSfJd^LtHML{<9D|*jj>iK3AqS#uM`F#MWP* z+2Ij2rI!kl5W$x`CHdoGureU)3_N&i_&-duWTYB`Jf@R?qAxT~k=J=G1F zv;GZpNBR^eyV(A%UmJe`+e9=tM#26Mjk1ywSmcB?%eKD-?h3IX3Z4r0SfmFnb+xgj zR%Y@@F}0`{yajA7C=#n+@BKh#U-rPRvUi)@im+))kb*TFh;Kw z7*M`9bs99&yeJDfwEnP>c#{`k3t~puLSjZa3oA;t6_!tDq<*>Ih$B5aq!X@|%TPl3 zLg<67R1%VW>_F^Qp^%tlCy8;-#L*Rh6KyG{qJ;$=uoG(LF?>C)5dLW=;js|%vj?$e zO+j>{!8I)c`Bs;xIFq4+wFKl!Z);gN(?*OL-W^xe#R)1C?(qyXyeDB3oKX>lD4G+V0CPU7_aD+Z2tqODGnKZQF{)yRumYM1z>Yn0)dg2bqw8JhEuOzQC&E}9yb8?kJSmOP^E7wpXPi}`;p_Di| zSLV#gwQ!;luEM3JxI)CUzh%JhiiNuz^m$Z`ShO~0Hv0b*{*^)J{uP%_?p`^yqfwaC9LmLdO;r*0)@q6G4GvX9 z&MCD4@S(G6q47-yj(HgXd-C^^IJr{a3&3C>17JrpyyO_6SsW7bFZ`$#YFBpedCKvU zyLaV~4Jtm4HSmAph${tnO9`l;gEuM|RZgy;z#FTm!mixQKw1R@z=>UFAJCHH3^Y4h z8fR%qZG1!{dN68VSw^#bBrcK5G^2zfCCq$952}3uI98Q`BwsmJGi^mZ1G6n<`-+($ zpMlZMNEav}5m-esr$fywoyf;e)EnUk^kTOnsAG3a7utaLU6_p$ z?s-usE8eDJD;swVZWV%IEyb)djbZ|&77#lz5Tz|Q%cai-N+sB5Z_b_aurpL%0MAHJ zlzXtpz-dX9gT(xt5(E(|vt{5}wq*&ror?V+Th8LswDCKTm$>Fo{MOL8{mfsIyn{vm zMF&Gh<`Jd^P-?Ik3)7eum&Y`3IvyrC^afD&R}DpvxuX18RgNGl;nMpr%8S}33xPQd z*wkepoRaEVS&)6G0K7v1yl%mOH#H3vu_~Quy<0O)O$8&YY-v+#D;wG`mpIL6_6P&2 zB6XO&$ou>{Iv^GK!N<4WQWR6*n{(pgg%WQsC~HQEf1$bcOX4;i?<{@}ZnirG-p8pK zLd@0iL`HrPhL<(VP~KCHZ(J}29Xwq;wD zp`0YK*QEIokg$8dpa#&@2+5C^WLI}QKWB&3_G9%GKJA`Tz@H>~f}Y)0Z%aJ9;r#p?#{m%)cW>QrR=>*o+C!MxYbh(6tz;x-2i0;8YKtT+Z0sjWu+hn}Ttg7O7;Ei7;j!|*^0WQPLFS159$1`)D4KPejAP}c z_~^ljC-{u%2h0@8<&Dc6(v`;BEVZR17aAHXCa9UQsOubF{%Zi<&$SjOmU!fUXVhuF z0S)06jGHuT0l&y(DU7D9U?}x1CDu=yN}=4ybzCll3Q9>qT&_Xy+4`06@+H-aZ!z~$ zOlh&j>{%M+R-WK;UUcvTTE4ZkhzbW8cze1sg_2S%0riG z)VjP>6^&WKzb;dDc`XGFSW9va_ww<2`@Ou&TA%S z9hMSQ<5`y^M3Xoy^nw&4rEEJxnKlbh3+0kjU#W zYqqN6;WV(##@LEbu-58kL$$lvL{d^EpXP3?JDRx!UYAf^2s*{^=%qzrhdnmV`^uW~8nLtCnef&T^tP4FqMt<|tJEEJYl9kfS!nf6O(y8zB~eCSzb zUOGa%3OP#UVzcCa=J%uO`)yqLP>jq!qkG41!k*VlHNwOK-u?}_!D36ye~PfD z)RY35y~z9Ziw(QO{}o}!3-_&QK`b_894OB28#b07mtPBmD!qFny{##UTRpX)pqV2T z)RZ)Yr-LnNQ;eL1p2a8T^1S%_-TlQQLJ+pw^^nuV z+x*2@;%R@(9I+Mdyc45Mxe_^0hB;Mqv$pWlueDLn4(z3wh8O(%QNudI1>4pEPzO8X zLcoTW)Dg4BHU<`8$6F6cw>O}%(GF9+iTv8HBluUg|4b9+45eCiCC;aIsEg8-o5{4* zb>%Ek``UZP4Mz`!!xfd?o6&|jOOvXes9RGHr5mR(tr|_MCnxu&c5G4YCAJXfaXzA! zBBC9moO)tUsj821?l_QE4@=KqHvo8bkj}udWelk3_A*;vz7;C3zkYw4ptyH-UM2J6 zYX!c%WEa_LYx@r$I2Ya=UZBjX?{RPT?QgxY1w5zJ|I878ypq|czp}+ll@!Z1%x;K!J>HTo2~z@Iej}fx z@aKA+*Bz1?AzJ-`a2~Gcn(h>nB(Il}P}&Hq=_IUx)t_zsg+(DYpMeJ77*Nq37kscL2GEg4Cu1>|%yEH{9} zGyzhoj*RqbBIJw$&A2`-Z6fBJ^Y~@D4X=()IcOI~hnh=nTrR39sCN4bsRfBLbuv@i z9~4wAWyQtXS=WFy<&QxuZxZWnx*`wfA6mdLzdi`zF6Q=-*t87z;B53=u)^Gf&lcss zye8HykR?iWy{DZ)f&aaCSq=xbe^+q0nP}0qX3(p~g`$XSbAg062h#e|Z-mqHgF!U; zzLSz#Ac24uyYmC-rS7y-Sx`>PSa*}wdt`{4?a%6*9{06;U!=hUS{0Afo2X$6sS;#P zYk`V-T(svi0X}rHg_zxMGchL8fr-K7-%(g>mtb#Ey+M=u3n{C$RD)|MQ_JIFG`ckx z;YGRHZhe!bVM=KuCi~iLP{YmJObeNJ$I*gpN5Dm^rqMD6dfyiSJ!m6>$#01Jl$s3m)6*j8&SVk9^BFjU<3fgF?rkMLu2a4(fSRw00GVy&8T?D~ z)p&ojaTF$DrT$5@t*yLU=-jpLZ9UpI9z4ovAoo8OsivfRD%G!>KW*Egu5(`ufFphU z;;5$m?L_aNW;E}+jN&UF*7W*2(2R2!$uNelJ>Z0&Mc{N}yyCapPe%`0atyHqJPVm8 z(U_c5Fn!%^FSo<=zV$43^wTjU)Rd7lkepJ)s;OZL%8hpAazQjBMG^-P%G_>E(=jBE z;9ogG;{73l^J$7a8IIpnzuO*+$uY1*4aFdSUC8OEb_y|QIiv$>LoP+g0OE+ZY>Bz@ z76T1JD7PagFhiVNNYhc6rb0&mox)^ba7QVEeel7F1793b;|{bz!ldW4w$k=`N|+i#K-6*%yPh<>6o1 z!**4evo=I7?2LkQs`AfL^s2KMw#HpRyIozTHR&QoV_&8%t;MuhvNo4o#2VCV$~C*! zu-XjN5T~%-)+A=d`=Psvg-=3P)~}I)W$0chG~tuiQ(6SX+x4_<1R>caw63Ld4cdxwH=-LhUyY55gREqtJ7X)@6p~V zR-9ZC_YKP?wrVmIy)nwVCy^v!e}~Z ztWD#xKfROD!txmB%G*1M+hopXJ!L<*{(Lar4~$U+&WZ}XzwD4XYxfc+?$rzR%-Su} z_U?ugp9&J1U0~o(y$tNvJK4~ID6txe?hQbVQ{`!hu+MuVO*FZ;n4+>6XmQj4;Bi=T zOa-l0o=j_*Dq`4hre&X(X~$9}=6lIB^S@4xD6@KJ{ZqN%+1IDsI;wJkR}#@u>Kuvt1x}OT{Hu`ln(UJR6A$WguQ2Sge#4R?%>lH1!p`J6&xeOGRIXDoS^iL`Z&riae z6&YrA65nRc_JZ@Np^h?g)@xd{Pc1PkZRmT{-_x!5xz@10zYCcWzNBPD)%r_nUhnV!1NHYCS`6o#=iY;X zOdnqq;cqGtzNv%*KZB)`JnQ}b{!;Ne57V~6VmkW5a_UYhCdZX6ApC6z9KF?K${mKq zct9JRC|Wo~+>zMJz#N252Ji(YamM8Lmzj$9+XFn4RLCj5)x>9drVWLN%s&l)3w2e? zInn2gOu^Gi!!RtbG{NH{yxYpNd0pBHKGGXSOq-R90k`tBS82LGT0R}P zuJP{l1n}?^Ov-IdyFRkCu4CjS?|=U+Pxy?9qzkyqDJGP6SgLcqr^bkz?Jvim0SSF& zTJ%`#uW{T27n8hxGHvEqG5EGHEq9QChPQ$aat@A7f-uSCl zT>Tf_pC~rs{*zFT{~Eb;4Scgqe!Bxtu@uz46yF9l#;UZKbKrg&*Vbko5;wnk!z}S! z&^v!4qvtTGa`QZxj3@Ge)MyD^pt@)I{$oeqsccln?YO+Z06fm&% z)^7kGM>D6WDUv6rBE*N&D5o4!5ltT|c&rH@P{Zf__$dNz(Vy`Hx-7EBiU)I3sG{Sy zJuX)8$rQ0b{xStM&q7k{m&W{AHmW#P3S%d^`ykHgCBo=Dq%D;x=`A#Bs<7{&sStpd zp;q}*@mdLJcVJul7Gf&8Y+nZgRQ!O}Us2n#-3$A^mN zGw`gh0T7RGPBHfgNycbz0<$PhlG@+EX+~4}yLyT7$7;8k13|t6Ww`7>S6^XZ)Nqi2 zd4m}!N&5$*&pyqS1LD|u(+~ARHJwq7a_82J68@B`^6u{9?Bf-B|Gzv=!)f`Sl6WhD z`?Ig{P7pF5U8odvX5L)+fZwg&3-(Y(u;nwGi5IQ*w7AfdKreTa)_OqA+v9oCwZ{o#a-R) z*Pvkz&{?@7C^=W=%$$$od$uIpC6J(-4;2A=%0MOqTNe}oPRYPs26iqg0^qBF7Nngo zRtRzPfu8uwfbt2%wSiD zR^QuTkH7^5%w)p*L-bM0{vcKanF?-9O)oAI;=kiJATViNd7$PzT*FPxfzv?ts8Rq;kd3Ue9~;2($FRnYu#($QqIj-uCpoQ_>cOJP(9fh@x-5Ta zI^H$BakbDhn*r;AGT^jUav+m6;+X~Y8UPCi6#+WPz+eU{4K@I7bbO8E$fny>F#jnV zxg3nFoHsTNF|dns63(;R9ejfJPld-QJ$V&1S}Rp!X%Bn0qVbS42IE+nLAf>3AkBf! z4Rf<1hYU9xdb<`aa-r{QG0|s}*E;$1f4_iHVbh@04^$VaSQyS6OZV5~mPN*RIMcj! zA{n${9U9klya5Q1Q(HLj?X(_<{UifoM@`ntN!6-dGbgu14Qu|VL;uT?*&Ua=c~Zm= zJZ{1VoXeRvzq169BQ>D-J-~%@Z@oN~Y@N{bT6Z+Q7Yw9PXg!#88^p%C&ju(Iu}iMO zX^guirEioRY2OCXkn@br(icZ_^!U`DIMBwLjGkVm{ZUA-5ABslDR1mmmgJ`fmTZK` z&)G@<)A>fRkayk$v~;c#b)dGJgx~gMRC~1ux@D8Z3&ooZEWf1$Y{}v~(kQTcxy^tV zKP>|1zjSk;$F*@A7Vtub`@bj-KiMoVNG_L3PaTYaGzOMdj{40nm1W%M6%N*k^XIi= zOZEQ1Q`J_J zR_JT}jm5Z9%ukeVy;Ty=l}8@k67mDJ&O+fZTz~zo9Ce*$Z51bdPjg}4pN7JYR1fcQ zU^A$;Ap_=S;!d-y+=HmqHn9v!W8yqKC?tqmLF62wS>8(RKFl$V5idf2Rf6lvQ8TRs zYZy7y!sY`~y|+WaOeavC+)Gfq?IK?EW+J{4PC0(=p0r}SxNUKOiCTQu2Sh(=;N$Kf zgorb8yR4j>?1mTTz~h4z6&~^v1xiq>9ddrN>+Q9TM`7mnK$jtu8U9v|+8t6@VSWf? zZva1BXYUT!V+hXU?8LbxiY%;@j}|)bLK%uXHf%Ve~cjQ1i&FV(uMsP1=p zFOtj1gW59kqjnJ_a2Jp&T?}Qcsq-!gA1k5}44mlCKrkKLB?9$5ri~pa)7A`hcM&^5 zle&0`Tx&B|5K=@b4F6uNz#w^t-k8o|~kKgLjp zY^gGB+AG#_rr(Di)zZ|SPw_Ex|g}}y?`u@&fbudSq3U zA#x-c=ZX-Skc)CV@r?Fiq&)KXBc6nPme+aT+gH**K$rVsL_{bWv6*snC4S%RH!ghb zlw7#fVL5j>Wq6t8{PsmNR2-}*XL^n~#gi5VRW^TGgY|8aSMh^;6)CrnNAqoa{1FJK z0Fx+VXAn6b5vS_w96=)I?#BGx_a0PDLfqZ=oXfG31@Oc^TQQgj^|`fi@a*D($KSWo@LtW zJ~GWSPtc!sv;MjYI2 za|W{a43lNAIwR^kz_iE=s&WpX3X9)CmVG8n14!ble;%Ir3iz|L$~tG-23OG3bf^%d{f;s z?%LaMaPliNt11M~qI>70#_WXdCxUGFv6VZhT&b+rJZf}aYQjtpN}J5kpf$YKQSO7w z&X+apH6Jai_(9gt;{KWA{OPWCaBQW9IY?P?gF0Uj9ysy>Z0NR(X)$!>f;cNtz_d$Q zG7TSV=M%myFM>8039Yl(SRQ{U!pUByeOO0TE=l3@F3IQ5@0N|Yx)}|9kALOe^i`B_ zsW6N1>(lN~P&q}c+RwtG$?2?zC0)NHYI%JLwIm-b0&KmE8?v=7i@=q98R%!^zzoHJ z@`>6!2F@H+0v1FcMX?Hh1Ko1cfZEZVzvan(`mWxk_@EXa@<>qhSRPVlg|*ntyCOez zJ*Z#)1m3=8{tx&4GX`#CWE16h_qDwJAWi}`!mOcuq~bYcU6J^$QqQhHv!+O?aaE%#b6H$W@+EYsTG5G&qMObh&GpdqBmeesNeu1JEhfP&jNJyYhU@VTU$0NjkI z$~$DX@pXG_o^HyW)Npm~vC(LvFPf-K2)-~iusc&C!UPYVHh=upPeL!9z`xQWhj4Gj zApNa{r!!T=)XHV*G#y^$A;i0)^~x#|t%{U6e@k|RJY9#Id;@V9)`&{>vGzsSV{Z%h zt9=_S+lhNLhPvm;zy<~|LH`DPJv{9V%bB)whn61+S9^tFt-PgLnRIu=ox-7aAi>4Q zAi<2{d^~OG>>V))-DGrLpp5$86>IE@cR^blEYmXXO5(Nl%gryQ-2XH{ua!A(Yd!I3#C@S{ z)P0EPB+0-e$rD=_8JNyMLMa*OS_;6KhoZz=20oRQ0l#uEUBUwaBt8I8wSob#q_hff zD2|sH58D_mQ@IHG?SZWDhTL)HcMt~3!gZAWx-_8(dtL&B^^$cM@({w#RguvH_<;&; zFs*v^!V-@Jts*Wa4z*-jhD=+`v=?<{+Pz2eWAe9#TaM%-MN_cKQ@ZaTNiwHXJ+yRv zlBWY*e=oc5jY^MR^@XAPBibleR_YdpGG>(hSWYlLjL`c!!_%)|$E`djbfc1N?wZdNOS^Zp5+EY?f(x zOv}T4G^RN|llTR~<)4Ap9XG}bY1Y5ypM?zE!JRJ#?%)TQzcTGQ))-8Se=carxR|^j zC)2WI+5x7u#^la?nNvKi$ohqBx$lRn#PR|w1J+Yo?#5EVK5v<)3#Eb^)eUN z=ysI%LVi@|-AJ#wxsYN7DavKdPDEi;3MqC}=A{Uijb1{^`BlH@X7pthhAg`@N1}V< zI_&4O0UI$Kl`eQ-ZIL1n#oY7V@+))$rzK*Sa@l)uz2K%+ujGx@+^ZAQ`MZE^prUdz z8bGsNiOJ~tD=2nzi(KyBYor=NUW>`1{A&Qxb^~Bd<6nym(qaY<>@)y;<_tab|~`56Y5_$%i`ilXT>jTtIg&&glHv z7K4j-d7cPtgt4}sFE!ql&szLi^zUF#ntZ>ey+Jx+3?5nGfV=aCj#gs0;ibdGu|1b& z!RDRN&eW~(J#Op@eotdZ3l1D%?!~9w^0Pk&J%zwE2&fzTBLu||0#=o9Sd^#YsP^=K zQE7f=)bkDI4(-ew&9n}1_k)a}0k8|7c2U>IQcKBx*b*7l3;?ZOLr)yS!D{qWqzSf; z=9DRihs})c!6WNh^v!GWMPv0Jfc^Fi_))@tHARrrKVRQk^gk3K38|}#uoyRc-qZ}E zZ*6Mcmb@>B<%ND0l46NSJOH z8iU#k&I{D#pY%?6u;mal@KPM9SA=6Q#VWAf*U#SfK%RzckeK&kW;c+DzI8OjAL}^E zZ!1pN$$$Q|Uy<-!40h^P+A~7%*AnGoR?C|!W?sRZ>)v;)KQtDs)v0@9M@x!%BucyV z0}}1pQiBwK5VMqbOgzvAMY3>krCV(r@c`l{!QSa3knMdm$oW3VBNvJ5X!7L|KMqD6 zd7+Nf)39T7>7$s2Ie&umFM~AFS%Vy1zUrOGh}%>RQrh3ql#YE8Rw-u0cP5UZ?{jn_ z`_E$Wq|Rp$9adqlg1SVLDh;%pqG*;JR`#bkI?2CsMd zg(AJ&Z~O@K`$e?OR$q{4-@O`S;$BA&K8M0hW(yF#A}ajCU*=1k6jy`B`!#Hz4>=kw z>8OayPoobGXg(X&vKLEZRaIY650)%YYH^m<6s6T_h;G7Tt$Jy0#~)JTlFtg?u5#By zDs|5zyrkmfLp}8r9#hhoSg%wPmsmShqCfN$v2$+G+pZOV%k$H?>RSj;Nl#zloz1rT z5WcVHBs4-%0j+ePlBNyr%goF#$2)b*a@FnvXEI+xn6Q$L5YE116#a)MPh9Ejd2+q2+%TVE4 zcjuT`JyH;Bk!MB4fo({$>@M))-4fKZlB%WdtQ>T7Dxs(Q_l2v8$ymJ5_`K>jWh+DkY0z zb@>MxE4)LJW(-YLJ7|#D4o)^yWGsyF7>NGM4wPb|gi&1+MVwQOm~cOOKeYBjHr2&; zqhu3>edGZX$kpt~a-n2eNj8nz?Co@It z0hv5>q0A}`+w<7M%F@W0tFgH=F9ZPza$`6pM zYYDj{*zMvhj{v1FJZP+IWyY)d$uN%>sz9yl&kQS}s*V-JGA6K?7yWD{ zRLy2uC^oH_Rw!wuOglMQ(mbrCdcPyH4{$7kp2%u-l?4zP+gjmBM>DJ;=lrXbI|Vt= zikOzMK+;@n1TEACw7MCRmJAwae^RZRKb=M|-GWJ-T7Nuc+X($PS*}O6l$)IG8yz5ShGtKQLJPt&l6Ta44=t*6f4u~#V8VZRP`*ym|wBzwF>2MDke`DtVa zAih)wm;`_=)%5D^bNo9u0R!wRu)iMCPkN#Uler8&^dMMS=2|cF#!Cteg}}vNCoyp)Xa0 z8?kT%y4X|)?d&Klp3Fdkxel;j0+$$g>!=0zbZQs|aQ#mKl9ueGh|{UPhIkspdf_a5 zT>1Iy?O-jZ4f$0OE$$twm=G(0Rk6;N;-Ia#>saCW9@7~(4zX`+`Bs}wDb9+Bk=knb z)lxgm;YMJfz_6?R$w`Z!#yas_eI;WfDt1=*CbFIj68n9o4sdR!vmLc{5jN?{Xx;gg z<_Z@%c_Ffr=_1>BOrml<0`18QA7|>h#=wPIcH9z|dMsR_=WzxDJ{03Bo8{L3M(T6e zwUrL#4_oY_$*u~ARolmMH`cM7H@$Ne=CN=C?eASo!)qbCoJ}d_zTDR9!bo5~BX-m% zAGuxbCW^71fzsnzz?kq7io6SS@l&UUAJCxqB>_*Zt$2g~>M0%m5O>-Brse)Q>l0>S ziQeS{xLcgnvK!HOcahck?nt-AO$lthjSO9MS2%L6rn}h0h$M5Dj>S9cR zJ|fu&A0&%cExsum>mw{RmjS$PCV&DTnV+0dS7&%Y`AUp|ja8NN9^q=W`EjvzkwcR{ z>LRWx6pg_ium(n0*s6*M6t9?7^{oZ_wM7GLtfY^+}Tx#Ri9 z+!Len-L*ZgdoyQp2Nw%^UtOp*@r8PP~mC#B*M673)h%2~lct;jVALIKvzT`_#R>V=zO%4N=4;RpXDTiPq>4 zd(b7->tS6(Xn2U?PW5ZMT5ChtbPh!c4%XB`zJ{^c&xm_%E#e?T+32@IcMb!R7|DnW z{T%6Pt2!Li3OV&3TQ`a`@qIw8G+Gd*h|4BDYMef82%go*sJh3MQWDD%b@qZem=NRg%4|gRg*Z5&>dVF=ry7~ z;i3ml42QOqMOwg8wNvXTd?4qfrV`KLcq{WwU8x!sVzFc*AK|?ubZ@}y*9R& zxW6@-VY3rj*q9Ffpzw0UKMc%0r3H*=(L|SVGN45@AM3>cv(QW)WJBx=BOwi|iPcB_lvj)EB55X9Rgh~D&x+`P!D zi9iY%skHnXVoQG^|eR-5kFv>E0MhD(})DnT-|R1v|(@n=2Y()&n;) zYIp@1)g^~p}k=nZE`BL9Wl70RpcdQh&7QMBkHA*r(O$*>;M4Gz;MMn#? zb2QMOX6m5ZqU8ks-i1Z|TrrJGXjFbxc{aU_7OTpUZ6K__g@prXLu2?qSZ)OqPZTn- zD$PIdZbA>+$PcRN(H(~Ip`dVBM!icj^t_hcl6$8-hBz?y-Y>lL9)=IF7OHa6RV}{> zZEY)trdw^1?z`;SVcWBy`<7uF);bZL2jXy)L3TY zQJGTX#5eAI1}@lW0Z-BVV1Z8z;7L7^aUs#Jz1UPrX%C=*gAQ=Cy(0E>t?$>#=NlN) z?8}!0-TJE@Tk)Qmh)1+C)oSr*Oazo_<<~_quZ+2T|5}OnVw3X@5xCJ*Is|6gSrFo*w^`**uWcM)?^->kXB>=5HrVAh#|qq2!(VCs7z_8ZGJY>5)@ z|50vnY}=oIZkfalT1mY6Z;F&%Q4nO3DY4?#68o{EFv^gQFu=h!lD1CL4lpe{M$!() zAdN2_g;gy&0ho$tatZi0kLo16ZX##~1KWEe3cLpJ)+5dS__4w%nUTTsl+Pa&Ke#uvk63T**+$3JvtOvnY{8 z7ZCqmsUf!LA_k3aOnk9QL(J$RIP;kJdbNgVo#~BGiCsiNKQJ=kV^vMC%uiK~sa99T zjzcQ+y;io4^tvhz1}i>&!!0Sjs~kJeSX-PbL9qs+#=TX=+xPh!zX@IHs@Su>W}`X{ zlKO6Z`Gy;lXQE=q<~p>wtzmmB{R-CkCgt?Ku24-Uf7W`{D$%X3@RA(1HjL_?nPwchP!6y952tUya&R$s)yE zOtv;x922I8`O8Y1^1A~S0)0s@&^L(cAb2Mn)=SnDU5hUD!Rld;TE2GLk+FH=Uu%vS zR;cg=%RX38(EjA4Ma4+=#28-$fd5(Onb!k)n#N0@V>}AtKSs2PQU+3fWWa@H{Rp5& zPXW~F31I#N2E1uZPf@PfOq)1S(y}J{TF@;p^OwlNleUgNa4dcp^VH4%U7BQfnF4k` zM#1d!?mX|<0PH=%t{xr-Oq1;C(|oPJ9wf=?g=AmNkU(iKg-@lwXWHMhBrT%1=niqc zLEAZ3(iZd(Du$9*ABFD*CH8^b<)tiF zjWYWvA|T>9#{+NmAXf^zt9Ny5Rx)Qj2wL=oU}C0BaAGE^;A^3Goi9D;2kC_GY;<~! zWPiLyVn>sr1C z-^m!L8LfWvu5rx?HxA$qs;P>;Yen#uTP zJbSZ(7w}V=ph<$%SvFYo1Ct@hmUCw<&5$BH`$_k}ttiCPYlb7z;oB(cR@AbKl*t+* z7M1q1p7mWN?cEUZG3YoHwAS4uZE!a~+0W62hcjT%LjqfeD&mUi^yF!c>L8g%_*J`# z$HOJ3=?Fh7VFsRKhYo`d1jiBfOd2K|*`p-uwG%CI#u=l4y4e4XlbpxFi5wKMbbh*| zIVZ_87hf_$Zv75pSs@4N&l)@0mW26zmJc zm@PRErzjPvPl_1h$D}|-mo-{|R{)BccJ4Pxt2$g1zy5I0>TY71Cwc7i!(+ai@DE2< z61SgLZEcmr^F6*Wq+S~K->f4PyBQVoc(^FhTUPmTiw>GO0$;05M+g_(WdzWvJJcwz zd>vw->25V(L@B%dEUEB;COfmk_w+vv1Mqu->M!&!d$p2?#rKo+9X~;(d%hMhqKiLC zKfUqD!jwGdAoL7%YqmHg*@I4@m4=KIdK!#`9=$UXNFAw&!_;%*S~mCu_wzEU{8H=n zvy$`bNZ|yZv9$AJNedXIh_`t^-Wu@83>oN(Uv(SbTP8VgmcgX_E{&MjjM-%n&+E%C zP!H<%Z25``Mu|f%Z$}}aX8-b^*Z>>P_ zqzj|Pr<3E)5S)j7-qA|UuTNBrXWFL9G<+PqWI<(rX9}*O`8*xlIUz6?8pmUeP2D=N z)AE(y0w*#2?dbV5IVD)S$fh~RvFV5pK{#mbPfi-*jee6EJw|MSEgyr#hhkxs6QAtn z?;$2SXgKc}NW$@haX8l!HdeHV~c`mlgA3LoXxcJilp6=wD(N23752haR16Y zeUr|0>!_wXOHiT;CgsPD>Xb50Zk)tkYkg`DSZ?B1y|UP{9_w_WyZDE@|2U-6w7#Tu zukUX{^;1RDYMlyTV?zo2k}3wHRZKhDNM`C;Q!p2&N*}OrPc;WVmd}r?s!v2*X)4)+ z#tUP`jfaY`7CI^xj2F7|7^u@q2Y51GEDu(i0N`G<1U^Ljn^BtyB8OcV2y8Eb7VS0l z$J67m`csDS6DTb)T~U|5BVC#xnq;Mk5YEL$3fIHoAN_HMN*bd>E( zOX?zNk0#2F@}XisJD!R4Ly^@DKLR@?thT`g0PY#eN{N&(m4tX zA5M2~H~DA`Iw;4!RL}eh$TLl;k4Df9>hwEJlxitW5f9)_8QL(s6wN0VvT7qH(8V-i zM3X6y8#h_XHJKv(b{D24rOCW6oFeR($FxaPByHIge=AKvGkyWRACAnhWhPDY$4#JS zc*TZu9cOPkb3amlh+iN4e*MWw`<;gWq9{D_uk77qCBMpj5WiKwGT{H5w5`*n&f;Gb z5$t_qYTmK4=q?+vx}nzQkuEtWPsI=wneJ~y5mSY!qoyKnH5O`7-egr$MgDYAH8mnrIbSOzW^m(vtT0I|%QCL_RXG zdanfb?)A48^9eELRm|!6Zyc)eB$}Oi6Rlt$^V`wXUlookwc%HME_XWMPnQb(U8&J@ zjB=?5(7rZKm*2$K{|V^9D^wMrOx<1e4}BBjP4`~Yp=sG+4RPgk;WYL#@nV4>R;N!; z3Qn^bAhvnxPieU|@UqPe(HaIavAbIhN!$z~e?m9dePiuI6kzC(^5^t7wG*tNRNStH zF}b7*&Hm|7@^GvM8IvyN5p$S0Iad&W_`28sl8NsSj#1>n^G*$0ikc~X`sJr@)-P*_ zMW0jU7sH$lDQ>pnmXWTQ5=2ZXccwU$wtprn!UU22C5Q`7GZlVa+HDr-jfQ@sC(aUc z$yBBv{f+59bYPYoj9m@;ZR!I{`+aBWwuk`5oGG~hvSQeCwaUNlVhQ%C_*H-2eWcjg z;`46SY$Vfuea0N@{|{LoU`xw3DdMvuZP)wr1F_t9#twH(Ro&qNeVMHUA?rbNAUk3w zMb3rrtetqACS{H=@k9oy9A?0s^5+N(UtroF1(IeqSI|7?Vz+rJHJGbJLfv@$r9bL4 zbGXr-xnf)|1kJ$WBHqBe7*LfrX}E2;&I9ql6+v_*la^S6Zl6p;K-Ej28S|7d@Z|Gf zOX$WtC6F!AeQom8wJ61H{HiT+mAvN558e5YI7(yZi_GlBUj|EG1kkb<0dC}W7r~0+ zp~t(+;IJB)Z=b>T4Zf4KKRIcy$zy>c;z?Hg=Weq;s388lRWJG`8&lX)Y)&^c4RoL_ z3l#D4Yp0VXSMEa*N3Bs$tMSSFmAxvJEx{TwiW#yHR_bl0MJ(xb6Fd>o9+?|?q0Y&L z(8R;EdOF_%&&r5|Ed#A7$s*8A|hTaClMY$ zb#Wo)K1*N&^-__Ul{N`eN+8rpJVJjiLS~&EByxU{a8*y4mRLp7x;h3{q6t+3jp_Yc zoC!qv8Z8Fg)KLq2iZJz}d{uuL72=AOqI{&R_RwaS5pnr$FP5Wew>W28{$l)uU-f7+ z2qCbUGjNIMWzkEJTK7OnD+xh9CIrGdT}d>wY(`IpXi+=>yhH$>890V`*{mv);Ot97 z11)%6OZ1)6DbbyH8Nw7TKs`&u{31i{)_M&)(`POQ`+DeO>X!7sS~_~mG8FOT>t0)@ zf?zW|-&&=-;V;$IVUHy-L=GZ0VskCPzPEsBqgpV{i@uOt9&Eg2->-9FB)GA1^YcOq zT`Er9CoP3sPPCNUyj0H6qW{=d)jM&_PB=?@C=_0tZ2dT zS24%XhoUf?slRn>yGj0G%Z10CzZ^Q;dq~>J_uyyWw0Z>;8TOaJ?G^H}hC{#2eji{d?&50i(~7KD3h#rL zF7dSZU@5n8u(Xg^A}oqBIl*!A6r}GBC0~DX(ryo>QZ&1Kp%($bu$C{v6LWdQU>l0}x{&-1ro>HbCgkP-)%Kqt}u9WP5UW$>IZ=-u*&zP0M-W}8bGArv7>N28Pm*2^2E1$W ziXHp7d?vO#Es6X9nP`ohoj%#NM)$VIdX##F{^@zi8o5TX7eiBE+n;zhp&9B|&G{1z zU!(9tx7llugyS_ScN21;J!jgG8-wY-;$2|rn9{x>k z^gc7)IC8NMrsL7&NB8a-Ibv`R&QV+qgWwb>j^_pga>NX55>xXlNh)IT9S$(0-8qW8 z7b;+*-OvU8aL+Mt&+3Lc)LbQCo~t?SYq2YCUv)wLib+7DSIcgWRb4y)Zj3 z?%jvh2K{pwR@wr7weo*F1+NbkU@=GVu77dQs1@4VW(-nZ+IGNg?r-lP`o}xSTMX!e zw_|L(mi*=n?>WOB+Mk@XWPhBy^$)^<+;~Om&CO1AsEzvc#*|2{H$6b`y3)0AIOWax z?UQ6UJj)ZtXi*QMQ71vjK4oD;x9~W45(f;J5 zt?og3d8mqXv@tY*)sWLK!!0JJVKrc6pF1&Ciq0n}MWUsWoVm zf}Qw0X_$6a9V+G_vk%d%)E?Yoy_TIv*_cgGQDKv$Ic*BU8V=@;a(Y(3=-OTAsDc8k zKb>s~B!9^!F+k~UhK`8il2&K47@)c_?a&!XyKx2u4o05Y?>SG8@_q=lmQbr6pFA!~ z_NSXgEtqeCis-A7*7vGZA*ZzidfmQpemoz%(kr)zhL4{u3WqV>!qPS4NpC-niMEUn zcA%x#P%v)mAIwtMO-DoJWm|PkzSZzsbO?495kJ`>_1p?gXFEtucRK`Ii)Z5*+0Mw4 z1c_`+2$m1Zi-~u5p94L3ql}mGJhh#I`!p5|wke_PNi7PU7ypWOeg(B(O~vzplD8@0 zp0+Wqoh<$?a6^B0$FJJw98V0U6N$mq=+QRJ;=np}zvVl=g~bt}omJ|5$Zk81KG{;k z?dZGHC=q|L@(IiSrx=3!3zWkNYJYOl4)qPD!+nE&>D+eF((XV|-)I2o?MD0c7yuh| zEt2!!&>cX2L$}r-l_+J0Y=aM)-@lcI;_tx;IbW@AF_aG0VIS~UnCOkSSy66^4l?O? z#ftoY7ehtE-+?Y2sYXTEo8C`S8!te4i(<-K(GiyjHMugODtE(d<-DuKfzN#C{|IVF zy>$L`8S{tIonj5^j*qq%Hi3$=`|GMP*5v$u2>2+XdSEHIi1a zCfJw;77JTWX22S~meXpK3xI=~iB{A4PU5j4NHG4p1m|SzR>b?0hr2zz!}mU?!m{c- zMI*)|t6aQWq`zS|lG%=sjZAwZY36%C^V`leM4;Lu_>!2G_q(L+m$ZvatGQd!-1f@) z?Ax(--!K^N!gq$t*(W(Cfs-3{bic$s%fQLutkfp<4x`L7|KFajkPFazqkp~Xg{>1|4lXrab|4u z->A0q{nDcy(f?Ik9IuVys6ASTN0R;4ev!rJtfJ2oNeew7&3dq>(v&YLTf$gsX}@QZ zb2>QT(N-RS^uiaCRstHEy5rEB)%iPX4z^R((v8Uapu!I=wLS>BT_2^~?1MsAHq)x; z(Sjq218p-2v84MFc+0?6105jZkdSD12*5=n9pGQ15PKSIj;71Q*rJXpg;QVv4rQ(W zhFngU4#{uGLGe=)_{K|L40TOaMjmFaRa}`856c;HoL6Ln&Zv`}_~dM?Vz;)@VLx|R z@#TRfarKFX27VPPrhMM7kf570`0PoG};RKZ8+rb$^^k^N+|r8@F&@rVFb0>UTWbqolT~ zM}?8=9z_Zs(M$`WnCK8AntfDcYB>W@iIjaD2g7b06?go;Fzs4*NvnTMep6K#aWQTS zl8Hq-E;qLIm7G=jg;qU{TMr7c6)Od3N>;~_WN;D# zfp~H;#8vb$QU9p{KQF9!6- z>ZDgv>!>9cG&wXQ?GGM)q)R8oQnu+SF4z>}KzWz(SqVpz%eJ3kEp#7&?s>oEF;yyv~5M>6#!>r!!(U zHHK+%cO-4=8FA$M64S;MOIpaEA&ACV98yK=HzUphcKA~ZSCh5PQ>gnN;9!f{vkgO>P`Xk*XFy9?O8~J(Ng@KnI60q`u>mfyRsfeoA{+BVO#v>p9fnJ&i!~#bxnH`nerxoS zQaBBDU$?+xO&S?F85ZS9bAIKXjow#)g&y_SNbX3AyMig@p^>4Lsr0ri$|V$K?gR-O zza$n2i8K4% zt40>L4ygngY;xniaOPH`ON7=q1SOk^uQUR;yJ6Rcu)t(>=tHB=WfYbcr>Wi zu)pC`rosiPl`TK4BU5lV)R-n-5vI+$290Nr=%8gsfVM3a=sQL~9n+%X#&fzyUI4%0 zvEaJ`A33Szw4l$WBFlN#p`z@J4)Ef-G`R1&w*y`yw|p8wo!cJdbwe1u+YJb>I?d!#081Wz@f7AhU|U`8hW$8FS} z+F68|;O$FI!{f?*QhMubYxKEDyYhqQ_Rl&p=Rb$qQt*9YGp}3F*usRi-F=&7K6~Dr@AKg$rP09R0a!$S@Zpv-A18E#V7t)}a z(~CQD4D-8ly!jufL4VX>u*y@sBhMnS3)Q0t!ZuOlRixCQbw#2{9AH{y_${V2Xbt0- z$?qViVgMWAvKZ)9ENi-%*YwnfNF*MKs3!$4VU_0Wex+iI!d5>M*u|mZ$L0H90-}E)AhV93dFhCkYfPG9VnmI>id!SaQg73PI+;Ah zo)~XCm8PYGC1NEzH!i&_Q6iM8+71$sbzvaglMQmM93mes!ONN+ ztJV2%)2>2^?SQKI`+bo;n0wzCSLuXp4x%aFwTZ>!PA9LJ#XLhqCk@_VgkH>dv2^PC z4m0N`Tw-Nez~W9sJmdexK9=*tm-FIJ@atFN?a)^^9%aQQIhVget}oj5EjJ^sb4ogEGeApG9IxLzdC6p zU}NblF5iy-eS1yPk3+0y_?Cc=EKxI^`TrLP8QwGi3I>7TO)@B9$Oz~K(*e>p8XF*C zW3*sm!3ous2UOSwk&uwW(rFT@VV-Tgq7u7 z5~Xc%E)*oBJ6HpRn=t(qHxBGo2QPUOghLbs8*#m76Qv^>83~CPoSu?L1?%nLeca1mFDHDL&s)9YUDB7}6U z9E5&4r|t$qc&3*L1XH3P2tpM`v|VH=zu4x5%mDvMNR>OBQa)x;|y^ZK(>YpNYC>T>%Akf?L*07_)udtea1 zkOz?DicA2=FCGW#TN#Rf-5IHbSjsz$L7-y3K@go`pZm9(V+6W%62LdBpg{PQ_T6o z_fe6M0-ga)4f9;#eV(pehz6gI16=}MeoX>N0n>oeKx%;Z8hIcqK>k<=iUbVt7K0`c znTP+Y0+9pbwmQu(j0Jg~>69b-2DIr?}GLI^<8-NAs$hH6< zQ5Jea1TxwpTLE&EBeEvo#=Hx%3m{8*A}=ELD>#uKat44kLCB>5YP>}j26&MX$PNJS zI0pG6kg4ocyLCylu_y~CuXinkZ$m>8ViLQ||0sekDJWBb9fdR$CqS;tKq*HDlIWYwaMT1rLZZco;gM62!FZr3 z7;tDl$|8^ig9?-wX#{TUphN)L)_W+=fTX$qL&1tgU{DNdKENYQL9GJzquxr?-RB6b z=trHTL7>kLDhm)*{u$~l9s)i7p^5{ue*l3AaS;93gA1-jh%R_weZYJ#K3E*UzXaeq z1Xk4$f&XKZfN_DCIw-(WK+f-|!7Kmm10(h`2B?Sz_=OGwJ))7psCoD>Vb78Ip24vg z{-^Ss1ze6u8>~+dyo}Jy5dzZz7P~~ij+{XBdh7Afbj11Fi}XJWG>%|&n3eQlh> zYzQRo1oHt}DqUbg0L{C>@qi2az2GZAUhf09f&gn6e-E(x2$7JY_+al+P{?3!yTL^8 z@qX|eu+j>b!BPM9e6za5Pz!?+6MrwP0?omi)^Ln725$q+W`e8TMQwC(ctnu zhx=F{rbe(Ft83(yLH{H>Ls?V$pZG}-X|l_fz! zn&kLjTOh21;m4I|=0KCHbfZlI+9bVbP{3MNADRUbphXk3^tK++OxsBRt015S+a%;8 zhVd<-Ar3;==@Qx+LSb|n%@$Y->` zYk=`alas?f_oJi3>*CQhfWEqipA^|2;F~;y-L;VT#jgL z2yABS88PAxAA%46-39sbU;8XK9Zq9CLqggmhVhmW5W!^F`Dox*y%5s>4vKNeD6okx z%|QOUdjZY=&#||Q5H-NT@nwhx1p>(~Aq>FOlD{FJ06e*ZumVVO1EB{{><@$sK<8Ts zE`Wh|kRTudSC|;05L8}7wcxyj7)r=Ez)MsbdB!7zyZB&O0~rP#l#k2S&DzH&RNqW* zUK{TTCkj>Viz!RE`HpT0X}Ni(dbKF z2=(-{7pY0&oAqkQxb*Z1=J7;h`)ERKv>SggX@kPz*I*AtvXK6?u2QHUFB3=sy20zV z-1OWh@9(gO&R~9YAcvEad}lP|%r#bxP~NbgE-SV^+TM;lS2H;MZ*ULI=V;=OE^m^a zw~!6|)*s#3)`0d?cvCDfmcobhf2L!ZZhEzitaR*qiM5TK7Lwh&B)_vh@Q-WpQRX&L z>hsfL-z8n=^68toaom5j{n1lHWgdVXgoUE}JTJ;dn$3XOXg z69z-MoS5d>zZe-^rcL}6Y28CSaV#^qT5YSQn)t?UsU0-XU~o8I__r|I)HRk(9HmRO zx0#AZDur+V_d?PliYgP_g{9ji%`eTUzL*|98$SbLi;H@;4O6o4;uXs6kS=FkwZuxN zdy>w`#8{3&l8JL2g(1Ogp%__5?Ftqj{t%QbI4(d-MGWX`Q)2k!Tc6?9r=H`LQhzS& zp!p8|!G#CykduE`v1Lma3RdhQHAuqf=;%9n!>@8XSMpUE(|pp=S4PeX9~ zQ$Mdy0t`5uWF7wV9xBf&YVsCTeR%y>l%nw)*=se5I zLhZx^3KlJ9U$N+m;<;bEJWxXRQ0#f(K`9*4X)E3}xa?}^6kNI*F@$9>`6(#X^OvHT z_n9Q;5_{`!X>eGX@@v}nFF2IwKA9Y6x6Th@9ZD*ACo~tULu(GW*#)Dm$9di1 zdm;?Ab(HG?r!=vLT0Pojy9x_AJSt8lrVqseRi?#Zff3xIy-613*TR+L0!jQ^A zRDOwc$znCV!`jVUPR~Wjz1;l*yEs z`?nmUuc_}SX^Ah37;7^-Ro3NmEt@)3&S-r^MfvZE#|9hfb<#?jX+!(k?%92>1M-djeNntGG@!OM2@OZP(^`<`RcZ@J35=&5`o^EHU@DuM zg*ha+7{Lannu<_uctG98zk&Ehdb>0k4B>)_h)k88~sEJ5+6w{Hzi z#>VNN9)Xof{C_`L1y<&KG*8?hVr8nM!)X18h+tZT7&tJ0UOr-Y<#UW_l>eP>fixHl zp#M&{=}6hPm)1x~!ppENdrT4-4<8>sY>pO#40?cy9UDo7jlo0&B8J($TV$YY!Wazi zUUt-SE0*KpTn5-u#TmSnl1Fm(6C7ojQGgG(R6S+5k#MO2}8V z4;`s#LTVmWJ2+}*0xg{f?QvQ1|Pj zZ=Q!rc)D=UI9Zi@Sn@T)YF63xe;UvYyLuQ_b$hsY&I~73-c+gws|T+wY?id1=R#M5 zuR^vKq+YvHyHK~cB)4c)H)&~}^6UN0{}LiA*dx$VA8To)XS9{Q3a`9*K^*4kBAvau zRXw()c}kseT~_m`@FmQ@pYD`Y?=Lg)Q$iY4?~*<7QhH(7v+}01=F!@vQ^Q@@pl4#? zNuWit66r(iyb)J6Z5ykA9>k5QoE7S;Mmx@gm1LUP@ndoM@%;z%@Rs@`9{XdKa5VF^Lwf%UDC{UtmT)}2IQ5uG8D*Yv{c-m~GhA?w~Hr`sX|Uzw_8V=I4+#jk{t9g>s{ zIE_)suh?SqPGM`s{<`wwSri>08m!EI6(2VeXTyR0Q~L-?z!;Nb!>74Vk6JuHq^H4~ zX<4PiS1`iUPsFduJ5E$lDIx*p!dEVj<>M7s%t*kL^T4_GVqnb7&~IM};f19IUWpcc z=O_+R&at7r?vC{)(c4ni^L`Iif6ktTXP?9$HBF?B5!6EKqWfL>hwxw{QG@x%Vj)nt zcNgo+VnRF5y8d4KMIJsfbncL%9&GN|4nqiBWPlir@nJ z{z_ndQuVp!)_YhZ>ZRD0j@`;ZslE~p8uv=r8l=uRDYc_wr2Xm%XMHL+4c5S@w7X?% zXBE`L)Kk+tsuW;>P773wXL#sUX3z22bL&;+Ho{rwHF7-0u=E^s>!cut4zp%LjG;P2 zcG7x52W7pi#9~{yd@()f1jDzfpSvtGL^m_g z^_FNWIfQmm^X_HKo1b0nc{Bv2gs`kk%CFV06 za|nJ(#6-X0x-5`L-kehYl|`!UUC7EUu&bC6$eT)t0eut4$}PBSU)lBCQT}N#!zlYw zE#Ekh_=7}X3u`^^ZcAm?R0gLK21god-c;3!r#z+30AYp0aO`8$3jV|L& zB|#x=bV^p|vK@c5v*MkXdYg*GLOOC!Q4Ig&Hr0#%}WJh0y-xy<>(NR}TGavj`g@>p~70?x> zPV4qr9iEEjUhg0N2H%IIO2ju|-w_0c+=k@HZmsl0qd_Mp8t zb#Xz~G+r?hZ*jg}Q0h&Va#*;}qL(ooqj{G1_ZY)`RL!b*2`->b>15hZQ-5;%-P_8d zKlW8bZ&=`I?BVDK&1-}D3tMjTao2qTv|4o+7mCM{8S||Ac>{MMod7u65G&c{qh2G&#j$QlYb4e}R=dR7=h4om$q!V*n z8^^=rc2rHd+Z?|n-{Dxah<3?iXDfz8sMs;#*-3TVCZEotKuKZsK#c;c{1d&H!=SH7 zfTHc|O#08L3~@^o%W=^BJK7u3;%D~CZp5au>-vP|23pr-PVN1B{CIj1f+`oA_V0qA zfj%3$(6Ta%t2hwRjVcz?uK#qsYT$666SCi|IyT`i-4w5u_X#TIOnfReN^IY3pb5>Y zvIMD04ZR9ybS`;GCj8?nIF*V!==f?&_HADytv5(1FNx)Q;)`JcXs44K>bB1lzp||E zeC~eLF^n)uoW{tAf_Rx(UPCEJHt5Rkk4YJKleL{nVj8*nK{f!^|cG5A- z)JmiS`LBM8b1L=Gil??btNj#+EeI{o9*fX?XYX{nK5u07mvTg4d;Mmx(#IuKb6i_* zk|QCOGwZ5^)_;jrsf?5RrablQjZqz@fI)rs3)8}HBdNynoi7_QTpZ`8tAEAhQbfdR z#{YKMPdIvo;((+2@*NK|j6ghBUyx492~F=Pg!#5=HGa`yRagGCxg))4tcxOa9a8ZTCeFGW1_Is86oDSo%TEUn^QGu*1aq?Pzf$UNhmW=2 z(Z_4l@)rq^$Qc6F9I>kWN2mgUB)JQpBB1`6kTU~9*oF5u%1asK!Cf$18AI_ng zjw837Jj>sK!xRfYX&i*e_e7L_;_%qFUypqwz7Y|%UQG5kZmEfXq-W%>PsG9M!W2i| zthtq@KYZONhEd)}T#qy7I^%qs zuR1dG=JOHX-Sg=$9eql>@h`P2?YA^zf}^+vY}KMpdlN?(L!qnly8^#dm?-{!SL+?C zj=P9^Y52bQJf^Vt)I}`XBdfl_fmrNo<`}M0g=)|1E;^qqkWiYCB}&@ujb1KFi(tGL zA4&--7cK9oTIJ6ai%-Hk=p!uew6{m9Q<=%x^dcsA*l-WfG|hAdow%zs4MRN2Z{B8~ z5uc9uqh=7-crid}nRY~e_cj@+=CAk6?ylzFwxuwus)|HsoFTSo&FZZ@!$U7#2GeYg zMiZ&l;t)1naoS`DKY@sobrFt&*dM57zXwpJaTI6NS-yNwEsY+FUsnXZF}#tA(O6M zJf?_HsYx?^dD2;-XOr#zT(&9`@tgs1*3W=tR?ik1_5>=Sq84&IvU+FngT%%Kvo2qKnzv$x>QhxR*)!w$4;s_g2sQR8Y3&{)iA4 zRnik$=FO&_-qA63mmJpzBXBG>eo+__M@gD(-g5}pDKWu*K-Hwt-V-VhzEZL1FH!CGr4c52r42Kj9*7pl9nbdE+bxG*bZsh0iYyS2y`e7lhXmom3+fQCdJ+Cg)>_NYWgi+Ws zQFuGvDae-Io$vb8rss7Zo-S>}SFzn^Zwf9lNc}c3JteJ+^sPyQIq#w#=F+Tw6=Xe_ zhS`pK-tlAIoWE;?-`+hSCs>VetLRFPR^p_dibK`IxS^kSwr(v*dLtY@zbkV3r9{Y_UaeYy;G$fBV#Q~d$z+FUv9rRe)NMlG^g*2T?doH{blWgrltx9 z_e%JPKoIP1aVZuq^=;=mYJ)_+$7U2dLd|)X{;-nLYkXO>Fc_9PdMOqxwOQfXB^$38 zln2d7lvR65$bHN^2+)24*p$?KB6=;&9rgkdH7JBbN-`#9866Wdz9I@44X+%(p<>u2o# z#q_$3Zn4}I?ER20-J@oBiPC|wqPu29j%5TrF+NGe$lSyE%_UDjXH$!;IpY0fpd&|^ zd|GJqz`csPh3M`}GuhW)O>PR3Kb25n-GI&aV_z;J>TL|aH->F zj;eHC!%gny2fta0qv`Bu5ysOebpNdRfOQ84)zaA&>t@tl&*;YEw0f zUYN~c=&jfSzUtUG`&gCP1ASUY@3z}9)Fi02;!g!UY{Bke6WwQlH?oIHxBb>Td~54_ z1&G#+k0n_sfMSR1_hR%zf0y87d1cox4v{XOD+$;@=@(bH9Mk(gm6q4xJN?Q86z#lo z)yO)6n-!CqI??iXw5_xqZ&aFbPR4$68&OXg^4uJC)nJr}8vk_1WcyWS`RvbJEp%R` zPF$toNuk_gW>6-+dnYW&=uU2vxNnuh(*jRWXCBi^k`IYan~dFz{%bmUwb@Z^#dq2g zLVo+vos?TQ%J|GpE9zH=qPf#^=tmJ8p**~OzXh%>cRWL53pcP^l1r1KmGx@^8kbo` zS$0mF+0!TsyCl{|f?piIZ%~X^Qinc1-SdFGax^5Us^JFq$);~Q@);9)2doC3Ivw`O z)Uc^*jPFMZ4W!~-VAJgEzoTOkd<0rbL(Z1T!9+VYUER`XI-jUKSn%KAKnt#UeNORO(EM;s(7T-rhr#Ap% zzN3tYV$UFyEieoEloWl&oA$|BlHtmU;R=7gYC5jOox_4X7%jSz{Ua!LBU*TQo<6`h zTPch$0X&jUyC4y$f-5lWWCq>Z_WXIzrPiP(UQYhA{O2Df?lV}-U=B+n?DKHxu9S0vLx_fn`t+|cy}7mG{IyM)wp zwWvgG_)N_l4sAPRl->CQT*ZGnxMRf)htIX^Io6nr4G0kZw7^x4vOa{`UVCL(Mp7k8 z73x2V1lc z5l>f`(GQmArJS}FDOY6j_gFblK5wJ~L;Qk@Ej7(Te9*;p7pQ%jH__*PsY-F>n3-2- zX6QeNAakC-Pn&BzoWFopd=rn*UQW2ihz{A9V?K(ZxMxt8)+lm2WPD&(FA5K9lrkuC zIGktADVc7*GEw-T`}jKH-w3qvivEhv*C?Ue%gmkFejd|t`0P5+F>|8m<({w5D%KOo zB-y(gSrW7RYl^4o{d4b)qy={JHWy@C;#`@KNn~YLUTO3L^kk{b` z24BjDmQ--hk(LECEc@Sha89jNJ@BiG%ZTFiTw!7YEv1ezKJORe9m`Mh53R9uKNJ*svr*4|ERm-=BpK>I`aGXT%QvB> z8BGzV!4JpHTOsT?N;j*VXV08UAkAtmSv=AP(hL!N4MS;e((j;G5OuI zK)PyMVdgZC6QeS^I+cDjYOdUrT3j}Xkz?1=%!o~u&5+mRP$9^nX4dA%`T^la!P=38 zmz%P8S74DYB2(0zCDh#9@P3ZamL!Rww6MmKBAdgiIj1FE@7%DCk|OIv$28OD-9~c; zlbkgQVf4GCVkNBKz8ln{n0pxhFgr)~v?!MPcCaw?Ty&zgdBLQ^{?KuL^%}Qld~W)O zE7qgAy0lgA7w8Ok^HsuC0_P*aqpp1K`dmGYNp~8<5!+l@@LKl@Qmx`w<-9-Lw+P2xnx%6FmHVbOtX0+PPlVfvPm z=-FzBogR<`+lKdu{{}D9pn`a}fyW6SFZRrm(PnAUJh`E{cZ6jSL!4mr)srYQUCxTRvXJ{XDkb0d;%DZ=%5Z1q&GZYq6w3kF}KA(V55Zcx>yq zE`>B*jBN@y?FYO+N888vEpI*8h3?W#&WOfAH8gx7`ZJO$x}-b(sf)4i%enAA=w*wg zkZY_2l)L%b{5nD#v7CwhV#8DGC^Ph4M(MrGS8EXoz3;{H#SS;9`hh$ojE>#%_1Llt z?CP$W{TAz-$*8H_>3phX{}krtcgSYubjgLPwjVCOV*2pYwTo~)$NbdA;m)DD`178S z1iCdQ&f(rB^mVSNeD|1EvfTTNrD++Sa4~+xVnIcwliuscHSD*kv&2OKLx^wo-1G-) z3^FhqEd*7~8iFFfAaM?F8(px^{$7un7p`U`Y~o0CCJ4Q8%D{@rHy&*t`!3nn%VZR& zEP~G>70(s_+pWQlLRnmju8>dlhv0o)W*xKvlyvR@X+Zz;m51%IGN_1Ts!k+IsxR&#HqEMzz{t{i8ImNX{qo$Z^0LbGhZ@*OaG zq99-F)aY^Nzt|YJMwq2iRnndZ+{X6_JDJ_(WomB}dyz~6TcvmU#p;jhOTuyvYwNHD zmQ(q4_}~lT%U0c`QpS|#RN8-dSjM4qR?KpC8PnVahNj_CsuT%yv;?3KO76#@pTS8ja@RPuF zVxC9ySa*e&P|~%4Ri};bgUaOu$dYK1yGqS#yz2QyOGmksu?2xY??jmM5*pN;Y77;eK##dLO)Fj2r7NiCf@v z-u(ST&=uQ5kJwdi2d3w}YOW(RYp{qmK1#?g$N(<$73woFhxTGel@vZLh1;0Gn)Em!qd^_-8C+p_#b=1U674;L*-L=#6kW%=vT zNCnUNU0scqW@{@FnL`PhpxqQ0+-9cSle!5B9umm%|CZ)@=X>E-)K}+!8jC69pMB^Z z1cy|jMzn-cAFcG3rI%mN2AQoY2nes1w6QHP&8}HDOFf`t#}k|0C*Nyj2^EC@gw0t# zF%nfjx!gu;aREA`*xEoka+ zCrxW5P0}6t@iHnO|7*Rns)4RvEkS<?L^Hm;zRis z;uk(;P!mqI?bwy4O5(oUwww6sKuPJ8yb}$zM*6e%0$DV9`ZU89n`Gx0X?oktqdj|4 zW&3@8vURY0UNE^BdR#VrcF^N7A6$F<#pB0=+qXvfT=2#@f$v`<(_-Tq{w(cF-+4MmYDwR> zyf>}R6F+`hP6ft)CL7#x@=b~=oL ztgTqzx<)ZmB=SS`69(hUHdvE?d$;b@{DKA_IsqCFxysHjXcL6h_4f1H{v)Mg; zABzYd`7SGuIVz_R-`(X+6oUX=TxJi!*uGhSku;9L?^mt4bd{HHq;m*`pbG|qCBY`8<4O%)s2^T)JwP0ia@-W znRMnv+}i@%_e5%oqVb%-XxRJyQnGf-kFf3eqFD4I1c0UF|TR2S_{HAU) za;MUQt|D0`hF|rbd0MXtv&QT)^{%8&Kc)@UHFYGVU^s3x3$cK`*CC$58;CIzMvZRfYss_^{DuS#+UwgbI5$gV_|8&K+>Q(zOTgOx=R8`f)S=GS#ZlZixCA{G%MNEzsEETL@RqWc& zZMl%IUGH|EAyu-#9a?O)7W@|GPz6(77w{Zf?6Q2xw>w^P@D;|HP))@R-L`5u}(m6l=!Xe8*v6FdGmAqVAu9XH_K9C=;vyy-p z9vYG5u?7BMixio|E-n1aQMrRZZRMt3kOo)tSJZ=xj$I5T&Iz(i#fx@dIc%bjUSWGt z3#YOh$EPEqK|96kpSbe=J|$3#9o#I_r@gVgxrBb;v;R97!~HeYMBnfxk->h+Vdtzu zO$+)lItT|nGlZ6@4?1!FHR3-|7CaeIhK48Q<~I+A&Y9`f zb-7va!d~_o%0TZ03s+XZkGS4waJlaNXqg z^IlR~Ttul?fPlS%9U78o(A-=b5EeU?h}qb{svtcabRMbQu|-l%9A6bo#&80dMjrlc!@|r&h(rKei`Ve#;n!g+aE0QG(>;I#aO*~(apL``ExzQ?aQjfsu~tH&DMW8n~z0m z@hEL?H_wPQu56uf_rFVd_;bD;vq_>uZFq8?wIaRw{BJ))%~gbm7rBtMg6-5HZ!ezj zz(+Mf?9}e0*^M*5_mx|vNspmrEAw>jj#++it?&xM?SKksnq{l)46aG9RAd6_cJl1E zKK&4jPYSGe?>rYhw{EG08_G^GJ3;Lmj|%bP!h58;SF4am_0A`qjGoajWktW1txZyE z8^~2mAQBIm$YU2ukJo(^dI;wIHTw0&i2TvYPKL1fbmo*#=5O=KV3+K-fpY>mNX-kSeQpE;Yo=9-(T#LMTsWUyE z?+^Rk`<*{#YW%~#!Gp`I2MU9I(}y0ey-ski+0P!)#~sMyZ))Ga&x&fl40`Sze;x{Y zpum0qG8j@9_$YVuX}!oXG7gu?>~1tvtpOg84Y4;oH+@mGnXJ#)(e#hPC>JX)}I z-yLjJ*a}_`{KWZ%)jDvE*8T_L{zj%=q7|%rNR44!?M(bE%CG?(q<1QyHdiAMvFjOW zxkl?_tyEN((t<+iX#2CrteBep8xrAfOtCNNMxP1q;r(wpQ~EEdBJ&e@Y{aq5+g_kq zFZPjd`a{WdXK?=deR;ZF!a;Y7Lcy5P=8%M}?d*EKGgphYcG#3tAm7qEH(Ds|qk0y~ zYY`)l^Y&R%jJ^nn?}q{zYT{?<$X5aaw2M>Gac=AxUpRSCJfcKDgGl<7L~vHW;KJom z)f`AGCbaknb7uD2^M2?ix(G-cFlu>v&k>|Isnve6dw|8t#i^ zE+LhOdbkmIImVxYGW`|r4GvEDzBOvs+xZK+=V;u00&mFGeh{<7EPsAH{vILx3fzV5 zcY*VAwR7b1yr1>r9YrtB`U6UqjM&z|x&Lhd!3~tD;pC>vU*uyZ+3U-%@6+md?3K|q z3KE^P*3jn3r}jkHF!)!o?6^DKm?HeMql(BYgnmzA`fO&r&@X#M`FzTH?hDC*r?3d} z*B*jP0QNlxIZVewQnae_ovFKGQvyrc{93kR|ziXH|At0gw?l-Eg1mKY8a535Ah zie$y0A@7kCe|Z%vf_Eq2RWi~zu5hxvP+M2^JwzKoV%0?>+OGulIk4i&X~B<6N@=( zuy=0k#}EDTi7ks}h4cBSZn^hek8b;C!pvvHna~7KJZ6U^XS|wp(V<* zSI)0-$0O@L;z~?3e&@}?*5b#Nn7;34=RlWoK>6V+l&!jF-~A0wDC2ZEy5SK&9R(j| zeS-LL37r1=!;dKjpMSVfQI3){=(u5I2{kmFFbE|Tj1SQd$*&Nf&8sB02Q?wdnG)HZpZ4U^o)e{i#=$=Sc7vF{wZiJXrsT|O6z$F;V7gHJim z+~^fTLOH$PfDwY9H-h+IwG5kYph62C#lxrw;U=HxK#L z2H(acnpS8`M2$Zp&#gQku~YskV_4zj0ouaO>VyCM=lpH4KlPJM14Ul!qR#C#1PT=x zDo-EwU;aN_eRWinU$nMJ$qY3~x6&mb5+VWuA}FDBw{%EKj7WD01Ja?DUC>X zBZ8!q#5eE!?sxyVF4uZE=iPPo*(YY0;jt3?N;sa#P1Aq}qUXvj^AO8th`D3m!EyT=iXE%y{So zkV!H>DxI9929e2{6KzuuPgSV(C%?^NAijT>>8akmr+U%38ccC3BPI^0DZ=`cSrWBLD~36)Dn6Int$IWc$u7VywvYx;<%<;-~e}JEvgnD6tI$=ynY~J zXp{QN?*7>ed%nSa8}(b0>o!+WfpcUOFx z4T*n_TE{(<%+6tW-v6q@6NR)>@$LbVK;EWEa%cAN6%rjMz&x(tOY}@p=zS4|nRaxWQ7DKsgEe%=%h& zGJ8s!y#e97KcE$w#usiU>LdKcCgA2aVX6%wnV31g#gcWG(vGu`UoEPg%OOryyugf1 zh?vlVY|{QnVKkS&RpQBO2v?b{%cgv(uCykx5~h}{-)sp|6@OY_8qg}S=+>}L^Xh0! zC8J2qo0oB?N{~f>Z^a%O^_uhdY#m;?!00U2v#2cVKh+sxW18Syu!|u!!CeBm*+vB z<6Ek!fmaBppoz(6d+hqLm-cTdrW8)!&yg=wNG@`Ca9s5MF{`&n!KTX_rU*PJ(t7_W zs)&{g)y5CVq+#ObT4T&TD=l?)^}cx0jW@u4J9NF#pTys0IcD~WsNuZ%b3%j)-oroi(d<62CpJ*)*(0P1RZ7 z*&{`z3dbMs)^7Z%b*sKsw%oGArCD#q&M29b^I(0A6#j!)vE%7H(OHJV9=Zb}_EcH{ z8EUhtRTjB>95FbTfSDtD+to8{{3b%D+=+qFBqAR z6Pp$ldtAb8rstly_Pj(*l%d`!aGtaCxIr;Cev&S!qc%P?(rYfZ)(Z7L#rORzlP;YP z)2Ac9BfNbQ>qC^=!yDfAH<+HNDkc~QR_JV)zF$>jM(;ebnI{P??>52nxtUzfkrN_C zW?gB$WPeO=(3=_hY}<0O%_v}JTl4+$gqntNcjkP++_vG7-9r1kbla7*eA$ut(Nk%e z*dt-Bj)&HFw!t2^|3U8@^Jon;S@8_>IG8L{yqKccRyp=W9ob#C@|#KLI{g!FAZZ-a zAEt9MZ?60|iPDk$N2a*XQ+q)%ensXtG53w>Um``zhKxOhz+y}H>%qwSE{YWmrGL~t z{R~augGqks5VJF46$U9-)&=Fz;@Ig0OaVXqH|i~VnQiU<<^Un+*I`D`5#d#?`8w0< zT>Qx4{rd0jC{3}4&Q)f;9y(M5dQ5Du6FXY|K0oH;mXt1FaEwmXf@Eq1M4;Pq1QAx| z0#!M(Qad)ZCCDB}=Y4q3Y9n)KL7Q48dAm1J)RNz#+B{XhD}~<3l^|Uf*yTewY2za+ ztL=C8S~7W2qlyAcEoPz9p~fA?&zJ9g;_!OrdrM;tfpROiFD8wUkgn5G{^H|hKwP$` zy`%MpKV{SH?XgjMgKMGCvkbzO+Q+RemOiFbvehgVrL|lh>|bqbD_#q$-^P9!R@V~+ z8}a1tR&GCQO273JM8!$$qsCF_pf1h9*TC@SRlp^JW0s34paE%XGsRF|WShfGs6B?~ zsW`QsX@;81lO{T;eUz`bKys4*`sJ&W_(+i_cy-2{H$2t`mTDRHZq)eDmhNqO(=9y+ z`j@SB`)l@AatBK!YoHm`oruSIl4DNYx0O9w#s@P$uJmxNDKO8Ht6I~f^?cv#p{qmG zB9!=)OJCYb1XYlb*vuXNJX+d$Hp^M1SJ z-SqO|^`KrxRW~Z$Dyd$fcguO31W#FKDl96?FWYzadaS(QmkZyb7;NQ3{g($lyrP!X zi+1+Bz!t+Z9$scF(^VWZOGN{FZs65b%LjSIGwFesTH-q$9eD6^*@dczgqjG$rxGm3 z_Pk`*DBIC;ZOI3US7-I%U*6xjpW`dt!@rWa#3Dl6Jo>_KNS07$p{i$2=JKtoL26T% zQ~sL^*EhwxqQ#*Lr>pl5B{zQsStYlrpX!kpeY@%2OV7ESq}Ko0L?{caeCAuY6q%hY z5CS_JDUV>n=kp~o7(%x_`$jwdT6(q<-5Tgi_yE<8zsD-g*tAr$2P+Gd`j%Pm&7i!& zQF-+(er=zUZXj*az9~fWAaU}hzmQ}|ndL)&T7GF&>+VD0$<7O2`q6va-2QxaYZDdC z2U;DM$YaswB)=fbtb^B++84gZ_xB3bh@JDC!u{`L4VEoeo!JHpJmAzBztAyZ{)W!Ddq!}VvHy1qM)7RtLi1y<&&BgAvgXL^cS8$j zbF_Ot)p!>V2m0>Y5$_RKKbX&nUZJpooqFutx+)iqmCha8%b4E3xVyu9_0fYIrO@zJ z`mvR31N4ClM=l!%)B zs8lShdUspor!9^pRm9pB%Z6SeJ>FH8vwxU$<#3{yX2V2WEi$Qf-tZZIyE)P?o!!AR zY(QbgE@if@NOY-^Z=U_M9O9s5k?Z@Q8Fr3dTg!udR~%@AYSmoG37#n~rS$SY=`Lko zK^YUAAW<`-in;g$h!1R6REO~@5#@M9O?of&zld8&*s&a$wCz-X#+su#JNLuoI(-;KZe-yx3&8PV;@rqksc{#)Fi&QD4U(9}65?`t7 z7umWiI}f)z2I2yApU(fv%?vx%Z{8s$4nUnYjlBD_-|o1En&f|7ar9)yL4nQ8XV59P zIZB{?#PT@qIyFDtX3JmAR7dHUOO&&H$HFU$Awo?vD5L@ zw8RJ`x`~wT(5JT5r`D&LY@WmV8lUcx{IonNRm7UxuWtE2BfFJa#w|)nOE{hlBcv=|deTAOT!c{jIptVHP5ke|K@m)!OT>ARv`hh@ecXNpC6(7Or$#BOt zp519|dGa*@)m~Ok^fjI6zOkwBHHH03b1U5ig%^|jZ?-17rbVAcCfXM1dqh4WF|Ttf zRGyXNeXx+bm$+ufFG`*T+ZUIs(n%eUoXh@H;jSmqAm3+oV&gZJr-wSO7Jb`Tj3P5* zvI(4`nx;IyzjNdGvj_7(L%Lp>zO@gcQNQ&bG8G~YE~_EF-$WCbildj4re8Iw(Dm7= z?_`uPv=#5eIqUiPA}-sNQPBV-5&B9IlUxK1+Ijg6i4J$UNKYLG*DW1wwU3PY#yqfFzqF*7| z#&9|L1sw?A`+&*61SGbCw-|v<7<<0nE&l( z^<@5SDsoC|bpo`Xwmg}@d8qOo`{6BYVmOgaD+ebJq?rlxXEJheEQF)%;>AW|8@WfU=`T>9J zOyUo`Yny-)|xdUdS=GZ($>mu}xV!W}2=rY2M6n z$00etv7LSCX0?V-7T?c@CNiiUxmtyPFYivP#Q891iRBgre7;eySE~+bqrWglIFk zsJkYbgq%^k%`vhklvMo&{$rLXXuD}LH6Ft3HZMF6p?MxqOBX_SVNK8QRjqkDf4Enm zFqLu_b$}9wR+C{r0wz}H({rbHbCG_OHgoPmu5^GL;t$T0y@; zL|7tHpH!G>!y{FapFb!G^(;)cpRQ&sGBxJrDERKwVW^}VyU-Su0$ocm} zKB^?k+p$+=SXx&$nGO#s-Ht6)S86sxKVz+)?H|2~RkA!0@Cdz+ntRE0&qLC$3a^vP z_5pE6Zl;{31{^`$#hhx!Hg&u)6X6voC~r@^k;tUJ_n59Ovg94dgJh5tnF&TngvXw( zAu*HOI-SI5HHvkUt!riaigGo^jGC3bWocQh5T0lfFGjl6VWGqJbkX20AwTlP66h{j zDb;Asv;McS9lWP{sP}EL%g(15v3F$9D&0~}Yx&%F4D9RWd7bh0MTHjD;q}{Q6>kmM zW6ZQ8gSUw)!b+$jr{9%U2 zI+OlSqY9XKdF=tQ8>+>>-;wS~24-NM#7pYf^6TmIAV)NSVJVs)o_+j}KOp`H6*-z{&M zcvlmP87X33^0?Z_JC<0enLRO2nJGNhQW#6ynC_nAra zH~Z)1V^f!DgwFDjMJ4OsheBJXpIunnJ|o(q zK}&kFUJ8uIHY>I)rN|}QnwBum(!fJW0dU)kkv^g*bH;Sveycib(V#b0_>~4F&VObCH%5me4lE0JgTE=m>*duWqBF7YB!o2w zCepdM!k+&@ihWaLp!icvCG|r-f;Hal>yuV~jl#(Hx5Aw}t=1LCRl4(ZqE&YvtgSfQ zW8jHO-8MO3*3IdaB3P&zt#ZE(_S11G&v@2v5vpKrIH`o9y(tgA%a#6OuOok1<>i-D zNzSh5@-@SVKYO$QALDiyp^JwmgK=d81s2nRx%Kvvo@Orq`iW zkth49%l<~}qKAabGXCEt+vpxkQiMDB)_A34aWgKVHX;?zEX|0UpKh=6Ei3t_c||O+ zWUf<0Sf6_A^Db~*^=3hb_B}feFZ}jduOENwKtTi!QIXpB*o`L6!|qoHcBJX$cq!9y z&5w75om2;QhEC@!vpFQ6>U^fmdiA=qpzh(B%4bBDoy`6xkAzdbhR42nhFnc!r4Z>? z6OpJ_sNWs2(}v3&4ppbRGu-|ojL2r&*zkqwf=;Gsuo?Qec#^NpW-(itm_vfc^t)PmUz2R{_9d+iKHb;JG}511-T#rqS7sY*i!UjT3@$^&^a}mB zLh0yREaI1hju?J!do_kC4Bf7k0rP$zqDi4%{gr{{o6!x|pbB*xhrj6Q+uE^!KDjwJ znBVm#B$u-$I(PF{PQ7rDP0Ty>8A|cqd+CgS?-6^H(};di5f$Eg@PkBqi`e*Azg@EA zhqPQHir7E;Ie%57`SX~9A$7}}gc`?qn0{27_$JuTLV8o+U%Q(44TYWnK`ruk-(3aY zKNWc2$5Q^}5Am2QC&8-BFz2CZ4R275t5`aRVq2#x+<--~{jV$Omqc^ZJbL1jUOAIU z-jE$v=r`_ywhdPaUk>XQRabW5RS2)fIJQ+M`>I(Us5IH65EuxQN zjWyNoyR$9fP2XU2KKZ8py>%~bCLfwh2`pPCB^LEkpY=U;Q6K170^G8qw3C=xPaMoz z3c4iGp29D9RQ4n%jAw>Sk*)9qg?~o;WtuQO=gZDIO2WF$Qyeb<>^%124v+KPhfmsd zU3tRe%Fp(_txwD{tj}(J_+Vsf+q>tEa+XZX_}X=NnW@lvIV*57NBk5gPDn=MOm0pARXzkVTBCW^<E(*}p)m4R1Rj6Fk}g@z3w4zisl)+?fIfh9Cag9&T18^Y^A4w{?(#Xq zAI5xwnHI`%>1BP7nd$PSk8nram{i3(-qfGcusvXwq-8L60oS!Z;tbWyL%;J&sQhhm zFNLAe?k;{P`GMX`=tOHPbWYn_sz2#|HftRuxhE}KVV;zu$Gwnryj}hPc^ZlOhHy;4 zv@*Ej&vH10hORQ~MSatU+=Z>SzFLVLG8jwiP{oU#Z;gpnIDg5k?(tUH zG0^QSu1#K|yq7_zU9$a0`)3qtR3Uco+Ousa23P@79o0W60@iHD+V{=gq9UZhQBVVJt%? zRlh78**}jlnz}Q5@%Nxp;nZf86cv@Fti}YVHzuo$XE#lSkGztROqbzKh(ZfHJ)a#d~+%;T` zZ!mpJ4pL3DZ@VF<410IAl)XnL$p@3%Nvs}ClG=Xh8Tj)>ONoBmr<0qpnGqTJo?9Y3 zrK4_q`oDj>Nu)cvFA2|(D2v&dK+imCxdZgRD%R|5R7(wuN6hxwNHU{1loILb^AvyY zihTDh{r7i%P)ne{Phhfl+^swjc{@n-?d=~Mh)Bb z+-L;dM*QZUZ~ng}IzO6=j{>2_e{WpmXWj5QlIXO@Z<&+!yD2n_SJ<>4?h{IEJ)fUXizsWFh=Tl~ zDd*qgO0z&O{*GqLN;9C)T-Fkjk6$$w$fC}Pv*~XSwW~KGayCloNRg9x;bb?~!{bfh`hj+=Y6a7pPu0nMnWGJ@4eKMrRKjMcgtZ z52r^+8KO zmP>gua~Sd5!sn?qO8c<)xnVJT@q~&;67150^|c;tjK$8tQdl;_@3dK(&9VJS>q@&^ z(M3!M^n78ycNStW7d3NUxah5wa2OgBP$b$n;t8 z)iSH7F_nk}{p_I}zU+z};yiodvMlk}@cr|jQi=KP{UZ}{0w`5(2U6cRQlxpe%pWaR zHemXnHX|PB{yHy-<8pOWu=!q(=zU%J!zo19Fn;;mOQVpClK6hj%V?QrGauE&UoMF% z!T;Lg8-feqS#BfHl;|zn$@?ATlBVk^9G3VOi9!!~wlc(izPFIuc_z1m{b_!V^lw)q z*}af>Q3!bwybP88Ow5hsFyAkrD8!TV)8nR>@^vq_UUADGa1=d^kT`L9J>eI`@;U!r zMp~&I=6>A6ywxFI?VzOzPwb!i9JVWd(>P`{q!5Hhg~z4KdKoTd7x{Qz%R`^1uIlmh z>S!dr%)HvHhls?LWi6g zp~7z4L&w#-v$8XL-(}`3F?oglP^o3!eD#f*s%M=x{fV{l-v+b){P}ohFLLV} zM@hzyB^P}*_CU1@NiFx$GRxu@UwNIdAJci(;_B>I6YERk5WB2O z=MdUI7HXNo!5{o;JtSwEoOyieYBn4 zAg{Esq)&SoAGVyhv!wi4YE@qTn)G9HRL|0j&R?0N!LFhYrKWmve$komvsQLOt}qg? zKfgGa=<}6Ou`Hv)3_#;?XI<39aM&Y~uVp;|Me4kPf89F5u?{ho`?1e~GJ=hQ7R@R$_A4TX|H$ z*wno%^6y_FJuix>S>8TR)JwFx4&mw=;75 z@ouoKU;CxiQ)+)!A&22d&Y{!JBZPh7EmCodZy+6?L61E)@>k0DYMz+hY`S!Pzs@w* zYJ~ZxefAhBtT-Fhx2STgK#fs3W>0poa+=1kcKXEgNQT1ecuIh8vc1=D5=@K4RL?J8xZY({zBux3# zOnUfNJ6i#TKz}HcNxWiDFK#BZ-g0VZIG3#Z=!>FY{J9W{{!6i>c?t6}zNT;b(fpR_ zNI;kAk|#NG$oG<1ROUK7X;ZqYhNxVbtZSSmea`XKHj7+&Mu-LKJ}J2Z?fodX`GuZE z;i#)`{nRZ2fD(c)_0+x8M}DsvoU> zp=^$#zn)L&K#7u%e!QzoXW9Rwi|&(NqDxTikCc)O^Y?aCG>GY{uK4NKT?RV{^UUMq zyT(2fI@x|E^q>6fdB>aX#f)E>(z6{4Cx_vaX7vasM{p_Bh>aIQHdg-0cY$2$A(Rs| z?#otrM)o4l;U}~#6?3nk0?UU8^Q6jb{Z)cONs3ZdR~4`-rw){!gfhnnW0 zXW{!PX96oO6E{{!CPY>UCm>ysrSe_MrHHP+(l;vz?Zo}!-?vxpO^~lVn|R%&UwS_p zW5`6iTh}Bw?|y0aZR32vYr!vNKgXwbzX;Xv9giW-C4?nq3rs(xRIinC|*}NSj|Q`wyHJ{KH={{v!}&JSR;1`TKl_mzVGN~Mr;&Ah38^MN2NApHfelDOvyzfMJSW&HFqyhP**o4LSb8D z|1f_V-9K+>jg{!1q*8q`TEFvo_M83K2kkHHMB`%ly28{I$h)>BCLuK;spD_hzi^~l zN_Ago(SdcOEoJQJz`8y(rIos-$)N~TUrF6DZ~u2DH^R)99P%Gtlit2O5ftYmi}^?S z=qNtlb?AcE#0r&Qb#@k0hllLS*?uQ;EtCZx;9$|sBIq@8d&XCtGR z%pa(INg`VKrU|R64;RtRlT(_yQ&da-iO205;Z!*zAJ?WWz0}WHeq6DO&k#~zP@F^T zRp39H?+{d`4R0ELc6nPw@!{Pz*BUJHrIxlWvXJF3wRMv1S*6gm* z)`Jv$S6L&cOzDZ=YxSMp>1hdvkB!%4&-T^2#VTdaRi6AalXrP3`2#=6@nhYKf4;=< z4P>q8=I&<$9qrLn;?Z)&`m*3`s`n_)DwX=DurCT<;19kCIFD0Y*xv}!A&Af=e5{jX zzL)FoO)<+xF>CYbi*7$x|Kq`8gTW8X?^0r>80!UU|Os6 z!nP{odKMS0Vh z+j%|uS5|nu;8BR*?;DV+6BPJ$)`b6$;9jUH-i~Ux8Y;#X<&tw#w8a>P*QD||(Hh@3 zIC$%wBr`a2QCW}b!7WLbq(f=4vmciB$pziWlr56w4ylLU+H}J)D__?8!oBq_onB_r z^d<`bYAA`p-{C4_P2cS!iFm&AI23j4PWO}N@fugyfqB@~`t#&UizY*8j5R-vim_1P zQ*P|nd?)-fx2tTaL^T*X)7P{fjxUCBzf6+7EAX1jm=USG7uL}E2vRB-7;+RAH<@2x z(hyRm_ek>0^!jwV%EFnVM4Jx?cw0N-I+Sc6nWJHH_gs+8=M z1XYqr2?gg)-%ne8Sn_Xqa7pju%K4XpUxI(z7gp?vt6z^eYI~FuwI#uLa{kf2j83w&;73DJ-ZQ`}D3(1w@3-(z2P+evL zmw9wdJvl1#=q%S!^C&F;rJ-^q;(Pvvk|O^zrz2)tItKMkc1|}ku5F*@I}cG=+8%1g zX~&IqF;0O#4$zmDF=lp9!@t7|T(&P>6y6P`-M`%vL|qX>&1`j^k1g!)TQc-)G0~Oh z`lhPf3&Tn&5~67g4t*HAywDmDs#roaY{K%NIcxRes8{jCHMyda4;a z($eECKT{X2Pe2He7i9-DY|&q!z)|EM>dGAZhnu=I>k_RD3feac=f#H9(b552KYmNX zFcnv-zSu_PH4S(W-Jz;j?k~UojDiJN`l@UC$gMSir~rns3^xtU%Yu+YDOkVZmY!L zB*{I&Nc{($E_XSqA50a5k|Wm%xEUFAc+yH0@gwN*Q$Kqa|9EE>)+=)*k@XBdzWA`O zKM7w?ELt$wcilVX+^ewK>{O5=qr)Gt=k2#xS>zWb`D2~9WGPB0G4=8^?pdguJ<&zT zKoH9O_2LUrrkF~t(+IwxvMJV*pt)?#%1?TH`lV#%Jk|2{NwpDkUr=*hT6UgQ`Zdwp z9uD9J#hK1=Tc=9mn)Yqe9Zvl+?2TUG+cpW*LYg^gn@giFlRdWFy61&G{!~lmotx-8ADa+gfg1^JIb_go=3ZH*-g!yzd4S%k~`+PL>!kkp&JVnr~YNy zAKR&h`E3?iTrU?{hCZOELj8U4-T$|D=H*~j_~rZ|?Z3bcLCJ0L-iL?u)`|}}rZyB% z9{q);sJkKMWzi$sP6|AdHoT?t7g!HPfNOvEqD3%whcYZKlq?vsXp~-3JN} z@v_(tYJ7!I?^M@NX=iRt(L;-+%2 zWt2k)n#=P3k*_vBcRutF73d#~TkT9W><8UH{dZw0=((sg7jMXOJ@B`!>-3-v*63dB=N~c(X9@QViSobyYpQal z>$Tf6zEqoSIE*X@VI~!*`WtT$(fE>NmfxQ{wff`&5nWsnU;GG8KH#5qb8o$UVM)f+ zYbV$kZJeNuyyJ`i`yG-E#oW}$c+JjsbZ}_$lUm%L=D~h~TR`;+XJ#mE9>z_aHOug= zzo8)hNh|&@6tgwcw?P-AZH~OHXD>*qtaVs+cAe~f>GOL@KlYxU*UDw}-r#zn%Hq3K zkXgB3M4vUS@#lhDfb+_ab9v|y&BBd)7vj`|D1w#Klcbl=hO3BkvYj~$m5C)!$UcGN zgUuW(hFEkdj1SM_<3G>NM+ZsC|1fNm;!vrtrenU$n?pHN>txS}X9-Qv{qbg`VIDf% z=4s(O=wj*d@l?yL?d3)I-Hw^BT_D!YjlXZtIYZPf(!bzt<87eFrgiybkp&NLf=oD&r=5;^e7UQCP?Kek6O=6w)8a#=~7yDKyyT+ zBY3tQ1wzFhPAu9qA*N4%JBK-iw)=9>uQV(YT+^g4HQb|E$Q#?wvRgS#D~|rn%=0_p z+b+L@@>a+%-Na*bVBYv${Z1qDC%)l^W?^(qwt25ReQW1GO57}Z@Tgd%Wl$!~qve+G z1SRuWZ>_q6we8FN*bJINA#V?>xZX*rnj+45?W98##qNzZ6p4Qm#le|>*kaR{Os1Br zbJ6})k92puuTjmKv5i_2ztr?N7@}>Y7}if)yy;Iqb~9iYl{}o~-~X&t+GYGG!3Vt~ z_ntVXS!nVT;HI+ro4HgCFtnE<5y< z$1-`)$0xQJu758a2!788>6xp#M&0nIJ(CE0kP(g2oqiWq^4-0r*z@N5HSx*Hu~urD z5yQWnLp<{cuy9=Dz*+&@?4y!s@&p6oa7#9t)J^jII!N6SCG9Cew9AUzW45x+fkKhl zTjLpN>J!WP;z?=tt6h<^r_g#E58|gpkMmvx@g7jBQ$m85!zwplNp#7GjO@#oZZ8#R zk4HzLbK*tExUcE0zdh*j z7veuq{!z(6;v>G9D~+TB$`ZX(b`w_e54}6PCau3I+pBy*1Q8w7$kz_2j^3h8jyy{j@-C>%ti`%Ca4ezi65s@S~AzBV4av@h=S2SBRkVeA_>~$fSWZ_ozpkN%R!B4ZD|G zDAU7Pq2QbkDz3t9#;O~Vd$D55U6ATi_u&QZ>5|E~Vgk`^f?q1+bRGdw33x-IeJBxD zX{5#j^H7a=@vpwQ`wIB`P(Ew`+mbo z$c7!<@vXBEM}4QXdQ@^RGYLyrFz>W!LZHwMFJ8U){=Td7$+5BUDDONAN7vX(c#e~^ zq>1M%FX?((MaUbaX>|iM={e!M`6pd$0{x@NF|ML0D|?`3AYyyX=!C4N667-^8w3C&NOU3|xPmzh7< zw?4Dh^^wlQO}n$4>E7UQEhGEEP5okO-5tRL&R!Lx(GTlFKX{Vjv%OJoXM5t3@c4Ne ze^j#Kp+9i-!yTYM!b@W z4BNK&qhw=E6`96RvRYPk727I@zj)1>H|4dsNNdj9I6sr>l^jfVb@DueS?U$BZ|)qC z+iS=)EADo*c5WITIfibaGM}%|L4F3mIY9fbvusNp8F}hV^*u%wah7fod>}t>+9mLl z_G=0Fvu2=hm#q=Gi+`X%yLgZ0Z4KOHmaEiVo9OW6<&9$Uwm;*S7Hb04jl|!%eZT&q zT6D=$ISIF!yZNAq|As*JBjb*_F=fv3=wV}u8#xrcUD*`zW6UQyQDU>C!K=tXJAzUD zfJD;>-d7ajzi1_cQSZWxhz%BsorE)O$$v{mZ$vZUUrYZl%M6xe2K_6LWDB4sgA?%n zsm0R9b%Oq*gu*gfkf5)_Np4{XgGq(~Vyy9S5=DTJiZPMo8^8lKlSJ|eK>8FC8-TSk zq<{n;Xh#&0;3y|MzmRMJJW=J{Bu@eUr++;p0O={_Q6CAwT#Hc}Ai?oOISi5{2x6&6 zuSseE`l(tF=nIZfj2g|xEQ_Tdi@u2-`9ea4ZoDr>8 z420v)`~(LT0pxLbDrj!%{Vb&Eu3^;F5%xNG5n)(B11Do?S z5RS5oJ00{KQ1#9L!2yiP1UUlB;NDc5Zcntal$6_5AtPMP;qyXc{Lye%|bYNirsKG)&KR-SA15jY!MZtf8sGG&W zNkBB355cMcquM8B?6hKW@&(uhc>Yuq{0PvG)Cd0n{1};lT><$KORy@yS;>L|mjRrV zBU#`KLh|QW0%FjUaWWcgog@&W_Z?wyOx!215}-L<1eUo;07zh%zJUFKU^2_V-+8h4 zY8Gq&v^y8TI1X6k3ivIPB`0PUJcWq}-*_K}X^0fxWc5q3hMpUYqkztzO@ z;M5P0M&KR@J*A88M^noE_kbL|po!(c^d2Ie0NkpNkir3XR->f3OIReSAv3@y#+nnE zH=;%}HjvVzhxeH1j8~#9i z0Lr6kjY17KXCT+j{y^-k5)q=8XowlmEe63>2rq0fjSQbKsbQ48WOlihqFi#3h9rFmjb^3NoOrhe!DXpc&*N zr8EI5A_hhojg?2!Q&Y}jn`hLNw78H$#1h>Ouq#sohGq$(V@STDAVIglC<)L4G?ZYB zCLJX{j;!zwB?1_c6DOrNVEq?2r4`Ut3 zgp+?v*#cm(A|(W8&vkzqgz?k?jhSCq%6}}}?W&pc~UIpc6z%EfWWio&nwb%uK z#cT{^5Ri&HZIn{D%-Kns>BeKJhrP+scm!BtRjeO4+OUlhfhq5x%mqSy(MO5fP`ZXG zp8|6Q8KYDM=FoJSQUC}!eu?rQkhSPF%3r{9&n-%6z$Ipz@*3#J>`^8H^2*1Q9zZ>| zfguh+D1u~=4nXcN1q8>!YygGe0sf4rA<0C*4zEfb7;cQsDm@xfP05ZfSA!6s8(#}i zV`P~iwt!{{3#5S#i#Ada5ulwZ4KV^dT|S23=)n_|A=^MiC^g6g5Q+9n$ZH@;eFl&h zKtGcy1P&0Ainu_OfMoi=fzXj+@k0ni7>IB%6cP%cRyc$lK+6b-IG~pm19=YE`x6hz z0Q^S1hk$@gpwl4LK)*^Bu%W7)q!L&_4r*zJdYkeyc`0Vi22ww}fb!5>D(Hs|SUlO9Y`{%sWo#5^nx>biuF= z>}HM!`oAK%JWzmS9rH#IO3#8tv^q2ah>H6qGzGVZWfpwm*hJ&$K>5+X-wKhVrF5XQ z7-lW#6fo9vZRkBfT2K#*z~05ID;$}OmBoB8fZ_p9(v6^vK-TnLLDzv%%h*FXfqq*@ zDDIHIbb{iJUlkW<1YmK(75W#D8}NW$0doD`(0HJ2&A4kcnk>9wXzzmR;(V&Nev6ayp0W~EDGS{*; zt+S849hBmsSw3KIC*@&6NVNYuC^5z)6$%2vvHJi$2hb`V+60u{ojfQZkS?AAC;|vi zrU)u~3ou3Se28_Q>Bfy;GXEV>SX0=8paOamI90!mKpg-r?r~^1V5NE%`WZlz6{rDV zrEv|4<9N;3g)#vB4S%8cu=l~5eHgA%)repY!1b^R0;>grafiX8L4ea|vyK53*!W5C z(2z++INF&AMurw-giT_FNSI(PfN(D}tR5)4AWj&Lu6&&vrUCdA=YxG@#p1l`f9<;( zup;0lFk=S`2lOl*U?>3B9AUVLadw6U;;vNZp~T-su?ffCrrhDQ$@VZ3^j-pXu=ibI zGJt~jYgie8T<$P09D)7pg@A-DRzVT%lFNxeFQ&neXvX(KFwAc+m^&b8`UdtDKzd(T z1Avo$Fk>J@v9~a0pyG9-U}@Mk`fm(u4cnZFg=rB2OF!KTK~{h@OpbOjfYPF!(Lz)h z$0QhzBAgQqO9X6uONHTX<}GP3C~l(0Kh;kdVz*3w_BwmcN~}L{zeO|{#P_)0VaTno`QJ+azqQTIo#D&=<&fi9(E}Hcxd%OY8v!j z3ieoFSclO9`4HQH4FJ}Owqc`y*7QDXk`S1GsT(C@2<*13NcLZKKulD3;MBl#K~6aK8iK({^T2WIlS>eOhFf{-6|ORL*gRurd}INP-IX}8 zT!DLe*i*?;2+j^9J4zC+iCe;xbhK_z?BIX>PZ=*7!$~pZ58)DkBPD700M4NdycsBl ziD&RlfJ(Q;7+wTy%eKz&VjwvPcX%8im+t}3#p!v$odB%&hMxdf;R6>10^Rh7&*9_g zVY=SI$AJFyp#RV{1fCBJoF*K;3Gg=G%z@_t&+~KPbHK45Q~|F5^hImnxPvGI1AhX@ zuh+vF0Xf13xFnD$nO68IaDYinz;Op+$t?UFD5b&;_&6Ys+WK!?Uw^~9fm`IeGq@a} z-*pbhZG?ym_z=)uyZo=8>l%Ix=rP|!1OVgAB|@A5&(m)qu7T-Ir$l@J+V`;=65vOI z9uWt~_c0=lfq2^PAliVU3FbkV0CMZRhynny@1Yq3cYr@n5JtcY$7hy^U~*tp-FN4W z0+y>_G6^*tUFME}qo-@I)ky1xz^&Fecf=>afT$+|ckVTL{f7!~5Nv>BTVF&DfTSn{ zF@W#@1diC6I1syIV%wk~1dgztHVhF3B(xwBfg_Q=h(UA#^6l{m+%2#9JwhKCFkLFb z2arRjBbb0TCL5s#$U*ZE1VBGkK4J~9ds%?k2XMCtp@56;GXj^;;4cUqOS*R{LJZrF zt}H`LV8tTJ5%++4YWapZ1FG?B7Xo+9Uj2^X2J%HQgt!m5QyfLC19JR}2x6SsB?RtZ z6I(&h0PZ!`5!%2!6z?EPfUtD-5Mn@o{2?L|u*-0XCA}_AUl9To;f0)5CFx%^5W-VJ+>GK(EFKGchD$zBq_%KHF6jb zQguh-UKbU6A#s`L@Ikr)q1{Iz>j2z)hl~N_P(es0z<5>&QVPJiFr+9J3*eDRpoxe^ zh5|8U#3RE1WKTxY1O0L-$S}Z6e;V=yfXrFQCcxZ6Hu58G+aM&8spG}&ev#y8Q*$bA zw8@|l38p;{DFu{0UNN!^yG@`g8j#o6X2mxo?&y5ggiHsF6Sg9M07fS}kjnrz^dRYg z{)t{B?p)vLN8*b2?;z3^m|c@`WDF48?le*XkQbdtdI4Crgxmx4vR9F>fP|9#LE?6; z$GgZ%;L>(-f+PT*Uz{NY0pz{6%x4g)-Y3z z0mhH0-@l&}20!~6yvp~vK zM5r*hqui=%uP0k!n3@Ou|H!%uu&9CkxXSY5(Q0xY~_5V9FxNv!XAKvet-LnXRa^m~Q)Kq>>KUpIxcP&Yl z%G=b%q*HDHX57YB>`k&PjM)v6S?G5TkyR$H=ObnOgZ7V-W$vhD&s13tBKMprOLoTf zahfcOga%~FmeDnLm5h7G?KQHOxLsv+9=yi@PsWgJ|#TaCTmCcQ9EQa=z4OO z%vxkPPJMK^0gE(YG5Ky`?AI=tElYfj;U1uuJtR)6{jycms;$|w8PwWphh;qNGwrCX zGPN@Mn2aZ@o*tLoCH%x`*+8;R)l0IKRPNSQ*)6*2Z^=f|N-^SzER*-e;FCL){um>f zHY~H8JWOx-LROOsHh3dzK`mWePM$;xn3>C8Q$-&veKbH zyS#v|CzNtu-lsnD=X8I?Up|+vJp$!tc+iVW-*m+pZZ^%B{858PF!FHHZn;W6pR^B; zl%JvkpDW3E5+bsyoDYQl)#X?Da?0-d@)`f4^9yWwXwZ*}k-wr2?$uD9K-Uw^6#m-7)|sV@d{_$vz7^pr?{=!O~L2F=syHorS6KeT#f5V0g7t-%z=ne?U;6}(e=Pf{Er;ek^X zW2`Aad91WAjK^-+7Q5l@iU4Gd6@zH>)K5_;sMq6D71q?-{W29iv$%J);)D+O6R#;Q z@n){875f(U^G@I7Af9PtwTO3oQOX4i^7Vo^S>$h`sdXz#lIvc&)7YZ=pRhoKhgD-nfnfE zR)&>3-{^I-abHObm2wLAa^#zqD)-yO_gL+|(ihk1vF^N8i`%-NBwvf4;vP?}%$ean zg|7AIxvTkTZV?xGwK~k>Yr%8&DJR^^u|D(Mo%9-1{S`BV z&)6Cn9rk41qO4tbiO!ypc6!(K?ssS$yxZ+wk4jeE@4k~3sV|SXza!o59e3vgS8>X{ zDlM{GUw7v@k##rSj}t!dj{9VC-*=DPZD6B4FWpbmEPLjIyPV)hpWJ)XwZ&KWnRLDR z-JR#=5BzdpMfdS09&bp|Ru&!|>3)-y2X`-fTaO=fZ|mUknM`Zufq%Xm<1UU^u0F6R52V?s@PnY0t+VDYT3DVdANvj+8liwxs78 zy)>TP$QCDco(Xgft?XHg^ywYt$p`-I7|*Ume_7A7HC<~r@|;V9;d~3vrDWSa?L5Os z-^Cp~dFFF)f+ru-*SdKYQePbJCe(fx&io}2t}9lOx89k+2_^F!;O!D{=< z^T!y>r*dR~Ud}w0I$eD$%Z-dG)MA+(JiXb^6i+Ap`OTgU z>4AdmsOKaqwd}a(E=nl2eBjxU=o`LyjwgEXPtR(6_F)s|Xif0A!p=@?eTxQqTI*+* zQ&!+P+e;bR@-Y@hM(do|paIS<%%^&!QeSATY({pe>7pD%cHJviMw6$1@l|f3y4KWE zYRLz$byfBuJH`B=>_OLcJ(O#yT#G~{&+cqbQcfd3s5(~p2jR<;l^yB&VUltLwRFJW z%51t<%~I|ozQ;_-mrt(Cl(}T@tC`B_RDZ%+WhM`GOy^(a z%6RWq{!rqo{8zb}1RuVxY)XRdZY#Akq@wRAcac#(+*R`Z$@GUxIaRo_P|33sXFn); z1|{g5vNr8kdO3M@CH`YBUe4s0HzU2)(RI@QyhN@p|ICCAYp}*RZN#!%tXx<^qew^Q z`iIvZFrE3sE1fFs-`$J1`g|`hzB38!=XHTv^KGD)j)bcRd(9;!vd4L45r0y$7hk%L zo9Jas)=r+`C8x$Lnd>!-yw`54*I{bp#nWCqH!$*?7gv7OWiRg4<*$3~r@emeD=(hz z@h$T5A@8sA)9W1>qq2!N-&XZ5=ly}K+ttRKPwzi$y)&r(G<)xwq}MG+?~26l;Ob3V zRDEMNZ@yOym3z16o4C|5_KSu)85u>Ae#XGd z>{oT~V7+5CZ={s4)~N2ycL7$lyp<;OWar504$JN^$6DZNU)#HocpAod^G9Hob-no$ z6#O(xRVnvmjgMeZZy|b?EJ7p?7QNCnrN_I{IbB z;99WE&w}cCz8qKDk6su$@aqY9K`nOSX9biDvomL2EBxp&&$ktRy6VZ zOzQ&r^zRjv#*~}xex+y~oBO>&088r}Y0hr^sPF>t(VxX|ye%_9puM>LJ2;5%M@&M4EU8OvR6$L6;H?<+ zozkjpS_FM1S8VyeAQiQ6Y`Y-uAQVp>7xW6ZGsXvvCUW^nK?C?sYwoSr?Q3EEoxm>K zwMNo(PLLBz>lW#t-#sOWKX3l|chGyjQvcLry?!bp+z<99)LC%q17-z@jmw-M{v_6M zK@fk2HF7b2(}!yEmjp%8Rhb&pgs#2QgZlAmcb~g=C>YhYWe$^qg7jvqf}#m;xHjl2 zTE)CJ1bxS?$HpL@Cb+jLh$sIFw+5N;;;nb@SnxmSk}4kMa;@+5jI`Ekb_DU^J!e;t z83|mh58}`KGxi5H@WcI++d)@p#ASaAlFxY99ZG-KYYyU_` z{fExM3FMXSx&-f~t9^X%V;YSg2L(@}`%y!J|K_3oS)#+*@p$?$#G56J50R(zi?m_) z24Fg^IVN~I1&U+SgF8~-@mUybOeOsm1$UzBxW&QIbj?l)<_nu9OM{j0Ce}NXH>Bsv z;K2mnSQXrl$n`e|7vi?kmf%Z7w%8UtjoLYHM=%feE%yW;AfL3}7wkoN=>Fi>6vGwA zgL!7m_GIv7-sCy08rJ&Zg(XHKmbtK4-=d-DKIQ3P3yQ{p&x2R+r*7YG^m=9u<8)@m zgM$O~?~8&1NV5Ce;7U|e?EByuvN21lywL{8L-?gg!kHB=a59=4{{CRPkWS# zkWMr@Mk+&$DY-jZ9pcWPLXWL4zxSOLM1};i^ilBsOS%xg^SBuqQilX6D}{(70^5ew z-IWi=HNv8mriY@@P`gVNh^Kiy_DYlEdVtrBSnh2njw;x!8X<=vqGinxJ~sB$4v~?_ zbI~CVWWBp}L%L8~YBdNkKS6&Sc@uPc(;UUlI`fXH5ZPLERn2>pNJu^0h;mW#?51|p; zEjgqD-A*UU*FkEoVGQ$m^(oHI4#8*UFw3*ou*u<0RI-88Oy>KB!s=nymSNd5#-6<0OFtkbWH%oMz25X$_X(@2&6PR8 z(x#v%yQGDfP+&~ZhcqTtHtr4arR$k}A&iU5-uWrAD_rcRF^kEt@Yc^g7&4w1?6N~r z=(;8+gy%+X=Z1_4!+nRBA&y#H`zk}5Q-s*tGPG(au5U(#E+c%_n$VGza4ml;)F%Yj zz;a=)YLjzRv)b1DaS)ciQ<$*>p35iA#H!bGW~9BoQ@yY^2-5my{lg|!!S&p#F#as8 zuSThS!fw$N_RPM?Fx%2mfnCz-pd3nfj5g{j`-wy#Rn3o5Wn8Ws7_`3Th<;_9kXWl&YWDysN?=T0@% zAkw&HeHCB&O>CfQi^0sUHBns$d3#e;MX<9+%~j{f+}DQ~?LLLESk9PD3{!cs+by^b z|Fl&7BB}qhR&^p9dUa7*(|u^XYBgQYcT@2-*zoSErKE*JPgOm#Puo5!9toE8Rq_4O z>s6+-EVzA4#oe;=2^Bw~_4%A?DuuG-e^smb z@O~I>obHA(bJ&z!yrJ^ax45F>Pryf96AB-_p_)k*wYsH})3xty)j5A8fvbhjq7FW0 z8J*V+@p8_;#? zU*Qd?-DekuC!zjzQH#ULjcYFpuTEwjy(T=3)KIJse@kL*HizSw3<7m-crX=ja3q}P zrca#=Paw6!E`)~>z5V6zd}>bRtKsJ3;4M-AQy;~pTpRU8T&}iJpTZ@xt@=55X0=oE z#gcg^^$8O^%DWJ!?rMyyrmGs8picVv3F@lla6Q#s-H?Zpg&%Y+J0O&(O~~ckSi&B) zIaBXI6l&T_{U=qst+$#llJoki`MxqMN&S}39P6692Zvi38U1o&-BQ&`DrL!*?~HWS zzZj~nN{&z=S^Y09Sw1gS$5G4MrmBDPqW;XX;|J8**OZD@)Gx|V^JfaFE7i%w=($Ec zmaa?Jsd;{?{U$YEoE_S#9!~U%S!%xD)bCVJrTeHo>Oo}E?fXEdk<_$DoPH@h>kJMQ zWvL_CkG;r>jXJ320|u z36XXEQIlOcmia^-tnd9w%~u0yh3YL-pxGPsQ1X$y@9J(mrSWc1lRsObz#&s!fc-iI z@m-BI+>QrKH9n-^Z8ObDD!tZ1bBXRp*=Tsq+tX2_=TE`o(vB`L4aU6uhv;2s>ZmuD zXZ&2mQRX2)>s{&x|-o_i?Ku_|w8=Ya{m2eVYvtX4FBQ_eboed&ff&i|D#GCqhHl zt9cQ8k8gP-;vc#{dn`gt_Wgb`B9ZR(@Pw!T%rN6ttCA&7vA;E%l2nwCDLssLico3m3t4U$a)WT8%#4O3P=b z2DV!6Ui<8|1IW5T{@PT&2I{-(MVoZwQ4+jZ)x)9Q`)P5vsfv~#^s%a? z{c1tm+~8YB>YqW~A#7qVty+(&d2m!V(i&4+yqjoK$o6|$XdBS|k610wGid&&{YAc{ zX{+Vw{OI=DYJ`vOs5R#UE+sbCDH(DHnlQ%(+HeN7E%g6%(N3pQ&EvJ6#ND@>md`AG z{?yi?`^`PHd;kvbrR9%t4)zhX9PFp%xyLPu+GPRYYqUtqkL&cw&^D!>-@Qf~?_k>& zCx!2>sJ>$ws`Y2Sd$g4i$UE#oRr|28(`!Rn#vUyuDwapIN~WB)aI~on8~0Ib>jh)9 zxf6f;A{GqQAfY0zzyGbCxQj*Wwe`HgbM}a3SOM^A7^$k?47jeIc+G5KRvULVaIe;e zoz!b-2Y*+OnoKN9=)-G8I{BDDOv59MLXV=@c!<(U#O!tc%^pbgox1+ibT61PQD3Bl z@r=uFMw^AUuJ$bPg4UKwG(Dv-&B2qn8`effRV5{^xbYI2ecEs+*JU4+d#)tXLT@iW z*12k=4c9Gyy2ha#@`l!w2a*W*)4!P8p4sfzDyTNM2KQ^Iq1zYKC}rLoW?&vr%$%KX zx}P!#u6SZrUn04RhO3sdUt1ljeccb$e00A_o~*?Itsm%v4uIaKGN*4ipw)tOi%1iy z^Q!V|c{0sGtsm*-6}#k{CDP1)`WqQlmsGW(Rxz_5OK+vKF)`7z{Rbh$syV0EZeGe1 zOyTuD6{RoZPuklnTNHDfFU)U&hpdORh@EWgAqe`rB_N-LU0R#7-iNf#%+vb3lFA0aVRGbw>-fZ-dU(8|-IZ zg^quZimsziq#d}n6PPP8`yNn>1P?nL)b9&8YyXGyMHgOK*Icc$H*q>0?rYlvoR#r# zM=G-to0qGt!A%A1|w|ZjbNef#|s>lxhDz@vhhm$Sh!IcJyQnjKcgEN>_J*;)7YW$Vj0J@ZK;y%+-dIjfO&yW z+7V`H3w_fnF}s^0mc>tNI{XzFyQ9}yN`zHO=T*-=uB}H+R<9YEHU=qyXBhHQiSyZ; z#&SMBl@*bchstp2-kVi}u~;d3G&gc2J#|7-azEctYWe~D>^AG=Xidq#a39YA`VeWgH0vo zdrDgq61$#4(eQH%=U?_-IPj$9!lZK|?gPprDD6C;fQ9+z&6w3`9+BjyK^}e?|oxH+@6kfMo=y27Foe|tO3EF+V7*evtZN+oKx%82qjiA>k7bBx+iS4@HB5sy^ zMjHXy+s{BixktqUtl8%?TC7f(%~_BGUUG8$OBqWz%auzc^5@sZWCwQOtQN^Xc8kb$ z-xibYSW2Ut?R zI}SLJKI)X{t^`85xC$igJYN*#5G~iucwwuPUhF$=poiiDXtli!G)oo_3V^W$eDJ|3 zQeR^Yd%2%0aUDdHpa5okN$bXb1sa!UT>^|P*!Pg)=ws7n+QGw^DZ9c=aemwIZ}r4; zfrdiXY(_?;jW;b3{#DDqG=T?pK$#c=H;v-6Z2m=UD{}khC$+E3!(|3wx(<`@3{SbF ztpQbQUV>IfB18pAm$d#=?4SMP23>;ak8p16XAJ*VPmE((m$X$;?m3kkTA7zy=+o7i z=~hR&(VWxxUjTDz3V}H_ja`}g5^sM70p8I9h>bROW3yLB^6B+6A^&SB5Y=UEAnEYp z-TC&rq4rP5vLiN`C0*9mC7w$wPXFVE=EcBd(&kNJ7ccYn*Y{9Z|o1;5wsSTHHQjP6Py=?QhFM@{GQh3S0U^` zA1(}ZbN0WhypjP#pEQ8^T-W-t>;c9eC5xy7SGv_52lyuoc6N#rl(C zPSWsa7BA2xlmD}p3L0Ii%(!b}>GkYdWZ_5jVm(->mZ1;HLH-;^>{Z#TYg!kwy;2nWgs&sue64@(l6R6~Q6DsNF zP-$-#vB21t{hWgVm58|k=vYEO&NraWOu14F@0*0gEGNW^#b+2hv)RiLE23}laxHEF z%}gtWuDGQQrY8J)F{38UA;FvGyEU>>)*oRHg)^M0KG!q*!+vFt};(z@~V zR(wYotP{+kmdLT&WMH>uXKwRJqJZS=+$;d)9UcH{-2tuKc0sGP9kPoa^GcTzpxIGM z%Dp>$tzexGV8?DL;Kq9A^E$>6dVjAJb!DB+bbJ~4ieRV12H1+ZKNY?Dc-XOu`_Y8* zXpYn*I}60nI)4pA>qUXFJ4?OGRor+N!gBAILLc4LV*ks25D@-W0MYlgmaO_czDtU| z2jJ2BQh@gdV>8wv7tzBMxj2HIzLkRW?`e?-V_yge`B@66T%h#@(4hc;0$JbtaGb>j zT5syzPx8|XEa7my(ZeB&rP_`fIv zP0o~$#WL#TZSz&RScabc&t`N>bSd`WJKXe39z)JQ4N3veAO{uvBp{%1DWK&O(J|w; zEYaAZTQz8xRL2Eu;uCEn6h8F?g+I156qa%K2B3Zl!2M4F#Qtd#%3BT~oq*B31hBoA zNdWutl$+N28GsXg4S!tDiS%+z;Dg=J>xEViv(E?6F}`@ zCKU`umme7Xye;I|Lr#RGqtZqT_T=Z<3KZ3?29KzJAKkMU+|n9jSl)BqbgLJrX4GU+ zZrfxN9Oin#87r4Fr7W$WML~){K)vF)}Hl$t+i#_8;Bie zqnCg?EHS{ru+|2m{V&}>!;1DLpB}AVp_1w=4V9R)yQ@uX*!Yzu7ED>Icx73bJ#nrV zI&dsHFkI5!b*rT%o!Hplg_x_uk3%Tb220Xvl0ps}N)`I?N*e|RLtaCV3R?{TZ&MJN zFr`zMYVF~g6+H1Lk+X2J@QOstj27#$`pmX z0v?u&RA6<35&;syX-7*Hnpnt(^3p;m=yKNplxI!un#kGhabiOIOz@tErQnwjP24!l z6E?l~7Dg7~E3t#yR4T+Q#U_nIBR7NIN{vh{FoJsFNv92(&Zx;>iJD z+C5xc+GQ7=o0yD0X$m8!Q%NZ|R{Ik-b@NY<=M-0h*s-~v#I|&Bw+0hx!S{FJ+-+q^ z+jp?sPud1FMk3P+&yuzjiKPq7x`SBWCv6~W`dQ2KnQ@n!Z9WA5I^kS4NAh+E%lfKy zVXHrDHDvP~{oTaVkU0zC%}-LVF?;h_t0Nw_QRPB@Vs^5CFGz!>4U74rjV9eX=D&ZF z1pPljf9WQo!&ItK$>vQpbzrr>aYNkt0*7{-BY?(pOkIBi)xHAgJ5K;Zzlu!Dj;w`AGBxT0r>zRMAG8GGzlK76rShkeH4nmSLDBB$R}I~L(w-i$Rqt`(*k z824ahE{0e$IHAA9G-->s>mtcVi)<59&j6nDpV*O(^8-41N>SAqm27k8l@x~Qtl3NV z@^-96DE3MbkTCmEP?t1F=!|hAZP{yp%H?gCrV=K3ysl`v354ybWB?W_@iU^9`-+=f&)>M&RWvyQ z8c8!_bC|KIt~RuZF@=Dvs$4*X4sR41YpSC(&^)3mdUAU7Ld){3Wlyy8ZoXD%dAG6o z$S{oLtJr`^qwE_)85^eVg$@WSN1el}m4m>9fm~olMZ90=bZl`G2(5vn2j0N-Q5g8t%C&kGp`mZWOiW)6P=z7 zB&5|LLW0?DGaWrjI!(0OIfCY$3o%GO@>Tktxt^x|&>wM#L(*CMVxC|hU@o+^{Pxr~ z4{>)27A4Y|^KX`6uA>Cw9dlH(@EVnqF((Thj)XI{1!#(!g4XnAd3!c8R@h_$A@B0J z#RgV|-{x58D4U&6^cwd{=t@i8|5{7X2i)iMwEN|~S;L=Vr?EPq^#L{7P!4U7`qY32 zg8M;v57xCdc7(7`A&GhVkOPWGh+))6+|TZ%s z2lwE?gL2#0c@*c=D@}aU={(*s~P|+cEVamJDWQM#8eYNQZ+LV7HY#qRkZ=ozq$bMVk~pE zvbvco_YoeH|JNb;s0&QyisnjJn3GwSjjj?Y-*v&%HK9=cj%!(-n>B@Cg{_VriB`8o zWepn$T7O%e2DDV7);WdjrjqjkOb_oq%?o1mI(@ zvtj4#bd=wHO+auL13=Fcn%ILD7jK~1u)pnfUet)tXRfkpXygIJ8)*)zR<}~@BfG&m z{kn47SvWx0@jnH6&jF5E-+_;!&IF9tXkRu^sfLtdPZ(lm&%)1%LA{Zr=~k42d#*5ZWXmRCDAm!YI03zoSqiP< zBph((AG&WbZrDL%#0E(mP`|bm`-`=3w(2ht-*m9q+J(MV=fOGXA(oG%P_09y3gtWL z+{nZ`)*U+%3D)jd#z=>sbxtYv+Bs%&c6_G@I|Wyw>MO9}ut6}9>NPX3RGFMS=ryxY zYhy`z`Ha3gVH=Ad6zOX6>`E!Fd}kd!-!*oD74Bax1ypt6KxYE7uayE8xNwKeBEauy zDL`3dX2agQ@W|!h3e@LCSv27V`h^~MQ!q&)p2e@q^6YfgQ5yLyq0b7Xs1xfw2~%?& zG$`i7_`Z8!XnJHOwE_l{n~pL&qud}O<{OFdW8=S>nX_Cs?xp7lc>Y}gb_gXjqZGPV z4!;0_#_)Ejz%wjb#s!X)pYKV;yR~4aciYP^mx@U4X`^ zxcjmj1h;lGz`o>Gz1?#gY0wrKs*>&;8p;ivw(M`Yxf2@*^{LF&)JC#R@Yr|wlaBUN zic)2)-OWW8`cN-u7q;t4zsDSait0+-{g`{HLN(lVl&$LR4qZp#HBQA%v0|fs z|5i^-s%~JX02A&B5nXB;Xf`a#Q;4`1YIK_KThnESItKQS~nUAn87Xk}z%g0P9ThvDDqi54u+SJwjALSb>-M5dVvvqfY_ozO zXFw;SRbc0WbTW!;E?f4_>Wg7^$hoY^4vZ6=U&mS4im8Q+^yQVtXMo(u=n+yt(%iye zmJqC?+(KF~>IuydrSHMcpnWBpPo{xZo^{WJ-T3J)ik0;TuWF`8OwhpaQg60eWhhjR zZ3*EaF)sxDV9oMFbd*T73e|a%T%+HhS8#qptN_lN&1cs?#*gCcpP+>G)j zI~UV!AS;UGv%jJuXzv-(0$5x{J|vQe)^#1xoLNF8ofBKsTIWIo;Upn{Y$%1~Y`}YF zPplOkr>O*Z#byH>Kv5yMRe_&59E}dZOGDw`#|7uSbCy_&9k;Y#XDV^8x=C{WJy8mk zSLRckx-tOy=~6%vUIWdR{fmbZwEEV(eCmG&9?}?fNuRmVnLi-m2V<5K{HNb*;RE7$tvGgpKsL*8OI5jCZ&tmaV}KOmyN7~XV-Q0tYbCw zdJvv2ys2b`5p+8|GRE|emrNmfOWdo}7 zCXT6&^5g0e4X+idXJtmMT_gPa|3a)`B-EP7%Yv{b_1=jo+ z-uyk0Uz?jDorOT>C#fxkWz-P!=!gULSM9)HT!3YPbU^yEq8cKB*nM7?4)oUWaA+-E z$+@wZnmT?^(y#v09^{ zq)(Js2#sx9RJ9&7`2(6rTa?MRN9p*n&Wt#Ri*9Jm9G|i=z2YbmS%J+Pg?_1Co7dl{ zHo9fr-{=-cJ7li#uI}<|F(Mf`!&1U#%q@k{Jo%ico936ImP=Uxfnm{HV6|vC2HgPdUpW(qn6PRtSdcm$IFzIYGO6srInQ@G+5~aMm z^>`g>1)L7zNOyK7saDK*FYMDY75~kv15d*`a#jrLY_*~o%8Ahhkd$xlYWVuXg&p8n z(x;I<(@Lb+vCzF%j_g{D&Xx*=FWdC20&H#ipYV4rv$)X6IyxM!XK8g%X}#6O#I*HR z&TK{<9`-&H(rSGPqGWOPg!ntLBL^;p_@NLl-K}_UF6QsQ*-Az&qonQDx{zeFjUyqy z#aq<_F?m-p@oWqqR(*+hLeGiS`3@JwFA~w}ASdE^_CcuVQ=bb~*N4L$Kgzl_Kw2)L zK2MC#CEBX<2AT)EU0=sft}A~2F@81D>9g@vLwX)>=)c77!88rTf}o##oQWCQ_8kLI zx)N*45*mn=SOZkE_M<3wt$~gnQoIJube^>}^R>4QV+j$F&NN9hZwTsBJ5JTH==Nf6 z*i6*QPMjLbVjozWv80x~QI?H>{42L+6W3TfGjD};FpF-^kwJu*d2+;!t!<>ELos*#++L)7-!lVC@1~2(#_HkQSaeHFlr36_Ekh&g`ETtZ zZXLu)m(tOZSoeS2+o{!&x0uJ{k@3RciU$Df2|*gx6qiyg>VJQ$R&x?kTX zakQlv-xBTW{8H$FH|IMsWyMHgSHtV`QH?Zf^z}72jvKvA-ycFWu`p+|H^oG}Ki`EP z-Qc~GoOR(N9jb2n9}_+NTwLHlEFZehNs9J+F>%6oYjM1iJ4h=)e>vf>)f#J@U-^y~ zSMaGHzO#iOMOZP^JIuzG6}IAz_=Aw26^oJPmGD9kewMx-RuQcM4XA6wS~a#&(!@cj z`He)ZU%!}$bukgY5z)M1F|kWS8*}`El#6fnKOpkP9I3$O3gQYPMl|I_Pj>x(Je0m9 z;$l4~;!X5zbdD4qNP6QoK#KO4AUx*RbdPWN*#^Hmgw>_-r*3u$tAinI*qGEuF10N> za_VW8*A`2XT5WYM^fPhs0fDU6I#-jpvjUm}h-QBN2?0z^|9z6_$#UC@l}MF6f84nY z9y*fjF9{$a%(0y=lDzxO`mAc*3y{1UZdzuQ5%n+CsALn`>6}TK+aZZv99VLPNLS+m zmer0Y4c@ea0iyQWvO#Tia)vJw$SFk95N**O$ovB(Na^;X3pWtn{E{terLyy658LzJ z`a(pPFgro4*ntxpcK}hY;zWOX8fRmI@=J+&=DHm{6?f*JG+>tn|1&}+2iO}B2Nu?m z>r|~HkQIR?h$Sm;hD8Tb3DW_YeB7VX3G1OV9mO8z{HmgPQ|ySfKOd?{C7Fs zdp5bFM}wwfB94|I9ewdWskPmR^1#Ew}B5 zJ&Wmv{eRzQyzQ*e5_GJYMHO%LG36^&?tOXQBnNZ3#MlhPv{dPHYbR;vf7;m&Na8 z#K}`9Q@1qhML!6f3_H}9IMGFRFF_YX-E#D!){`c*9~fE z1K6A1$QDiyaByNX28i63U8RUdzA&E;)o@ zeL=vj+NFTn(GE7h7m6*r11*X!K~s9*gaG{_j_ZKk{K|JQJ%gDNXpO{RQ8|- z)sxUI*uWk<-8Y-SNev~SIg9V>AWjeP+T3Sew|ND-%|(sU-0z}TLqW>1#r32%wKC9L z*w&uHJ+?HJMO=l5UJxNwcxW5Wp3;jaEkb%hLS|bb0mjE+khTt1JiSYUv6BzJ?~0y$ zik_6N0=mSBGP~m(94P6@jbA|0!s7|4!7}0<?QmgAg-^uf^N zF$Q*g&9;wD4l7#pg>G&*kWwtio@>n?JJ@d7T-XM`JM^qnHUYYbP3+50L1a^DT^5xN zX65?vysB3}(DHW*TGTEFS7vn;Pg^Ndn{G5tzXi?wfj{X%++lkJ|Ji>0!S^eYF%ok# z$&KvK_c%@agZ3kjXxJnic5r7~`|~k$kboLT41g2ECs54jc>uS5*Z{y`rwuR?Fax-v zO9)82Ab^4aI-X{#(LN>T4LV$jTttkdN1k04oUw_5Q?|5W^M5g6w6`mp{j7G=z-h%! zCh8P4580;98NUJ}C=cB&72GFfpsp2nIG412vr%^sL~Ut4wZ|ipSc!d3;+p3Sgyt=u z6HUb|lXNO7{i*5MqD)jUq@qEODjv%q=o-TCwj%2odSS zMOa(D_i&9cMDYfQx6;Aj|B=dsvQC3|s7V|I-IiIiL4$P>EXfw%e#srA<3FYfkj1v? ziScv=O_W-|0`IKS@!x6Xn0L5I2Q_wqM><=dWl4i|{FmiTRurDv3H1ZeMbhYB5if8Y ztP5e^2kT^H^J!kj7h}*x8?h#o`dekD9ipQ%@1uu6-LqcIc&IL%9UY=mQn?x{t_~T1 zwf_R-zN9rwNf|1#F10EhF?)dc@&_y~RWzm+3BxPxYB@SG1)jo?#1r2uKcL5AD=`^H zOWbNW%NweTr4H&r$+`{`v138CUn3X8OwJG~O;Yx4D%g)V zb(FC)!}uV%ISlP=A1eUma9sdt)uJ$CfjgW{ff}W;R>Km8^XF_^hNIl7IHnx|`+OcQ zj#|7*{CxZvQclUpJWB2JDS!eAsD9Ej$9vs zirS49h{s4Bk7e@xZC9U$x#(9yO(kXpXwOQLhvd93bfltLdM!@1_a;8`W*@Q z+~W4BT=fGGV+V24U8j1wp^!OC7{y1~=uueR)SBVQGC#tO_}W$lS|W9+H*@VfcxW5+ zRFp)e5p#-J?~X>UTREEV@M1nrjm>yDHqEGNvTyo~-;g&WilUIR1!!-Z*IcH%?Yh(z&uLrcMg>^9=eGzVV!p zo(>#Iadir0b;t7rN5}D??{xW1SMi(!4W*I~FqIvhp25Gl?f4g&m{T$r6`TxFHN(n) zLj^d4z}68G(2?Cv<|FGlfdgBWfMFBFDEU6gdsjnv+C%(FLxf4267DW-oSf-!6Rif< zPk^Z9c+)W~fOgukXA^Wv+5yVq8u~n8+a_Q;dZ~R09NxjnftMwo4J$9sD(121RKl}v zq7XsffhvZh;!5D9am6Bd+$*};cpxT)L_B$wj_aW;W|Bytzv$WH_%gU$fB3)D?Q|?- z5_h|Mlh6!Bf2t&qWh6S8vCzqUZit!;piZIzaQwXj%_QK;Kmk0OtmCI*w)g9~tU7Gh z4^A#!$W$04IGg^(_kF!_G1)d)(Cnw+6O_CE;+=Y$fHlJn0G+AROaX26C_%%Qr7YN( zDLjj}f`H27N&%_k;DhwC35qQaQvv(nSSvLO<&*{_nULXA42T80Jq2$xoI8d0=_^82 zf0sh5P16NJk%Vag;$|2CbGB(3w^9xP-*6rr-M>-qkCg)GyvoUng-_>As4*RY z={f-2KP&2cL6u^#*&^hr)e4?PJAQ+QZ z6e2^gB+MI|Gle0dRCq|e}5Y#~7=R}Cob0c>W1HtTjV?E{z_&*Y26ZUj_) zU;ymc!Us-{h81}p!HXZ2f{Px(O|1?WZ@c@6`hJIK_*zlRdvt6aSHgLV32m;b%Np`3xJNpsf#YWBN zR!=2btpS2|9XAyCciL5HL@~qeKQZG_qTqBM=qw|v+4$50zi~jlz{=ov2EWvc8zl+; zv?O{XINllKP5g#Wt$|+}A7!m4l@4-9_cEh6^mG?6q^y2m?}b z7uzetKO7wzM)i8I?F;$C<(mu9%F!cPW(vX%zR^a<;c71et=ecovm5Vh&eBHXKRos3 z3A%KG-;XH;KVQV1?iT^u5#dM{%GvQJ-jvgeUkt=yf`ECJoPL=Lr6=xz6@%#+>34pcB$QwX{KV(=owF7Xmw3MhefV z=ck}HE4){j6uifD*u*VH!!%4d0Rw8pN}-=`CyQX*VCZioE;V9C29i9mOSu4c;ZkeBdjVZ9t2ZU)UXFkhYAvDYg*d00pJW>DQ z!P^1SiZ^qHulALdGxL+E5ufn05Y%TM4AFLJ4Bal2>xw zW)ot8kC&pxO6-Y<%k949nZ@fpEp zHHh77xUh@yE*=cu6SQZ?Yq+?veye$vqX^z#s{~fE3j)a}#J6?{V#fm4@Zns24UocU zj;Pr*L0nG6ZOu8cGAmlcn`*xn#3k{ZSd$Jw@?bfVsCANxC8s1o8yrL8C#;M5+<#XG zaXjlkvHsOi=CB?k<=${uGGLv~p4_~p^76zsV1I_NE_KH7!wu|~%z6W+5;_WDHqzv8 zKk!p(RXX+fvaEF?hrPRK$&-!1t3sxfXFjuEuZu>Yi(L@M4UMwVm|L1VT0K%JfwX3+ax*Fl1Gje3)1Y~ z7aKNq6L*7%O#rZBjM;|Vdg3PTIWvf6w_DK8>ft!oHu2d1l7M0OaSbs8aAVP%xs(>0 z0c7tp0QPM8X6~8$2)MJq6kxW6FUZ5U08rpJ8O5UPSaO~Vj>>Kk$*-qPOYlP&{uGS#iiG z$Q%cmQawAdjBR4)whfI;`^qx6A@BP0tBVCwZ|AMAxgEf(Z`4`N`0*OfKn~x|1JgVL z4j~pAfK%H=?&jy8e;nV3W_HH(0IdxFu*CUQirptmq_aLe?YOE2e9aa+0_n2yvoXuu zDXMi~Rdcj1bm(Vh7U~^sRthDB53*qF3-D0_TpsD**ujsJ+8C#A<#fAzK# zOhTzie}k5EighS54!mLqS0_3mNek`2cc5N-Cj#Uw-pSRLofg0i0-QVrV82srl6G4- z{%;T3pNj;WRQ4(_1E)C~h+3$Jdfr*zdLq2S4Lw;wqRKLsu~Wz2vM_x7M7$k~q>5vAYeP#Wa)D_ja1#?ESZ^L)nNOzaOHK zX9|V`xIw+wiFSF8pxG{VwO}<5= zV7DtH46Z1Qf18e?D9@B`U}gSsxzLwyM4=4Md2x@_(tv4D-6 z)OYQ2bXYAczNGDczEW^nWOGydW}|fB8d2-GZ2owC3DK^s6SSu5Vd@{*+|<@N0FG}U zpsGea{6B{bO_weG{ss*mgr1I;G#u}hLZL`DYLlyd*@oXEsa-Y;25l~1x;4rLt<_ed z`LoSiU2Vh4derJQ<4(;&9rU$i=|ne!<>m6@)_IWe$99t8%C>EH^EE#N8o`3JUJ(T!mlpnS+(=7)~xYe zUP&&Y-v5?DKOg3+Hiv((@G-mR%8VzwIkP(d==>Kn<*AE(d0pBvh*R*YFk!t0{I!vZh4Gn9aP6)&nfl-pbrGIC-!c3tj`&) z>pVga;P>pTBnB#H2DvCW03GN<-irsi&v|t+n zRlE&=1$%p(hj_aa01gEc;KQ1o;GwoZ(OQKI+Qt*&B+T|XdDj-oP&1MeDv9wE*}W6| zd9Ly#$~A2*%5^>|&VQDCuej`brBj^X#21YHDL#Lhe8p%Ix>k$!g-L3#?nl4 zr)|-qh*PNSW?um$o)RJcjAh_;dWoJ1yhOS5IoKX@Hv*yLE~i{Ta!*m{1hD&LrMYoP_m8TiPJWMgN7Mk*WZdcoB=RtqyeyDoj{=mR{ba8i7z_v(SMe1 zsbfmmQ^rEM<)gWBH%OL!GMj%Mk3)mba=mJw1?|KnqE%$~&fx@h%2~dd*+@Y9zYKsi zJNK8HIkP**MR}eBI$~-m^z~Gr69hVk(A|F(wk`Z;tM{OQna+r`zhR$_1`@%L}0WTr6lwDKI8U1alq%9!o@3)0Uu< zeJ*l9eG$Owg$MEjgZvqmnO6mrXXs zvH6#Db*XczpWX4Sog*e1-?B;D8yi@`6>P{o|K(%2_P?lR`T?S8SkVF4um;}XLJyiU zIdYJY%Iw3xyi+VMgF8A~(6(lyX?-vAri~=vPObqkW9H|?Pf8!?(sKTSo6tKgV;e-gbh^pMlf9QgbN6p=3W7oH&Y8f@DYu|S-&yMIMG(?kaeq9ua2v3pne z52dtMq1DkdqTGzDJWQt(?d&&55O7=XTpdz{rOL zs9F9)HypbWfb9(c1+NGQV$rWr9d$oM4J5#`&;VGnLpMaY*gw|v-EJ73g3kJ-qJOJg#Nc6;qxycA;L{&xi~>)#&U0Q@#hFUhwpM1AmvG)9A}=l zd7o)-16XBd0Ib=B+kF3;MgY!d{Vw6i{Rs6K-vQ9u)&N+s3$`+I!w{O(DeL58w7o65 zO`39E!Y1AkC$0likDj8JIZptO^zhn6Oq~W5tGVGlH@ye*Cl3+%sMSv{&xL?pkLFb&o2A;*;+p zVw3GQo zlTqNLy@!-D80T0>aBM?aITrO$^n1~gPA6xA^%HC_Wq;eiz;4fOzvhkF`w)#f*F*q5 zon_@x9`Q}1?<3GV<9rLrCpwF0DzjwAVr6!0!XsXE4zc`bSBfRRJ9knN#{OKg!SgB@4o#E8>?)}a`x;eI8POGcDVgAr8exm0W!->21$a`c96`| zFz0tM>69CQ;n?^;!?D>A1G^==`daKBJ+>&XZbX+{!In>|@!^qz-Di|cbPKu1i0#WQ zPC@!5q%NfFhmr+*=V#nVBXKdgK1I+D3fc{#Ma>j6<#TZe{6|hq(sh!)Crzu>#mb41HrFKBKrIiL0=Xe&2zol`a;9?~KoPB4$?9k%?Yo3le(N)5Wb z#~z26L*ZxmlLnfcZKC?v01lS~ka$Ukx8aL5XeI$WuL|H1ZpebOylQR^LH1!Ok|0up&%Gr$U)@3w zpy)#EE+fCCw1KfLuqcv-cZ(;2eeGMmhRuD8$~NK%CaGufqC`F4cL2QJ2w?1+Vt`~% zz5Twg4?6R|5p+N~X8ax**R$p1wpSdsyc?SLZE=Lz{K@5OVg{h2?*UxMWd zSfuW87VCre&@9YS?r4Yr{%b4e`=N2&Fs!AGv%&A_KHw~AlC|87HL5GtczYhEg!ck_ zBG{!{v9ZkOgUD0ATe|ZqJ$LK~KItH>GsjQ-#A4S^D4d}*6qfy7 zADtlJu#Yf|kFOkWw=F(<81fm&7OWV^WD#GmA#uQZb}-bv{EG-#yW4fxL%+pekE*4M zoAQxt&^MS%Q(11w21MdFkM>`AwaTxk_Ch5C>cT8qh|c_8Ab)TRu0p$4>11KeGQWxg zsEUwzQ>H?{Isb{_^{N|0THx)QqA%>OFQ4%*LVm%2*gaU%Hy!^lfxN0qUkC8aM@B$8 zE!1Wg!9(LhHFBEKS~q+M1rH^pj-Jts%%Wtm-^B^yRe|Tv9D_w@nI_GjU`zU)=T9zt zhXvO46y?76lq>mj7k+T1ZyPUl1Dt2y1;_b+TUP>>WBR>SXwfF6eG@9}UOQ37TC~_B zl%2FN7`qz#o~;v#G9g(Ke)gs8VaUFdnK8yPgPAdQ{qOTUpHFZ7yRPqYx$pCw^X&U` zUUgj^jxm_+93E+7Pm4Z_tX%UMigada6&X>?EE{8bF4_0Y)>uH7zu;m|{{=Qy!X1fl z9uVAn>vR(&xd&>CIyoQKu)G_s`l7jJ9Q45^7==3+$x*k*Uig@{INhsR20M>)I9wfS zvk{f@t6MSiMRPm3p+M8|Q=iXu+ApJ(Sth(VonsY+2L!fCS82#uZq?~p5x-5V0?R(C zakJhbDHyN7&)BL|1sfGdr8>J~NItu05UJd7FQri%nC1~$y_1)Qn=qU!b~*~*w`-xJ zIOsWEw4v9!iZ{*HQP>SYCWFqU8t@MRrs)DJDHB+uRe`n!)K6EeFh+vVJ)=Wosws8p zSXJAabXZprXOx5Oo(3F5MQ}@~*g^(Z)rwn_m!8nmTn~E2q3Kjp8dGv(+v>iR-={w~ zbHwr;GUP0hrCtElLaWjQG@#E?V~wiNIHZY|s78aU;*lO6S26Lac{w7Xg)KI$s)~p_ zW!9)Qv#tK0H}bU5@)95V@=I!UAJ?0bswwRK=twna=+~Atc+;`AwvLrfIx?=94g7+p z;(>IZq#q@s1>&*BYlM*Y`f~i{0|Z32qe#d z7U?VIT)4~{^pNc69w@JO`idA`$ELpQcny(xkE*A>vVL779$}#HiJ zcE{IPGzqLqOJi(}RYwxIa}-_!ip^u;8eFlVm{?nD>Dd!Z9y2zBBvV>Lslzjdt4S?a zEkOE~qulGO${gEq#!3^;gIh_{x;%tTFp9ukC3ANuYpX+@UBwIAZN{)rHe6yaj0L7+ z0<3qO#Qv#;7uC@CX428DcCh%alE(Z5DVb&>LT}~J&BjRVxxms)0rejzp&(O5yuFRT zGVii8nY+UG;l>{%RrZ6eK4qAS+|J`LhLa`n3}H|$${0I6MPe>fA$<0L=GvK3W%=Y@ zNU(XOOqon$%oO%2oNI>AmNPiCE5*-1=)cT_sZUJgB}<~ExiA%B4lL+Li7f@jc@THB zTy2qE#QRirJ1Q`;^Ce3gVa(G8;U^jiurW=u5tbG**xXnnnPrSP zJe16z%-pjPj1M)p73JI277>2rMJ2XM0A<)J!e4W2oQqzBD{5F|#g)ZTx@4=g=V%%> z8uR%$vSb}L6x8QQu@RaS9gMIu`TEo~(GJGrdkV&xw%ZBgMGQ8bZAX!|xCQjyPT>PY zM|*&@Km$HqU}wp`B&BZ!n;iu$9;3+WB7f9I9aHV_1v|T1w8dU=hnCB%rOR>+I5O4F zf~Ez*7ZQ3;PX|yJ(==2+2Vr#vgR3*Xfo4?bpa>`IZng_OE?|~>+@WIOAKLs)-ju8y zMWQ?%q3QhpzA}!A9cNc)yX*f>Kvr2=R=f{meo%oU|9M=pu60Mb*Y} zeBh|~b2}*c+^5Y)WW-@)gj!}l`8g?km>lDTc)Tta%55p#NkncNgAHzJBA4Z?n9y@4 z#e-EA9$U6_I?U>0_Nva?85H2Gw1Ub6XN2x}|66Fjk6gsy`NwvYGQ-J^oPM`!C_fmA ztCB5TK;3!{=b|s{!UQU={~zf1^wxDmzD=cum-B{7T+ugteuHZJ(M42fLs!($BX1?q z3F8864q&YQ2Z_!20O2+0vpE%$e>INEL@MSZ73!9{i!Qm!QSkWV?d@V9s;<30Wz`Xp+QE#cfrjDkosBPQd7ve)@zW|LY$iFoDNVQ{ zbPq9YdXQx*MevESMqQ8z3}v9lM@sYDVCb=#hG}gMhQ|UhUzmANQ^N$-RoEMKd|iOi zxMhGCJJZ&>qR@{q=+@MpmWA6p(5rfiIT_Vcyg4@Q=3GqqP#q7!uqcgC)wN@-%FEXc zw67=L)VlJ!^oz5qTRlLiOV}M$FLK=5eG4U?ect|W+4x<^4)#T$?#+5oKz*ehN5W3` zOS3eTMJ8m_tBF40LY)^C))#5MSRW~A(nDioVGnx~{=$m%F>HKdXFOjI;xFN0Evfy> zNpYiKccl$-C&eAXH}|!tfPwa&RO~LMv!x7XMQgz3+oWTPKo6kr1_<;!TJIsuZ)Y%X zkN|zie6YPa8G6du<=RG0@AxifKGLe*VJsR#S)NK$@*irCrNezqY_nW8{M{BYZI2nc zdZ_{bKAuV_V*A_^l{_zwLwl3yXnR}!)B%@#bOS`=X2RDPC)(Gbe90VP=E)=t(|NLe zEqWg>U*egr@m?N)4rskq#XkMdnHu@s%zYGb`K@z{CM#xR?>!Ma zb?VjdW(xLEginXxJ;E}gQ00=GDlU2_!vUnyk>lZYA}%5U@tBL|rQQ_txNT3dx9yuy z%ousx8{&(IJiQBa9NeTW_EkJtLFvumHzy(RB@~RhAV-yc6E!6RKSjLk_KNiz-4`Rn z+whA1v076bKhY=?{ZNqCbt%AKaiXn$vQ0Af(p+L6{S@(HS^v|NXmeDceXy@?EN#f& zUlH%0J!jgkU}s0$E6HRxWNm(FrSLYz4zt8Njb2gD=l_M7#4Qv%=7ie6oD^NWg7#N@ zzq!M4>5Sy(=w7;g5BbM;9MqRMf?BgYHg^KV%04v!2^bnIu~D5I%;^}rsKI9km^j(4 z9Ff`sjvqV2H%&t@)}6FWZFb%z?qP3bW^CM=c>2rM%gi)EdwhkTdfgR5rHaBQvtEs$J3p3n`%<4aqF5F( zwthIpHdY*I^e6}8v=R6q2EM|@?d}gItw(7|`K2xKGH9XRpaVnQ@Z349;{DZJIKNcb zXU&?%2;E}^jcJ0UJZP+lE&igeM{@Zz;2^SFy+gJ&jU|0)J$sH6U*zByNT*s}AH>^B zH8CFv(iSFPSAD#i<=N|MQ4<)7SkM1$MfZPm6b=PNHU~BZGYYOXn6h9XVw49@Q%T?=6h``wzsk5+Dz#PTO*qxocphwB~BF7OtB(o7e#y#;=n_n zPJT$44>|;O#Y_3fS&kO~%@y&jqvI$0r#?rTdgIJXJ(^VcA|(@=E8@jEB`*nJhZ&~m zDAb)q3o2-?h==D_vI43FV<6d#5lvlz7u2BGAjN?m)Nrgxfh|OlhPFWbEiEN6yM^4I zVl35$F-N-9LR9L%7`yB$G0&EAZT~#7t;sVN?6AaD9Ji(gO37(06+RkVgMW1M2S_Yo zkYjC)BdfGlz-5QRTd8==YR~OT*bF8j@f~4;!Ihs@P zKHQfE;}r;IUXqrn&5p*nN-to-e5xcCwpJ{@w&FjT_LQkOqk)SYt;sw@_5q{YK*v#H#+UZD5wr4p zjQzPM;kpFELLf^8GCbuF<<%N9As$owgA`MVz5btCOT#B z#y>BiY4StF_NpfO`&}vjUt2|dvSW~~=a6tT5&leDCzYhleJMHeJB9C4FZ>SHetxL2 z)Pg+?mn4ndEyy}OekP3|aa_BTkGwHXaiXbN0mZ;(4&rGoaiv|8s#;T8%*r>5iCe)>iT;}Y3H)DKnWW6P-k9wApMnNG; zS14Q(g20_-$iT-!vC?}SBD8*BqGw7u;&h5rZE;hGceC>2HrCR%% z&ppF1?J2-KP+gGsZ%XktVWNfi4TFkweA}d}Qjapjlm<|Hma+FQDKcEaH|p?NPvHk6 zx^ah@%Td-*Xj$!4d1FTr;Yts=BU)n`d;jB)nFXn2OfdzFP;mcT*V#<$%9NLwZ8avx@r^%J(Arsf(Z=DIJNI9Om^u05JuX-&; z1l0Z91T!gl$qXviMT&CT76}!*@#LIUfPnK<3ujr;V8FH;*gq`Gv2ooLUiB|x!nJle z;z2htFZ{v;zRLMkp9O_?m#sNtirLBu7?qWJ6}|uVrR45PV|HT^7Zf*S9mTNcMI5=r z_QI@!{S%9+>D#>Q=s8H&O4Ogas*L@+i4^^=hZwA*dLRl1n@P;Pxih{W-b18yD-$Ix zB=JNFe`f5LRuXI8Qz!`U39L#Ri7k{^He=5CSOUlCeowjct5>}1%g=~XWp9v=+Db{^ zUQ+VAlb-!~&!e(W$d~O{vLUD5e7*PhY>|4MYH;@Jczp`ik6wY1wHso7zYvg{+b z75gBiBO(}cq{deREO_odk-;wAC?ZPn6mtYoS~^|aO(>!VN^5&hN%1VfnPW9$@6(&Z zgR$_(IidQHQJ=!26n3JzI0_4}18eHA+ete*9VM*aW$^e~4QSa{CZuFs;)k?{QLDUCnfe1UG9ewB%+@z$065WZ7u~}S#ri_mW1nteo8IQoMLm6GY{w$ z;;fTNCH)lfDUx>M`;7emgC8Q7Xt8e>8I82uu2N6yM^hhe3hNn?VLy2P$M$75c-=U2 zx;y~KLWj)V4XHF*WWrxeT&*XGy8XpsJE%Xf8TBQ0slK~8^_i_X8fms^X3iL-WF~$M z@ca6gld_o#`YZfZlouR2#zThQ>EZ4`tp^BGT?T--=D0)Mt%%s{qRn;4*j zIYmazihGH_d2yhYP;N31I{X@uYph}kmy%*q6U&%)n8a2L6w~pojJbE0*!_VD`^Nvo zSdU(e+0*7;?$U=hj~Ee!tsU}^lpFY|_x8rom>6+DkQ;-*gQjy}H##!i-IzLEm)9hg zpSG~!2U{K(a@2M9KDoq-Iy)d1fkSbu6N@vFb+O{S@-SmJ=1I(dJ`@@ZlDk50hvx2^ zgYN1xlzM*6VEmhta( z28#jAWiUcVtddyFV3BPT8QYsKG4s`^CYtNimza37RuX1I6!!A&IRseHdWo%B?~d>8 z;RKEE#HTQ`ZG&Wrh6r=_7<1kvF^8dYF;uq+0{?8VQ9fpz#%R@Bo4;A(8`A}Hgzf}_6!xZ76VBq1+|L_yjL6}RZ zH>}T4%rLQGojDBQ&J{@e_lL=t`pvZd{usgyMmTlFABLGfXKUdem<}2)Oot7Jig=uQ zGqGg2$gW(*CLUzWp3WactJ1u;Dr4fC3RC$RxCytX}T=^wQR&)>lU`(Ia82M;8s-#luE> zoom0Z9v&7{ zI7(#JMJDR^)Dl(6JWg(Ow0!!k`mfO43A)vV^`%ca@xD}ok|63)L;|pP%Ng?|N)U4SjD1)kv3@I2wuXta$xL4Gri_ax9Enoz4)$Cn#Rnvc z_BkmLD$>#joY;|&5gG(n^J8AlIl$x;d!E4N2|_UsLcgNz%Js@{hl zu}f>*hAznG3wOpMR_=SXgb6L$>tRZt_+yl)1;O8g#%IR9MS9NnVw}olLieDSs7^5l z;m--)!Z0gO8wc|BX-U2shwCe0XFLojbeyQwQOrI*TaL{bC+{;YiR>8o8LQ*h*b7h( z76;F1#kof@91j&=o>IzqT!{)DFZYf=-5&n52C}gqe(JF+gObOKvFj+p>HYoMgJS>n zaHTKf$|bsGIFih79t#3$c1tpJ!?^DbGeXwG$rKCJ+61qi4fYqoRn_96fjG%qpp+W zkTkWuP3b4_qfiLyQ4KrOlSH3$WD=6POOfH;Oj3mB@5NJ3)V+W(Jo!+Ed(%ithD{dB zuEfa*ZPZj^(M`)|RK)d=Gy7os7Jly9IPzS>tEH5m*3#3A45!G9I$&96j|a>R#N%ny>G(rUHsT411BPC1QAR=3#7)5zt3Szh^ND^gJ6@#>3PouBb z<7-X@x$nDgBt=dY^VE1ItU8n<5<7Sr(}AfnvXhpU{@M@y!$w3_J$gBG)`qFatM6+m zb6Ojrstmxu>ZXe9sZc4|f0~>I+$cJm{Rk2rkSz6xWDXx>T&g>!iN;{e!x>^6aGe3dX}FfanXRUZ8}>*%R|S*non{rwaxB{%aWDGoW;{S|Fx38jirME zQO}=hO_3_glEpN^IR$2NrfM;KB{fA3P)xL%E{P@6JR*dotac%0SMaNg-`BsKlmYNgDQ`9XJ?`+oB_JFSJ9XiAOVPyQM|8*SeBpO5OwYiE0!(!2*^115 zVq(QyNxYvaXMK57ww^eLlFPHG7(YGopQR{V0{u_7_}vcipMak_PNtMHOKHkYY!-CK zuaLTrt?9(I>pN4$p*l?K*e?4;ZTO1{9LkFy$rhLql;_GJ1wG69hwohUU z_IcJ8)egFC=79Kdza%2&$cvhc zmMu^m(&mc3%ylltjNgxFvFbEvuBaZr=>5@9q|=2)@f{Na7PE@Uc{`5@@*-5p13pcXdWVy z8s30oUY}luH>gQx_bA5V9z@`8zod3Vl&)bNtsdEmCw&WGL@Vcut&J`7p=!v+^32a0 z8|dQ;exk~lAZzsQ-x0JwMK6%Ef-5iH=B~!O;4Wt>&bPkkQO!lzqDh{w7*YSKUKUim zK$doMqx`PFqw*xpt~gP8fop=AFjcAcLcZor%@?8+>y9o*OdIW0le`v6WwU}exnU2d z3O`^|m*=LRIE)+JS||@@9I6i8HW*SKXi{p)05V^s@aHPS7r|C3z6Z0rvrq%NFA-p?B>+bp7oZ|$ zD>JveO2EL$-rv=o%Za1`RH4pk83NvZ=S4-K-qz&#-phfKmWjNW z4o0`TKItsS0ob`^iukZfpVJSn{)%WFMVYA&;cBEU7iVyx%Mq+Y4GxA@w_K)u+@)rx zmm?TYQq-%E22{9Q3Ff}4gWmCRY2a_*rylHU;IlK!6%UFt^~QJg`1=Y-am)(Xc`2AW zl(j-GH@`$YX#NG^QxQG&r1lG*GB3x@Sy*jvb1FQ6T@L6lSP30L){;rJ1{1bYq&=Dm zcf4=rARr7W*@m-cqRj0=reE4>X#@JQQbwSEq@Bf1M1TiVbvND>?}Aucrk6Kdojia) z&2C6^(dz8Z{5q=*YL&W!Zj0AJLVlGPRFABJ$vi(TrcWOvVV4GCv%e%F(&R#&u_kz9 z%nE>2Bk#uECbU0I>`Yu{_9k8%YguDb>Y{1|5QzUZFGq|fIcZ8iI%FqLc$QUas_yN} zi5HTX)!kz~QFzD81`5*^L$Xg7P1Y|RL_Xf}YKeq&5n=%o^Fp-*A2mE;>_}HFW=Jlp zg>b9YAQpv5;$9fC^XY0)YRi~d8!ic-H8|D&9F8(&mMd7=oZSw5csvNJ9(6ypwwpGL zm`yGl^LN+@B()Pt2K~JDFDKmvu(!pt8-DP=A8_gfG1t|5Js zqVk$$fbkhAna~VH_|Bhjz^GUc+Fl{%>g8b4C@Fb*6f%tcn>us-yVuF!6uazG5T=ec zojhtErH2`E^SXi2vQI9UzUZ4*)Y*&tGQ|=zJ`-^%nn3=USjcV56op;LSmPfVv!VY$ zpiFJnvD|{R^|*CBe4Xfrr!sVGF`$NYVVzu?7TbFi^EbAO(JIsf>}o1orwC`dMdx?4 zodTIG{faWWD~0}5>xKTj_0WHr0Qu9q^&)1*S%CU%qA^)YEegz%18)3$&wB@;uQv2q zt8(H`e9bmXVej4P2&i{=t2g!A?v0N>ZS&TrFZ^Be?zkkxRGsaDs!u-IqC&RJ2Do#d z0PSgfwy-`Qpzfa26ubeGU2)3Q9R-p1Z`SGuhiucKsvr^P_gS>6J-S)FZ2$s55 z=-9FQr2WfDDWRYZ;^tY>2AJr5Rffw&IK=%3W1nzf%4Wl^BkG?vh)5d!1R@+qqfE5@ zN$$?v%$;n_8&3b?r#6y#TS_j4B#$v+ANyrqL?qbhy}HJEQqfPMc9gM&ws4EML9wMK zIU*NAa)8yWLS`Frc?g4db()zY7C>v6SZBzD6Wz=aqxx%LIuT^LQE7;j1aE}I0Y@re ziNr5D2JAG-*qL+j=q8^(jv*pDDpltTv=gB@!nrRWRqu?P-fmiP96q16NeSR)+&dz? z<87$nw^VN04CYqR-IKC6p~1&*k~MW>_LSO9P!M%2D=LepENEkcgA=Nb$#SVuC9Ffm zQTP{nxk-$|4x5pr!#(NMCd{bAHj7R?fw3P4(xYw2wT+uaAs%Gx+6am9x2VM+;x^<_ z<2{J(3q%(iN!q`h6bHCZ;^2X~n&Zgvy{!L*)ZeH-YDwcnDcL{KN1sx2Ma@{33u~>$ zN@DR?5ceeUjET{3qQtt7j0eG|k|HiwbAMX#1kI>Envr^>U-W~NkKdxWb0!Zm{BMyV z;?V|@>b~+g+$yo=`#<;?ko{C2GvNlG2kh5dVAwiY(jIx@vQU>iU;}1JEPs|yZEBq- zJNz2meUd$qFZb|MuUI#(km3*W#FC_pRn%T3vEi$HEVTyvY-NLMB(rp@xFc|ov2GhB z)_I!(zu6m+1-v{ESrBg4quN$v!DCc1wb|F3wSjnq8?_CJe%s2JJvH6tV$T_o``V|pbLGuR<& zn8yxae%BDr-+KnPGCcNX#~6P6br%xfK?wx z`Bq88EP=M{ME}s2idZr?+Lsz_a`nl-0L9mr z`V}B;BV#C_0KNaB0_@-++_csIC{+=L?={s|h1)=d1@isCiZ>0zd93t>oV!Zq*)UqR z2Zi9fOC+$%E?Ag5LW>#FqFti-W;3yRR5`-qKEAic1M$hYrybUzz%QfHsQ1_BCzX?5 zyIV1%_PfP(g?_uCZR$8R%PYI1OnjQIC2;?Ix9D_h?g3Gi$opu=)RBVcZ6Z&6QXNWB=wz?3u*M z7#p)$VqN#j-sxEX$9HSN!Ys_5)K>hqO39rX$P4b3(7)K|Zr99CdJPryUg$k2{Khd#Y;! zn(O;nQQs4CsaXO_ce();9>aOvLjyl!?eGwA3{0f4WF~^<#uDk;Ixq@`_F%0Mtm-HJ z#nSVb5`iXKvk=y{)fU$3P`5(4dVG6f%s?YVvjF+4ZUFzbCiCNHW_t=nDvJ?ZH!@ga z)kcaYe9V4N9|%MYx#hm~uUtgIrluarQhjB9^_?EJEq1J1%c{={tdY<>mwZuv$GXh9UbCh|qxnT0&eN5qok~ z#+F3xK#U?#!s>bCJxVN&x9r<_&JDW zHq+~wK0QWD%M}=k;WLP;U8eX|q04%Hmb7MypE;eqAR0jUDTGO$MN3X&?3s5;40PKV zGh54;FTFb@dSTPkz)aUktnX=oB>~eJK#NZ+ZDFJY|I-_~#ZQizNySQ4>VF1%cZFM! zFL>={?8;Nu-2RV;T|#Z~KsT$-$CPaqg8D$|!ZT31aeD>Ekjl3ERp(BuE z3&o#RYS50uu*@qLVfk@NiaC2I`OUcET;tJ^3PE{vNj(dtBTrUfjKuPWH_ED?t6Oj$ z1^EzD7xnaK+U4?rE?)MlMSjI1vjdBvGxhp6T0Hp3$-Fj{w;$OVlzJK7mX+-re zi0}><5WbU+KPzoU(~rt!WeTJD1_G@^$1liO4J=xEFAG|aBaL-b>6_@_PX!K$m9})P zwv5~q2-&~!Q_J>o@~34^kbQbvZgI|WZZR|k6~P^A(0VGh*PVr02WsHrk1s^Y)ot<5 zh}-J=f|09RPVu{626%BFwi9`;UH~j>>`%!p{2NfrMa7CmlYX~-XbMsGb)y!2)>I>U zOe6YT`t41LIQXiI#i*YuY8_h$QGe;%om*0A{iO!+P}u@KNoSR;UI=BE;Fve*lF|(2 zzU2~{?#(bQ=0sh?{f+5aTiJS?OF+lRYH15fERj>D;x!4IK63R&jM}O!q)}Fh(v3%f zUrRGug%Vg5KuxsJ)>opJu!_OOMCvC||`dRc7Sy=N>s zSz`WI#0)v~3b3qHEmoc8T@ke@lL;k55)ZH97Wl1VIXUTK(KCzP>C{C*s~gpbb>+lc zToro4uR_lc+2x4M*9DQwM57!n!Mi&;*MN=Pq{U3AWRt%>b-5KUd}@^#TO9Ol3~ zibUYF8#3*wPpUqhg0$~P?NF!v(Ftj#%}GQ!=7xxH!VPHHcv=#6kE9C68teY44;6Nm zR9q{TlKI0C(P@u_3YVKu@!bVU47n+CZW3cD7bW)aBJ4FdDA%hE*QP9gRU2;0&=}O6 zjmu>guP3@CWVGiksObF%W407?OA(uv9eU>`|Bg!81jDv^Jw5n8uETg=@t?oF=yADz zJ}RhOs~+EoMd9GGYUN zz3RP%bIJ@krEao#(C}3c_I^x|T|2JJaD$MT+)Y-EnOiI2C3oxJ$wXmzey;?ihxl`B&LibAY*CV9-ZD>Z+Ufzc_{q7QL z@<3o+9x&EZVk;!Jg)y7n5_<)VGhq1M;faS};U`oib*#EYNy)CL0o(-BA_^^LAU=sG zVs&-Hwf=|V)bALINVncV8LrJ8QTy#nfwhg5*kEhyU~%FG&cFKREtGu+(`seGgEhgw zHcYnND0txO=@4I4$@VOIRVr-zJ%XLE;WBXfCb^J_mDo1tlH(@H$&PJ0vFb)B;|YV> z{>nHhscooiAD6J4BQZk8_pDe=W>d^B@(SuNFype416xtaFJj~9BV)l?TFi)={VHlx WpI<>N-dK)U^{Y~+`iuYZsQ7;>qT-PN From 738d68a495c1ada25ed0f01373496b0f81ea4622 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Mon, 5 Mar 2018 15:55:36 -0500 Subject: [PATCH 051/375] add todo notes --- core/todo.txt | 3 +++ todo.txt | 57 +++++++++++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index 3fecc039f5..d6c2f103ef 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -33,6 +33,9 @@ X https://github.com/processing/processing/issues/5404 gohai X ARM tweaks for shaders on the RPi X https://github.com/processing/processing/pull/5297 +X Fix 3D on contemporary versions of Linux +X https://github.com/processing/processing/pull/5428 +X https://github.com/processing/processing/issues/5308 jakub X fix line joins on triangles diff --git a/todo.txt b/todo.txt index a4dcbd9745..d145ea455d 100755 --- a/todo.txt +++ b/todo.txt @@ -6,9 +6,34 @@ X NullPointerException in ContributionManager.deleteFlagged() X https://github.com/processing/processing/issues/5342 X move to Java 8u162 +jakub +X Fix scrub comments for empty block comment /**/ +X https://github.com/processing/processing/pull/5265 +X https://github.com/processing/processing/issues/5219 +X Fix error checker crash when className contains [ or ] +X https://github.com/processing/processing/pull/5304 +X major fixes for the net library +X https://github.com/processing/processing/pull/5378 +X https://github.com/processing/processing/issues/4419 +X https://github.com/processing/processing/issues/5360 +X https://github.com/processing/processing/issues/3970 +X https://github.com/processing/processing/pull/5389 + +contrib +X detect errors from curved quotation marks +X https://github.com/processing/processing/issues/5133 +X https://github.com/processing/processing/pull/5152 +X Refactor to use a few Java 8 features +X https://github.com/processing/processing/pull/5134 +X Remove "Pipe Organ" from exec javadoc +X https://github.com/processing/processing/pull/5282 +X typo in Italian translation +X https://github.com/processing/processing/issues/5365 + welcome _ just remove the welcome dialog; but what should the default behavior be? +_ or should it only show up for people who have used <=2 but not 3? _ Welcome dialog rewritten in Swing _ https://github.com/processing/processing/pull/5210 _ Welcome screen doesn't size properly for HiDPI screens @@ -25,7 +50,7 @@ _ Rename dialog is unusable on high density screen _ https://github.com/processing/processing/issues/5368 _ change up the newline handling _ https://github.com/processing/processing/issues/5327 -_ Contributions manager fails to complete install of PythonMode when no windows open +_ Manager fails to complete install of PythonMode when no windows open _ https://github.com/processing/processing/issues/5309 _ update to launch4j 3.11? _ http://launch4j.sourceforge.net/changelog.html @@ -39,30 +64,11 @@ _ problem is that any sketch that uses a library, the lib is stuck as "in use" _ https://github.com/processing/processing/issues/4973 _ an incompatible Mode prevents the PDE from quitting after last window is closed _ https://github.com/processing/processing/issues/5112 - -jakub -X Fix scrub comments for empty block comment /**/ -X https://github.com/processing/processing/pull/5265 -X https://github.com/processing/processing/issues/5219 -X Fix error checker crash when className contains [ or ] -X https://github.com/processing/processing/pull/5304 -X major fixes for the net library -X https://github.com/processing/processing/pull/5378 -X https://github.com/processing/processing/issues/4419 -X https://github.com/processing/processing/issues/5360 -X https://github.com/processing/processing/issues/3970 -X https://github.com/processing/processing/pull/5389 - -contrib -X detect errors from curved quotation marks -X https://github.com/processing/processing/issues/5133 -X https://github.com/processing/processing/pull/5152 -X Refactor to use a few Java 8 features -X https://github.com/processing/processing/pull/5134 -X Remove "Pipe Organ" from exec javadoc -X https://github.com/processing/processing/pull/5282 -X typo in Italian translation -X https://github.com/processing/processing/issues/5365 +_ examples window not updating on install +_ open examples window +_ mode > add mode > libraries > install video +_ did not update the examples window, had to restart pde +_ was able to save over the video capture examples b/c they were a library high _ menu bars broken in High Sierra @@ -833,6 +839,7 @@ _ when are prefs saved? could instead save whenever changes are made _ and then if the file gets modified, it'll put up an error message _ also, this may be part of why other sketches aren't reloading properly _ simple prefs implementation to set key/value pairs using a JTable +_ https://github.com/processing/processing/issues/5425 _ prefs window doesn't swap ok/cancel properly for mac vs. windows/linux _ don't bother having a "cancel" for the prefs window _ make prefs dialog modal? From f3d7e49fbf724e98430bdba7f11818f06bc8113a Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 07:47:28 -0400 Subject: [PATCH 052/375] fix up the todo notes --- core/todo.txt | 4 +++- todo.txt | 17 +++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index d6c2f103ef..a8f55b0890 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -6,8 +6,10 @@ X set colorModeDefault to true by default _ add circle() and square() _ add push() and pop() -_ Table.insertRow insert duplicates and cause ArrayIndexOutOfBoundsException (with fix) +_ Table.insertRow()) causes ArrayIndexOutOfBoundsException (with fix) _ https://github.com/processing/processing/issues/5406 +_ blendMode() with PDF isn't showing the warning about it not being available +_ https://github.com/processing/processing/issues/5105 data X added setIndex() method to IntDict, FloatDict, StringDict diff --git a/todo.txt b/todo.txt index d145ea455d..f7c728de9a 100755 --- a/todo.txt +++ b/todo.txt @@ -5,6 +5,9 @@ X the old 144 link must have been removed X NullPointerException in ContributionManager.deleteFlagged() X https://github.com/processing/processing/issues/5342 X move to Java 8u162 +X menu bars broken in High Sierra +X https://github.com/processing/processing/issues/5272 +X no more responses, had to close jakub X Fix scrub comments for empty block comment /**/ @@ -44,6 +47,8 @@ _ submit the form (as if 'get started' clicked) when closing the window _ whether hitting ESC or the close box on the window _ https://github.com/processing/processing/issues/3911 +_ Java 8u162 may be breaking fonts on Windows +_ https://github.com/processing/processing/issues/5413 _ windows defender blocks processing 3.3.6 _ https://github.com/processing/processing/issues/5329 _ Rename dialog is unusable on high density screen @@ -59,9 +64,6 @@ _ move away from using a temp dir at all for sketches _ -Djava.io.tmpdir=Z:\temp _ add pyde as a supported extension? _ https://github.com/jdf/processing.py/issues/284 -_ “could not move the contribution to the backup folder” message while updating libraries -_ problem is that any sketch that uses a library, the lib is stuck as "in use" -_ https://github.com/processing/processing/issues/4973 _ an incompatible Mode prevents the PDE from quitting after last window is closed _ https://github.com/processing/processing/issues/5112 _ examples window not updating on install @@ -69,10 +71,13 @@ _ open examples window _ mode > add mode > libraries > install video _ did not update the examples window, had to restart pde _ was able to save over the video capture examples b/c they were a library +_ lib examples not properly marked as read-only -high -_ menu bars broken in High Sierra -_ https://github.com/processing/processing/issues/5272 +_ “could not move the contribution to the backup folder” message while updating +_ problem is that any sketch that uses a library, the lib is stuck as "in use" +_ https://github.com/processing/processing/issues/4973 +_ issues with updating modes +_ https://github.com/processing/processing/issues/5424 _ add select/copy to the status bar _ https://github.com/processing/processing/issues/5271 From 23343355ca47715abd4dbdd7e7358153fbea3812 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Tue, 13 Mar 2018 15:35:26 +0100 Subject: [PATCH 053/375] Output java files in UTF-8 and force compiler to use UTF-8 --- java/src/processing/mode/java/Compiler.java | 1 + java/src/processing/mode/java/JavaBuild.java | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/java/src/processing/mode/java/Compiler.java b/java/src/processing/mode/java/Compiler.java index b68e6df738..cfe9eb97d9 100644 --- a/java/src/processing/mode/java/Compiler.java +++ b/java/src/processing/mode/java/Compiler.java @@ -68,6 +68,7 @@ static public boolean compile(JavaBuild build) throws SketchException { //"-noExit", // not necessary for ecj "-source", "1.7", "-target", "1.7", + "-encoding", "utf8", "-classpath", build.getClassPath(), "-nowarn", // we're not currently interested in warnings (works in ecj) "-d", build.getBinFolder().getAbsolutePath() // output the classes in the buildPath diff --git a/java/src/processing/mode/java/JavaBuild.java b/java/src/processing/mode/java/JavaBuild.java index 9b2f9c7717..1001ad14b9 100644 --- a/java/src/processing/mode/java/JavaBuild.java +++ b/java/src/processing/mode/java/JavaBuild.java @@ -24,6 +24,8 @@ package processing.mode.java; import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; @@ -249,14 +251,15 @@ public String preprocess(File srcFolder, outputFolder.mkdirs(); // Base.openFolder(outputFolder); final File java = new File(outputFolder, sketch.getName() + ".java"); - final PrintWriter stream = new PrintWriter(new FileWriter(java)); + BufferedWriter bw = Files.newBufferedWriter(java.toPath(), StandardCharsets.UTF_8); + final PrintWriter stream = new PrintWriter(bw); try { result = preprocessor.write(stream, bigCode.toString(), codeFolderPackages); } finally { stream.close(); } - } catch (FileNotFoundException fnfe) { - fnfe.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); String msg = "Build folder disappeared or could not be written"; throw new SketchException(msg); From f2f066a0d7c285fde01c60044fd9338f4f632327 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 12:37:41 -0400 Subject: [PATCH 054/375] do the same thing with less code --- java/src/processing/mode/java/JavaBuild.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/java/src/processing/mode/java/JavaBuild.java b/java/src/processing/mode/java/JavaBuild.java index 1001ad14b9..4091707fcf 100644 --- a/java/src/processing/mode/java/JavaBuild.java +++ b/java/src/processing/mode/java/JavaBuild.java @@ -24,8 +24,6 @@ package processing.mode.java; import java.io.*; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; @@ -249,20 +247,13 @@ public String preprocess(File srcFolder, File outputFolder = (packageName == null) ? srcFolder : new File(srcFolder, packageName.replace('.', '/')); outputFolder.mkdirs(); -// Base.openFolder(outputFolder); final File java = new File(outputFolder, sketch.getName() + ".java"); - BufferedWriter bw = Files.newBufferedWriter(java.toPath(), StandardCharsets.UTF_8); - final PrintWriter stream = new PrintWriter(bw); + final PrintWriter writer = PApplet.createWriter(java); try { - result = preprocessor.write(stream, bigCode.toString(), codeFolderPackages); + result = preprocessor.write(writer, bigCode.toString(), codeFolderPackages); } finally { - stream.close(); + writer.close(); } - } catch (IOException e) { - e.printStackTrace(); - String msg = "Build folder disappeared or could not be written"; - throw new SketchException(msg); - } catch (antlr.RecognitionException re) { // re also returns a column that we're not bothering with for now // first assume that it's the main file From b02f5d437f01363e0ff7df3c9199cfe9ce7e832a Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 12:38:14 -0400 Subject: [PATCH 055/375] notes about font fix on Windows --- todo.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/todo.txt b/todo.txt index f7c728de9a..bc0eb1de96 100755 --- a/todo.txt +++ b/todo.txt @@ -21,6 +21,10 @@ X https://github.com/processing/processing/issues/4419 X https://github.com/processing/processing/issues/5360 X https://github.com/processing/processing/issues/3970 X https://github.com/processing/processing/pull/5389 +X Output java files in UTF-8 and force compiler to use UTF-8 +X https://github.com/processing/processing/pull/5436 +X PdePreprocessor change is breaking current source +X https://github.com/processing/processing/issues/5413 contrib X detect errors from curved quotation marks @@ -47,8 +51,7 @@ _ submit the form (as if 'get started' clicked) when closing the window _ whether hitting ESC or the close box on the window _ https://github.com/processing/processing/issues/3911 -_ Java 8u162 may be breaking fonts on Windows -_ https://github.com/processing/processing/issues/5413 + _ windows defender blocks processing 3.3.6 _ https://github.com/processing/processing/issues/5329 _ Rename dialog is unusable on high density screen From 9eb63c103ba7f74e1486dd13f880b7e2cbe3600e Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 13:08:18 -0400 Subject: [PATCH 056/375] erase types and make this if() a little less confusing --- java/src/processing/mode/java/AutoFormat.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/java/src/processing/mode/java/AutoFormat.java b/java/src/processing/mode/java/AutoFormat.java index 659ae4f5cf..8aa3cbeaa8 100644 --- a/java/src/processing/mode/java/AutoFormat.java +++ b/java/src/processing/mode/java/AutoFormat.java @@ -436,8 +436,10 @@ static private void trimRight(final StringBuilder sb) { /** Entry point */ public String format(final String source) { final String normalizedText = source.replaceAll("\r", ""); - final String cleanText = - normalizedText + (normalizedText.endsWith("\n") ? "" : "\n"); + String cleanText = normalizedText; + if (!normalizedText.endsWith("\n")) { + cleanText += "\n"; + } // Globals' description at top of file. result.setLength(0); @@ -459,8 +461,8 @@ public String format(final String source) { ind = new boolean[10]; p_flg = new int[10]; s_tabs = new int[20][10]; - doWhileFlags = new Stack(); - ifWhileForFlags = new Stack(); + doWhileFlags = new Stack<>(); + ifWhileForFlags = new Stack<>(); chars = cleanText.toCharArray(); From b040160c0c2225ba2af229387e9cf65d1a43974b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 13:21:32 -0400 Subject: [PATCH 057/375] include newlines at end of files when saving (fixes #5327) --- app/src/processing/app/Util.java | 15 ++++++++------- todo.txt | 7 +++++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/app/src/processing/app/Util.java b/app/src/processing/app/Util.java index fd8f8c39d6..dd98d4b604 100644 --- a/app/src/processing/app/Util.java +++ b/app/src/processing/app/Util.java @@ -162,12 +162,11 @@ static public String loadFile(File file) throws IOException { * Spew the contents of a String object out to a file. As of 3.0 beta 2, * this will replace and write \r\n for newlines on Windows. * https://github.com/processing/processing/issues/3455 + * As of 3.3.7, this puts a newline at the end of the file, + * per good practice/POSIX: https://stackoverflow.com/a/729795 */ - static public void saveFile(String str, File file) throws IOException { - if (Platform.isWindows()) { - String[] lines = str.split("\\r?\\n"); - str = PApplet.join(lines, "\r\n"); - } + static public void saveFile(String text, File file) throws IOException { + String[] lines = text.split("\\r?\\n"); File temp = File.createTempFile(file.getName(), null, file.getParentFile()); try { // fix from cjwant to prevent symlinks from being destroyed. @@ -178,9 +177,11 @@ static public void saveFile(String str, File file) throws IOException { throw new IOException("Could not resolve canonical representation of " + file.getAbsolutePath()); } - // Can't use saveStrings() here b/c Windows will add a ^M to the file + // Could use saveStrings(), but the we wouldn't be able to checkError() PrintWriter writer = PApplet.createWriter(temp); - writer.print(str); + for (String line : lines) { + writer.println(line); + } boolean error = writer.checkError(); // calls flush() writer.close(); // attempt to close regardless if (error) { diff --git a/todo.txt b/todo.txt index bc0eb1de96..a10c36fe7d 100755 --- a/todo.txt +++ b/todo.txt @@ -9,6 +9,11 @@ X menu bars broken in High Sierra X https://github.com/processing/processing/issues/5272 X no more responses, had to close +_ change up the newline handling +_ https://github.com/processing/processing/issues/5327 +_ explanation: https://stackoverflow.com/a/729795 +_ http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206 + jakub X Fix scrub comments for empty block comment /**/ X https://github.com/processing/processing/pull/5265 @@ -56,8 +61,6 @@ _ windows defender blocks processing 3.3.6 _ https://github.com/processing/processing/issues/5329 _ Rename dialog is unusable on high density screen _ https://github.com/processing/processing/issues/5368 -_ change up the newline handling -_ https://github.com/processing/processing/issues/5327 _ Manager fails to complete install of PythonMode when no windows open _ https://github.com/processing/processing/issues/5309 _ update to launch4j 3.11? From f442e3fd5775bac1d7b88f1e4d222bf119c0fa23 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 14:08:25 -0400 Subject: [PATCH 058/375] notes about newlines and temp folders --- todo.txt | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/todo.txt b/todo.txt index a10c36fe7d..49b579dda7 100755 --- a/todo.txt +++ b/todo.txt @@ -8,11 +8,10 @@ X move to Java 8u162 X menu bars broken in High Sierra X https://github.com/processing/processing/issues/5272 X no more responses, had to close - -_ change up the newline handling -_ https://github.com/processing/processing/issues/5327 -_ explanation: https://stackoverflow.com/a/729795 -_ http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206 +X include newlines at end of files (i.e. when saving .pde files) +X https://github.com/processing/processing/issues/5327 +X explanation: https://stackoverflow.com/a/729795 +X http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206 jakub X Fix scrub comments for empty block comment /**/ @@ -65,9 +64,6 @@ _ Manager fails to complete install of PythonMode when no windows open _ https://github.com/processing/processing/issues/5309 _ update to launch4j 3.11? _ http://launch4j.sourceforge.net/changelog.html -_ add a note about temp dir to the bug on windows temp dirs -_ move away from using a temp dir at all for sketches -_ -Djava.io.tmpdir=Z:\temp _ add pyde as a supported extension? _ https://github.com/jdf/processing.py/issues/284 _ an incompatible Mode prevents the PDE from quitting after last window is closed @@ -90,7 +86,16 @@ _ https://github.com/processing/processing/issues/5271 _ possible fix (just copies on click) _ https://github.com/processing/processing/pull/5345 +temp +_ inside Sketch, makeTempFolder() would be the place to modify the location +_ perhaps make a 'temp' inside the sketchbook folder? +_ on startup, check to see if there are a lot of files, remove them? +_ or maybe auto-delete once older than 24 hours? +_ also don't search it when walking the sketchbook _ untitled folders are stored in temp folder +_ add a note about temp dir to the bug on windows temp dirs +_ move away from using a temp dir at all for sketches +_ -Djava.io.tmpdir=Z:\temp _ clean up /tmp folders used during build _ https://github.com/processing/processing/issues/1896 _ don't let people into the /tmp folder for sketches @@ -98,6 +103,8 @@ o don't use tmp folder for sketches? _ restrict more things like "show sketch folder" _ don't allow adding files w/o saving _ others? +_ clean Windows temp folders +_ https://github.com/processing/processing/issues/1896 contrib _ console hiding button? @@ -183,7 +190,7 @@ _ malformed proxy issues http://stackoverflow.com/q/376101 _ docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html _ https://github.com/processing/processing/issues/1476#issuecomment-23229990 -_ could not write to temporary directory +_ could not write to temporary directory (virus checker problems) _ https://github.com/processing/processing/issues/4757 _ Export Application fails on machines w/ non-ASCII chars in user name From e2b1c380f6d210ff21a08ce0b9b0262a6005802d Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 19:35:38 -0400 Subject: [PATCH 059/375] fix rename dialog scaling for high density (fixes #5368) --- java/src/processing/mode/java/pdex/PDEX.java | 44 ++++++++++---------- todo.txt | 4 +- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/java/src/processing/mode/java/pdex/PDEX.java b/java/src/processing/mode/java/pdex/PDEX.java index 52280c0e49..fa9612ecb5 100644 --- a/java/src/processing/mode/java/pdex/PDEX.java +++ b/java/src/processing/mode/java/pdex/PDEX.java @@ -18,7 +18,6 @@ import org.eclipse.jdt.core.dom.VariableDeclaration; import java.awt.Color; -import java.awt.Dimension; import java.awt.EventQueue; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; @@ -648,9 +647,7 @@ public String toString() { } - private class Rename { - final JDialog window; final JTextField textField; final JLabel oldNameLabel; @@ -684,26 +681,28 @@ public void componentHidden(ComponentEvent e) { ps = null; } }); - window.setSize(250, 130); + window.setSize(Toolkit.zoom(250, 130)); window.setLayout(new BoxLayout(window.getContentPane(), BoxLayout.Y_AXIS)); Toolkit.setIcon(window); + final int b = Toolkit.zoom(5); + { // Top panel // Text field textField = new JTextField(); - textField.setPreferredSize(new Dimension(150, 60)); + textField.setPreferredSize(Toolkit.zoom(150, 60)); // Old name label oldNameLabel = new JLabel(); - oldNameLabel.setText("Old Name: "); + oldNameLabel.setText("Current Name: "); // Top panel JPanel panelTop = new JPanel(); panelTop.setLayout(new BoxLayout(panelTop, BoxLayout.Y_AXIS)); - panelTop.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + panelTop.setBorder(BorderFactory.createEmptyBorder(b, b, b, b)); panelTop.add(textField); - panelTop.add(Box.createRigidArea(new Dimension(0, 10))); + panelTop.add(Box.createRigidArea(Toolkit.zoom(0, 10))); panelTop.add(oldNameLabel); window.add(panelTop); } @@ -717,28 +716,27 @@ public void componentHidden(ComponentEvent e) { JButton renameButton = new JButton("Rename"); renameButton.addActionListener(e -> { - if (textField.getText().length() == 0) { - return; - } - String newName = textField.getText().trim(); - boolean isNewNameValid = newName.length() >= 1 && - newName.chars().limit(1).allMatch(Character::isUnicodeIdentifierStart) && - newName.chars().skip(1).allMatch(Character::isUnicodeIdentifierPart); - if (!isNewNameValid) { - JOptionPane.showMessageDialog(new JFrame(), "'" + newName - + "' isn't a valid name.", "Uh oh..", JOptionPane.PLAIN_MESSAGE); - } else { - rename(ps, binding, newName); - window.setVisible(false); + final String newName = textField.getText().trim(); + if (!newName.isEmpty()) { + if (newName.length() >= 1 && + newName.chars().limit(1).allMatch(Character::isUnicodeIdentifierStart) && + newName.chars().skip(1).allMatch(Character::isUnicodeIdentifierPart)) { + rename(ps, binding, newName); + window.setVisible(false); + } else { + String msg = String.format("'%s' is not a valid name", newName); + JOptionPane.showMessageDialog(editor, msg, "Naming is Hard", + JOptionPane.PLAIN_MESSAGE); + } } }); JPanel panelBottom = new JPanel(); panelBottom.setLayout(new BoxLayout(panelBottom, BoxLayout.X_AXIS)); - panelBottom.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + panelBottom.setBorder(BorderFactory.createEmptyBorder(b, b, b, b)); panelBottom.add(Box.createHorizontalGlue()); panelBottom.add(showUsageButton); - panelBottom.add(Box.createRigidArea(new Dimension(15, 0))); + panelBottom.add(Box.createRigidArea(Toolkit.zoom(15, 0))); panelBottom.add(renameButton); window.add(panelBottom); } diff --git a/todo.txt b/todo.txt index 49b579dda7..39eacd7885 100755 --- a/todo.txt +++ b/todo.txt @@ -12,6 +12,8 @@ X include newlines at end of files (i.e. when saving .pde files) X https://github.com/processing/processing/issues/5327 X explanation: https://stackoverflow.com/a/729795 X http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206 +X Rename dialog is unusable on high density screen +X https://github.com/processing/processing/issues/5368 jakub X Fix scrub comments for empty block comment /**/ @@ -58,8 +60,6 @@ _ https://github.com/processing/processing/issues/3911 _ windows defender blocks processing 3.3.6 _ https://github.com/processing/processing/issues/5329 -_ Rename dialog is unusable on high density screen -_ https://github.com/processing/processing/issues/5368 _ Manager fails to complete install of PythonMode when no windows open _ https://github.com/processing/processing/issues/5309 _ update to launch4j 3.11? From f74f3f5d482d389638d27d0bfeba5522f7fabd9c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 20:01:25 -0400 Subject: [PATCH 060/375] make note of fixed NPE with close button --- core/todo.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index a8f55b0890..1f03b32ec8 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -22,9 +22,9 @@ X https://github.com/processing/processing/pull/5251 X void cursor() don't work after void noCursor() in P2D and P3D X https://github.com/processing/processing/issues/5330 X https://github.com/processing/processing/pull/5340 -_ nullPointer on close button with P3D and noLoop -_ https://github.com/processing/processing/issues/5214 -_ https://github.com/processing/processing/pull/5384 +X NullPointerException on close button with P3D and noLoop +X https://github.com/processing/processing/issues/5214 +X https://github.com/processing/processing/pull/5384 andres X textureWrap() not updating when changed during draw() From 606b637b7ff744de79225887bd97fa5c340d1bbe Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 20:13:09 -0400 Subject: [PATCH 061/375] show warning when using blendMode() with PDF (fixes #5105) --- core/todo.txt | 17 +++++++++-------- .../pdf/src/processing/pdf/PGraphicsPDF.java | 8 ++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index 1f03b32ec8..fc98d0f441 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -3,13 +3,11 @@ X fix exception due to version parsing in Java 9 X https://github.com/processing/processing/issues/5275 X remove useless deprecation on PImage.mask(int[]) X set colorModeDefault to true by default -_ add circle() and square() -_ add push() and pop() - +X blendMode() with PDF isn't showing the warning about it not being available +X add blendMode() to nope() calls in PGraphicsPDF +X https://github.com/processing/processing/issues/5105 _ Table.insertRow()) causes ArrayIndexOutOfBoundsException (with fix) _ https://github.com/processing/processing/issues/5406 -_ blendMode() with PDF isn't showing the warning about it not being available -_ https://github.com/processing/processing/issues/5105 data X added setIndex() method to IntDict, FloatDict, StringDict @@ -46,6 +44,12 @@ X https://github.com/processing/processing/pull/5354 X Make un/registering methods in PApplet thread-saf X https://github.com/processing/processing/pull/5379 + +3.4 +_ add circle() and square() +_ add push() and pop() + + _ make setting the window icon automatic, based on files in local dirs X https://github.com/processing/processing/issues/5123 X https://github.com/processing/processing/pull/5202 @@ -70,9 +74,6 @@ _ when doing createFont, can we add it to the os fonts available? _ add separator option to loadTable() _ https://github.com/processing/processing/issues/5068 -_ add blendMode() to nope() calls in PGraphicsPDF -_ https://github.com/processing/processing/issues/5105 - _ WARNING: GL pipe is running in software mode (Renderer ID=0x1020400) _ is this coming from us? if so, need to provide actions diff --git a/java/libraries/pdf/src/processing/pdf/PGraphicsPDF.java b/java/libraries/pdf/src/processing/pdf/PGraphicsPDF.java index a84c6108f7..f9b1c8bd9a 100644 --- a/java/libraries/pdf/src/processing/pdf/PGraphicsPDF.java +++ b/java/libraries/pdf/src/processing/pdf/PGraphicsPDF.java @@ -550,6 +550,14 @@ public void filter(int kind, float param) { // + protected void blendModeImpl() { + if (blendMode != BLEND) { + nope("blendMode"); + } + } + + // + public void copy(int sx1, int sy1, int sx2, int sy2, int dx1, int dy1, int dx2, int dy2) { nope("copy"); From 6836d5c2724a7d2e962c0967aa50d1a2c5a9c4e0 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 20:15:29 -0400 Subject: [PATCH 062/375] fix ArrayIndexOutOfBoundsException in Table.insertRow() (fixes #5406) --- core/src/processing/data/Table.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index f96c152307..2b6ac51727 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -2428,8 +2428,10 @@ public void insertRow(int insert, Object[] columnData) { } } } + // Need to increment before setRow(), because it calls ensureBounds() + // https://github.com/processing/processing/issues/5406 + ++rowCount; setRow(insert, columnData); - rowCount++; } /** From e9fcad806bf9447635f88187265257cac3d1fa4c Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 20:20:51 -0400 Subject: [PATCH 063/375] a note about the Table fix --- core/todo.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/todo.txt b/core/todo.txt index fc98d0f441..cb5296544d 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -6,8 +6,8 @@ X set colorModeDefault to true by default X blendMode() with PDF isn't showing the warning about it not being available X add blendMode() to nope() calls in PGraphicsPDF X https://github.com/processing/processing/issues/5105 -_ Table.insertRow()) causes ArrayIndexOutOfBoundsException (with fix) -_ https://github.com/processing/processing/issues/5406 +X Table.insertRow() causes ArrayIndexOutOfBoundsException (with fix) +X https://github.com/processing/processing/issues/5406 data X added setIndex() method to IntDict, FloatDict, StringDict From 653599f66c78a64c35a821ffe9b31ec145148130 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 20:24:52 -0400 Subject: [PATCH 064/375] reorg a bit, also note fix for #5406 --- core/src/processing/data/Table.java | 1 + core/todo.txt | 2 -- todo.txt | 33 +++++++++++++++++------------ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index 2b6ac51727..fa0e0c59fb 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -2434,6 +2434,7 @@ public void insertRow(int insert, Object[] columnData) { setRow(insert, columnData); } + /** * @webref table:method * @brief Removes a row from a table diff --git a/core/todo.txt b/core/todo.txt index cb5296544d..b9813eb080 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -48,8 +48,6 @@ X https://github.com/processing/processing/pull/5379 3.4 _ add circle() and square() _ add push() and pop() - - _ make setting the window icon automatic, based on files in local dirs X https://github.com/processing/processing/issues/5123 X https://github.com/processing/processing/pull/5202 diff --git a/todo.txt b/todo.txt index 39eacd7885..cbd554e491 100755 --- a/todo.txt +++ b/todo.txt @@ -14,6 +14,9 @@ X explanation: https://stackoverflow.com/a/729795 X http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206 X Rename dialog is unusable on high density screen X https://github.com/processing/processing/issues/5368 +_ windows defender blocks processing 3.3.6 +_ https://github.com/processing/processing/issues/5329 +X this should be fixed, simply by a new release jakub X Fix scrub comments for empty block comment /**/ @@ -58,16 +61,18 @@ _ whether hitting ESC or the close box on the window _ https://github.com/processing/processing/issues/3911 -_ windows defender blocks processing 3.3.6 -_ https://github.com/processing/processing/issues/5329 +manager _ Manager fails to complete install of PythonMode when no windows open _ https://github.com/processing/processing/issues/5309 -_ update to launch4j 3.11? -_ http://launch4j.sourceforge.net/changelog.html _ add pyde as a supported extension? _ https://github.com/jdf/processing.py/issues/284 _ an incompatible Mode prevents the PDE from quitting after last window is closed _ https://github.com/processing/processing/issues/5112 +_ “could not move the contribution to the backup folder” message while updating +_ problem is that any sketch that uses a library, the lib is stuck as "in use" +_ https://github.com/processing/processing/issues/4973 +_ issues with updating modes +_ https://github.com/processing/processing/issues/5424 _ examples window not updating on install _ open examples window _ mode > add mode > libraries > install video @@ -75,16 +80,6 @@ _ did not update the examples window, had to restart pde _ was able to save over the video capture examples b/c they were a library _ lib examples not properly marked as read-only -_ “could not move the contribution to the backup folder” message while updating -_ problem is that any sketch that uses a library, the lib is stuck as "in use" -_ https://github.com/processing/processing/issues/4973 -_ issues with updating modes -_ https://github.com/processing/processing/issues/5424 - -_ add select/copy to the status bar -_ https://github.com/processing/processing/issues/5271 -_ possible fix (just copies on click) -_ https://github.com/processing/processing/pull/5345 temp _ inside Sketch, makeTempFolder() would be the place to modify the location @@ -106,6 +101,16 @@ _ others? _ clean Windows temp folders _ https://github.com/processing/processing/issues/1896 + +_ update to launch4j 3.11? +_ http://launch4j.sourceforge.net/changelog.html + +_ add select/copy to the status bar +_ https://github.com/processing/processing/issues/5271 +_ possible fix (just copies on click) +_ https://github.com/processing/processing/pull/5345 + + contrib _ console hiding button? _ https://github.com/processing/processing/pull/5115 From fac4717af2d665eca5271795de387112fd258b1b Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 20:53:11 -0400 Subject: [PATCH 065/375] add another try/catch for createWriter() call --- java/src/processing/mode/java/JavaBuild.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/java/src/processing/mode/java/JavaBuild.java b/java/src/processing/mode/java/JavaBuild.java index 4091707fcf..0022fe2220 100644 --- a/java/src/processing/mode/java/JavaBuild.java +++ b/java/src/processing/mode/java/JavaBuild.java @@ -248,11 +248,15 @@ public String preprocess(File srcFolder, srcFolder : new File(srcFolder, packageName.replace('.', '/')); outputFolder.mkdirs(); final File java = new File(outputFolder, sketch.getName() + ".java"); - final PrintWriter writer = PApplet.createWriter(java); try { - result = preprocessor.write(writer, bigCode.toString(), codeFolderPackages); - } finally { - writer.close(); + final PrintWriter writer = PApplet.createWriter(java); + try { + result = preprocessor.write(writer, bigCode.toString(), codeFolderPackages); + } finally { + writer.close(); + } + } catch (RuntimeException re) { + throw new SketchException("Could not write " + java.getAbsolutePath()); } } catch (antlr.RecognitionException re) { // re also returns a column that we're not bothering with for now From 3fb7cfd3c38d74da5f506078611db28e278b5043 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 21:07:18 -0400 Subject: [PATCH 066/375] write release notes for 3.3.7 --- build/shared/revisions.txt | 122 +++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index bb84fcd9af..ddcd8b515a 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -1,3 +1,125 @@ +PROCESSING 3.3.7 (REV 0264) - 13 March 2018 + +A rollup of several fixes from the last few months. + + +[ changes most likely to be noticed ] + ++ Windows Defender blocks Processing 3.3.6. Not sure why this was happening, + but hopefully a new release should be all that's necessary to fix it. + https://github.com/processing/processing/issues/5329 + ++ Lots of fixes for the Net Library by Jakub + https://github.com/processing/processing/pull/5378 + https://github.com/processing/processing/issues/4419 + https://github.com/processing/processing/issues/5360 + https://github.com/processing/processing/issues/3970 + https://github.com/processing/processing/pull/5389 + ++ Include newlines at end of files (i.e. when saving .pde files) + https://github.com/processing/processing/issues/5327 + Why do this? https://stackoverflow.com/a/729795 + ++ Rename (refactor) dialog is unusable on high density screen + https://github.com/processing/processing/issues/5368 + ++ Detect errors from curved quotation marks (a headache when copying/pasting) + https://github.com/processing/processing/issues/5133 + https://github.com/processing/processing/pull/5152 + ++ NullPointerException on close button with P3D and noLoop + https://github.com/processing/processing/issues/5214 + https://github.com/processing/processing/pull/5384 + ++ Fix exception due to version parsing in Java 9 + https://github.com/processing/processing/issues/5275 + ++ Fix line joins on triangles + https://github.com/processing/processing/issues/5353 + https://github.com/processing/processing/pull/5354 + + +[ somewhere in the middle ] + ++ Fix NullPointerException in ContributionManager.deleteFlagged() + https://github.com/processing/processing/issues/5342 + ++ Fix scrub comments for empty block comment /**/ + https://github.com/processing/processing/pull/5265 + https://github.com/processing/processing/issues/5219 + ++ Fix error checker crash when className contains [ or ] + https://github.com/processing/processing/pull/5304 + ++ Table.insertRow() causes ArrayIndexOutOfBoundsException (with fix) + https://github.com/processing/processing/issues/5406 + ++ blendMode() with PDF isn't showing the warning about it not being available + https://github.com/processing/processing/issues/5105 + ++ textureWrap() not updating when changed during draw() + https://github.com/processing/processing/issues/5322 + ++ Cap frameRate() to 1000 in OpenGL + https://github.com/processing/processing/issues/5404 + ++ ARM tweaks for shaders on the Raspberry Pi + https://github.com/processing/processing/pull/5297 + ++ Fix 3D on contemporary versions of Linux + https://github.com/processing/processing/pull/5428 + https://github.com/processing/processing/issues/5308 + ++ cursor() don't work after void noCursor() in P2D and P3D + https://github.com/processing/processing/issues/5330 + https://github.com/processing/processing/pull/5340 + + +[ changes least likely to be noticed ] + ++ Fix JRE download issues + https://github.com/processing/processing/issues/5284 + ++ Update to Java 8u162 + ++ PdePreprocessor change is breaking current source + https://github.com/processing/processing/issues/5413 + ++ Output .java files in UTF-8 and force compiler to use UTF-8 + https://github.com/processing/processing/pull/5436 + ++ Refactor to use a few Java 8 features + https://github.com/processing/processing/pull/5134 + ++ Remove "Pipe Organ" from exec() docs + https://github.com/processing/processing/pull/5282 + ++ Fix typo in Italian translation + https://github.com/processing/processing/issues/5365 + ++ Remove useless deprecation on PImage.mask(int[]) + ++ Make un/registering methods in PApplet thread-safe + https://github.com/processing/processing/pull/5379 + ++ set colorModeDefault to true by default + ++ Minor bezierPoint() rewrite for performance + https://github.com/processing/processing/pull/5251 + + +[ additions! new features! ] + ++ Added setIndex() method to IntDict, FloatDict, StringDict + ++ Added resize() to IntDict, FloatDict, StringDict + ++ Fix entries() Iterator in IntDict, FloatDict, StringDict + + +. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + PROCESSING 3.3.6 (REV 0263) - 4 September 2017 A collection of mostly minor bug fixes that have accreted From 877b334c464d9891e6c08882b609c5848034f65a Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Tue, 13 Mar 2018 22:26:36 -0400 Subject: [PATCH 067/375] staring 0265 --- app/src/processing/app/Base.java | 6 ++-- core/done.txt | 48 +++++++++++++++++++++++++++++++ core/todo.txt | 46 +----------------------------- done.txt | 49 ++++++++++++++++++++++++++++++++ todo.txt | 48 +------------------------------ 5 files changed, 102 insertions(+), 95 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 925152750e..d9404fb66d 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2012-17 The Processing Foundation + Copyright (c) 2012-18 The Processing Foundation Copyright (c) 2004-12 Ben Fry and Casey Reas Copyright (c) 2001-04 Massachusetts Institute of Technology @@ -56,9 +56,9 @@ public class Base { // Added accessors for 0218 because the UpdateCheck class was not properly // updating the values, due to javac inlining the static final values. - static private final int REVISION = 264; + static private final int REVISION = 265; /** This might be replaced by main() if there's a lib/version.txt file. */ - static private String VERSION_NAME = "0264"; //$NON-NLS-1$ + static private String VERSION_NAME = "0265"; //$NON-NLS-1$ /** Set true if this a proper release rather than a numbered revision. */ /** diff --git a/core/done.txt b/core/done.txt index fdc186f8b8..e849da92d9 100644 --- a/core/done.txt +++ b/core/done.txt @@ -1,4 +1,52 @@ +0264 (3.3.7) +X fix exception due to version parsing in Java 9 +X https://github.com/processing/processing/issues/5275 +X remove useless deprecation on PImage.mask(int[]) +X set colorModeDefault to true by default +X blendMode() with PDF isn't showing the warning about it not being available +X add blendMode() to nope() calls in PGraphicsPDF +X https://github.com/processing/processing/issues/5105 +X Table.insertRow() causes ArrayIndexOutOfBoundsException (with fix) +X https://github.com/processing/processing/issues/5406 + +data +X added setIndex() method to IntDict, FloatDict, StringDict +X added resize() to IntDict, FloatDict, StringDict +X fix entries() Iterator in IntDict, FloatDict, StringDict + +contrib +X minor bezierPoint() rewrite for performance +X https://github.com/processing/processing/pull/5251 +X void cursor() don't work after void noCursor() in P2D and P3D +X https://github.com/processing/processing/issues/5330 +X https://github.com/processing/processing/pull/5340 +X NullPointerException on close button with P3D and noLoop +X https://github.com/processing/processing/issues/5214 +X https://github.com/processing/processing/pull/5384 + +andres +X textureWrap() not updating when changed during draw() +X https://github.com/processing/processing/issues/5322 +X cap frameRate() to 1000 in OpenGL +X https://github.com/processing/processing/issues/5404 + +gohai +X ARM tweaks for shaders on the RPi +X https://github.com/processing/processing/pull/5297 +X Fix 3D on contemporary versions of Linux +X https://github.com/processing/processing/pull/5428 +X https://github.com/processing/processing/issues/5308 + +jakub +X fix line joins on triangles +X https://github.com/processing/processing/issues/5353 +X https://github.com/processing/processing/pull/5354 +X Make un/registering methods in PApplet thread-saf +X https://github.com/processing/processing/pull/5379 + + 0263 (3.3.6) +X lots of contribs! gohai X shell discussion with gohai diff --git a/core/todo.txt b/core/todo.txt index b9813eb080..16e379177e 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -1,48 +1,4 @@ -0264 (3.3.7 or 3.4) -X fix exception due to version parsing in Java 9 -X https://github.com/processing/processing/issues/5275 -X remove useless deprecation on PImage.mask(int[]) -X set colorModeDefault to true by default -X blendMode() with PDF isn't showing the warning about it not being available -X add blendMode() to nope() calls in PGraphicsPDF -X https://github.com/processing/processing/issues/5105 -X Table.insertRow() causes ArrayIndexOutOfBoundsException (with fix) -X https://github.com/processing/processing/issues/5406 - -data -X added setIndex() method to IntDict, FloatDict, StringDict -X added resize() to IntDict, FloatDict, StringDict -X fix entries() Iterator in IntDict, FloatDict, StringDict - -contrib -X minor bezierPoint() rewrite for performance -X https://github.com/processing/processing/pull/5251 -X void cursor() don't work after void noCursor() in P2D and P3D -X https://github.com/processing/processing/issues/5330 -X https://github.com/processing/processing/pull/5340 -X NullPointerException on close button with P3D and noLoop -X https://github.com/processing/processing/issues/5214 -X https://github.com/processing/processing/pull/5384 - -andres -X textureWrap() not updating when changed during draw() -X https://github.com/processing/processing/issues/5322 -X cap frameRate() to 1000 in OpenGL -X https://github.com/processing/processing/issues/5404 - -gohai -X ARM tweaks for shaders on the RPi -X https://github.com/processing/processing/pull/5297 -X Fix 3D on contemporary versions of Linux -X https://github.com/processing/processing/pull/5428 -X https://github.com/processing/processing/issues/5308 - -jakub -X fix line joins on triangles -X https://github.com/processing/processing/issues/5353 -X https://github.com/processing/processing/pull/5354 -X Make un/registering methods in PApplet thread-saf -X https://github.com/processing/processing/pull/5379 +0265 (3.3.8 or 3.4) 3.4 diff --git a/done.txt b/done.txt index 787ecd542e..36fb431d47 100644 --- a/done.txt +++ b/done.txt @@ -1,3 +1,52 @@ +0264 (3.3.7) +X downloading the jre broken again +X https://github.com/processing/processing/issues/5284 +X the old 144 link must have been removed +X NullPointerException in ContributionManager.deleteFlagged() +X https://github.com/processing/processing/issues/5342 +X move to Java 8u162 +X menu bars broken in High Sierra +X https://github.com/processing/processing/issues/5272 +X no more responses, had to close +X include newlines at end of files (i.e. when saving .pde files) +X https://github.com/processing/processing/issues/5327 +X explanation: https://stackoverflow.com/a/729795 +X http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206 +X Rename dialog is unusable on high density screen +X https://github.com/processing/processing/issues/5368 +X windows defender blocks processing 3.3.6 +X https://github.com/processing/processing/issues/5329 +X this should be fixed, simply by a new release + +jakub +X Fix scrub comments for empty block comment /**/ +X https://github.com/processing/processing/pull/5265 +X https://github.com/processing/processing/issues/5219 +X Fix error checker crash when className contains [ or ] +X https://github.com/processing/processing/pull/5304 +X major fixes for the net library +X https://github.com/processing/processing/pull/5378 +X https://github.com/processing/processing/issues/4419 +X https://github.com/processing/processing/issues/5360 +X https://github.com/processing/processing/issues/3970 +X https://github.com/processing/processing/pull/5389 +X Output java files in UTF-8 and force compiler to use UTF-8 +X https://github.com/processing/processing/pull/5436 +X PdePreprocessor change is breaking current source +X https://github.com/processing/processing/issues/5413 + +contrib +X detect errors from curved quotation marks +X https://github.com/processing/processing/issues/5133 +X https://github.com/processing/processing/pull/5152 +X Refactor to use a few Java 8 features +X https://github.com/processing/processing/pull/5134 +X Remove "Pipe Organ" from exec javadoc +X https://github.com/processing/processing/pull/5282 +X typo in Italian translation +X https://github.com/processing/processing/issues/5365 + + 0263 (3.3.6) X update to Java 8u144 X fix issue with call to remove value instead of key in mode contrib hash diff --git a/todo.txt b/todo.txt index cbd554e491..95e1d1c02b 100755 --- a/todo.txt +++ b/todo.txt @@ -1,50 +1,4 @@ -0264 (3.3.7 or 3.4) -X downloading the jre broken again -X https://github.com/processing/processing/issues/5284 -X the old 144 link must have been removed -X NullPointerException in ContributionManager.deleteFlagged() -X https://github.com/processing/processing/issues/5342 -X move to Java 8u162 -X menu bars broken in High Sierra -X https://github.com/processing/processing/issues/5272 -X no more responses, had to close -X include newlines at end of files (i.e. when saving .pde files) -X https://github.com/processing/processing/issues/5327 -X explanation: https://stackoverflow.com/a/729795 -X http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206 -X Rename dialog is unusable on high density screen -X https://github.com/processing/processing/issues/5368 -_ windows defender blocks processing 3.3.6 -_ https://github.com/processing/processing/issues/5329 -X this should be fixed, simply by a new release - -jakub -X Fix scrub comments for empty block comment /**/ -X https://github.com/processing/processing/pull/5265 -X https://github.com/processing/processing/issues/5219 -X Fix error checker crash when className contains [ or ] -X https://github.com/processing/processing/pull/5304 -X major fixes for the net library -X https://github.com/processing/processing/pull/5378 -X https://github.com/processing/processing/issues/4419 -X https://github.com/processing/processing/issues/5360 -X https://github.com/processing/processing/issues/3970 -X https://github.com/processing/processing/pull/5389 -X Output java files in UTF-8 and force compiler to use UTF-8 -X https://github.com/processing/processing/pull/5436 -X PdePreprocessor change is breaking current source -X https://github.com/processing/processing/issues/5413 - -contrib -X detect errors from curved quotation marks -X https://github.com/processing/processing/issues/5133 -X https://github.com/processing/processing/pull/5152 -X Refactor to use a few Java 8 features -X https://github.com/processing/processing/pull/5134 -X Remove "Pipe Organ" from exec javadoc -X https://github.com/processing/processing/pull/5282 -X typo in Italian translation -X https://github.com/processing/processing/issues/5365 +0265 (3.3.7 or 3.4) welcome From 15834fa3cd0a8546bb3907042919dfced59703f2 Mon Sep 17 00:00:00 2001 From: gohai Date: Thu, 15 Mar 2018 19:01:22 -0700 Subject: [PATCH 068/375] Serial: Add support for opening Raspbian-style named ports Raspbian uses "/dev/serial0" and "/dev/serial1" since a couple of releases, and users might be looking for those. Built from: https://github.com/gohai/java-simple-serial-connector/commit/4b316077c7f054bb76629e0addfb4e359cf0427d --- java/libraries/serial/library/jssc.jar | Bin 40174 -> 19748 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/java/libraries/serial/library/jssc.jar b/java/libraries/serial/library/jssc.jar index 93269cfabe6c4fd659642b50796e358f6bcfa4bf..bf5640670cd9b0c13c78a18e63ef40e8ba664ef0 100644 GIT binary patch literal 19748 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