From ffff8df490e09085e434468d90693b517742259c Mon Sep 17 00:00:00 2001
From: Emily Toop {@code
+ * long aEntid = txReport.getEntidForTempId("a");
+ * long bEntid = txReport.getEntidForTempId("b");
+ * EntityBuilder builder = mentat.getEntityBuilderForEntid(bEntid);
+ * builder.add(":foo/boolean", true);
+ * builder.add(":foo/instant", newDate);
+ * InProgress inProgress = builder.transact().getInProgress();
+ * inProgress.transact("[[:db/add \(aEntid) :foo/long 22]]");
+ * inProgress.commit();
+ * }
+ *
+ * The `commit` function will transact and commit the assertions that have been added to the {@link EntityBuilder}.
+ * It will consume the {@link InProgress} used to perform the transact. It returns the {@link TxReport} generated by
+ * the transact. After calling `commit`, a new transaction must be started by calling Mentat.beginTransaction()
+ * in order to perform further actions.
+ *
+ * {@code
+ * long aEntid = txReport.getEntidForTempId("a");
+ * EntityBuilder builder = mentat.getEntityBuilderForEntid(bEntid);
+ * builder.add(":foo/boolean", true);
+ * builder.add(":foo/instant", newDate);
+ * builder.commit();
+ * }
+ */
+public class EntityBuilder extends RustObject {
+
+ public EntityBuilder(Pointer pointer) {
+ this.rawPointer = pointer;
+ }
+
+ /**
+ * Asserts the value of attribute `keyword` to be the provided `value`.
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be asserted
+ */
+ public void add(String keyword, long value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_add_long(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Asserts the value of attribute `keyword` to be the provided `value`.
+ * // TODO throw exception if error occurs
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be asserted
+ */
+ public void addRef(String keyword, long value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_add_ref(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Asserts the value of attribute `keyword` to be the provided `value`.
+ * // TODO throw exception if error occurs
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be asserted
+ */
+ public void addKeyword(String keyword, String value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_add_keyword(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Asserts the value of attribute `keyword` to be the provided `value`.
+ * // TODO throw exception if error occurs
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be asserted
+ */
+ public void add(String keyword, boolean value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_add_boolean(this.rawPointer, keyword, value ? 1 : 0);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Asserts the value of attribute `keyword` to be the provided `value`.
+ * // TODO throw exception if error occurs
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be asserted
+ */
+ public void add(String keyword, double value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_add_double(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Asserts the value of attribute `keyword` to be the provided `value`.
+ * // TODO throw exception if error occurs
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be asserted
+ */
+ public void add(String keyword, Date value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_add_timestamp(this.rawPointer, keyword, value.getTime() * 1_000);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Asserts the value of attribute `keyword` to be the provided `value`.
+ * // TODO throw exception if error occurs
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be asserted
+ */
+ public void add(String keyword, String value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_add_string(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Asserts the value of attribute `keyword` to be the provided `value`.
+ * // TODO throw exception if error occurs
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be asserted
+ */
+ public void add(String keyword, UUID value) {
+ this.validate();
+
+ RustResult result = JNA.INSTANCE.entity_builder_add_uuid(this.rawPointer, keyword, getPointerForUUID(value));
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Retracts the value of attribute `keyword` from the provided `value`.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be retracted
+ */
+ public void retract(String keyword, long value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_retract_long(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+
+ /**
+ * Retracts the value of attribute `keyword` from the provided `value`.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be retracted
+ */
+ public void retractRef(String keyword, long value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_retract_ref(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Retracts the value of attribute `keyword` from the provided `value`.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be retracted
+ */
+ public void retractKeyword(String keyword, String value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_retract_keyword(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Retracts the value of attribute `keyword` from the provided `value`.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be retracted
+ */
+ public void retract(String keyword, boolean value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_retract_boolean(this.rawPointer, keyword, value ? 1 : 0);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Retracts the value of attribute `keyword` from the provided `value`.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be retracted
+ */
+ public void retract(String keyword, double value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_retract_double(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Retracts the value of attribute `keyword` from the provided `value`.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be retracted
+ */
+ public void retract(String keyword, Date value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_retract_timestamp(this.rawPointer, keyword, value.getTime() * 1_000);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Retracts the value of attribute `keyword` from the provided `value`.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be retracted
+ */
+ public void retract(String keyword, String value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_retract_string(this.rawPointer, keyword, value);
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Retracts the value of attribute `keyword` from the provided `value`.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @param keyword The name of the attribute in the format `:namespace/name`.
+ * @param value The value to be retracted
+ */
+ public void retract(String keyword, UUID value) {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_retract_uuid(this.rawPointer, keyword, this.getPointerForUUID(value));
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ }
+ }
+
+ /**
+ * Transacts the added assertions. This consumes the pointer associated with this {@link EntityBuilder}
+ * such that no further assertions can be added after the `transact` has completed. To perform
+ * further assertions, use the {@link InProgress} inside the {@link InProgressTransactionResult}
+ * returned from this function.
+ *
+ * This does not commit the transaction. In order to do so, `commit` can be called on the
+ * {@link InProgress} inside the {@link InProgressTransactionResult} returned from this function.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @return A {@link InProgressTransactionResult} containing the current {@link InProgress} and
+ * the {@link TxReport} generated by the transact.
+ */
+ public InProgressTransactionResult transact() {
+ this.validate();
+ InProgressTransactionResult result = JNA.INSTANCE.entity_builder_transact(this.rawPointer);
+ this.rawPointer = null;
+ return result;
+ }
+
+ /**
+ * Transacts the added assertions and commits. This consumes the pointer associated with this
+ * {@link EntityBuilder} and the associated {@link InProgress} such that no further assertions
+ * can be added after the `commit` has completed.
+ *
+ * To perform further assertions, a new `{@link InProgress} or {@link EntityBuilder} should be
+ * created.
+ *
+ * TODO throw exception if error occurs
+ *
+ * @return
+ */
+ public TxReport commit() {
+ this.validate();
+ RustResult result = JNA.INSTANCE.entity_builder_commit(this.rawPointer);
+ this.rawPointer = null;
+ if (result.isFailure()) {
+ Log.e("EntityBuilder", result.err);
+ return null;
+ }
+
+ return new TxReport(result.ok);
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (this.rawPointer != null) {
+ JNA.INSTANCE.entity_builder_destroy(this.rawPointer);
+ }
+ }
+}
diff --git a/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/InProgress.java b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/InProgress.java
new file mode 100644
index 00000000..0af3fba8
--- /dev/null
+++ b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/InProgress.java
@@ -0,0 +1,195 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * Copyright 2018 Mozilla
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+ * this file except in compliance with the License. You may obtain a copy of the
+ * License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software distributed
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License. */
+
+package com.mozilla.mentat;
+
+import android.util.Log;
+
+import com.sun.jna.Pointer;
+
+import java.io.IOException;
+
+/**
+ * This class wraps a raw pointer that points to a Rust {@link InProgress} object.
+ *
{@code + * do { + * let inProgress = try mentat.beginTransaction() + * let txReport = try inProgress.transact(transaction: "[[:db/add "a" :foo/long 22]]") + * let aEntid = txReport.entid(forTempId: "a") + * let report = try inProgress.transact(transaction: "[[:db/add "b" :foo/ref \(aEntid)] [:db/add "b" :foo/boolean true]]") + * try inProgress.commit() + * } catch { + * ... + * } + * }+ * + * {@link InProgress} also provides a number of functions to generating an builder to assert datoms + * programatically. The two types of builder are {@link InProgressBuilder} and {@link EntityBuilder}. + * + * {@link InProgressBuilder} takes the current {@link InProgress} and provides a programmatic + * interface to add and retract values from entities for which there exists an `Entid`. The provided + * {@link InProgress} is used to perform the transacts. + * + *
{@code + * long aEntid = txReport.getEntidForTempId("a"); + * long bEntid = txReport.getEntidForTempId("b"); + * InProgress inProgress = mentat.beginTransaction(); + * InProgressBuilder builder = inProgress.builder(); + * builder.add(bEntid, ":foo/boolean", true); + * builder.add(aEntid, ":foo/instant", newDate); + * inProgress = builder.transact().getInProgress(); + * inProgress.transact("[[:db/add \(aEntid) :foo/long 22]]"); + * inProgress.commit(); + * } + * }+ * + * {@link EntityBuilder} takes the current {@link InProgress} and either an `Entid` or a `tempid` to + * provide a programmatic interface to add and retract values from a specific entity. The provided + * {@link InProgress} is used to perform the transacts. + * + *
{@code + * long aEntid = txReport.getEntidForTempId("a"); + * long bEntid = txReport.getEntidForTempId("b"); + * InProgress inProgress = mentat.beginTransaction(); + * EntityBuilder builder = inProgress.builderForEntid(bEntid); + * builder.add(":foo/boolean", true); + * builder.add(":foo/instant", newDate); + * inProgress = builder.transact().getInProgress(); + * inProgress.transact("[[:db/add \(aEntid) :foo/long 22]]"); + * inProgress.commit(); + * }+ */ +public class InProgress extends RustObject { + + public InProgress(Pointer pointer) { + this.rawPointer = pointer; + } + + /** + * Creates an {@link InProgressBuilder} using this {@link InProgress} . + * + * @return an {@link InProgressBuilder} for this {@link InProgress} + */ + public InProgressBuilder builder() { + this.validate(); + InProgressBuilder builder = new InProgressBuilder(JNA.INSTANCE.in_progress_builder(this.rawPointer)); + this.rawPointer = null; + return builder; + } + + /** + * Creates an `EntityBuilder` using this `InProgress` for the entity with `entid`. + * + * + * @param entid The `Entid` for this entity. + * @return an `EntityBuilder` for this `InProgress` + */ + public EntityBuilder builderForEntid(long entid){ + this.validate(); + EntityBuilder builder = new EntityBuilder(JNA.INSTANCE.in_progress_entity_builder_from_entid(this.rawPointer, entid)); + this.rawPointer = null; + return builder; + } + + /** + * Creates an `EntityBuilder` using this `InProgress` for a new entity with `tempid`. + * + * + * @param tempid The temporary identifier for this entity. + * @return an `EntityBuilder` for this `InProgress` + */ + public EntityBuilder builderForTempid(String tempid){ + this.validate(); + EntityBuilder builder = new EntityBuilder(JNA.INSTANCE.in_progress_entity_builder_from_temp_id(this.rawPointer, tempid)); + this.rawPointer = null; + return builder; + } + + /** + Transacts the `transaction` + + This does not commit the transaction. In order to do so, `commit` can be called. + + - Throws: `PointerError.pointerConsumed` if the underlying raw pointer has already consumed, which will occur if the builder + has already been transacted or committed. + - Throws: `ResultError.error` if the transaction failed. + - Throws: `ResultError.empty` if no `TxReport` is returned from the transact. + + - Returns: The `TxReport` generated by the transact. + */ + /** + * Transacts the `transaction` + * + * This does not commit the transaction. In order to do so, `commit` can be called. + * + * TODO throw Exception on result failure. + * + * @param transaction The EDN string to be transacted. + * @return The `TxReport` generated by the transact. + */ + public TxReport transact(String transaction) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_transact(this.rawPointer, transaction); + if (result.isFailure()) { + Log.e("InProgress", result.err); + return null; + } + return new TxReport(result.ok); + } + + /** + * Commits all the transacts that have been performed on this `InProgress`, either directly + * or through a Builder. This consumes the pointer associated with this {@link InProgress} such + * that no further assertions can be performed after the `commit` has completed. + * + * TODO throw exception if error occurs + */ + public void commit() { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_commit(this.rawPointer); + this.rawPointer = null; + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Rolls back all the transacts that have been performed on this `InProgress`, either directly + * or through a Builder. + * + * TODO throw exception if error occurs + */ + public void rollback() { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_rollback(this.rawPointer); + this.rawPointer = null; + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + @Override + public void close() throws IOException { + if (this.rawPointer != null) { + JNA.INSTANCE.in_progress_destroy(this.rawPointer); + } + } +} diff --git a/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/InProgressBuilder.java b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/InProgressBuilder.java new file mode 100644 index 00000000..81072fb2 --- /dev/null +++ b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/InProgressBuilder.java @@ -0,0 +1,382 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * Copyright 2018 Mozilla + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. */ + +package com.mozilla.mentat; + +import android.util.Log; + +import com.sun.jna.Pointer; + +import java.io.IOException; +import java.util.Date; +import java.util.UUID; + +/** + * This class wraps a raw pointer that points to a Rust `InProgressBuilder` object. + * + * {@link InProgressBuilder} provides a programmatic interface to performing assertions for entities. + * It provides functions for adding and retracting values for attributes for an entity within + * an in progress transaction. + * + * The `transact` function will transact the assertions that have been added to the {@link InProgressBuilder} + * and pass back the {@link TxReport} that was generated by this transact and the {@link InProgress} that was + * used to perform the transact. This enables you to perform further transacts on the same {@link InProgress} + * before committing. + * + *
{@code + * long aEntid = txReport.getEntidForTempId("a"); + * long bEntid = txReport.getEntidForTempId("b"); + * InProgressBuilder builder = mentat.getEntityBuilder(); + * builder.add(aEntid, ":foo/boolean", true); + * builder.add(bEntid, ":foo/instant", newDate); + * InProgress inProgress = builder.transact().getInProgress(); + * inProgress.transact("[[:db/add \(aEntid) :foo/long 22]]"); + * inProgress.commit(); + * }+ * + * The `commit` function will transact and commit the assertions that have been added to the + * {@link InProgressBuilder}. + * It will consume the {@link InProgress} used to perform the transact. It returns the {@link TxReport} + * generated by the transact. After calling `commit`, a new transaction must be started by calling + *
Mentat.beginTransaction()in order to perform further actions. + * + *
{@code + * long aEntid = txReport.getEntidForTempId("a"); + * long bEntid = txReport.getEntidForTempId("b"); + * InProgressBuilder builder = mentat.getEntityBuilder(); + * builder.add(aEntid, ":foo/boolean", true); + * builder.add(bEntid, ":foo/instant", newDate); + * builder.commit(); + * }+ */ +public class InProgressBuilder extends RustObject { + + public InProgressBuilder(Pointer pointer) { + this.rawPointer = pointer; + } + /** + * Asserts the value of attribute `keyword` to be the provided `value`. + * + * // TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be asserted + */ + public void add(long entid, String keyword, long value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_add_long(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Asserts the value of attribute `keyword` to be the provided `value`. + * // TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be asserted + */ + public void addRef(long entid, String keyword, long value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_add_ref(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Asserts the value of attribute `keyword` to be the provided `value`. + * // TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be asserted + */ + public void addKeyword(long entid, String keyword, String value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_add_keyword(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Asserts the value of attribute `keyword` to be the provided `value`. + * // TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be asserted + */ + public void add(long entid, String keyword, boolean value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_add_boolean(this.rawPointer, entid, keyword, value ? 1 : 0); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Asserts the value of attribute `keyword` to be the provided `value`. + * // TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be asserted + */ + public void add(long entid, String keyword, double value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_add_double(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Asserts the value of attribute `keyword` to be the provided `value`. + * // TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be asserted + */ + public void add(long entid, String keyword, Date value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_add_timestamp(this.rawPointer, entid, keyword, value.getTime() * 1_000); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Asserts the value of attribute `keyword` to be the provided `value`. + * // TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be asserted + */ + public void add(long entid, String keyword, String value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_add_string(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Asserts the value of attribute `keyword` to be the provided `value`. + * // TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be asserted + */ + public void add(long entid, String keyword, UUID value) { + this.validate(); + + RustResult result = JNA.INSTANCE.in_progress_builder_add_uuid(this.rawPointer, entid, keyword, getPointerForUUID(value)); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Retracts the value of attribute `keyword` from the provided `value`. + * + * TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be retracted + */ + public void retract(long entid, String keyword, long value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_retract_long(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + + /** + * Retracts the value of attribute `keyword` from the provided `value`. + * + * TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be retracted + */ + public void retractRef(long entid, String keyword, long value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_retract_ref(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Retracts the value of attribute `keyword` from the provided `value`. + * + * TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be retracted + */ + public void retractKeyword(long entid, String keyword, String value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_retract_keyword(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Retracts the value of attribute `keyword` from the provided `value`. + * + * TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be retracted + */ + public void retract(long entid, String keyword, boolean value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_retract_boolean(this.rawPointer, entid, keyword, value ? 1 : 0); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Retracts the value of attribute `keyword` from the provided `value`. + * + * TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be retracted + */ + public void retract(long entid, String keyword, double value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_retract_double(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Retracts the value of attribute `keyword` from the provided `value`. + * + * TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be retracted + */ + public void retract(long entid, String keyword, Date value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_retract_timestamp(this.rawPointer, entid, keyword, value.getTime() * 1_000); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Retracts the value of attribute `keyword` from the provided `value`. + * + * TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be retracted + */ + public void retract(long entid, String keyword, String value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_retract_string(this.rawPointer, entid, keyword, value); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Retracts the value of attribute `keyword` from the provided `value`. + * + * TODO throw exception if error occurs + * + * @param entid The `Entid` of the entity to be touched. + * @param keyword The name of the attribute in the format `:namespace/name`. + * @param value The value to be retracted + */ + public void retract(long entid, String keyword, UUID value) { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_retract_uuid(this.rawPointer, entid, keyword, this.getPointerForUUID(value)); + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + } + } + + /** + * Transacts the added assertions. This consumes the pointer associated with this {@link InProgressBuilder} + * such that no further assertions can be added after the `transact` has completed. To perform + * further assertions, use the {@link InProgress} inside the {@link InProgressTransactionResult} + * returned from this function. + * + * This does not commit the transaction. In order to do so, `commit` can be called on the + * {@link InProgress} inside the {@link InProgressTransactionResult} returned from this function. + * + * TODO throw exception if error occurs + * + * @return A {@link InProgressTransactionResult} containing the current {@link InProgress} and + * the {@link TxReport} generated by the transact. + */ + public InProgressTransactionResult transact() { + this.validate(); + InProgressTransactionResult result = JNA.INSTANCE.in_progress_builder_transact(this.rawPointer); + this.rawPointer = null; + return result; + } + + /** + * Transacts the added assertions and commits. This consumes the pointer associated with this + * {@link InProgressBuilder} and the associated {@link InProgress} such that no further assertions + * can be added after the `commit` has completed. + * + * To perform further assertions, a new `{@link InProgress} or {@link InProgressBuilder} should be + * created. + * + * TODO throw exception if error occurs + * + * @return + */ + public TxReport commit() { + this.validate(); + RustResult result = JNA.INSTANCE.in_progress_builder_commit(this.rawPointer); + this.rawPointer = null; + if (result.isFailure()) { + Log.e("InProgressBuilder", result.err); + return null; + } + + return new TxReport(result.ok); + } + + @Override + public void close() throws IOException { + if (this.rawPointer != null) { + JNA.INSTANCE.in_progress_builder_destroy(this.rawPointer); + } + } +} diff --git a/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/InProgressTransactionResult.java b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/InProgressTransactionResult.java new file mode 100644 index 00000000..c7b39c8a --- /dev/null +++ b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/InProgressTransactionResult.java @@ -0,0 +1,56 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * Copyright 2018 Mozilla + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of the + * License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. */ + +package com.mozilla.mentat; + +import android.util.Log; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +public class InProgressTransactionResult extends Structure implements Closeable { + public static class ByReference extends InProgressTransactionResult implements Structure.ByReference { + } + + public static class ByValue extends InProgressTransactionResult implements Structure.ByValue { + } + + public Pointer inProgress; + public RustResult.ByReference result; + + @Override + protected List
{@code * String query = "[: find ?a .\n" + * " : where ... ]"; - * mentat.query(query).runScalar(new ScalarResultHandler() { + * mentat.query(query).run(new ScalarResultHandler() { * @Override * public void handleValue(TypedValue value) { * ... @@ -88,7 +88,7 @@ import java.util.UUID; *{@code * String query = "[: find [?a ...]\n" + * " : where ... ]"; - * mentat.query(query).runColl(new ScalarResultHandler() { + * mentat.query(query).run(new ScalarResultHandler() { * @Override * public void handleList(CollResult list) { * ... @@ -100,7 +100,7 @@ import java.util.UUID; *{@code * String query = "[: find [?a ?b ?c]\n" + * " : where ... ]"; - * mentat.query(query).runTuple(new TupleResultHandler() { + * mentat.query(query).run(new TupleResultHandler() { * @Override * public void handleRow(TupleResult row) { * ... @@ -121,7 +121,7 @@ public class Query extends RustObject { * @param value The value to be bound * @return This {@link Query} such that further function can be called. */ - Query bindLong(String varName, long value) { + Query bind(String varName, long value) { this.validate(); JNA.INSTANCE.query_builder_bind_long(this.rawPointer, varName, value); return this; @@ -173,7 +173,7 @@ public class Query extends RustObject { * @param value The value to be bound * @return This {@link Query} such that further function can be called. */ - Query bindBoolean(String varName, boolean value) { + Query bind(String varName, boolean value) { this.validate(); JNA.INSTANCE.query_builder_bind_boolean(this.rawPointer, varName, value ? 1 : 0); return this; @@ -186,7 +186,7 @@ public class Query extends RustObject { * @param value The value to be bound * @return This {@link Query} such that further function can be called. */ - Query bindDouble(String varName, double value) { + Query bind(String varName, double value) { this.validate(); JNA.INSTANCE.query_builder_bind_double(this.rawPointer, varName, value); return this; @@ -199,7 +199,7 @@ public class Query extends RustObject { * @param value The value to be bound * @return This {@link Query} such that further function can be called. */ - Query bindDate(String varName, Date value) { + Query bind(String varName, Date value) { this.validate(); long timestamp = value.getTime() * 1000; JNA.INSTANCE.query_builder_bind_timestamp(this.rawPointer, varName, timestamp); @@ -213,7 +213,7 @@ public class Query extends RustObject { * @param value The value to be bound * @return This {@link Query} such that further function can be called. */ - Query bindString(String varName, String value) { + Query bind(String varName, String value) { this.validate(); JNA.INSTANCE.query_builder_bind_string(this.rawPointer, varName, value); return this; @@ -226,15 +226,9 @@ public class Query extends RustObject { * @param value The value to be bound * @return This {@link Query} such that further function can be called. */ - Query bindUUID(String varName, UUID value) { + Query bind(String varName, UUID value) { this.validate(); - ByteBuffer bb = ByteBuffer.wrap(new byte[16]); - bb.putLong(value.getMostSignificantBits()); - bb.putLong(value.getLeastSignificantBits()); - byte[] bytes = bb.array(); - final Pointer bytesNativeArray = new Memory(bytes.length); - bytesNativeArray.write(0, bytes, 0, bytes.length); - JNA.INSTANCE.query_builder_bind_uuid(this.rawPointer, varName, bytesNativeArray); + JNA.INSTANCE.query_builder_bind_uuid(this.rawPointer, varName, getPointerForUUID(value)); return this; } @@ -262,7 +256,7 @@ public class Query extends RustObject { * TODO: Throw an exception if the query raw pointer has been consumed or the query fails to execute * @param handler the handler to call with the results of this query */ - void runScalar(final ScalarResultHandler handler) { + void run(final ScalarResultHandler handler) { this.validate(); RustResult result = JNA.INSTANCE.query_builder_execute_scalar(rawPointer); rawPointer = null; @@ -285,7 +279,7 @@ public class Query extends RustObject { * TODO: Throw an exception if the query raw pointer has been consumed or the query fails to execute * @param handler the handler to call with the results of this query */ - void runColl(final CollResultHandler handler) { + void run(final CollResultHandler handler) { this.validate(); RustResult result = JNA.INSTANCE.query_builder_execute_coll(rawPointer); rawPointer = null; @@ -303,7 +297,7 @@ public class Query extends RustObject { * TODO: Throw an exception if the query raw pointer has been consumed or the query fails to execute * @param handler the handler to call with the results of this query */ - void runTuple(final TupleResultHandler handler) { + void run(final TupleResultHandler handler) { this.validate(); RustResult result = JNA.INSTANCE.query_builder_execute_tuple(rawPointer); rawPointer = null; diff --git a/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/RustObject.java b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/RustObject.java index 35f7b8fb..e55c4e5f 100644 --- a/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/RustObject.java +++ b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/RustObject.java @@ -10,9 +10,12 @@ package com.mozilla.mentat; +import com.sun.jna.Memory; import com.sun.jna.Pointer; import java.io.Closeable; +import java.nio.ByteBuffer; +import java.util.UUID; /** * Base class that wraps an non-optional {@link Pointer} representing a pointer to a Rust object. @@ -31,4 +34,22 @@ abstract class RustObject implements Closeable { throw new NullPointerException(this.getClass() + " consumed"); } } + + public Pointer getPointerForUUID(UUID uuid) { + ByteBuffer bb = ByteBuffer.wrap(new byte[16]); + bb.putLong(uuid.getMostSignificantBits()); + bb.putLong(uuid.getLeastSignificantBits()); + byte[] bytes = bb.array(); + final Pointer bytesNativeArray = new Memory(bytes.length); + bytesNativeArray.write(0, bytes, 0, bytes.length); + return bytesNativeArray; + } + + public UUID getUUIDFromPointer(Pointer uuidPtr) { + byte[] bytes = uuidPtr.getByteArray(0, 16); + ByteBuffer bb = ByteBuffer.wrap(bytes); + long high = bb.getLong(); + long low = bb.getLong(); + return new UUID(high, low); + } } diff --git a/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/TupleResult.java b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/TupleResult.java index a9701682..d1b4c327 100644 --- a/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/TupleResult.java +++ b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/TupleResult.java @@ -126,7 +126,7 @@ public class TupleResult extends RustObject { */ public Date asDate(Integer index) { this.validate(); - return new Date(JNA.INSTANCE.value_at_index_into_timestamp(this.rawPointer, index)); + return new Date(JNA.INSTANCE.value_at_index_into_timestamp(this.rawPointer, index) * 1_000); } /** @@ -150,13 +150,7 @@ public class TupleResult extends RustObject { */ public UUID asUUID(Integer index) { this.validate(); - Pointer uuidPtr = JNA.INSTANCE.value_at_index_into_uuid(this.rawPointer, index); - byte[] bytes = uuidPtr.getByteArray(0, 16); - ByteBuffer bb = ByteBuffer.wrap(bytes); - long high = bb.getLong(); - long low = bb.getLong(); - - return new UUID(high, low); + return getUUIDFromPointer(JNA.INSTANCE.value_at_index_into_uuid(this.rawPointer, index)); } @Override diff --git a/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/TypedValue.java b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/TypedValue.java index 943e9753..3c89a5df 100644 --- a/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/TypedValue.java +++ b/sdks/android/Mentat/library/src/main/java/com/mozilla/mentat/TypedValue.java @@ -137,12 +137,7 @@ public class TypedValue extends RustObject { */ public UUID asUUID() { if (!this.isConsumed()) { - Pointer uuidPtr = JNA.INSTANCE.typed_value_into_uuid(this.rawPointer); - byte[] bytes = uuidPtr.getByteArray(0, 16); - ByteBuffer bb = ByteBuffer.wrap(bytes); - long high = bb.getLong(); - long low = bb.getLong(); - this.value = new UUID(high, low); + this.value = getUUIDFromPointer(JNA.INSTANCE.typed_value_into_uuid(this.rawPointer)); this.rawPointer = null; } return (UUID)this.value; diff --git a/sdks/android/Mentat/library/src/main/jniLibs/x86/libmentat_ffi.so b/sdks/android/Mentat/library/src/main/jniLibs/x86/libmentat_ffi.so index 1160a11a546c46605fc3983810c8bd47ab9b1091..6edd9a182d6f80217420c9a77d3a63d4a9891559 100755 GIT binary patch delta 1795924 zcmaIf4}9bIT_65$ihDIQfLk)EQnyiCGgR=308=zDpn}T;7!Y7UfV(J-uThAT6Bnmd z!5{%16P;lycMt&vH1I$$XNdIx4a_E(8Df|r#tpR13~k&t0cMDCZ2Ez>{XUYOM-r1x zkH_bppZDvlKi}_1pSR`nwN88ZQ!gD~{Qg`m{y__+?|t7J-};%=CmxR`0S|>)c@vE{U0yYe{kdbU-I$gi%aPT zPtSc8PM+nJm+Hk!_0pyKO_%DAzf^zn3+r<9c`pp6S9$N8CMWQ&OUJ+cQvE}h>Yu(; z|JtSc>;-i>ivIWoK@`1Y^6t1zSKw0p>Pz(-FV)MJ>QBB@uRgzC2``j+eh}&}x>SGp zrTXnRzG3dcw?26(efOpMn=jSheyRSh8-FzS;1~bMrSu y=im6vm%gc-{vc}}m@NC3U#j1J zseZ?$x^Ss3UaH@Hsor~G{f6kq3xnu;F4aGL YRk`d2R1y-W3P-}v;G zJ^01HcPah-OZA^!s{i~_9nHOPv0irL*_S=|`UfthA9bmI{f*xV_ex$$Kjl*W88<$3 z{=xDWTuL`C)n9$7e&kYJxKtM})!%Tb-g{wPj`m*|L^m$g-*>5QgnIP-SE9A){&{(H zE7ZNlmFT0@$Dyu$!IkK Gtp_ZHy7zg{)t?sXWadirl;dAEsk2w2&sAR!b>)k%M5pTahC0e$iGJA$HA0>J z!7EY8@t+BGE9V5u;f#K3@_?^;?hNmSdf_YXo#D%)j|d+py^ZHi=;K2@`m*QhaIR7I zOP@Qz!leG{=T7k3LfzPW?gal~sEdF5O7wTb36&>H^7A2R{q-x+KXJyt5$gELl_=+o z|0L9vPref6)eA2R7x; @y%DFZ*#mF>cLyCL=W8; zm8b8~kB1 !up*CLiT;K9HK9&FdL;_qmrO6< zlS17Jbx-|yp{|6DQogr~w?YtYUx}V^hi?pZExf?JC-}ZlH^T8haQyv~`~QQm0_tCx z)bF|yy+{4Kq3(R`bM>Exy7t7C=wn0sO;+qxFApbp{Yp9dneZiV5`0n!isjJPRwNzj z-W#t(-{J{#p{|7&e4F~6p dR;lE9St5>40Q~znGv)^+idR_Q9o1Eaw?++&w`uaUi_@hEy{Jtwu!wIc~I{L0F z(Yh=A!ceEf7pi}F?}S4=2p90B>Qbmj<*h5xuM55_1ldqeR&w%!KNjkIsQ q0#!U5S3*@lOnOxf0&9 zKM`a?(As_O4*5y__0Jvu`cOB%;Y#!lPx!u2kHQIE_xK+Vb^e>LMEmMr3U%>^uS8k( z?@jI>j^De0|MQ`t|2yFhU*`_5{jhKal`By}{TZQ7A3pcB{T-oBe$$oc hS)*V)8wz+vJL0b*X;+rTSwo)qmqs z{i&Dgw_U0~|M~S~|9#2xgHV6PrF!#Hy>+QBUaH@Hss4sbb@h4mmrt(v+n*Oq>hHW% zf6t}*@KSwrseb<}ZhYZ~AK&=Ig;&KMefY75p4z#7_4@T|*P} z9&KNH^qpb$jwjyy)V1h|t4}<<{n(>VMo&Kc rK2Uz@Jx@LIa5%fCpY#Ope)zGSVtBwqS4)rWL=V5?+V$|~Bad7y?nIM2UV9{Z zq%gUrM+#3|+ln69zV_7BNx8K>S)|EgY;8|gW9#YSCr06f9=m?+$>?e+oPTk$LXQ;R zGvSGA?+VxX^iw-Gim&|WD^EWep7!w@-}=foy=-fHy688GAF*`fCtmr+a&f0HS&oOE zczWk*>7mKpChy1OLMP|+)Kin{k#~p7+j)2=dgtuVo$F6O`N+dNSKqQSUCL;-s_&eg zaCoiBJNLxnlas#w#N^L#WU?@m=bfz76Hh!`3=e(c=_j9f_-n#RUk~qVar#WN_k8*y zVRvj_4U4&R{gEe%(L)b~vwrg0^!<*upSpVW@$dxU`F0+A;_9_`Zaw^-=;_&p*xH^h zSXiye)|fo}$;sp2dHw3u8(;LmYs*)k+<9#0JrBL(>BqLWu3mpAEa^k ce3T z|LUQwYfryp`|67wdHm{o-hJ)*){7n5zV_s!FP2}w`p)RZUO$}UV=w-Q$<>9$2 10BA%JdT&2|C-asPZ#I|J$kZ0ALy7B`ap-DTcYRRqx}4hKV78f zAH8?bHhQr`_x93@9lN*q_ZsR&?o)o~-kts*>vr!hm)7nDOLy-+A8`5Z-Qk5xSpLg5 z{4Y=B|FMqup5w*W^4@CQyVnO?&dJ8J@5;|@ycb#I7hBv*{W1BBdT5euy ~wQ@n800uQofU*~4D!_`S24-Q)SMZXItde&kzjy!|78{>Cr8>VfiOPwrg% z%dbm2? vChmDFC?dFHXgvoBwozSeW^ z{a?BF KfPmR6$ z#zO4nA3VAHLz6q*_?*~V<|eOn;~QhK2cLg=vkQKBCtUMZ_-LNq=O<$yxiY;^xTY65 z9zMUrC&`N(c;+`Ad-hecm-(<)f7HiKpJKXSAA0EFC%3L&du%H_^wEcAALQW^^pVFO z^6C2BSD$^=M_qj)eD4xI(kF`%P5yZFiSYTm^L0;Mz47_4F5GCpdU0;@q5l5geDxFI zM<*`}e+`@bNaiEM_l%R EVxqhWk@ z7<1wIF5kXJ@Q3`(;Iq-AQS?v4 JpU?qEsReI<1~y<3gbVA@eyJCNEmm*nA|>o z^3Wd)lm8jUf194p `xKA{uFcT6VX_8%wD{`O*+{l&C?;Xj^rWs|=G{XiHeVT{6fYZ&)# zlYhsV-2QyV^d}YX3-j>fxag(#g@2q2ukfn!zjyR)oUjwdtuX#|7{_5uZod=8PfTaw zFJZwS4x=B&KM&(i!}w=md|ViJ!}!TCemRU<82=)S$?cEB_|7oi9>y<*F}Zzj6n$2- zIGay@qC1(+hf{0IzB%|S=I;uQ!}wkGe+~YA82|Xj!>{}7XKw!CBMZ;8KIZE;?t9}i z?|Xf|{Q9|Y=q>Jgj|G$02me~Q`q#Yl3&QNxlXdvu&vfjoCe?i(7XEzjZ$2uU@TxFA zIgHPp6yf%G7+*G>J@?1D>8FK9f6NCz5~>dh<5NTRnos`fFnh1#_jpa1eEPkDd%-U? z|N6-zU;0?6u7}x2y#4#b?C&`i3x1UOgwG1&6=8hCqzJdy&4|*${V !z9o#m8OC>q@x@_GZkZX;=LCNtjGqeQPr~>QVcffYTbO)!7&q<( z>;>N+#vg_8e &kN(qjh}!0>u+S=@F6!wuV1=Rd_(+3@AdOHYHyhT zpqE51x$)o|UvuNXzW&W2`>>bIMRVcn$4hSf eBl))w?{torQy%HzpN+!=ssDBInMKb#+l$UlT2}yX|6N7 z_jq~w0-J(7w^`&aE8J&|2W;?&EgrMOQ}*`CvnxCk40z5FFBtuu+5PY50v8$Q5))iz zk}FJ=O;)+a4A+_E26NnGo?9$%n?;_m%krs7kGI+983(+>A z5&++~G(ta86> zQsYh5dB6q_+2j#hyu~(;+2IMhET5Y6c$ >_^Y7LF_X`&I0ApNa zoJ&k_nMtlN#Z{)c#>{*5|GFT{4d%GXJhxcjHjCV0iMy A F2*-omp-$$4%zB#R4nb zW0m`?@h0oRY5#WwC+zZ+J>F)YbKgGOMDx6#3w(evE;7!gZ`c0`!7`IvVT!9vbB!6U zGtVs+xXmJWzFq&91iRd0mHVvmCL26tlSgdvgk7GpS2nrLKF>Jd9S(WU5$|%$3r62D zdyD2c&-+ *Z8M=;_A=l}lf%pYK!%S>^NS#Gkx z9agx{`qa>Whk_Q5+2w5xc+N5BYO@nv;35-TVVdjAO`P=qmY~R8R(X>R9 _qQpEI94|B|(y_%y5HwZnMHYR=Lj_Z?et
=WI#mIM4gJzy}!PBI9L~B__DcBv+W?D%ZKe0*l<^ zK2O+X`P8Jx+wAlH8?!51V}|R@a)UW;GS4j*xIMER6$K^kvcf%9xz7`JdCDGdv(GaQ zcxP(pzoFoqBaV5&=%)9Y^SqyH%y6AqZZOBqiIe`%3$|F`HjCV0iMyiWz2^ z=QfMn{cinV5$v ~k=6(*J@H z$Be$md&C9C7-xb>rkG}iS>~9ZIO+d_pvV#{tg^;Bn{2Ve9{U_{$T8=?SO3StWb$+V z1d~iN%T4CF#R7}0u*NzYY_j#e`oAscu**IN9C6I~@3XlWW1I;lnPQrm@6-QTL5_JA zSz?7%*4bp69d_Acp92odCL@j+9oT$aV2lZ-m|>QA7Fc41RhH`}O}5!#j{}YveZLcA zj7v;#g( 8Ax9iD`Ul>7E-=P86HGG2G&9VyoHNO@z#>bmu*w?iY_Q1|+w8E*-pq1z zCK&LXBVI82q1g)D&jl_r&SfUK$~4!Rof`UYQ;_F2i`->}`>gSR4IZ(@V|IAT-o#1& zp9uy$=ZF`Ke%K0dfs2eY!6Z{mGsA3f+W$F0o&^?JVue-KSZ9Mxw%BHeUG{!h|DOp4 z9CF0y(3Nw64=~0>#+hJ}DW;h@)c-j_o<){eWsP+<*kp@scGzW)eGbYdBaRvU!`T(j zGsXl{Omm%CZZgkp7P-rE#blo~9 {WX|6NNP3Bo- zh5M}WfDIl6r~Tg&9J9ky_ISnt&pF}+qvq_2@8<#+8E2xY|5pSlW|(811(sN0jdeEJ zVuw8rIBe?wv0(nkW@jE_f=Q;BW|lb?xWf{6S>ZlwWs{q%^N>v*vBhI{c)~9G9CFP0 zA9sN)CrnbzaDzE+GS4C_tg^-ikJ#cdJ2T7Csi4O*4tUNHFBttJn~V!wWSq-Pa+T?+ zq5sweS>~8$fkl>BVU;!3* _v z{l6i|G0y^vtgyxgn{2bg9{U_}#OPW5KmY9PiWV4SoCzkGVum?xGS4DQtnw!7&+7jJ z!4ca$W`{lYIpC0E&i!L=5$|V=i;R~|5==48EH|0wHjCV4g;myAXM;y9w@f *+voCzkm$~4!QnOTn31zF};V38G8S!07oZ1EP`?6AlF)X;xJ!H5@(THZr0 zFvd8OOf$ ;Zpv5-3>~qL5=YMu~B{3$LVum>uSYkCe?f<%<$u_&} zbI390e$G 8Rl4EiB;Bl$Y$B3#STx|W1mBgIA-+o-U`N;V3KKOSk9RgSY(M6R#{`64K~?g zn;mx9V}E8j8VH6Qam?tSxiT&=#yAs9GQ~7A%rZAM^j}_3WQkSQ*<_1tcGzW)eGWL} zh!+zl{U81F*%i)lo(qgI!4;;s#tb)@W1dBpSPf45zb0s~$u>LevCkpLj5@OmSzwF_ zrkLh>NB?I9o6K{YMeee~eb#uu29Ma{F*`i%lxJt$6P$6tbB=hy=oe;>yPpeOWSq-P za+PVWmrb(VWS-kBa+ekEv&I89c*GWu* J;}(nDWtBJC;1SzA zVXtg*#v$)A`el27F)lI5Rc5%sJhxfm9?Lb812%b!9iFn!I~?(X^Idy@aV|5(wVC1H z{{@>YaEBG{v(7`dc+4(ubHH f=-2E4#<;{JSDE1k^W0{M &++^^5hbb*UZaD{2EGsi6!xyveVvcV&^Cr 2|L+NEJYbWz*x@Pryu%SMIR6{=0OMR{>NoWN znjp(f7P!L-_gUv5TRdi$w>jWB$G@Tf=l+d7z(ppw!Zg>J;}(nDWtBJC;1SzplN0uM z#v$)A`b~R)F)lI5Rc5%sJhxdcne4H~12%b!9iFn!I~?(X^SA8*#<@JR9Hj(n%yN?j z?y$mr)_KSlkJ;sI4tPE_^xs%8_iyb1E;7Ltrn$}>w^-yZtGvkuk0ws~zb!ank7pe6 zE~DSF2N>fLlU!wn8_aV%IPL$EV2?E(u*qBO@RWVt;fNQU|80AKaW4P1{!a W|y})m>T-;TrlR`f3OF*$OKoI<~noSVv)P7@+KP-C;fjUX!C?Uo^i;#jLz%< z#<;{JSDE1k^TBEVZwpG?V~q!F@)kQhWuJFA;sxh_#~xt(cl7_VAjLIixyb@|Sm8eF zJY *eV~q!F@)kQhWuJFA;sxgi_Q1??6c;Qr#WiNR$pUv+;Xdm;WQ)h_ z^7howe*?ie$DI35_5c@|;0n`RXO3Gea+g)!oH*(KhTw>8p0LL=4tbZ+f3^o0;}Vlx zWriEUY5(U1+bnU9H6F0ZTkP ?^LNrOjh^MpN~amc%j{);`p7?+sj zDl;r^nB=+568Bi+0h_$V4o}(V9gcXx`TsgS;d1oAY!bz}%oNv{ WpvjbV2n#l2B-bMD#&ny zd2X}BJ=S=@CU3FBQ}%g>qr3Y5LNNbl_5kBtW{PXfa+3w_u)=-TdC1nE>HlLvm$y0K zImev)pY{M3ncxc3TxX73ES61nS>;VOc*HhO*y9<8yvyi+*#nGmiRGlpDl^<*p4%*O zk2M~!$y@C3lzrZrS&l}63(k-20miw^6xW#LCJWqQh5M}YaBAqkmf)CO-sXVk9CPmf zvj@1y1Xq~mI&<8bIO+eQV3$?iWP?X+^MpN~amc%j{@fm5j7!03|0e~j%y5HwZnMNa z)_A}sZ?VHu_Ic;e_5Vn4!TG rvQ(R+~n=EjL74Ean!@tn~Ex|Fnyv+g6Ip*Aj zJ-|gKxWY8ond4U3q{v-Xd6NwuvCR|qc*Y^`GWy^40AnmKnIyT&3^$nPHcQ-NjR$P< z7CSs;e`fgoe}WM&IRAg_0miw^6xW#LCJWqQh5M{e4gGg0Xz`d`-sXVk9CPmf+5=o< zf-6jOow #~KgV {=V4@J-|4Znc^C=++=|}tZ<+8`^vKyI25#a z%r0+pz;li{_mbK3EO3ztt}xAY=E^2pEOM7s-eiMEZ1aRYo^i;#j6P^~qW7~LGg)Gi ztITkNd2X}BJ=S=@CU3FB)0yR{FSx@IFE~GE4=~PUrntr|H(B5gE8L$N`mZiHWQ)h_ z@-_!N=a_RZwFkJ!1Xq~m`ou~9=LB0Ua+g)!WP?X+^MpN~amc%juGj;?Y5&IrOH6W= z8E!DoZI-yl8V}gyEp~W%MgR8&cR1n&=U-+IFwSMBxW+6uS>O&U+<%$=uL};@;xW6t z%>mCj=G?qJz(ppw!Zg>*COK}g$X!->lMNoR%@g)`#v$)A`rz4#mhU%-afwN;GQ$n# zxy=&ySmObkyv5GU@c;i8^m&IPUU2?H>;cBP%oNv{ lMNoR%@g)`#v$*r9DVrgOz&rmOH6W=8E!Do zZI-yl8V}gyt(oD!PA@oRpLaOo1?Ly+0miw^6xW#LCJWq|8v3sy*k_%GZ1I>~-sXVk z9CPj!_5c@|;L5~F|EC4(%yElF?y}08Z19L}p0LL=4tX~?{rrz!X%8^QB__Gb3^$nP zHcQ-NjR$P<)+_aYM{vqM?{LHm&VPhGz&Mwg;u^EuWPv*$q5ms_eb#x%7LVEGZ4P+O zG3Oqz2e`-tSIQ=7t~19i7P-qRZ?eH7wt2!H&p2fHu1WOQ>;cBO#3Wal;Rf^EW{G>O z@qo>l<>;26!&CNoha+Ba{v+)H#<|QC*O=ud3sXb??FcH|XPt*^@t9rS=78rMbM964 z02i5 *cgL!VV#68w{ zz-CPU-x73q%0BOK#0$>9+8$t>%S>^NS#GlMYW=?>sBoWk9 g=wxc$1N7Q%PMcO!6UYL!XD399-7=`^cs7BF)lI5Rc5%sJhxfm9&0?9S&o{5 zTkPrvQ(R+~n^Qyo6$Cr1aG!M^vc+R|d7A^CbIiHd+5=piIO+d{ zV1;R}Gsi6!xyveVvcV&^dBPsgg46yV3hpv`ojt%9mzd-#Gu&XF+bnU9H6FZ9|2GA< z*x@Pryu%SMIRBtMz&Mwg;u^Eue6T!wU_r3M3iny(AzM6Vm$y0KImeuf&t7kVi)E7p zSD5BHbKGK)yR7mi8$4p0C+x9&W-{bmMz6OA7~>L?TxEtE%yXM1?y)wr932Rnyu}Vr z+2 t10miw^6xW#j=<@6Vn}Py&Sm8eFJY oQz@cTam2W;{dJ3M8d zcR1n&=M(k-<6LHnYg0r2Wd)loaEBG{v(7`dc+4(ubHH *cgL!VV#J!Kz|24q@o4myi zPub@kj(EZOkFy6D=Q2}V`#Ald6>PG=9agx{IuF_6F}u9Y0na(+TzPqRrVCtTf-6jO zojGo?$X!->lMNoR&GLy!k7pe6E~CF;4=~0hCb`NCH<;%(OEb&So}k79HhGI3p0dw7 z9PxtlZ?*>*=Q2}ML;tM_vfN~WJFIY@bsn DA8!wEkqNFa&2{Fu z#UgiE i<1KjR$P<7CSs;pLaOo z1?NA(9$=iyOnrj>UlU}x$pUv+;Xdm;WQ)h_@-_!N=eTS#_lfoZ7n$G+(_CkcTP$*y zRo-NSM=ZBZPT1oahrG+^lk5S;xWpt^nc)WW+@4vEN`gJsc)%uavBOjLd50rjaDK%e zV4TZSL;s}&Ys_+!1@5rIeb#x%7LVEGZ4P)oank=|!Q3a?16*W+D@=2pIc~AYT~>LM z4ITxj{ofXxu*WkFd6&^!>;cBO#3Wal;Rf^EevAGu3HDgy0h_$V4o}(V9gcXx`A@M2 z80Ye*=>L>pjahE8z#Ue&&pHp;;xW6t%>mELCS%T}>;Wz^!4;;t&K$Q` fLlU!wn8_drvN85rD_gLcro4myiPub@kj(EZOPqhaapBnma zS&-ryv)p8XJFIY@bsn WwdG!FvcY&xylSTm|xZZ+kz7JSmObkyu}Vr+2 ZnD4~R=CeP582`|yS&Xo+2ovK&V7bGz(ppw!Zg>J;}(l7vC10Db(030Y_ZJ_ zyX>*g0f!uM%;+;`7c|d>ndK-Zh%>bmu*%xh(0_G7gH5*BW`|w& z*yn&ljyPtNwgOz3IO+eGAkGAnOfk(2v&=Ei0*frM!YXUQY5&&+4K~?gn;mx9W1j;K zIpUbnTde>W-m3p&f;baQGQ~7A%reJ33oNq43ahNWwLCkcx}d=(TWqt#E_>{Az#&H* zGx{tmz=g6&jBzHIWQu8Km}QQ67FcA76;@fUnbg@}lP$K{VV6DjIpB~Zjv0Nn6_{C$ z76dWInP8GBrkP=uIp$elktJ4Gof`VDCaAN)CR=Q?!!CR5bHE`-95Y(80uv|wzaWS) z&IFT8G0hCK%rVabi!8CiYH-^BH9?&XHrZmE9d_Acp92m#;+WCftiap!|AHXKI1@}V z#WXX_GRHg%EV9H3t8df)H9?&XHrZmE9d_Acp92m#;+WCrSb?(10%MFb!6Z{mGs7%% z%(K8EORTV5HL0=A2AgcL%?`WlvCjdA9C6I(Z%tPq{Qo~@lW2i4#+hJ}DW;iWmO18G zV38$OriT8j3Tmvg!6sX5v%@ZX>~p{&M;tTC=>Pf2Wb$=@F~*r-k}0N{VU{`OSzwVR zR)W+1uL^3cv%w}?Y_r2Id+c+-Ax9iD`ds}#|G8FxF~*r-k}0N{VU{`OSzwVRRz6q% zR|PfJ* f=Q;BW` *g0f!uMJaO{*AFW#fE-=P86HGG2G&9UH$2 z4mjk9<8}QXeSsC=0%MFb!6Z{mGs7%%%(K8EOJAV>D}pL(th2!;TWqt#E_>{Az#&H* zmrbHCv;tgUjBzHIWQu8Km}QQ67FcAtWKv<3HP+c+lP$K{VV6DjIpC0^ndN9Kh`z`Q zaDg$#nP8GBrkP=uIp$elacbzllAyvWYpk=uCR=Q?!!CR5bHE`-6DR#Y7DQPqzy-z_ zXM#zlm}Z7q=9p)J#o)C6OM(iktg+4pn{2Vo4!i8J&jE)VW%d795Ph)~-~wZeGr=TN zOf$nQbIh~A;uq`xlAyvWYpk=uCR=Q?!!CR5bHE`-Ws@ mvk;v2e^F3k zg;myAXM;_)*k*@a_Solu!wvmE5{wyrnHAsyV~jJwBvVW?!z^>mv+!m5zbGiN!YXU5 zv%w}?Y_r2Id+c+-VcBHFF{3ZH0$gB>aVD5#ifLw;WsZ543noRDSYeel*4bc_Ew {A zFmclVL&1n+Mma0M1;!X>f=Q;BW` *gK~Db< z1tX3beWexP0%MFb!6Z{mGs7%%%zvf+F9?b(vBD~Ath2!;TWqt#E_>{AP&OHI#4)3< zvI1OSjBzHIWQu8Km}QRTyh(vYmRMnxHP+c+lP$K{VV6DjXNLd&r(nnt$Be$(3UGlj z#+hJ}DW;iWmbs~+|MG$Yi!8CiDr>B>!6sX5v%@ZX>`$EZ|3EP0h+{^ZR)7nPG0p^& zOfk(2v&;pj{ht>USY(M6R#{`64K~?gn;mx9V}Dcs4+KMwIA-*AE5HTD7-xb>rkG}i zS?1oZ|MP+Zi!8CiDr>B>!6sX5v%@ZX?3Yaj9CE}lqrYthxWE|WOfbn5)66i-a?T{r z0*frM!YXU5v%w}?Y_r2Ido#oD{}Bv0 !i*0t;WpCo7|NDXgha7RtC~pP0z!>99Fv%3t%rG0A_J2;0XMshQSYeel z*4bc_Ew OyChphk?7-O6XCYfTI8D<|Y&z>+R$g{vAORTWU8tZJZ z$rjt}u*+WAq|X6|9C6I(9aew~j4{pxlT0zq49i)Q9P=!&$Pz28vc@_aY_i2RJM7LZ zM?FEG0}eUjn9(CvfD4Q<&IFT8G0n`>(0^G$j(HYXWQi44S!10IHrZmE9d;*9`oAaW zbHE`-95dRo0$gB>aVD5#ifLwo)Bev2a?G>9B1^2W${Oozu*nwN?6A9~|9gTy2OM(5 zF{7(ifD4Q<&IFT8G0n_X{ht-&m}h}SmRMnxHP+c+lP$K{VYh73W1j;KIpUbnJFNg0 z7-O6XCYfTI<%~&|Ip$elktJ4GWsP+<*kp@sc4n5NuAs+02OM(5F{4MV02dfzoCzkG zVtQ)mzl aVD5#is|6A z|1*LtbIh~AB1^2W${Oozu*nwN>=g8WSI}dh0}eUjn9*ZafD4Q<&IFT8G5whS&j_;2 zG0y^vEV05WYpk=uCR=Q?Q#R?c$36!fa>OyCudxDLV2p7lm}H9Ov`L0p=9p)JMV44$ zl{MDcV3RGjXNKSZCFrupJ_j6f#4)4CtpFDoW1I;lnVK5 ~8$fkl>BVU;!3* ~8$fkl>BVU;!3* ~8$fkl>BVU;!3* _jUG~`LfJ2TrW^~;OaDg$#nP53- zl46<}W|?E21r}Lig;myAXM@d|<)|fSv%@ZX>~p{&M;tSH$_j9SF~*sg8u~9ONHNU} zv&=Ei0*frM!YXU5v%%)XN&mM5ZFbmYk9`g} bm zu*w?iY_M52X|c@?yX>*g0f!uM%;;TKfD4Q<&T_&e$rRJfFv}eCEU?HDE3C4{IvX>? z@Bb6D*k*@a_SoluLykCR^lmG_1;!Yk8u~9GNHWDVGt4r_JPRzc#0smdvChWCN&hzm zEw 4mjk9V@A7HfD4QT zr~MxnB$#B1X=a#Zj(HYXWQi44Sz~=y|2G6pw%BHeUG~`LfJ2TrX7mkKfD4R$gZ_^T z5==71G&9UH$2bmu*w?iGeiFinryMn4!i8J&jE)Vam>hDJkJHjrcU}_kYJK2rkQ1qc@|h= zg*7(VVu!tnll~tFMvN-nE5?~*ifLw;Wu8S=SYv~&;I#icf*uDPG5RJa#5j{oGs`@S zEV05G>)&+m^Iy xyE&FaFbiy=Ks&v{lG<0t^Whxb7ob{O(;=OQC3|Q6BP?&kxj`^ zQ88CVB}1j8M4+NVr9weLWd#xweW<9Yu*j&WNJuF$NvWu)sHm{0C`ZL4BSS;^J!khr z*}eDsyZ4pv;q1(r^XGZa%+4;F3{zna%!h@r*eT~ Y*pJ zKtE`MVK5R#D^>o-q973_!&I0Fb6`F!hGnoER>K-t4;x@JY+;@G--d#AXxQrNkr8@8 zPv{N(U;qq*5ilAi!c>?83%4TwOHoh->tGXXfvvC|8n Q-}02l@%U^I+{$uJe>z Vd2#aA_IX0?b9c+M2um!flcGwAxJ23aq z6M91n^n(E|(+oBgguw_H38P^wOoYiW6=uR5m=6nKF)W4UPC5UoP*4NwU;}J{t*{+- zLQ@{54En(U7zQI@EKF3Y{7*$e4lIPFupCywI@k!CpblGM2keB#otPr%$vX4jf`R}T z1|wlKOoYiW6=uR5m=6nKF)W4UuxcmrzZL~`un{)FX4nFC*a|yfCp0|j>ZuXBK@;?X z-j5>xeNo^Ct ~+)SO*(m6KsL4upM?n z<1WlS^n_{N*swr97yxZB3`W9e7zYz!5=@4fFdr7eQkVSif1#iT*24za2wR{ITVV(6 zgob?d6na2UXoeQ2oPWM32!K{-gW)g&+F>+|fw3?dX2N_}49j7aQssXQ3hH1JY=xcB zwAV(1CIp#}QE0BD0@Fk%n# zKN1DeFcv1lWS9ywVGb;WrLYRt!3Nj@b=bNG`QM2GH$u;#7xad{&<|Rn4MxCdm NEizfVJggmIWXTT=U)*DieVWnht;qK z*24za3|n9uY=?%&T^%t(59p~>`EN#n1^UAP7z)E+1dN2yFcv1lWS9;!VLmKmo%vsi zf+|=8>tF+HfvvC;8lQ0W&;&i9H}r!6&<4YvK>kOdAQHyHM3@XyVJ6Ih`LGz4!y4EC zn_&yopFsY%qo4zJLQ^4v5L#dW41*Cc3P!^?m tF+H zf;w!49k3G`pLBIB&4dk4Xn}q(0ER(3jD#^T7AC_~m J}h*ZW++8LIjn*;unsoB zCfEX7VLR-E#-|XJ&=Yz?Kc}330VuG+Fc<+NVKj_|i7*+a!c3S0^I;(@hNViC|K%vC zf;F%XHozv>0$X7_?1aXr(R1hty`dkpvCjMtLqQ~rhOsaarotRp2uooVtb L{ !8+IkTVOjh?!^>AZ|DaDVA$U7>pu#jVJu97$uJ#e!aSG{ zi(oM 0@GTt(GEMI@dZ~;P0$m1Ltp3zt {g>aZPl zK;ugo0q6<6pauHE0BD6_FdRmvVIvC0!Z?@=Q(z{{f_bn27Qqr&1}kATtc7Xy*l2{! zP={@>0~$&(0?-3`K{ND){?H0Tq1|PgAqoX?FbSr^ELZ@GVF@gQ)vz8mLmhTN!^^G? zcsS+!^Fo0y^oOA^97e$y7za~eI?RFvun3mHN?5H_`Cp5I2G|H&pbp!h;T22)^nhN_ z41J+Lw8Bsr&N}noj)Eu{2a{kr%!3861eU>SSPL7W4%?vNRZPLF$bT;s_(Fde3d3O( zjDblo1!lnlSOUvoC9Hw9uXbPmQP2pRp$ aY!VK*Q_E7U%)JoT}?T3VfkIw8Bsr4(%`s#=tn31XEx- z%z}BaK&kS-2n8ju3|7KwSPSc6BW#8`Y=a%p@CHTzdO$Pl%zs}L_(LlUg?1PN<6sg@ zf$1<07Qr%D39DiK8_54g6zH%6x|O?H?g7ov7y3gh429v)4x?ZUjDtz#$p3T{ B3K41VKuCU^{^2( zJLUY-QP2iEprHaigC5WenxQZBhgKK{!(jxp!$_sd|0op1!Z?@+lVCDTftfH1=D<9d z4+~&1EP>^$Gyf}5Py=gW18jsXP>1cX0~#waV$c(MK@0SS0hP#qD+ ~l+VPhroUq?Y3G`xkLKrd*4zR(X^p$&$@2xx~fFb*cAVIv)8!8}+1 zOJF6eg$=L~wm==W!wzUXfR4d54{VsBKeWM67!K_)8pgmxm<}^x7R-TpFyAF#|4~o~ zi(oM 5Vtc7*39yU1T{A)x(6KsYpP=~Fs4YtD$*a-~>T|;byZqNih zpr=yhzZVL;p&44BFZ6@{FaTPi4Ti!n7!D(#9Y(Uw{EtFGG>n0 i% zSuh9Y!F*V75cyw-f+AQ9OJFH1gXORiR>5jm18ZR&tcMM-@gVZQ2?fot1?sRBw!wDT z0Xw0g3Ud$Lpb2_FPw16~4R2_M7U&E8pg# ~-#SOaTe9ju29PF4P+pb0j^ z7O2Bk*aq8S2keA~w-E!-4Vs__^i(?Y9|hjf3@y+X`oREbg*F%p!(cd!fOZ%OqgZGD zN24GH#= `*J}h{ +=j zC9o1!!&=w~b=U#js$C8BfM%zhf4(TN!cb_3(J%(a!Z?@=Q(!7ghdD40=EDM|%Ku^% zl)zG02CHB-tcT684H^!khtLfDp%sS0aMqdsb`(UxIG6;}VGhiLg|G;g!D?6w8=($6 zpxe91f3J64EjL47XoX=g97aGpjD%4z7RJFum;{qy%DZW<6Q`pf4;I2ASPIKv6|9D} zupTzTW~jq9XgK0JuPF^19?%ndK@0SSe$XGcO;V=ru!DN^M(^9dK0}Ej(EQeLF z4mQ9h*aBN&JM4tU8uS=?x=b^8qrd|FpbbXANEi)cVG>M+=`a)K!F*T%3!QTQ6{DaO zmcuGo1M6S|Y=Sy$g&nXH8s9_Dp(iveRsLI0;12^}C=7# ;;_6JZief$1;@=D~be z083yQtc10&{wVUl5d}KzfNsZJBjE*op%sQhJB+Gz?H>c ~l+VI$OG8%#4axEkOA&CnNGVJNi2C>RHmU^>i#1+WBG!djR7 z_kW|H8S1bD8oodSp%?Up{xB4V!zdU7lVA$Wa?1HvfPxZO2CHE$Y=q6Q4R%1cFI^4w zg1*oS!(kMRQ>y$=LP0vrf(5V$mcdF`3+rJsY=efcFmligeW8_g=6@&(>@W((!6cXt z^I!oift9ct*289~!w%@yi2V0xbhXqBeW5?J!f
!muZG16r{p*m K-t3+rG#Y=Dih2{yx) zG;HXw6}G{4*a17C;XA|tbb}`70X?A?^oC}bX2FIp^n?B|09v69hQcry4kMr)MnXfg ztHCDd;WEwOiGolV2E$ M95hlT8nBtW4FBJvpFcW6M9GD05VF4_J zMX(r_z*1NS%VDKb<$o0ls$mVRg>|qVHo!*M1dTtqhS&|7pa=AXUeKF$=D!&Q7U&E8 zpg+uk`LG0*!5UZxo1qRnq47soL%n`P{+m${0Bz6?qhKOThB+`FmcTMt1M8saC)bHR zq3=(~e}5E&!3Y=w<6tVxgaxn&mcuGo4;x`CY=>@XEv^=MKnwJPp)edq!&sOC(_ua= zgq5%k*24yvremWGntpaQ$P6ve7usMLjDj&R8K%NKSO805xl8`{KTuE)TVN|R{Niem z8}x=2XoaCL5=O%$m;!TPzEjS>5)_od8dwLLp$ _8B=Wxu1(mQC) {k4?}6 zdO>g2b^S+y1^Pli=npet7R-TpFdr7cLRbWgVF@g4MgEtepd41hDp(C`U>!7^!JI-9 z^nw=X4{b0UMxH_b$Dkk)roc>?2Mb{dEQi&w4%Wj)*aF*NCv;2u)zt$}Xoh~!A6j7; zEI8{rt^}6DDp&*SU;}J|M!shhp$0=*6yKlsoWohbEfNd)(=g>C{;gPLB>(F;%Ebml zgmMZ0Wp&D>e9=-y@!y`Oyp{hF3*|C{p-Figzo}J58w~Br g zmG2XjZo*Ki{D%M9eq}8G`mXX${%1Utzw+(8vZpXqEAQfwQLg5%`77fLhC1aM{%8M` zY4HX_gW5>oFCr+<^AIW%`R@f)-fb|nDDUARRfZc3t;*R3Lz|MPu3b6TVCYar@b42U z=kbt#&)&knU! zKPAV6zmj7jK*>{NRdQ_DlpGtON{)>%CC5g%l4B!6$+2Pop7XyK2S=nT;NXZ-a&SZ| zWB8wDR&s2_DmgadlpGt0%AYv~l)rEcC{J( AVN^gz< Vh0p(DRfveO;0LQ@hi4~vUFOK)1>IcPQ&)(Y;47stErtImSjxdW` zZVyZNnToLwiENRU S{F(87*SS~z{4_Vi+v`l%Y{wUqx;FhVx2vmbnrf5#{!E`6xjgvr+7P??A&`Gq z;E1qzF44j)o_0N^2RAgr;+;|Bv88(Lz%6Ii_THWu;>mlR_Drwx;SJiDDt!B=Y;*P1 z@kh4gianj3rGu&BQ|-~M3AAH_@Y3EhO{RSt#Pyp0(z*2g262OSamifjzfqXAUi^}E zqnJ2nalvH6{EVX>r@vdVa(VX%1aN+AI#RgBd5V_o6k~cyZ$t8cu255Y%2kH7S34pt zZu*CPxTU<2-D}Hd*)J7)&}$n-fHsEDpl=kull=H)o(%6v)wijdmpZ<34z7b!aMO|B zG7}67yOKP+{If&7yOR96c9nb3O=;p0ZGL6~eU>Jk*1`szq2zQiLYuiFh#pH9AG$YA z4Kg^6^1z(#rQ6m|rUy2On6$Z@U5(^1Fl8LHaP%2e>yD{uF}P<==Cv=Q)ztMyNq?TE z)H?$W$BY&ZB}3P)Xx^7A%Q$G}5bNi7Z~axrGSsGeHG5YX@1LDf%712DG^9qS^~mTj ztXrJ@MhllX&K~aa8LJPvm~k=9kQS6`3~pOL=~zZJzr?4z;(T}W`5b;0eM|CWLloL@ zAvRE*_B5YO9iaZl4P4x{E5g;DE!B>rYbRtJR1Gks^+~-m A|L-^6{8DfL>T}%-DkRj%1KWq!437KN3 z_IX+Y-I6IbYjs0|=<`hBtKDY~qRW{gSmWHJDO<#yBA1G`h^R@)K0#_+IOt=tm#A}R z&+>@x(wF~TJUe@dr?c3Ti|_IYqOn`W9onu93G~QTai{k6sz5rwRoI4qa|9JRjwauk zZOBdO;uJO~bcJVo@CfGI8AOY=iP>5xZ#=zC4AX8;O`z&+VxqR8Aehc=6Jxd5nP+HN z76+rDIGA3|5<|4>&j->+Ssa!1lY{79hZx@9`?+9VHQsf!-5P(M^VMsCKIcv=?R5zA zuoKS)8+a+<;BU@Oa^t}C;E43xa(- t1w`pF?4)a=g&)5`7Q7VRvbv~0U@Xg^Uf z*|LS#ptvW44cuaj dXt@L27n4%@DOQ8L^B3%3U;Xo3P@KR7)Fol915#!{( zpDFecUN(a2r;v3A?|bo+DYSNnuxMM76R2>9@VYUithKA_dVAMo{hd!j)GQt7*VAA) zJ; r*(q*(L?IusP}LR72gG+B zc!opC?&yd&bnP$V^wD459n7aN^Qyti(WEZts&Thftr}lEkU$Z6BF1i-&Fx9H*p@D^ zFVSy4t(s&$-JeVRb2BWjwRSD#Vn1iG$FZ3vzM>cosl+@z;>An65Ic?~53+MZnz v8slu@8t0218L1X8LvkNJ)QeA4ES#&BqeJb+WnsEB1<~@|9ECP+{;u6T zIzR6TrVn s%E|N1osz7_}{!E &MYzjx)DP&E~&J;;7@ z53kV~8%%~2OZF_2{ id)!pfxr-S2-`5_LLaYZ)Q@Ux-U{Y@tk?
@$TPY@+ND|`li#4qpw@etcpojjFh{p;O9^!&5px}mLq@QbY` zhaS%XtNzb@^5xxZ`nj#s=*+WX +q}%?Ia{?p_>3{(IG&tVp2Qdqss- z7Zym`^J0N_Ndn(gIB$an+9!R+!^yqz>ss%oKYiD9N_w6r;^+_?J@!1WCwFZPruU!c z(0X-C@SYchx0c6K?el_oT^r{%g&JNE>$TUu45V91_@KDOfwaCvWNNn$veD%dzH4lH zCWvl$QSA3vlpdsJ%Ep~D={>&)qzf;K$NKG?#-&Tt_07}y!sCAg(cXQ0i9cI8o$B|A zVb}EilW*9LsTcXutsDLdqON^n>@E4*rmML+na^F#-srKVi$|IFaa`07oL2{^Jeg^- z=Pog3&oJmmzvUI%X5mY%u76YFJo5B%SDkM9`|Uxr?j;d0`P>WBRGnN`KQ+@A;|1^H zt$)ic=i>CK>yroC53J)8a;nFxSu*RNqz6;;OT0o4iAtcJrQ$lRY7%$2RM@l)ym5ai zhvHD)_^edKMx9R!Ht?O YuZI|JU6%1dm%8e8=#HDL z2F^y+p3mGf6VxiqxBmL(cJ5u6#Vc1`B6wxgC-If%k(b4gfe*Ct<%8QB@4?lX)qhL$ ziIYRA`eos%`KAZaS1*g3wMRDw)6iG={$ziBAkBV-r*q(^ffV Ns{Fh{rBB*^=zgm+1YujGG(bER5prMDtHp zjzs;h0F~zt@xHfml7}s@b89^HEvG`dvwx|p Auv0P7CvgrmLR(Ly6{PRjt|GV zRJF0H${qhyiGzpo!Pv_YppH*ehaGjb#+eRQ{nmeuTH-q8iIX9Q70V9r+eZWH`GQNh z5o!VAN={@3QNbHx>eydy2r{fhb={5ljLXn3R2OqHgu31kmIYs*2{N2E9k`S0 Oh2T)$ga#2dK2M72QqImhLdJDt(l#W8X67QQp# c>R8SQu6p{pV7gS!EAI3^I5ghmEPl~9h-SVi z!UC`DaMqn|v#5NS6~K$1P$$+eT;dqv>jeK0;FxK3=)72|RY(ujtaRv2&fm2sLg>_+ zT $x)LdZ;exypZaZt`cw8Mc$iBe!1JZkHz51K-cL4^oi?uh2AeL z)8qIEUIw;w)C@KhAse;=w<;tM>8U`iZr!7V`z(Zo+OisDnJ!^o*?ytoU-jSR=IK zKl6QWrI^~^JHfeT+a0Iu*}YU+>sJ*{rrnhyN6Y3|x4gx71T|Z2l<*d3a>JTn`tU8j zH{N`IFpWRJ7kDq;paWu;)*hZf;}41@+KcxES8P2fEJBk>d`DI#0 Oe=lzj)>Cs@@Y~Ji$NaF&}q8d)s;QNq}P2HOp6ZjLa}vKFg l %Y3i9qxLOd;Bwyn=<*3y^j1QuKBVw^Ok|!qTh?t<=u`-z6J|Yfk zEqy1`!!_Jr-{3&1s1ftb1uLAV^WzFaQh9mf1V~l^Y|A!U^l_gBlI1 _$mku2ji@YDd(-}M`9o%1zz@=Q9x@+*z zho835gkya9>+Ca`RvqI@ oy6u~07R zL9Ore`a5u67nv_i^&;~JB4$|Oi_Y7~+$~nFEO&mC Une5uOE1u>I&o0kLOvhyHSYN21e)=Yu*x0JQ`$#js+|8k z9r{SD8#=#-ie$&JEnV)J+oT!`V_XxD$gd-CipCN(`pNkGZ+`?WLDL79-@mz4YnF z;%@nIF@=62!ewT$s>hdJ|3oa2#$vjvo-40;j^@;hZNr~ zXTv*3PSd1A*FK{Ib_|E^Er(IJv%P%*#lDo-aWz6+_lwV!Az^+$4O)(9^ zi#Gr1Ih6h~O>?KOj|-E?p|={uFd6bRecd1|{rG8t@n0P ?rej&z> Av (GTUj3C=H*CfgQ*hV6!*XL`7wz=7E|+YZzjdU1qKo=ZvaV64PqI!`R!_37mXCMQ z*z2v+#N+hf*J6uyPmzH>?eZC>8LmUzRX#>bzTvo=j<~z#F<0EZQ{ap{xubyQe z@2*tZ)LO?Q(>;>&ESv=2iypr@qZ1T0Xmr5}U=oVYVxV@(s {8LQ#|xh`tAquq};hvRWzLr{V2R-;7(Or6ixa`Y?90JsQf1p zB@KDhw?)*;M|P9>Bfg;=>caz~rt#xPT+_Mh5jCBW^vTa+#L%EC8j|+!IrVr%Ej2SK z@)zMDD|6|tU$`ClxoWBLqy4{duY7Xp>@PeVU*}NZ3GuLu&LQj9VkCWWf=9b=&K_NC zF`wA!8lt}=?aD=B!;l2ptMdXpDw|H~yrQ*ir|V9Nhlbv8MYHnJEM)ug?P|i7%gYWj zpAv)Rj}Dc;{pt1NVhCNWPcTu+DPF(sa8T(fZkxA*&Yj}6J)K4Oo)&ZE!Ynm~o>YHY zY!E(lORKPGFAq$hwXNKtm~He*D^HW$My4}j`_PG3G@}ouDTgzKrzv48y>Uj|A$x75 zfxq&={IrEaeia+#qAhgrSDuConbiNR*ee%iQq@_G=d&5)( H$qI1b14pf7*phl!&$cTv($;|J0;=frIJ?k0*p$ESX36Q!RM zS;9zH|HhXFj`cn?;dkLH_oq|T@1jJS(n+@Sb>ZDKif9+P-n+Iq=ft&WUzz#i-4kf{ zmm)+qZFI%TGaKpdKlq9?=8A#%kJKNwQH9BJd1wQ5eI-W9$2X9rQLK?Z8)!!(Uw6Jw zrB52gYPl{|1;;cQnCeV@(U(?s@I~;+J_vys54%FZ_%K~{fkR;A6{q}<5ZLgLD+Go; z QI@h}K(puNLv2v|z-8i1?S~n=!xo()_`Q6yR*Nu$U= eYc$GGtozRb-mU4`( zxZ-k`UH7 3%ly$?eh#k3tXE5nX^H;IS-fypp6kLN(S264NT`sSyk5x0dug&! zjxxS>Z&w$I>i+%cexr<#x7 ad80hFnk*(cUp}^))|$AcRjVsr zGRYAVHT9l;Wld(iH$Sv=*7U+pbLebeY1Tach^K4a o @{#v #Y z$1!B@C;enz3~lTuAC;yUy4I6NqjwKl;VB0zAM%tlw3xH;^sc8YlKWOrY=3#PT)To^ z?9V$6T0wvGm(%6X%PDvOSM 8 kPT9i@aa7`YGqUXx%NAQQII6A*}~Z z7|g9>=M0wNTJFhs+LATsdU >Pg20ba3(r|A%O8atY7X@!0 zv`(_GZ66e({B`@FRdPueEy^A=O)R13hRPgqBl!>G8U5(zcv?J6ZkOX1(+|VsZ24m( z`T5AD(h*5pd?blWG}J7; bZCwoqCLN`iyj^k zJcROx%V)G+?ipkqA#ae+ETFqb$lGMt0{UQtTrPjM)7X*nBRRmX&Nh(TEqu!I`LxU; z@09cA(_xEzN1lnKO{3&+ZNqo*w0D#&lpoHcn@4k-?w?16qj})Jj-bFXa+mmn-XFtl z3yP>XF-8s)a@gEGW94Xheh&GLl_TY+b7 |?8)nj!@v?r%9sI%i|GIy_^hG@71V}F$f5{ptXLM1< zC2O$qolDkRMHr<9%Aqu4qD qv1k{ov2}GU#UN zF-c~sChkrR_LtMUcE1ulm+xUdnjnYM5D`3H+(ge< jZ zN2jVr=ZX__)np#g^EZ<3Wcj`9e &4A*$Vv%TK4!jlpuUd}s>g2g^IPep9-rbXf3<=4t=g(9|og z_RHUor}w7F1leSz>qBISeA-I)hHy3ERyrEOQ~v`kvvEV8526&CJazMd$*yqRTFV{h zn|fpJ?5M*hjQq}GDZlqD?0(gcPmybSS?6cnxp!Z5z6Ij<3|@{u^#>=@-Wz3(vr_?6 zxgQmQv~;SxMXnB{7pBTvr74h(#qvCipC;GJ_y8)N#(~s3fO>>- QLh(nmnC5^o^@SlP9@4G{^t{*CD^|SO4!0_4fad z4$YeA>d>DPTpcQ$a7BkMj(2tFvGJ}BT|eH{p%(r`>z@vp_-?cNnz*5glXI5bC{K=~ zQQ Y +E?d^9ba$H{3MO`pw^8?~xYU8Ic `YC3cSJ-6P1cfKQ(^ zf?ip`%?TetUoMcZ%5B3{3{R6Yhg0oBzOemaR^jVI) W45 z1?R}X{`BVxxl?9(()N||m}SUdHE92O#`5n}dHK0`S{ozplcW2o6zNZwVx+G;aV?Fx zo%1l~TH1U&UzZNj;5)dNzg$DsJ7kMATtmZF$&n+!^+4YI@67Pl4|q`QDw*r-O#3R1 zyPw@@Y%B-N9(PJn&T?0IQ7oV7OLyNX7s`2k>F}L$rPg|N7p;0g?w{T7%9OY=$Hza( zpVU-Y3e_;@Sn?GMjP4bi)zgcNj;pduEd{*gzHK)D`MdkQf=-*KS*T}->_@Nnndm8> zHqrXka_n` 8IIGpxdoazdna)U|)_ufC7q z$b8#Vou*=oI&bjN^=8Kfcb`x?8zRGId~f6()OVoN^CVB#^CW)YuAV0)tLI6fe2Cs& zZd7;3TdLhNt9XBYInMe1(yort*Y!~=)Dvm^Tr+!?^RZI)wsO_ZOp9tRH*#CC%N;5k zRCAq;<_@@5ysFxiJIgya;N=!xgt_V^>d}vfo_&?8&+3EnP`}(A>RD8-=YHNnJ%_s6 z^=j_6e`b|@`%didJA+?PPkFexcO7#+ChBRp%dt A~OkKMXYTtxM;azu|kTuUB>PLo5gP3BG4lQmQBJr_9h3hAt6+L$!w z_(r_mlDqLDH_4bA`MN$<|95{zqFVJlEyo#>j)<}rJ~_u~x;lQW`oP=B-8bb%JXY?i z=J9`?wK>Oyd-rXx?&hWQ2s;mn9L-PF!giK%$Nr92Rk7+{UJ16s@``9esI>ZZ5Af|= z5uZg(B6q|U!>@O6oyeWwW9x^|j!-${8jHhj;yuj{yLz@~b=c{qFU3IW43*wPJ^6Ep ze=b#5=H<(Kx)+q5S1u?$u%PsCEhw*GK`~-MF=9c{oW0E5`cLRxdGEjriuRuiio}8< zv7ksSC;|(Lz=C3ME-0U9 bk66+KA^;T9n uLyi8dOxtguK@%}=2ix$WmgBS6Q z`Od#C(>se~q&9^&`bWxG`T0e9_(6GC8@WB6=C2(;M0`lM|JifEEqy)_ya>46b|lw% zFS#hA)vf!&_PK-CxtomqO}=Y6KjVeHYm%P&oLV!yZad;U=B_;6->ZB7=N$2L=pi}& zst5Q$hsmOMJX>-8Az5|RpqDqstK}uP%F@Eqy_6RqrT#n7hg <5>6xm)fz)%W z{9dEF>q*}#@7JzfVx;BUWT)&mgKo=`HFEr38t#yG`BFZ=72 a3_IwihheYX5q$glEfRxZCgd?c?TFPASikU{hAz&laZx4*~Y$OG}T@r3J=XeW&os7mxve$l z&NMps^O;X7gyD2Q6!t;k2X6=ibq+8NUQ~#ez0@&%GLCxjC(b(Y%bZ**R^E1mzpZf8 z)A5^L!=J(NXR`W{m^qv^x$6x0$iw-Ghri?F?zx-Djk@7ce!#LLn|3_P!x5WJ2Oi~N znw3poJu1h@VcC0j@#VRlA5QM#XARfh7f<$Ga^8e@lQ>9bsvzMnxj2JlvYxQrd11+( z>B+_X-AHHgIuCu(cKUD^&-VjKJR-Z~P;C)!xaZ5EH{76V`HxU*a{O1Q{XHETAGk7~ z+j0Ef_=+w0GD*lWS@h>_IahwOts-oXyq#zMHF|;M_419E>06SchI?;yUGBP)@5`=; z;q{Lj<~Yr $zraD=~>GJHEZafJ4x(C6i zKb>i$(B(b7B)e>RPj6+)@}52-lNukB<7BXf-a9;Tg2 h@i$+)l80ox=k4wj#+RLw`q M}u8yblLOD$<;*EC;WtY4y zosK-obK5t)!s99FEu?)PO?aB$z1{dcEqI!v_1TS-`ZP!DmW}k-(|qT;Vk1@a>j5Df zopYX16U|An{K%CVy(+f5EBzCy{hULr7P#IUseci#AR}YB=R5h%^Y8{*UL-98zFWon z^K4iD(4+c7j}&j7ZSxx^h>G})f_Vd7=7Z#)sWj#pj+yzs8rh%Wr#i3mKN0$j95b!A zubLUZjAIQ~%uE>PrgLUSEcn;VxSmSdx>Ganj(Ga)8TqZe_hEYVS$@wl?BPAn$zSB2 zy`(=UhsmwakXtdYhRqMs)M7cpr|QA(IFHJ%P#>8(`xd8e7MJQzKS*iC9Od^s$X@{C z_eC=wq{d=7P8-x;qn>-EG7Ep)Jm}{qKYuxw3n-{<#*^rTly1(e8g1m0$UrCI6Wr z{yb(`r*9ZXZ|s%kVY8i8{I4{b$gj|AUV{f}YU4w%!9%q5ym8WN@G!BS!k?Fc#)%y6 zwDa~pQ~HK<=ZN=Geert!YMHz_&4YL63_O{lR=}f<3;O&yoHS#dNi*2pC!GgI<;;Vl z)XaEh9BaLDW=>*eHg`YLb>)oe;ilF?KGHck%Qn4xCOTf-3JZ0g&L2cR=;q*WnDPyf zM@9Avav49lUP~uRIC4)VR|LE$SBc&~KjmDbPn)Tl 7 zCti_#1wV1x_p1C(2HZ{C%j7Vv{K#dRUpe0Ug=1w>3^Uz?*>&~An?KL#4zmpl`I+x) zGFqEE%t&Fc%kRWD6(iq}RYIJpXfBs-LN=`CuitReEqJHm>iyC#v~?kKD5iqfi{lae zys1J)X;1qaE1E0hJR#;+On6I<79yM$ACR|ciK~oM^}fv3Hr`>Rn-0oBntaRIu)!7S zAIKhpQmfn$6uvzgNj3v8E#bZTWzZqaLT;hh(+(`*I`I z9pdN0N#&Q-R}%(S^sMHUVdQI*(8IicKG?0|(C_Z%(3|6F#$g`0wF8W_{jl68YAXWY zl@=k6(6S@^+@a-GBYk^>8yHvS8ad*Tv(vW+`MKD}8d+jKALYz1HOXD!# K?eW6;o^F!$MmXi4j}72qSjk z#eYU@h|sKK=Fn3g^1aBDR(|I6p|oj3`WeYsCvOoS(4smSBi^F&IvJ+b*p2j8o%~a~ zdvZMe@sYek+uf6|Js-=1Vq3+4PvmkTZmmeJmqUd%F2YFppGvbVdA4Hzr_xtwfB4Ly zA3o!Y_VP)tv&h>nl2*sd(1D&5S;u!&@6V(+`80C2kwO~yEaNA-V$(R|56;h!hTt?g zqN}2+A((?Ro<95{_&YJf6`PTTh|MvL9Gj(s{uP@MR}9n8aXe{X^P~B_9pw00rphsW zDtdh*O+q|Ip5MyXwevR_>HTjxf7TVy4?Q%mJx%hG_GSM$dyaE3-8d$mMjhuT_&ffr zSb3atM1H@U?)^?i$t}C-{qOkUU*K*U^ga7?e#M&a {;(!g zFMb8f$+I5l;+4xuUH5XrUp={cgsZ8V`)^uB-j6aw$W3|l(NA)QoWh@J|11M2yhUcq z2Y1jHE&MT9=#C05{8nh%gf21-n&R&{$k|}W< 9(50;$*x}<(M99hgNM=` ztupV<>n6E|a>o@zIUx2wn`C?eO?th@zlPFzKWlb;_0Pp;=s>=^?sd7=cJ=yU?)$6x zavjH)o~37a+Bck}*Us?$MQY#K^!phZXbtPD&SN^-)9rLx?ks+s%-=e(xbYL^ajqBm zSALH6?0tIhzg~0aqho%R{@zum_`_;-bf41$Gmbfr=J)zb?fMPwf=YjtTeb21`JLZc z`JVRfcq3gpE3^A&J}3-)4zr$JgboGEIrL;3zrTC3A9lXp&q%qy@y_k*vGZT*OEc;- z%oh!FX#6?e`RZ%=bDeX1rI}Yzc23R`d~@3IyPT~(JeC*nc3vJk(k{C`F0WrQwg+Xj z%P#GBUp~PDQTzGrZL-D;`baZDewp*yLj(qn(} z6T(Y `+M=P&7^MNF{&|T8!i0XG4JwdE!Nj$%%;1#_+t32F`l+{$u;hEL!Iq)eZB0G zq_XrWp4#l>D~4+K^;(&>{jcyhf7S*I_qT^!v45w*wf~g+o%;`_X;Pc6oxTuGnNs^i zOFuiCmT1~A?X)4D)@xdV_RSz8{j6zbxiqPJD0)z8>6E03e51x|tij7jhkEeq8}6y# z)yrFGU!I=5r 1PcfS2sU2)zLoc{%cWPx<8_C^6 zv&gZre-Bi}LJ#dKsm1g$(#mUjjE>)4vFTdv79ow_)2Can?nf>Cv}?6BZENU4KP}N` zY40m$Dj03&H|Og6D&MZet-=$Y+G*i4xz`oDb~hZm9$1cDs|IMvV$^frpvC|Cn$wk^ z0$km?red*|c1dbipX99}nnTK`mQXW)2U@%Fmo*imhH0Cn{9+NkXx3(GNk6Tjb7t*( zIk%HOAFj=nm;WO32< My!5Lc2k;j}|m>q&84~d6B|LYS(FlM+jOwQX3^VU*zYT z+7Nl?MS4s9JoO?qkJN?_A99gzWcfEu@K(olGw%9oL)50~(B?Jt<4mnhT%gZqX?D>; zv7@w0!w>%HJc!>%-kMzz;F>$ k6(==Kesl^;$LnAEO zSvl@J^&6$lm*4zBVZL13x9$Jm+N#=V^Jr~?%xS0BM{B Raagu+(vs >euH!IJ3>(6w( z^4*^)+RF3a{NWm!eq>Oa*24FTfi;6}5iL{`tX+fT0k{vXk4 EiHqXOH9;FzK(d>CjpoLSzs3D3CYs$^M2fQ&P4ro7U{~iVJ!~z) zRB;tRE?;ixZ@NOUZ9o@$uFzoqU37(Jv=I%Ik0#O9HX=0W@n(Y;JmEhy>Tve jHh=L4=5=7X*F!CbSMd7pP)KQCGS1oxUWF ze5Wsot9wDk9hr*1rLaV%;%{{V8~82lOJpkk=06bF?r(GgoBfSWU_)i$c*Zis6=X5_ zGlMNW^R> ^Vh)Q$=n_(kaInJ%vE( zpQ4WKz~UaC j!I`{S#q1*msh1y6Xm` Bb3x_pL)1K4QG1h%;uNuiiGPP%p(YanCLJdPU?Y-F0 z-*k-pGa%4~eUeS>GDNJh@+bwg!4OVAN^fOg9tIwzeHmbiO^?#g8KSmGTbE7MGsUKm z-bWlg&$ex6|7gAE?EjyswK_uAGr^mx9U+h2BFs{B*qDF`vh%u@XO{B;^W$vl)myAq zLJm`LZ?L}`hp1&A;BoX2W%dEjSaOIa_W^y3IYevwfH}`wlTBat5%U6f9h9I!5P?u= z SdE)xPMG_d%-MPefE{_z@O#`%u zN}hLG`ckic;@v6@4oJ8#wzi}@e=DIB*k24$-rc`_YJV}xBu0Fgy?yI (V*?xAAxNH&|R%FxYnyt=@Pm$y9*$U26KCK3rKHXmZdC}S=JeFat4H4fd_jgdk z7sPy}|BmekUJxTpBI> ;qcqe;%lWgII&1^Fz4TB8V zb@TSK!^A{DdkfHpi&M&@4OD9c>I~noebWdr*(4e+%--H?q-btZHm;))qtH;`y6ws< zVxLL8H!pkD;n6}-GC!iDIpS?)_v-D><%&0}=1sZ9`?rJk228=od~ErZS;=R *ZM0UrH ze-8;T<1tf3jpUuUdF1lo1FN25%6-Yc#j*fNJ2`|v!BOPEeZa+rD|+VqkAYRO**uMJ zAXyQqEH}`W>M`x}oEjjd9>YxOxanSSM0@ QHbpyE{3JPoI0o!*D}W+L;NBeRh0 zH!yJI%huSujrO32&9@l72rN*A-mv&k&tDsPsIWFeQ~X(|SE^pl6QT<$z_#oQFNp|g z#`cgZ+)x}O;fOFYyfHJuBONU{Q0>CV9V&B^VNr>|Nb K@|79xGiBx?$l`ej- zJeB%B`@cq|-!J+PRJz}h`TsSQriPYKDHH$yG?l&*|Gz_}e_P5?>8{XHDxCy(k1|yH z9x^4BewtlErOT9n@bK4hDuL6%vBj+aVTXpXF3$Eo@p?9ez=E$V5VUhHbeRXoXG@d5 zOla*|H!p8|w##G~40Fx4Hrn2$NiO;Oa?~S9s>$YRlXoU
IfDJ4nETpB2HKJ=Slsre2}AL(k>RVvo=axykuwE__7PFq$V5-Y zrRcUTiTB4)@EKoQCGreXYi2K+&l_Z*+|aE@0}K9yMy@?#*|1qZ8ai97_M-q*W9VF% zv-}dFi#!|!u+p4$lmTffE|+s@Axk?s0f5;#a3AwpHm&!r?5oVj@L)7LG=2@^38#V~ z%i% `)qu22SIiQmp%j`+kBW^quW49x* zr7anPd?omb?DOWSdKQVae!UuA^$U=ygQ~~UoQ+k&@~-59)4MVZ37{Lw+EY|*+9RIn zu3Y`E_jsmzGx)pw= VgpgE$hF{TQRRZ8_LQ#L9lUed``QgW@mxQ6p6A+$5E0<6 z#1-YaTvIj;epI2oxG-DL>u1$K@hKh_pH&+M745{x<8b0*^u~ Tp=#l{*~mkAU;EQlUr4>5WBe%$d?)YV7@bPr`izI+Nxrkv$aj1D>G@Vi z{-V-+U3nK+Iwk|T5XRc-8{=Z{Bqy*phTWbL8la{5@a&{%$>^MYIy+SI1P#Mdq|RSf z46k-@7Ff~rGn@`-kzUPkZ5ZUn3-z#OJ?d-yN6Wo!n|>bI2IKLj{TZ&leS64iE?7$p zuGbq3gas7_V%x({w&^V1Fk_2M7+S*AZiA^EK2z|gJugbz+gkFp=_~*_pc`y0@4Bs& ztrZ-dazw(uugzjf7bNofV4btsXCDG;+CsRo6g>}`s)heG9kk`G4L~|ZLHiM*=y(t= z|BXSI&4Zx*07ykq%z<&aABGus-A(3Ctx^PdWE{GFSj)X{gS{TUGR!EwHIIkI#Z!*l z o0?JOp1Pl@4)SxV7fmr!Ye)=Fpfr{r@8kF{wM*k3Ft8P8)Y5GrC6LY zOQ*8dE7>&pWR$lu;~`Bs9~Bw2c%~#+Tc-#N(GFg8o2^G8 sH!vDk>=cj}6XroDyowuxQuAn2;mT zx1BsT?z}8Q@zx51CYME}fpSZwYspnZLtY*UCeQ}FM4w@F-DzT5Ds-kxjK7$Hc5ioy zshixgbUZMmZagA@{2a~)67t{y#%BH0jq}vYAa4wtpkg}F-ZfY}H$%|v_O5lsjzz`f z)4{cIo-0}^-38s{E_fCaELU6JU!NiDg0-!O-FcIB+GepUW?Ohy^tB$rgd20^tL6Nv z&+qfH_P;Qrvm>%ytZiI!=tqCGws`IhK~)35kUHQYGC&PiCT^nWGf{puM}JZ>+}uOM z%Z@^qDS=*IfMGM~+!O-JM&`VG=PE%pt`Fx7%zD+5%n@tp%h@6zd^56Gn%VI$d*A%w z*)%87)gQ*ig$-QmG)ZAluJJX@Z(N6H0ApvqV^3uNGjsk)q#Aq4SXH|`4bvukE7lYI z(Ac+PVCZJ%J|2a`QI2`|CakBzLB>mMP&K{eTQMLI#Zk)EDHbrNH9>Y^rcvh6FSNq9 zVw42 E3WbCT`M|p-w*0eeu(u)m-t}_9&mMu%)+&W80wltorP UxH4sft5wu=KL&;ljQoq28!GXvr9k{lrRXD@|*|{q1m@mTU z&V!1T#0WKs+E;LmReqREAq$}L!}aB7@GE9c7W5S|)TP0S3wgS_)~TP1r=mi}DgeS& z;X}0qE8IqN!s?$qQWpZ$mw6P$zaQjLfBt ;XyzhQZFm4APmMDC05`}rh_ z<=^)v(GdQ9WfIL@B>a@=)oAS^5v_zzA{>KKm9rD6F(LicBI-h-h4-Y1WoO=98$OX1 zl4z?mm`Gm}6h)OM(jSCQeLq3aluEAk*iA0=Ezy`fD!Z!6#0iLIhnKlw6)Tt~(9X9+ zhX^sD3`_(SyZ^dViZ|2O6{L` h89&RHNm4{iGE^!nSPZJorjIRF#moZ`!1!d|DV zZ;Qstz47F^Soo=1mxB0hRa_g0BmN4-g;#7S#-pL^a7^=fLEi4J@t*OK`hZI(&EnUP zeJ#9VZNU$fETAraXod&nH9=S1T^pN&5Qq=ve_t&hE*6Dhbl=@IIPcz9Mq=hqkBbX` z)nygCwdY>G&MZD=Q!lPFgPl6k?yi+-ML%PQwsk{jFIDRb#fvS~P1^!OwShF;@m|RK zATDCIWvW_zE|KD)y~(7Ez}7N{E9a@2*{J=hQF|$uxz5`mYNsGtnum6alg=1P65s_{ z*j;PSIqXDU($qeg O*`009A9f=~}`dLMVe)-(ps z(5d>sn-%Q4&>u9PS v|C!a;IM|lH8)u)#F2BoY= zV$tM8-MtUa1@2mM*UogRnrpDSc|bPEXMwku=<}+en#+_r?ZzO9neezbm^tdAoi3WW z7o2n)oKjH8mWWMKfRTGjewS99t7;F%V$uhEib kWJdDcHh_1XOAAG*@sK zJ63>`Wa8(=-7DFr4x@K&n&rCOoqK83pK OP!Lc6{Q>6?wxN9>BH%%9vONBId?c N4%odI6p$3T+eIasvp*FxpUE0?} z4HafQjOwR``7}bE@*b*Nz_WMksM(+rmLpId^HDLypHO`R$1pBWb5$KV2GCGK!SBoy zY9RlvKB0#2@8>7fW+Dvado8zO%lge7Yyy6&3rEYo*(RyeigS+_Zf0lTBYX(V&|1zf zrWa1C5#F+hlMCydMDU{JCsnV`p)Amp^IFZn%rk}h2RfA{6gI ;2?U%Z zP$ 1VMmY%5IHJQ& zzD#%ru6CsBB%D-Qb@nLQw@mn|IVeFPH(J+h)Ynl~PQ7)%8~+xn--GgWJ5MQjjn2rX zQ5Lnns&MUSzghuxuaA_IQF3UE!PQ~bA2|!|3aU+x@vW(ByGgqSB!sBbP>J^a6ca*^ z1|(Efd+}@4feF6BaXK_6TiyMChJiUmub`2%f4K-Ty-e5iAJYmEQ}1Qjyg}zFDk9Jo zx#3Kb;%3Wm*Z!7522QPU9Xiv16~bc1e0Frq=bJsV$)kl^gXpFiRE*P3ApE8{d{n62 zI%K*`vEYgQraD?8U=@gj=yHBy5**{wNxrizLYV4~W_<;gs`?7Qfu4fzgp zi<9T`?RmzXq-5)@SO*H{dSugSf7gJ<1`6H !lMCnuM#)TkONTmW-Luxnc0uxwsgy7JU+&DSa24bix_-z)~LgB;Ze zkfZhklqeu?>n)DAf;G_OUD=7lAWRRfHlGwDE!z3klItBVxR02y8(4Hg;$E3(+^J!* z3U!cGbZT~;$2$`)(4F5Gq#oCsl%WoXv;3@u$_eBE(hzzt5L_>uA6tR3~$;GUMA zp-nm>y9DN8w=U4rJve=+BOSc{=c8OEidhFUET{c&a|-rxkCnnZ;Mme=l);9tm+*BU zXidqcyfD{><{l`@ED9&JbZCj`^_3#b9A1*>ovxjGQBQo(%~2AO l#l-p<)24+mcz86f+tBzKe}oA7SA19z&LJSYX-a9 zqGDoT7-ZcPjf@To%)^*q LVB0L@dj)uxy0BT&2y4?z0*los3!6;7Wp{vlg2{1)Bk5!P zVU}eJomt{pgBFMQ)nzNFeStJ*@@3?4I+oP$Z@-4gXoKyRSQju-0_0pBBKSPI2K2Yw zZG`z{Yh{1kTFDoUneITmuvW&RVmz#s3ACRgeUdv$TV+=XX@dh&&wsU5eqH5XtUwg; zUTCNaizI@t!6KO{Et1CYILwkfKOjvuOUnHuN*jc=R1^-YV~DZA1mD9}J4+5cl*W2Q zq6?P{NhTt$GkrfW+>fKr0_9v;U5*=Bm=O8I7*^;1x%8|ZFW_waBz@%w@`BHWT%XOp16%Zo(D+zuq?Z00y4KYarA2&=qwF$}Dl$`}Y?)29=A4xpt5rizQGlfG z2yNaeyiCALYLqtZ6xFK`os#mxmq-f*6nCvM0(ckIC^#~Cx8yoXZY3m-)5J+*u&zZJ z(!J9SCq7&|)HDGwwnJ}SI{Ws@P1@543fQ_a$)q)M9U|ryhf``}*EFRdk(M`xx?++X?7}U80t9<& ztuf_>*w|YejL$C>d10CR%1$S1smIYPho`}4 ;_!V!6M+b8(3A{x?`i4fLYntZvjg$;* zle{U|DgyOO58(ZF2nW>3D!Tda+`%P6Q(-A^+)Em}i<5LWL*J{do&q-Z>tyn=itwu5 z#z@$$>W;_sV*MuF{I)*<@57xsyw-1f)pn~2c-qz>Nwg*(zUd=JC(+e>(L? t~9k1Uk9u}9TO+o+>c_t`o4|5`4r;3C+x+oaOqggVXfELK_ zKFFM9nG6t`JKj;yLwf)vHb7@;^XeE=0K?Iby24|yW4V}Ov&l3=1XXX7E)m47kt(R| zrp*qgs2Re)Q`eo3i#a%n|DYsv3K}@M?s`Dd!?y$Q50b~5Ewa%NAE4aRAVj%o-=~#@ z)hL|OdQ=av091PSG;P Z*xogFJ8h1u2#^T3jG%i4MpL33IF2=jwm3haXR6)L8pt9Jc?eiPiNqd-(G5CHHwz z%3l>ClvF|E{;Cid=*ZWP=T3(2#wfAjuL{0NWlK02zW+{f!h#LoyI$aF23k)TzR#rS zhHv$5QwX%9hE=N@J4Mzu0v+f^+B;!jyEt(Kg*%Qq<+Vz4ni{6wpcHB9jreJ_T;0a0 zTbg>k07W E;E zzJtzn8`o^4G9Cz20!2$e7kYjU%oezfHD?YY058*Hnie)R3|1~uGj6 p=$S@LfMU>LHGc}tl61^3@q~337-@2Dfv*+R-N&K}k=B= RYu_lhRrI=9Ru?gUJNss-KmP3=HH2i%m?^8i8L2g z%>qh*!Wg6K@0Hlx)j&CBVEyNOU_B^Nw|2!ON^6%=F_B(fAmT*ebrUT)?dne_7l^9$ zfB69y_@%+?7>4WL4PN6r>IScrj=I6CR!807^?L{1;PpiZ-QcyPgKqE|-9a~ab?TrS zy!<=p2CqBqrNPVOMQav`Cd#t*y1gs4y|j0kEYz7qtoPsT PNmEh@%pF`U#a&}-Q{faxacP=*PiDDEYg19S4n~@v@{ysN zpJqOQ%+~vP&V%)+2Kdz5m%un3HYQb8VzIml4lqS^oXWlO^m3I^PB$|xgXI_u4?>-{ zwzhg_vb`h1yuB>CF5}xA-tTmqlEHn$!F~HTX )x=2hsATZXv=9IPB7t{+=Vf)Rn0+#)x;xI8WXs%V>*g8F S^fQHt!$dxu1Oul8IVR4MU9tIM|?PHTK9VtKtYq}sH|Jb;!F36$6-(Ip6^~W zc25{=uzPlR1=a|;d$wW}p1OM?N8dg9LGGUXAa~D}f;xYwG!< &fH>g1POUlUJ}RpFqD8!;+zQ84Iz!s zJNW(63?a5S#?(n98%8~rfk&pq(d1>q5*Xpgf5Hw@El#(C{EC6s?I0KA6fi8FM28(@ z3)?fw+d+N_&ZeuuZZ#FmgEVO5GL%w-2G6E$(5NSYN-^LGgGSX@HfRJZxABcl{yo`( zVA5#P= Dpz- zc>*Qv) Lf<|%c{0W!@@SfpC zd`2IP;w}z{JKV4s?qbgW0FoWF5lw9qEWP8tG3Q6}?hGAZ0c_;MEqU?wj;)L1&ak!_ znn2ZT4dwhC%V20RVxb%Guy<|kf?xN7`}W*o*gw3je- wf9@{fzijVL$;=d3^CaD*~Xn+P{wo4aLZp1Udf_vnj!am&U0 z!9n?Z?&|ORL(PfbniG$N_qPOwceMCc`qrF}Z(1 anM&$9ioxWX|pcy+U@ZjK(e z;t+;b54{5(=52x1Y)vgK16|G2pptNDmk?Jt`VvEMl#e@V&cj!7@x|&m&1_xFC;>UU zyIU(b516g1I02e@0CJUps^y$2_y$Gf$FS_GNwzn&A);jz9#>slhR%&HMy@-W@Gi+U zbM89iA}7M$)nq~$r+o9&yAan4?I?g4oh~!!ewt@gUMI9XIo@@zc{aX<;bM<>HT@Fz zjeWSQ$=va7PHXeFko=4083Qq9`JbDo-GRxxa1Tx;C9am3%)yxbEN+Q!0`)fMf6j%r z;1B$OJ!Q4+obm>$@l?raiij&RTVDXwylEHB`E{W0!3^2m{V=PMz}~|i=vVM(+-dW) zHCzjmhq>D)zf)@d;Gz6IcT>*XQ8?qGKZ$>0>H@>zM_GxzC~?zg0g`1wyt<)X%*13a zYFDepoiSTucoepEY?a3Z7THp*mYd0i>>b;fl9JoSX`{a_xQ9-5G$su9-&_i=Fepq} z+?QtSIlVVd6PD|TZ{Yo%d!~>_*~#^ k3_4*(sut(u2q^^ zCjWiUJoPV(DHjzeYTnk%#ri|r!atG5!<>m iT`iuggcbSy=fZ#IeTlC-iolR zW+oDN!Y~^^M^v|#YL(o|?Xaw`7gk3%O!pl 3VH0j0%1wONM_zI(__HiLrsN-i zH83=9V^ZG5eK3D;W*5Da?BSCa7>-+Dl@5S+;=b7mXm%MmC PQ>hu@(1i$FB)|(ag->hEg8 cQO`J z{+>) 6g ztlp3@54SH&-LPSu`PTyVOCX~a#isADVHRLkV}*nJZ{>`5kTadBQw<+#5Jj^ K{>)B*l-pwQ0&!WALV<$&@g{WF$wv6%4rlrXN zzWjMW2wg1JIE!4~yt^8<%*_pTv*kH2r$nofxUwYClCJeI633Jz!s;1rBz7oCgw^vw zq=ebl3yI~ep1UI*lH8M4&+FA4I0U9^^K~G3n~_)^NdNx;#ES9-khI-U#vyR(rch@I zV*o?dO_8iw)-~v98Q7hDwb`|#oP_ l8+4&}!>jny{gq7` zD0`D>$tNPQ&09Z0Y3`AxJ)2=HLMi0N%Xz6TC18(qZO9opFYHRno)D~OuaTxT%1EYm z)q(>N86%rQtEsL0Z+2o1><-`boc=|_Z3(J%pBp3mT6fB=rnb-1^F7#iy*lIjRXXbs zya)C>IPLRsUGyirHB#>`T4KU520Ma>ve#*Su=DpgrsGBh%~1l;<6X2Eqr`%e5~^!S ziF98s;wg(5qWO*A6yBUQuitbR6i|=5HWC+aIPvkXoal6h= I z`0%kpZ?DH4baMz5uNMo&Y6OU)4We1hGMK8(RgAE19$LF|hNRzChGF6ZU^x#A70Ue0 zQ1CvFhqhZpw{S02U%ttaJO#!n+lhHS5V(c6MGO>g;vwotqj2}vxeb-^Kb=l(w~C-% z9fSdcLmD_>NEg3S@(AHFsAJ(W@Z7`WN4>bXp)=RL`Nm?8Wo^I<_mgSkRuRzioPvQU z7lwC2U^$jnuBoM{!|>17#}QL^4*jzcw<<#tpK42?+eGbvQ};>+pDiaH9Yfz<0kQ2A z;qGHmMek=wD$Uu3P*?YG4Q$gkgepMb#s1sDem>fTAd?~_e&k)bE~FcXGv~kVq7RJL zjeBYgu5)7tT(TFXG<0rjP 1W+#t$x11L&6=~k=I3HTDQ#|h*cw3HPS$duSIE&^y8{@0^>c*$M9*^~wcVKRx z+HE6$T&vQ2eK&&pO38V*DoXKrH{Sw<6fAsyWip>|-@xA{fYTFacyk7}CvR DU)ys2F(dF-0F2?ZgS}2f4>Ze9h#a zU@!Qx_!`I!&AP)uOzW*!=;(0-M03GI;}fC*V%%70zzOl5*aW@vKPP~KD=VN+ibkRW z9>(*-Ar}j+Jt+djP&|B&hXGkG7Ie$QzQr;bvQpt|kii_SC@^T2&F$xu>zbxLDh_w9 z+uA8tP1C-IH$b~nXloxH2JyoRJWS+=d_26v4@2>=^OOh+FdPlMv3H-r;9{HP?@7Qb zwCgVV{*0(8e*NhtRXZ)3i(?m)DCx8qCIZ%k)0We4b$$Q0w~O(~iH}jwZk@G@9)FGU zmu}u%bO!c;a~F~*{)`yXCh{Xj*1gaVb`Fq}Yy|=iPovFR(!BnOP&Dmpw@SDYi6Lc? zh@?*62v70tcRD6M4OZ)*eW7pA1rCo4?e`ce`auNxWW_Pza|l>8<%Tb73>%Dq+k%R| z6g`#CimBaMMAd7TVUS+#S +?V-w_y80 zR+`qb38~+Sf2uXe >N+cE{QQhJ)cB#F5?aoLUVa2)u+*|OQLSY&X6upoaSB U9znJ8t=1#*Q}RS2Ak?pR)WOVRNoVP^0ff zOXW~E8uq;y?EmHiXY2svEd~N-#Wr-~djzNS{W6JGUlnn5<_eGuoJv1j0mvS|P?f9b zeH!Mm@l{bnWSx=48q?UT2q)NhG0nM(6;x4A?V=1@O}}16y>|B*l^WFKn($U?-lybi zqJE>2l{3pS3Oy-ZxbNyhT>_?{Be25K Iv^qTT7NN*!l}& sY$e3QD~0Ag<+aYpRN1>yAb4G~lpkz4 1bH$Q(SVycFg^Z+CgWFB z!B~Na8q$|Hg_k;RIot<+)|%H=Qh(;jh*BEXqIQ}{4IW-7A>;n>@8 qocMPDdHalk_!1s6kAMC@&4}e+ zXQblHz3c|#PE&4(2-;XA+El)5*Ktbv{V6zI`gfc*?lEu@_Ha6JtNgU?{`Z>Sd}h?F zH!GYzybXpN5=g0cL=FGdzw<)&fRe)yQik(l)}H<4F-^K7npNxr?IE)R^G_i5(|1HQ zapimjUA+UMJrLiBs@@d`^8#IEnZiA|H^ZFW8V^jME5VkZHVj8(_jxiOCkOa00lZe! z<}n{Yjkn8X-cFZ!+h68wvwVY36n4DAQ=t5UqlMeW_SAa_n Af{?~#udKc5t~I(W$;|#L$5hDB%*&|lZ^E}_1wGl8=yHz(p0kfPHoB-x?banO z?|h++FFm+Aysq*$(klzA)o?Gd)!aLfwSCiXIFGA~FXBp6r%lndO&96b@1kzoKIpyU zhPDm*ODLk)!O~Z|htF{F@#4z*QlZ~C4?E5fY5TLN`ya5EwVg_Ne_-F+dx4hzA^g>q z7tqS>H!J$Ip28+wZ|e~~$iH!~PP(liJa8?5#zbP+^&^Em;5dNK+m}V24-p@7jfU0v z k){KT2eKjisRIWaPk=SPy`2i?!$2NRf-n&PV(fu?sJ7* zCJOk1K@@%bQ214*?-blD_SW`RqvbW+{PH@2X=x*oSPu9J7$zBbl}~sa9HA$jy>a%U zu{O3OH@L+HK*MNDg5p=dkO+qu_!9W*Kryw&uLf$f8p~KV`dq4<^4GU$G#1k0NDIpJ z(gId=Vk8_Ta$U6VxCE|$BQi)S9Ykho`;ktbQ@p&~>wC!UI792bE}8cHDT2hIJy|sH zZq0x^qpta0apzJGzznUco-RF%3=5^xWwlrKlpDeKa5dHlfbph$4CTSh{Do5^`SD{H zK8D8f zN{FtS22wT_{cYOf46H;XK(GdD%d0tK%zA;x2HsEU%@lLo)W9A z!(>{Ibi}msg?b+OCb)qMJ U(j*T$orpV(c`~FWQ!)>I1i99bRL zTc*4AH3(ZSvn^|RnFNP~ekK>^U|TL|gl}+pLw(`Rd#>GvFQ3wqzeOv>`ZZnr8&O_+ zeNB}fAxz-FWeP<<5^Y;eaD(A`x2=<}bzcJaIP!hm4*yubOVWGv67*;9;vMQ5^R#5> z_l@hD!j;xO5~CV8DY61f6