public inbox for [email protected]  
help / color / mirror / Atom feed
[pgAdmin][RM4818] Unable to handle loss of connection to server
7+ messages / 2 participants
[nested] [flat]

* [pgAdmin][RM4818] Unable to handle loss of connection to server
@ 2019-11-14 06:44 Aditya Toshniwal <[email protected]>
  2019-11-15 09:04 ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
  0 siblings, 1 reply; 7+ messages in thread

From: Aditya Toshniwal @ 2019-11-14 06:44 UTC (permalink / raw)
  To: pgadmin-hackers

Hi Hackers,

Attached is the workaround patch to set the default connection timeout to
30 seconds instead of the current value of infinite - 0, zero. The input is
present in the server properties dialogs advanced tab. The workaround
applies to the RM4724 as well.
The permanent solution would be to expand the nodes asynchronously -
https://redmine.postgresql.org/issues/4933

Also fixed a bug where sql editor is not closing if the server is
disconnected in between.

Kindly review.

-- 
Thanks and Regards,
Aditya Toshniwal
Sr. Software Engineer | EnterpriseDB India | Pune
"Don't Complain about Heat, Plant a TREE"


Attachments:

  [application/x-patch] RM4818.patch (8.1K, 3-RM4818.patch)
  download | inline diff:
diff --git a/web/migrations/versions/aff1436e3c8c_.py b/web/migrations/versions/aff1436e3c8c_.py
new file mode 100644
index 000000000..b5952418b
--- /dev/null
+++ b/web/migrations/versions/aff1436e3c8c_.py
@@ -0,0 +1,27 @@
+
+""" Update the default timeout to 30 seconds instead on 0.
+0 indicates wait indefinitely which causes trouble when network connection
+to server is lost.
+
+Revision ID: aff1436e3c8c
+Revises: a77a0932a568
+Create Date: 2019-10-28 12:47:36.828709
+
+"""
+from pgadmin.model import db
+
+# revision identifiers, used by Alembic.
+revision = 'aff1436e3c8c'
+down_revision = 'a77a0932a568'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    db.engine.execute(
+        'UPDATE server SET connect_timeout=30 WHERE connect_timeout=0 OR connect_timeout IS NULL'
+    )
+
+
+def downgrade():
+    pass
diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py
index dc39a1393..72f9e11a8 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -28,6 +28,7 @@ from pgadmin.model import db, Server, ServerGroup, User
 from pgadmin.utils.driver import get_driver
 from pgadmin.utils.master_password import get_crypt_key
 from pgadmin.utils.exception import CryptKeyMissing
+from psycopg2 import OperationalError
 
 
 def has_any(data, keys):
@@ -128,12 +129,20 @@ class ServerModule(sg.ServerGroupPluginModule):
             except CryptKeyMissing:
                 # show the nodes at least even if not able to connect.
                 pass
+            except OperationalError as e:
+                current_app.logger.exception(e)
+                connected = False
 
             in_recovery = None
             wal_paused = None
 
             if connected:
-                in_recovery, wal_paused = recovery_state(conn, manager.version)
+                try:
+                    in_recovery, wal_paused = recovery_state(conn, manager.version)
+                except OperationalError as e:
+                    current_app.logger.exception(e)
+                    connected = False
+
             yield self.generate_browser_node(
                 "%d" % (server.id),
                 gid,
diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js
index 99fed949e..99297d4da 100644
--- a/web/pgadmin/browser/server_groups/servers/static/js/server.js
+++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js
@@ -732,7 +732,7 @@ define('pgadmin.node.server', [
           tunnel_password: undefined,
           tunnel_authentication: 0,
           save_tunnel_password: false,
-          connect_timeout: 0,
+          connect_timeout: 30,
         },
         // Default values!
         initialize: function(attrs, args) {
diff --git a/web/pgadmin/model/__init__.py b/web/pgadmin/model/__init__.py
index 629e98f37..b22868fbb 100644
--- a/web/pgadmin/model/__init__.py
+++ b/web/pgadmin/model/__init__.py
@@ -29,7 +29,7 @@ from flask_sqlalchemy import SQLAlchemy
 #
 ##########################################################################
 
-SCHEMA_VERSION = 23
+SCHEMA_VERSION = 24
 
 ##########################################################################
 #
diff --git a/web/pgadmin/static/js/sqleditor/execute_query.js b/web/pgadmin/static/js/sqleditor/execute_query.js
index f714c2b50..63ad7721b 100644
--- a/web/pgadmin/static/js/sqleditor/execute_query.js
+++ b/web/pgadmin/static/js/sqleditor/execute_query.js
@@ -12,6 +12,7 @@ import $ from 'jquery';
 import url_for from '../url_for';
 import axios from 'axios';
 import * as httpErrorHandler from './query_tool_http_error_handler';
+import * as queryTxnStatus from 'sources/sqleditor/query_txn_status_constants';
 
 class LoadingScreen {
   constructor(sqlEditor) {
@@ -83,7 +84,8 @@ class ExecuteQuery {
           self.loadingScreen.hide();
           self.enableSQLEditorButtons();
           // Enable/Disable commit and rollback button.
-          if (result.data.data.transaction_status == 2 || result.data.data.transaction_status == 3) {
+          if (result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
+            || result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
             self.enableTransactionButtons();
           } else {
             self.disableTransactionButtons();
@@ -123,7 +125,8 @@ class ExecuteQuery {
         self.updateSqlEditorLastTransactionStatus(httpMessage.data.data.transaction_status);
 
         // Enable/Disable commit and rollback button.
-        if (httpMessage.data.data.transaction_status == 2 || httpMessage.data.data.transaction_status == 3) {
+        if (httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
+          || httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
           self.enableTransactionButtons();
         } else {
           self.disableTransactionButtons();
@@ -131,7 +134,7 @@ class ExecuteQuery {
 
         if (ExecuteQuery.isQueryFinished(httpMessage)) {
           if (this.sqlServerObject.close_on_idle_transaction &&
-              httpMessage.data.data.transaction_status == 0)
+              httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_IDLE)
             this.sqlServerObject.check_needed_confirmations_before_closing_panel();
 
           self.loadingScreen.setMessage('Loading data from the database server and rendering...');
diff --git a/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js b/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
new file mode 100644
index 000000000..075264296
--- /dev/null
+++ b/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
@@ -0,0 +1,11 @@
+/* psycopg2 transaction status constants
+ * http://initd.org/psycopg/docs/extensions.html#transaction-status-constants
+ */
+
+module.exports = {
+  TRANSACTION_STATUS_IDLE: 0,
+  TRANSACTION_STATUS_ACTIVE: 1,
+  TRANSACTION_STATUS_INTRANS: 2,
+  TRANSACTION_STATUS_INERROR: 3,
+  TRANSACTION_STATUS_UNKNOWN: 5,
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index 70d4bd348..5512382d4 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -36,6 +36,7 @@ define('tools.querytool', [
   'sources/sqleditor/calculate_query_run_time',
   'sources/sqleditor/call_render_after_poll',
   'sources/sqleditor/query_tool_preferences',
+  'sources/sqleditor/query_txn_status_constants',
   'sources/csrf',
   'tools/datagrid/static/js/datagrid_panel_title',
   'sources/window',
@@ -52,7 +53,7 @@ define('tools.querytool', [
   XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, httpErrorHandler, FilterHandler,
   GeometryViewer, historyColl, queryHist, querySources,
   keyboardShortcuts, queryToolActions, queryToolNotifications, Datagrid,
-  modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, csrfToken, panelTitleFunc,
+  modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, queryTxnStatus, csrfToken, panelTitleFunc,
   pgWindow) {
   /* Return back, this has been called more than once */
   if (pgAdmin.SqlEditor)
@@ -4178,8 +4179,9 @@ define('tools.querytool', [
           self.unsaved_changes_user_confirmation(msg, false);
         } // If a transaction is currently ongoing
         else if (self.preferences.prompt_commit_transaction
-                 && self.last_transaction_status > 0) { // 0 -> idle (no transaction)
-          var is_commit_disabled = self.last_transaction_status == 3;  // 3 -> Failed transaction
+                 && (self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INTRANS
+                    || self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INERROR)) {
+          var is_commit_disabled = self.last_transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR;
           self.uncommitted_transaction_user_confirmation(is_commit_disabled);
         }
         else {


^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: [pgAdmin][RM4818] Unable to handle loss of connection to server
  2019-11-14 06:44 [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
@ 2019-11-15 09:04 ` Akshay Joshi <[email protected]>
  2019-11-21 06:20   ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  0 siblings, 1 reply; 7+ messages in thread

From: Akshay Joshi @ 2019-11-15 09:04 UTC (permalink / raw)
  To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers

Hi Aditya

Following are the review comments:

   1. The default connection timeout should be *10* seconds.
   2. In case the network is disabled and when we expand the "Servers" node
   the database server(for which network is disabled) should be shown in the
   disconnected state.
   3.  For the above case when you try to connect to the server and at the
   same time trying to fetch the properties of the valid database server, it
   takes long time to fetch it.
   4.  Case when the network is disabled, the database servers password is
   saved and pgAdmin4 tries to connect the server, after connection timeout,
   there is no message to the user, only spinner gets disappeared. We should
   show a message.
   5. We should improve the error messages "timeout expired" and
   "Connection to the servers has been lost." to the more meaningful messages
   like "Check the network settings, check the firewall status."
   6. Install database server on Windows and Enable Windows Firewall. Try
   to connect to the same database server. Spinner is not showing, as a user I
   am not able to understand is there any action started at the backend or
   not. As a user, I'll keep trying to connect multiple times and after the
   connection timeout of each request dialog pops up.


On Thu, Nov 14, 2019 at 12:15 PM Aditya Toshniwal <
[email protected]> wrote:

> Hi Hackers,
>
> Attached is the workaround patch to set the default connection timeout to
> 30 seconds instead of the current value of infinite - 0, zero. The input is
> present in the server properties dialogs advanced tab. The workaround
> applies to the RM4724 as well.
> The permanent solution would be to expand the nodes asynchronously -
> https://redmine.postgresql.org/issues/4933
>
> Also fixed a bug where sql editor is not closing if the server is
> disconnected in between.
>
> Kindly review.
>
> --
> Thanks and Regards,
> Aditya Toshniwal
> Sr. Software Engineer | EnterpriseDB India | Pune
> "Don't Complain about Heat, Plant a TREE"
>


-- 
*Thanks & Regards*
*Akshay Joshi*

*Sr. Software Architect*
*EnterpriseDB Software India Private Limited*
*Mobile: +91 976-788-8246*


^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: [pgAdmin][RM4818] Unable to handle loss of connection to server
  2019-11-14 06:44 [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-15 09:04 ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
@ 2019-11-21 06:20   ` Aditya Toshniwal <[email protected]>
  2019-11-21 06:28     ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  0 siblings, 1 reply; 7+ messages in thread

From: Aditya Toshniwal @ 2019-11-21 06:20 UTC (permalink / raw)
  To: pgadmin-hackers; +Cc: Akshay Joshi <[email protected]>

Hi Hackers,

Attached is the updated patch to fix the review comments.
Please note, there is some problem with psycopg2/libpq where it hangs when
network is lost - https://github.com/psycopg/psycopg2/issues/561
I've also changed the code to make connections after the "Servers" node is
expanded to fix - RM4933, so that the servers are listed first.

Kindly review.

On Fri, Nov 15, 2019 at 2:34 PM Akshay Joshi <[email protected]>
wrote:

> Hi Aditya
>
> Following are the review comments:
>
>    1. The default connection timeout should be *10* seconds.
>    2. In case the network is disabled and when we expand the "Servers"
>    node the database server(for which network is disabled) should be shown in
>    the disconnected state.
>    3.  For the above case when you try to connect to the server and at
>    the same time trying to fetch the properties of the valid database server,
>    it takes long time to fetch it.
>    4.  Case when the network is disabled, the database servers password
>    is saved and pgAdmin4 tries to connect the server, after connection
>    timeout, there is no message to the user, only spinner gets disappeared. We
>    should show a message.
>    5. We should improve the error messages "timeout expired" and
>    "Connection to the servers has been lost." to the more meaningful messages
>    like "Check the network settings, check the firewall status."
>    6. Install database server on Windows and Enable Windows Firewall. Try
>    to connect to the same database server. Spinner is not showing, as a user I
>    am not able to understand is there any action started at the backend or
>    not. As a user, I'll keep trying to connect multiple times and after the
>    connection timeout of each request dialog pops up.
>
>
> On Thu, Nov 14, 2019 at 12:15 PM Aditya Toshniwal <
> [email protected]> wrote:
>
>> Hi Hackers,
>>
>> Attached is the workaround patch to set the default connection timeout to
>> 30 seconds instead of the current value of infinite - 0, zero. The input is
>> present in the server properties dialogs advanced tab. The workaround
>> applies to the RM4724 as well.
>> The permanent solution would be to expand the nodes asynchronously -
>> https://redmine.postgresql.org/issues/4933
>>
>> Also fixed a bug where sql editor is not closing if the server is
>> disconnected in between.
>>
>> Kindly review.
>>
>> --
>> Thanks and Regards,
>> Aditya Toshniwal
>> Sr. Software Engineer | EnterpriseDB India | Pune
>> "Don't Complain about Heat, Plant a TREE"
>>
>
>
> --
> *Thanks & Regards*
> *Akshay Joshi*
>
> *Sr. Software Architect*
> *EnterpriseDB Software India Private Limited*
> *Mobile: +91 976-788-8246*
>


-- 
Thanks and Regards,
Aditya Toshniwal
Sr. Software Engineer | EnterpriseDB India | Pune
"Don't Complain about Heat, Plant a TREE"


Attachments:

  [application/octet-stream] RM4818_v2.patch (30.4K, 3-RM4818_v2.patch)
  download | inline diff:
diff --git a/web/migrations/versions/aff1436e3c8c_.py b/web/migrations/versions/aff1436e3c8c_.py
new file mode 100644
index 000000000..45cfb9b3d
--- /dev/null
+++ b/web/migrations/versions/aff1436e3c8c_.py
@@ -0,0 +1,27 @@
+
+""" Update the default timeout to 30 seconds instead on 0.
+0 indicates wait indefinitely which causes trouble when network connection
+to server is lost.
+
+Revision ID: aff1436e3c8c
+Revises: a77a0932a568
+Create Date: 2019-10-28 12:47:36.828709
+
+"""
+from pgadmin.model import db
+
+# revision identifiers, used by Alembic.
+revision = 'aff1436e3c8c'
+down_revision = 'a77a0932a568'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    db.engine.execute(
+        'UPDATE server SET connect_timeout=10 WHERE connect_timeout=0 OR connect_timeout IS NULL'
+    )
+
+
+def downgrade():
+    pass
diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py
index dc39a1393..6b6ae4c53 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -28,6 +28,7 @@ from pgadmin.model import db, Server, ServerGroup, User
 from pgadmin.utils.driver import get_driver
 from pgadmin.utils.master_password import get_crypt_key
 from pgadmin.utils.exception import CryptKeyMissing
+from psycopg2 import Error as psycopg2_Error
 
 
 def has_any(data, keys):
@@ -58,7 +59,7 @@ def recovery_state(connection, postgres_version):
     else:
         in_recovery = None
         wal_paused = None
-    return in_recovery, wal_paused
+    return status, result, in_recovery, wal_paused
 
 
 def server_icon_and_background(is_connected, manager, server):
@@ -121,19 +122,21 @@ class ServerModule(sg.ServerGroupPluginModule):
         for server in servers:
             connected = False
             manager = None
+            errmsg = None
+            was_connected = False
+            in_recovery = None
+            wal_paused = None
             try:
                 manager = driver.connection_manager(server.id)
                 conn = manager.connection()
-                connected = conn.connected()
+                was_connected = conn.wasConnected
             except CryptKeyMissing:
                 # show the nodes at least even if not able to connect.
                 pass
+            except psycopg2_Error as e:
+                current_app.logger.exception(e)
+                errmsg = str(e)
 
-            in_recovery = None
-            wal_paused = None
-
-            if connected:
-                in_recovery, wal_paused = recovery_state(conn, manager.version)
             yield self.generate_browser_node(
                 "%d" % (server.id),
                 gid,
@@ -151,7 +154,9 @@ class ServerModule(sg.ServerGroupPluginModule):
                 is_password_saved=True if server.password is not None
                 else False,
                 is_tunnel_password_saved=True
-                if server.tunnel_password is not None else False
+                if server.tunnel_password is not None else False,
+                was_connected=was_connected,
+                errmsg=errmsg
             )
 
     @property
@@ -352,12 +357,16 @@ class ServerNode(PGChildNodeView):
             manager = driver.connection_manager(server.id)
             conn = manager.connection()
             connected = conn.connected()
-
+            errmsg = None
+            in_recovery = None
+            wal_paused = None
             if connected:
-                in_recovery, wal_paused = recovery_state(conn, manager.version)
-            else:
-                in_recovery = None
-                wal_paused = None
+                status, result, in_recovery, wal_paused =\
+                    recovery_state(conn, manager.version)
+                if not status:
+                    connected = False
+                    manager.release()
+                    errmsg = "{0} : {1}".format(server.name, result)
 
             res.append(
                 self.blueprint.generate_browser_node(
@@ -377,7 +386,8 @@ class ServerNode(PGChildNodeView):
                     is_password_saved=True if server.password is not None
                     else False,
                     is_tunnel_password_saved=True
-                    if server.tunnel_password is not None else False
+                    if server.tunnel_password is not None else False,
+                    errmsg=errmsg
                 )
             )
 
@@ -409,12 +419,16 @@ class ServerNode(PGChildNodeView):
         manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(server.id)
         conn = manager.connection()
         connected = conn.connected()
-
+        errmsg = None
+        in_recovery = None
+        wal_paused = None
         if connected:
-            in_recovery, wal_paused = recovery_state(conn, manager.version)
-        else:
-            in_recovery = None
-            wal_paused = None
+            status, result, in_recovery, wal_paused =\
+                recovery_state(conn, manager.version)
+            if not status:
+                connected = False
+                manager.release()
+                errmsg = "{0} : {1}".format(server.name, result)
 
         return make_json_response(
             result=self.blueprint.generate_browser_node(
@@ -434,8 +448,9 @@ class ServerNode(PGChildNodeView):
                 is_password_saved=True if server.password is not None
                 else False,
                 is_tunnel_password_saved=True
-                if server.tunnel_password is not None else False
-            )
+                if server.tunnel_password is not None else False,
+                errmsg=errmsg
+            ),
         )
 
     @login_required
@@ -949,19 +964,33 @@ class ServerNode(PGChildNodeView):
 
     def connect_status(self, gid, sid):
         """Check and return the connection status."""
+        server = Server.query.filter_by(id=sid).first()
         manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
         conn = manager.connection()
-        res = conn.connected()
+        connected = conn.connected()
+        in_recovery = None
+        wal_paused = None
+        errmsg = None
+        if connected:
+            status, result, in_recovery, wal_paused =\
+                recovery_state(conn, manager.version)
 
-        if res:
-            from pgadmin.utils.exception import ConnectionLost, \
-                SSHTunnelConnectionLost
-            try:
-                conn.execute_scalar('SELECT 1')
-            except (ConnectionLost, SSHTunnelConnectionLost):
-                res = False
+            if not status:
+                connected = False
+                manager.release()
+                errmsg = "{0} : {1}".format(server.name, result)
 
-        return make_json_response(data={'connected': res})
+        return make_json_response(
+            data={
+                'icon': server_icon_and_background(connected, manager, server),
+                'connected': connected,
+                'in_recovery': in_recovery,
+                'wal_pause': wal_paused,
+                'server_type': manager.server_type if connected else "pg",
+                'user': manager.user_info if connected else None,
+                'errmsg': errmsg
+            }
+        )
 
     def connect(self, gid, sid):
         """
@@ -1125,7 +1154,8 @@ class ServerNode(PGChildNodeView):
                 %s - %s' % (server.id, server.name))
             # Update the recovery and wal pause option for the server
             # if connected successfully
-            in_recovery, wal_paused = recovery_state(conn, manager.version)
+            _, _, in_recovery, wal_paused =\
+                recovery_state(conn, manager.version)
 
             return make_json_response(
                 success=1,
diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js
index 99fed949e..08364783e 100644
--- a/web/pgadmin/browser/server_groups/servers/static/js/server.js
+++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js
@@ -292,6 +292,10 @@ define('pgadmin.node.server', [
 
           // Call added method of node.js
           pgAdmin.Browser.Node.callbacks.added.apply(this, arguments);
+
+          if(data.was_connected) {
+            fetch_connection_status(this, data, pgBrowser.tree, item);
+          }
           return true;
         },
         /* Reload configuration */
@@ -732,7 +736,7 @@ define('pgadmin.node.server', [
           tunnel_password: undefined,
           tunnel_authentication: 0,
           save_tunnel_password: false,
-          connect_timeout: 0,
+          connect_timeout: 10,
         },
         // Default values!
         initialize: function(attrs, args) {
@@ -1273,7 +1277,14 @@ define('pgadmin.node.server', [
         }
       };
 
+      /* Wait till the existing request completes */
+      if(data.is_connecting) {
+        return;
+      }
       data.is_connecting = true;
+      tree.setLeaf(item);
+      tree.removeIcon(item);
+      tree.addIcon(item, {icon: 'icon-server-connecting'});
       var url = obj.generate_url(item, 'connect', data, true);
       $.post(url)
         .done(function(res) {
@@ -1289,6 +1300,37 @@ define('pgadmin.node.server', [
           );
         });
     };
+    var fetch_connection_status = function(obj, data, tree, item) {
+      var url = obj.generate_url(item, 'connect', data, true);
+
+      tree.setLeaf(item);
+      tree.removeIcon(item);
+      tree.addIcon(item, {icon: 'icon-server-connecting'});
+      $.get(url)
+        .done(function(res) {
+          tree.setInode(item);
+          if (res && res.data) {
+            if (typeof res.data.icon == 'string') {
+              tree.removeIcon(item);
+              data.icon = res.data.icon;
+              tree.addIcon(item, {icon: data.icon});
+            }
+            _.extend(data, res.data);
+
+            var serverInfo = pgBrowser.serverInfo = pgBrowser.serverInfo || {};
+            serverInfo[data._id] = _.extend({}, data);
+
+            if(data.errmsg) {
+              Alertify.error(data.errmsg);
+            }
+          }
+        })
+        .fail(function(xhr, status, error) {
+          tree.setInode(item);
+          tree.addIcon(item, {icon: 'icon-server-not-connected'});
+          Alertify.pgRespErrorNotify(xhr, error);
+        });
+    };
   }
 
   return pgBrowser.Nodes['server'];
diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py
index 2a17b3a2d..67dce0942 100644
--- a/web/pgadmin/browser/utils.py
+++ b/web/pgadmin/browser/utils.py
@@ -17,7 +17,8 @@ from flask.views import View, MethodViewType, with_metaclass
 from flask_babelex import gettext
 
 from config import PG_DEFAULT_DRIVER
-from pgadmin.utils.ajax import make_json_response, precondition_required
+from pgadmin.utils.ajax import make_json_response, precondition_required,\
+    internal_server_error
 from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost,\
     CryptKeyMissing
 
@@ -377,11 +378,7 @@ class PGChildNodeView(NodeView):
             if not conn.connected():
                 status, msg = conn.connect()
                 if not status:
-                    return precondition_required(
-                        gettext(
-                            "Connection to the server has been lost."
-                        )
-                    )
+                    return internal_server_error(errormsg=msg)
         except (ConnectionLost, SSHTunnelConnectionLost, CryptKeyMissing):
             raise
         except Exception as e:
diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js
index 42d2eca4b..6e466052a 100644
--- a/web/pgadmin/dashboard/static/js/dashboard.js
+++ b/web/pgadmin/dashboard/static/js/dashboard.js
@@ -543,6 +543,7 @@ define('pgadmin.dashboard', [
       );
       const WAIT_COUNTER = 3;
       let last_poll_wait_counter = 0;
+      let resp_not_received_counter = 0;
 
       /* Stop if running, only one poller lives */
       self.stopChartsPoller();
@@ -563,7 +564,7 @@ define('pgadmin.dashboard', [
         /* If none of the chart wants data, don't trouble
          * If response not received from prev poll, don't trouble !!
          */
-        if(chart_names_to_get.length == 0 || last_poll_wait_counter > 0) {
+        if(chart_names_to_get.length == 0 || last_poll_wait_counter > 0 || resp_not_received_counter >= WAIT_COUNTER) {
           /* reduce the number of tries, request should be sent if last_poll_wait_counter
            * completes WAIT_COUNTER times.*/
           last_poll_wait_counter--;
@@ -571,12 +572,12 @@ define('pgadmin.dashboard', [
         }
 
         var path = self.getStatsUrl(sid, did, chart_names_to_get);
+        resp_not_received_counter++;
         $.ajax({
           url: path,
           type: 'GET',
         })
           .done(function(resp) {
-            last_poll_wait_counter = 0;
             for(let chart_name in resp) {
               let chart_obj = chart_store[chart_name].chart_obj;
               $(chart_obj.getContainer()).removeClass('graph-error');
@@ -584,7 +585,6 @@ define('pgadmin.dashboard', [
             }
           })
           .fail(function(xhr) {
-            last_poll_wait_counter = 0;
             let err = '';
             let msg = '';
             let cls = 'info';
@@ -613,6 +613,10 @@ define('pgadmin.dashboard', [
                 '<div class="alert alert-' + cls + ' pg-panel-message" role="alert">' + msg + '</div>'
               );
             }
+          })
+          .always(function() {
+            last_poll_wait_counter = 0;
+            resp_not_received_counter--;
           });
         last_poll_wait_counter = WAIT_COUNTER;
       };
diff --git a/web/pgadmin/model/__init__.py b/web/pgadmin/model/__init__.py
index 629e98f37..b22868fbb 100644
--- a/web/pgadmin/model/__init__.py
+++ b/web/pgadmin/model/__init__.py
@@ -29,7 +29,7 @@ from flask_sqlalchemy import SQLAlchemy
 #
 ##########################################################################
 
-SCHEMA_VERSION = 23
+SCHEMA_VERSION = 24
 
 ##########################################################################
 #
diff --git a/web/pgadmin/static/js/sqleditor/execute_query.js b/web/pgadmin/static/js/sqleditor/execute_query.js
index f714c2b50..63ad7721b 100644
--- a/web/pgadmin/static/js/sqleditor/execute_query.js
+++ b/web/pgadmin/static/js/sqleditor/execute_query.js
@@ -12,6 +12,7 @@ import $ from 'jquery';
 import url_for from '../url_for';
 import axios from 'axios';
 import * as httpErrorHandler from './query_tool_http_error_handler';
+import * as queryTxnStatus from 'sources/sqleditor/query_txn_status_constants';
 
 class LoadingScreen {
   constructor(sqlEditor) {
@@ -83,7 +84,8 @@ class ExecuteQuery {
           self.loadingScreen.hide();
           self.enableSQLEditorButtons();
           // Enable/Disable commit and rollback button.
-          if (result.data.data.transaction_status == 2 || result.data.data.transaction_status == 3) {
+          if (result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
+            || result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
             self.enableTransactionButtons();
           } else {
             self.disableTransactionButtons();
@@ -123,7 +125,8 @@ class ExecuteQuery {
         self.updateSqlEditorLastTransactionStatus(httpMessage.data.data.transaction_status);
 
         // Enable/Disable commit and rollback button.
-        if (httpMessage.data.data.transaction_status == 2 || httpMessage.data.data.transaction_status == 3) {
+        if (httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
+          || httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
           self.enableTransactionButtons();
         } else {
           self.disableTransactionButtons();
@@ -131,7 +134,7 @@ class ExecuteQuery {
 
         if (ExecuteQuery.isQueryFinished(httpMessage)) {
           if (this.sqlServerObject.close_on_idle_transaction &&
-              httpMessage.data.data.transaction_status == 0)
+              httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_IDLE)
             this.sqlServerObject.check_needed_confirmations_before_closing_panel();
 
           self.loadingScreen.setMessage('Loading data from the database server and rendering...');
diff --git a/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js b/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
new file mode 100644
index 000000000..075264296
--- /dev/null
+++ b/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
@@ -0,0 +1,11 @@
+/* psycopg2 transaction status constants
+ * http://initd.org/psycopg/docs/extensions.html#transaction-status-constants
+ */
+
+module.exports = {
+  TRANSACTION_STATUS_IDLE: 0,
+  TRANSACTION_STATUS_ACTIVE: 1,
+  TRANSACTION_STATUS_INTRANS: 2,
+  TRANSACTION_STATUS_INERROR: 3,
+  TRANSACTION_STATUS_UNKNOWN: 5,
+};
diff --git a/web/pgadmin/static/js/tree/tree.js b/web/pgadmin/static/js/tree/tree.js
index 33397e80d..e317aeb81 100644
--- a/web/pgadmin/static/js/tree/tree.js
+++ b/web/pgadmin/static/js/tree/tree.js
@@ -9,6 +9,7 @@
 
 import {isValidData} from 'sources/utils';
 import $ from 'jquery';
+import Alertify from 'pgadmin.alertifyjs';
 
 export class TreeNode {
   constructor(id, data, domNode, parent) {
@@ -261,6 +262,9 @@ export class Tree {
 
           const parentId = this.translateTreeNodeIdFromACITree(api.parent(item));
           this.addNewNode(id, data, item, parentId);
+          if(data.errmsg) {
+            Alertify.error(data.errmsg);
+          }
         }
       }
     }.bind(this));
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index 9d9ab5c84..8f5897f3f 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -36,6 +36,7 @@ define('tools.querytool', [
   'sources/sqleditor/calculate_query_run_time',
   'sources/sqleditor/call_render_after_poll',
   'sources/sqleditor/query_tool_preferences',
+  'sources/sqleditor/query_txn_status_constants',
   'sources/csrf',
   'tools/datagrid/static/js/datagrid_panel_title',
   'sources/window',
@@ -52,7 +53,7 @@ define('tools.querytool', [
   XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, httpErrorHandler, FilterHandler,
   GeometryViewer, historyColl, queryHist, querySources,
   keyboardShortcuts, queryToolActions, queryToolNotifications, Datagrid,
-  modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, csrfToken, panelTitleFunc,
+  modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, queryTxnStatus, csrfToken, panelTitleFunc,
   pgWindow) {
   /* Return back, this has been called more than once */
   if (pgAdmin.SqlEditor)
@@ -4182,8 +4183,9 @@ define('tools.querytool', [
           self.unsaved_changes_user_confirmation(msg, false);
         } // If a transaction is currently ongoing
         else if (self.preferences.prompt_commit_transaction
-                 && self.last_transaction_status > 0) { // 0 -> idle (no transaction)
-          var is_commit_disabled = self.last_transaction_status == 3;  // 3 -> Failed transaction
+                 && (self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INTRANS
+                    || self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INERROR)) {
+          var is_commit_disabled = self.last_transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR;
           self.uncommitted_transaction_user_confirmation(is_commit_disabled);
         }
         else {
diff --git a/web/pgadmin/utils/driver/psycopg2/__init__.py b/web/pgadmin/utils/driver/psycopg2/__init__.py
index 4b3e2204b..94dc2976c 100644
--- a/web/pgadmin/utils/driver/psycopg2/__init__.py
+++ b/web/pgadmin/utils/driver/psycopg2/__init__.py
@@ -14,19 +14,21 @@ object.
 
 """
 import datetime
-from flask import session, request
+from flask import session
 from flask_login import current_user
-from flask_babelex import gettext
 import psycopg2
 from psycopg2.extensions import adapt
+from threading import Lock
 
 import config
-from pgadmin.model import Server, User
+from pgadmin.model import Server
 from .keywords import ScanKeyword
 from ..abstract import BaseDriver
 from .connection import Connection
 from .server_manager import ServerManager
 
+connection_restore_lock = Lock()
+
 
 class Driver(BaseDriver):
     """
@@ -80,21 +82,30 @@ class Driver(BaseDriver):
             return None
 
         if session.sid not in self.managers:
-            self.managers[session.sid] = managers = dict()
-            if '__pgsql_server_managers' in session:
-                session_managers = session['__pgsql_server_managers'].copy()
-
-                for server in Server.query.filter_by(user_id=current_user.id):
-                    manager = managers[str(server.id)] = ServerManager(server)
-                    if server.id in session_managers:
-                        manager._restore(session_managers[server.id])
-                        manager.update_session()
+            with connection_restore_lock:
+                # The wait is over but the object might have been loaded
+                # by some other thread check again
+                if session.sid not in self.managers:
+                    self.managers[session.sid] = managers = dict()
+                    if '__pgsql_server_managers' in session:
+                        session_managers =\
+                            session['__pgsql_server_managers'].copy()
+                        for server in \
+                                Server.query.filter_by(
+                                    user_id=current_user.id):
+                            manager = managers[str(server.id)] =\
+                                ServerManager(server)
+                            if server.id in session_managers:
+                                manager._restore(session_managers[server.id])
+                                manager.update_session()
+
         else:
             managers = self.managers[session.sid]
             if str(sid) in managers:
                 manager = managers[str(sid)]
-                manager._restore_connections()
-                manager.update_session()
+                with connection_restore_lock:
+                    manager._restore_connections()
+                    manager.update_session()
 
         managers['pinged'] = datetime.datetime.now()
         if str(sid) not in managers:
diff --git a/web/pgadmin/utils/driver/psycopg2/server_manager.py b/web/pgadmin/utils/driver/psycopg2/server_manager.py
index 8ae46c2ee..1676f7e38 100644
--- a/web/pgadmin/utils/driver/psycopg2/server_manager.py
+++ b/web/pgadmin/utils/driver/psycopg2/server_manager.py
@@ -25,13 +25,10 @@ from pgadmin.model import Server, User
 from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost,\
     CryptKeyMissing
 from pgadmin.utils.master_password import get_crypt_key
-from threading import Lock
 
 if config.SUPPORT_SSH_TUNNEL:
     from sshtunnel import SSHTunnelForwarder, BaseSSHTunnelForwarderError
 
-connection_restore_lock = Lock()
-
 
 class ServerManager(object):
     """
@@ -292,80 +289,79 @@ WHERE db.oid = {0}""".format(did))
 
         connections = data['connections']
 
-        with connection_restore_lock:
-            for conn_id in connections:
-                conn_info = connections[conn_id]
-                if conn_info['conn_id'] in self.connections:
-                    conn = self.connections[conn_info['conn_id']]
-                else:
-                    conn = self.connections[conn_info['conn_id']] = Connection(
-                        self, conn_info['conn_id'], conn_info['database'],
-                        conn_info['auto_reconnect'], conn_info['async_'],
-                        use_binary_placeholder=conn_info[
-                            'use_binary_placeholder'],
-                        array_to_string=conn_info['array_to_string']
-                    )
+        for conn_id in connections:
+            conn_info = connections[conn_id]
+            if conn_info['conn_id'] in self.connections:
+                conn = self.connections[conn_info['conn_id']]
+            else:
+                conn = self.connections[conn_info['conn_id']] = Connection(
+                    self, conn_info['conn_id'], conn_info['database'],
+                    conn_info['auto_reconnect'], conn_info['async_'],
+                    use_binary_placeholder=conn_info[
+                        'use_binary_placeholder'],
+                    array_to_string=conn_info['array_to_string']
+                )
 
-                # only try to reconnect if connection was connected previously
-                # and auto_reconnect is true.
-                if conn_info['wasConnected'] and conn_info['auto_reconnect']:
-                    try:
-                        # Check SSH Tunnel needs to be created
-                        if self.use_ssh_tunnel == 1 and \
-                           not self.tunnel_created:
-                            status, error = self.create_ssh_tunnel(
-                                data['tunnel_password'])
-
-                            # Check SSH Tunnel is alive or not.
-                            self.check_ssh_tunnel_alive()
-
-                        conn.connect(
-                            password=data['password'],
-                            server_types=ServerType.types()
-                        )
-                        # This will also update wasConnected flag in
-                        # connection so no need to update the flag manually.
-                    except CryptKeyMissing:
-                        # maintain the status as this will help to restore once
-                        # the key is available
-                        conn.wasConnected = conn_info['wasConnected']
-                        conn.auto_reconnect = conn_info['auto_reconnect']
-                    except Exception as e:
-                        current_app.logger.exception(e)
-                        self.connections.pop(conn_info['conn_id'])
-                        raise
+            # only try to reconnect if connection was connected previously
+            # and auto_reconnect is true.
+            if conn_info['wasConnected'] and conn_info['auto_reconnect']:
+                try:
+                    # Check SSH Tunnel needs to be created
+                    if self.use_ssh_tunnel == 1 and \
+                       not self.tunnel_created:
+                        status, error = self.create_ssh_tunnel(
+                            data['tunnel_password'])
+
+                        # Check SSH Tunnel is alive or not.
+                        self.check_ssh_tunnel_alive()
+
+                    conn.connect(
+                        password=data['password'],
+                        server_types=ServerType.types()
+                    )
+                    # This will also update wasConnected flag in
+                    # connection so no need to update the flag manually.
+                except CryptKeyMissing:
+                    # maintain the status as this will help to restore once
+                    # the key is available
+                    conn.wasConnected = conn_info['wasConnected']
+                    conn.auto_reconnect = conn_info['auto_reconnect']
+                except Exception as e:
+                    current_app.logger.exception(e)
+                    self.connections.pop(conn_info['conn_id'])
+                    raise
 
     def _restore_connections(self):
-        with connection_restore_lock:
-            for conn_id in self.connections:
-                conn = self.connections[conn_id]
-                # only try to reconnect if connection was connected previously
-                # and auto_reconnect is true.
-                wasConnected = conn.wasConnected
-                auto_reconnect = conn.auto_reconnect
-                if conn.wasConnected and conn.auto_reconnect:
-                    try:
-                        # Check SSH Tunnel needs to be created
-                        if self.use_ssh_tunnel == 1 and \
-                           not self.tunnel_created:
-                            status, error = self.create_ssh_tunnel(
-                                self.tunnel_password
-                            )
-
-                            # Check SSH Tunnel is alive or not.
-                            self.check_ssh_tunnel_alive()
+        for conn_id in self.connections:
+            conn = self.connections[conn_id]
+            # only try to reconnect if connection was connected previously
+            # and auto_reconnect is true.
+            wasConnected = conn.wasConnected
+            auto_reconnect = conn.auto_reconnect
+            if conn.wasConnected and conn.auto_reconnect:
+                try:
+                    # Check SSH Tunnel needs to be created
+                    if self.use_ssh_tunnel == 1 and \
+                       not self.tunnel_created:
+                        status, error = self.create_ssh_tunnel(
+                            self.tunnel_password
+                        )
 
-                        conn.connect()
-                        # This will also update wasConnected flag in
-                        # connection so no need to update the flag manually.
-                    except CryptKeyMissing:
-                        # maintain the status as this will help to restore once
-                        # the key is available
-                        conn.wasConnected = wasConnected
-                        conn.auto_reconnect = auto_reconnect
-                    except Exception as e:
-                        current_app.logger.exception(e)
-                        raise
+                        # Check SSH Tunnel is alive or not.
+                        self.check_ssh_tunnel_alive()
+
+                    conn.connect()
+                    # This will also update wasConnected flag in
+                    # connection so no need to update the flag manually.
+                except CryptKeyMissing:
+                    # maintain the status as this will help to restore once
+                    # the key is available
+                    conn.wasConnected = wasConnected
+                    conn.auto_reconnect = auto_reconnect
+                except Exception as e:
+                    self.connections.pop(conn_id)
+                    current_app.logger.exception(e)
+                    raise
 
     def release(self, database=None, conn_id=None, did=None):
         # Stop the SSH tunnel if release() function calls without


^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: [pgAdmin][RM4818] Unable to handle loss of connection to server
  2019-11-14 06:44 [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-15 09:04 ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
  2019-11-21 06:20   ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
@ 2019-11-21 06:28     ` Aditya Toshniwal <[email protected]>
  2019-11-21 11:18       ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
  0 siblings, 1 reply; 7+ messages in thread

From: Aditya Toshniwal @ 2019-11-21 06:28 UTC (permalink / raw)
  To: pgadmin-hackers; +Cc: Akshay Joshi <[email protected]>

Hi,

I forgot to mention, I've also changed the dashboard code. The dashboard
was sending graph data requests, but when the server lost connection the
requests remains pending for longer time. Because of this the server gets
flooded with lot of pending request and in turn slowing down the entire
application.
Code is changed so that only a certain number of requests remain pending
(currently 3), above which the request won't be sent.

On Thu, Nov 21, 2019 at 11:50 AM Aditya Toshniwal <
[email protected]> wrote:

> Hi Hackers,
>
> Attached is the updated patch to fix the review comments.
> Please note, there is some problem with psycopg2/libpq where it hangs when
> network is lost - https://github.com/psycopg/psycopg2/issues/561
> I've also changed the code to make connections after the "Servers" node is
> expanded to fix - RM4933, so that the servers are listed first.
>
> Kindly review.
>
> On Fri, Nov 15, 2019 at 2:34 PM Akshay Joshi <
> [email protected]> wrote:
>
>> Hi Aditya
>>
>> Following are the review comments:
>>
>>    1. The default connection timeout should be *10* seconds.
>>    2. In case the network is disabled and when we expand the "Servers"
>>    node the database server(for which network is disabled) should be shown in
>>    the disconnected state.
>>    3.  For the above case when you try to connect to the server and at
>>    the same time trying to fetch the properties of the valid database server,
>>    it takes long time to fetch it.
>>    4.  Case when the network is disabled, the database servers password
>>    is saved and pgAdmin4 tries to connect the server, after connection
>>    timeout, there is no message to the user, only spinner gets disappeared. We
>>    should show a message.
>>    5. We should improve the error messages "timeout expired" and
>>    "Connection to the servers has been lost." to the more meaningful messages
>>    like "Check the network settings, check the firewall status."
>>    6. Install database server on Windows and Enable Windows Firewall.
>>    Try to connect to the same database server. Spinner is not showing, as a
>>    user I am not able to understand is there any action started at the backend
>>    or not. As a user, I'll keep trying to connect multiple times and after the
>>    connection timeout of each request dialog pops up.
>>
>>
>> On Thu, Nov 14, 2019 at 12:15 PM Aditya Toshniwal <
>> [email protected]> wrote:
>>
>>> Hi Hackers,
>>>
>>> Attached is the workaround patch to set the default connection timeout
>>> to 30 seconds instead of the current value of infinite - 0, zero. The input
>>> is present in the server properties dialogs advanced tab. The workaround
>>> applies to the RM4724 as well.
>>> The permanent solution would be to expand the nodes asynchronously -
>>> https://redmine.postgresql.org/issues/4933
>>>
>>> Also fixed a bug where sql editor is not closing if the server is
>>> disconnected in between.
>>>
>>> Kindly review.
>>>
>>> --
>>> Thanks and Regards,
>>> Aditya Toshniwal
>>> Sr. Software Engineer | EnterpriseDB India | Pune
>>> "Don't Complain about Heat, Plant a TREE"
>>>
>>
>>
>> --
>> *Thanks & Regards*
>> *Akshay Joshi*
>>
>> *Sr. Software Architect*
>> *EnterpriseDB Software India Private Limited*
>> *Mobile: +91 976-788-8246*
>>
>
>
> --
> Thanks and Regards,
> Aditya Toshniwal
> Sr. Software Engineer | EnterpriseDB India | Pune
> "Don't Complain about Heat, Plant a TREE"
>


-- 
Thanks and Regards,
Aditya Toshniwal
Sr. Software Engineer | EnterpriseDB India | Pune
"Don't Complain about Heat, Plant a TREE"


^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: [pgAdmin][RM4818] Unable to handle loss of connection to server
  2019-11-14 06:44 [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-15 09:04 ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
  2019-11-21 06:20   ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-21 06:28     ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
@ 2019-11-21 11:18       ` Akshay Joshi <[email protected]>
  2019-11-25 07:06         ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  0 siblings, 1 reply; 7+ messages in thread

From: Akshay Joshi @ 2019-11-21 11:18 UTC (permalink / raw)
  To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers

Hi Aditya

Following are the review comments:

- Update the timeout in the comment section from 30 seconds to 10 seconds
in aff1436e3c8c_.py.
- Asking for the database server password even if it is saved. Reproduction
steps:


   - Connect to the database server, saved the password.
      - Disabled the network. Try to connect to the database server.
      - Enable the network, try to connect to the database server.

- No error/spinner visible on GUI when the database server is connected
using SSH Tunnel. Reproduction steps:


   - Connect to the database server with SSH Tunnel, saved both the
      password.
      - Disabled the network and Reset the Layout.
      - Expand the Servers node and try to connect the same database
      server.


On Thu, Nov 21, 2019 at 11:58 AM Aditya Toshniwal <
[email protected]> wrote:

> Hi,
>
> I forgot to mention, I've also changed the dashboard code. The dashboard
> was sending graph data requests, but when the server lost connection the
> requests remains pending for longer time. Because of this the server gets
> flooded with lot of pending request and in turn slowing down the entire
> application.
> Code is changed so that only a certain number of requests remain pending
> (currently 3), above which the request won't be sent.
>
> On Thu, Nov 21, 2019 at 11:50 AM Aditya Toshniwal <
> [email protected]> wrote:
>
>> Hi Hackers,
>>
>> Attached is the updated patch to fix the review comments.
>> Please note, there is some problem with psycopg2/libpq where it hangs
>> when network is lost - https://github.com/psycopg/psycopg2/issues/561
>> I've also changed the code to make connections after the "Servers" node
>> is expanded to fix - RM4933, so that the servers are listed first.
>>
>> Kindly review.
>>
>> On Fri, Nov 15, 2019 at 2:34 PM Akshay Joshi <
>> [email protected]> wrote:
>>
>>> Hi Aditya
>>>
>>> Following are the review comments:
>>>
>>>    1. The default connection timeout should be *10* seconds.
>>>    2. In case the network is disabled and when we expand the "Servers"
>>>    node the database server(for which network is disabled) should be shown in
>>>    the disconnected state.
>>>    3.  For the above case when you try to connect to the server and at
>>>    the same time trying to fetch the properties of the valid database server,
>>>    it takes long time to fetch it.
>>>    4.  Case when the network is disabled, the database servers password
>>>    is saved and pgAdmin4 tries to connect the server, after connection
>>>    timeout, there is no message to the user, only spinner gets disappeared. We
>>>    should show a message.
>>>    5. We should improve the error messages "timeout expired" and
>>>    "Connection to the servers has been lost." to the more meaningful messages
>>>    like "Check the network settings, check the firewall status."
>>>    6. Install database server on Windows and Enable Windows Firewall.
>>>    Try to connect to the same database server. Spinner is not showing, as a
>>>    user I am not able to understand is there any action started at the backend
>>>    or not. As a user, I'll keep trying to connect multiple times and after the
>>>    connection timeout of each request dialog pops up.
>>>
>>>
>>> On Thu, Nov 14, 2019 at 12:15 PM Aditya Toshniwal <
>>> [email protected]> wrote:
>>>
>>>> Hi Hackers,
>>>>
>>>> Attached is the workaround patch to set the default connection timeout
>>>> to 30 seconds instead of the current value of infinite - 0, zero. The input
>>>> is present in the server properties dialogs advanced tab. The workaround
>>>> applies to the RM4724 as well.
>>>> The permanent solution would be to expand the nodes asynchronously -
>>>> https://redmine.postgresql.org/issues/4933
>>>>
>>>> Also fixed a bug where sql editor is not closing if the server is
>>>> disconnected in between.
>>>>
>>>> Kindly review.
>>>>
>>>> --
>>>> Thanks and Regards,
>>>> Aditya Toshniwal
>>>> Sr. Software Engineer | EnterpriseDB India | Pune
>>>> "Don't Complain about Heat, Plant a TREE"
>>>>
>>>
>>>
>>> --
>>> *Thanks & Regards*
>>> *Akshay Joshi*
>>>
>>> *Sr. Software Architect*
>>> *EnterpriseDB Software India Private Limited*
>>> *Mobile: +91 976-788-8246*
>>>
>>
>>
>> --
>> Thanks and Regards,
>> Aditya Toshniwal
>> Sr. Software Engineer | EnterpriseDB India | Pune
>> "Don't Complain about Heat, Plant a TREE"
>>
>
>
> --
> Thanks and Regards,
> Aditya Toshniwal
> Sr. Software Engineer | EnterpriseDB India | Pune
> "Don't Complain about Heat, Plant a TREE"
>


-- 
*Thanks & Regards*
*Akshay Joshi*

*Sr. Software Architect*
*EnterpriseDB Software India Private Limited*
*Mobile: +91 976-788-8246*


^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: [pgAdmin][RM4818] Unable to handle loss of connection to server
  2019-11-14 06:44 [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-15 09:04 ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
  2019-11-21 06:20   ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-21 06:28     ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-21 11:18       ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
@ 2019-11-25 07:06         ` Aditya Toshniwal <[email protected]>
  2019-11-26 03:37           ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
  0 siblings, 1 reply; 7+ messages in thread

From: Aditya Toshniwal @ 2019-11-25 07:06 UTC (permalink / raw)
  To: pgadmin-hackers; +Cc: Akshay Joshi <[email protected]>

Hi Hackers,

Attached is the updated patch to fix the review comments.

On Thu, Nov 21, 2019 at 4:48 PM Akshay Joshi <[email protected]>
wrote:

> Hi Aditya
>
> Following are the review comments:
>
>
>    - Update the timeout in the comment section from 30 seconds to 10
>    seconds in aff1436e3c8c_.py.
>
>
>    - Asking for the database server password even if it is saved.
>    Reproduction steps:
>
>
>    - Connect to the database server, saved the password.
>       - Disabled the network. Try to connect to the database server.
>       - Enable the network, try to connect to the database server.
>
>
>    - No error/spinner visible on GUI when the database server is
>    connected using SSH Tunnel. Reproduction steps:
>
>
>    - Connect to the database server with SSH Tunnel, saved both the
>       password.
>       - Disabled the network and Reset the Layout.
>       - Expand the Servers node and try to connect the same database
>       server.
>
>
> On Thu, Nov 21, 2019 at 11:58 AM Aditya Toshniwal <
> [email protected]> wrote:
>
>> Hi,
>>
>> I forgot to mention, I've also changed the dashboard code. The dashboard
>> was sending graph data requests, but when the server lost connection the
>> requests remains pending for longer time. Because of this the server gets
>> flooded with lot of pending request and in turn slowing down the entire
>> application.
>> Code is changed so that only a certain number of requests remain pending
>> (currently 3), above which the request won't be sent.
>>
>> On Thu, Nov 21, 2019 at 11:50 AM Aditya Toshniwal <
>> [email protected]> wrote:
>>
>>> Hi Hackers,
>>>
>>> Attached is the updated patch to fix the review comments.
>>> Please note, there is some problem with psycopg2/libpq where it hangs
>>> when network is lost - https://github.com/psycopg/psycopg2/issues/561
>>> I've also changed the code to make connections after the "Servers" node
>>> is expanded to fix - RM4933, so that the servers are listed first.
>>>
>>> Kindly review.
>>>
>>> On Fri, Nov 15, 2019 at 2:34 PM Akshay Joshi <
>>> [email protected]> wrote:
>>>
>>>> Hi Aditya
>>>>
>>>> Following are the review comments:
>>>>
>>>>    1. The default connection timeout should be *10* seconds.
>>>>    2. In case the network is disabled and when we expand the "Servers"
>>>>    node the database server(for which network is disabled) should be shown in
>>>>    the disconnected state.
>>>>    3.  For the above case when you try to connect to the server and at
>>>>    the same time trying to fetch the properties of the valid database server,
>>>>    it takes long time to fetch it.
>>>>    4.  Case when the network is disabled, the database servers
>>>>    password is saved and pgAdmin4 tries to connect the server, after
>>>>    connection timeout, there is no message to the user, only spinner gets
>>>>    disappeared. We should show a message.
>>>>    5. We should improve the error messages "timeout expired" and
>>>>    "Connection to the servers has been lost." to the more meaningful messages
>>>>    like "Check the network settings, check the firewall status."
>>>>    6. Install database server on Windows and Enable Windows Firewall.
>>>>    Try to connect to the same database server. Spinner is not showing, as a
>>>>    user I am not able to understand is there any action started at the backend
>>>>    or not. As a user, I'll keep trying to connect multiple times and after the
>>>>    connection timeout of each request dialog pops up.
>>>>
>>>>
>>>> On Thu, Nov 14, 2019 at 12:15 PM Aditya Toshniwal <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Hackers,
>>>>>
>>>>> Attached is the workaround patch to set the default connection timeout
>>>>> to 30 seconds instead of the current value of infinite - 0, zero. The input
>>>>> is present in the server properties dialogs advanced tab. The workaround
>>>>> applies to the RM4724 as well.
>>>>> The permanent solution would be to expand the nodes asynchronously -
>>>>> https://redmine.postgresql.org/issues/4933
>>>>>
>>>>> Also fixed a bug where sql editor is not closing if the server is
>>>>> disconnected in between.
>>>>>
>>>>> Kindly review.
>>>>>
>>>>> --
>>>>> Thanks and Regards,
>>>>> Aditya Toshniwal
>>>>> Sr. Software Engineer | EnterpriseDB India | Pune
>>>>> "Don't Complain about Heat, Plant a TREE"
>>>>>
>>>>
>>>>
>>>> --
>>>> *Thanks & Regards*
>>>> *Akshay Joshi*
>>>>
>>>> *Sr. Software Architect*
>>>> *EnterpriseDB Software India Private Limited*
>>>> *Mobile: +91 976-788-8246*
>>>>
>>>
>>>
>>> --
>>> Thanks and Regards,
>>> Aditya Toshniwal
>>> Sr. Software Engineer | EnterpriseDB India | Pune
>>> "Don't Complain about Heat, Plant a TREE"
>>>
>>
>>
>> --
>> Thanks and Regards,
>> Aditya Toshniwal
>> Sr. Software Engineer | EnterpriseDB India | Pune
>> "Don't Complain about Heat, Plant a TREE"
>>
>
>
> --
> *Thanks & Regards*
> *Akshay Joshi*
>
> *Sr. Software Architect*
> *EnterpriseDB Software India Private Limited*
> *Mobile: +91 976-788-8246*
>


-- 
Thanks and Regards,
Aditya Toshniwal
Sr. Software Engineer | EnterpriseDB India | Pune
"Don't Complain about Heat, Plant a TREE"


Attachments:

  [application/octet-stream] RM4818_v3.patch (150.2K, 3-RM4818_v3.patch)
  download | inline diff:
diff --git a/docs/en_US/images/server_advanced.png b/docs/en_US/images/server_advanced.png
old mode 100755
new mode 100644
index d7e9919e897131d86e10471dd2152cd91a45c06d..83a7ad1788bdb6691ca19a568ae09e384210caa8
GIT binary patch
literal 56042
zcmZ^~1yCGJ7A?%+!QGuCxclH1Ab4=M5L{<)ch}$nf<th3_aK8qaCdiyNA}y@w^i@|
zshVP@yKncst@oV19j2rpg^EOk1O)|!DkClN1quqV2L%O9fC&GVQb6w$3I&BCWg#xE
zBqJ_Pq2y@y&BEFg3Q9UGQ3F9!<u_iY&KDVTKSb$wZDC*XWZz{=V#Lz_L6o7$?v2He
zIAV@KD%X?f3@#6+Jvl%c)UHaFth^1WE-EdJfFq{2`(mi~yyCISzshs_!Uux*eBN2%
zhw)WFRiq!4bOH>1#~Iw97SsIxWlA%T*%yjLY2EPr&XJCvnVCq0u=!PGWyyC|sl1uC
zsXgPhB8LWJ=pKr~0mBS&>q#Kg2LQ#gE^7)0h2fR8;{MG~HLOs?nj+wx7^B(-BNwys
z1`1cX>iqkD5XA}%RBHd`?`o)V+hBKfN@3&+^Hu*pYE&4qP~(*1B!l?puozNe0`x3)
z!C2z_Yq95WinGGJ9Kn2Ut))h#<&qz^l&W;ohJRf9)NlI8>X#eS29uI-#xb(%YjGSc
zmZcLaf0heq)QHE#My?X-J?(`~6zru{%L|qJvY1=o$%k-*!b<6kdnT4k!5ze_8&8Z~
zHevQPyr&7H2iG4j47o9kX!V1bo2Gwo%_nYZA!kIhAzte!I~c`+@RC~L{6QIGt2?`}
zz$MC;xxSoU9481tol-gpOci&poSTAJ!UB8^9iD@6u=Uq)SJM}6jK_B$Fexp)t+fjn
z1@ui=hQFiFL@;57HL(%ts!@E7oIX2Rzf`>^7F}XYsQe!68h9ZyAzp_Vm~C{hQ01Kc
zUPgswmW~NAZ0@c-VW;2X$f1~(N9<RF{~uNTl&teU800m7)yqw`N&iL(r%cyR+;*Pn
zK=M{Z2^cg)IL0hrYM2qId6A{r#c5=pUuN9^^g$6k3~2nQZ-dm5T-1JZuu3Q|fzpUu
zJ>HbXT9mYb4~jk7*E4Wmi@zbOk@2mu^}10YZFR3AB_@C6)n>mVwd`G$*zM5;tt&yi
zN=(G%Yd_@@Y?$t&Xkqn)X7@@P^G;y$bip|I2oUK9tlJNG*{^0>zt+<Td<0{VVU}Y9
z-!&9Q;Qwwf4uSjVt3W`hs{-mz=Gt_Qoxw)$f}s%J>Q8NaXWuo@Ep07;*nbnK9sLnx
zdTjuD%?)O0F0aaM{Gv33_?fkD-Ad7h#%9b2&s4GFC>A&ux!&#=Y}Ot<cAql^?Hcp2
zfTiP4+6ghHsl5DSRQj&6(nOQP`5k{wZ%@gd%M3kHI9|mN4Z=leN7%qrud4Hx6YbN5
z%?D*c4GP9D?c@NnU~rOL`UiT$s`VcRgBzdka;2)4^p-sVO5Re_6~8p(W^MsS`gc0X
zJ|s}9>_sCFIs-NEYvU$R1a>d8S{;Eg1D~OyYcFxD#p=*B^byYv^I(3`ni!&$`oWYA
zkh%hVFi^TXT``ccMCnuDTNwQhwcx+`^BGdo!fhLV&_pQi{8ov21ntq~Jr0W&fW3y&
zh`7+@WRG8-X?uop<;P<PC5nM1CPfg+X6*Ne3KGh{5dceNB+ZExlSj2LjYlPlGf1+<
zpGTq<rAnz22i!8-!f=G<ivd$K#Dz$sUtrz)8q=b3iHs`ogHa9wswZeUF*CxyW#5~#
zY5OxvF-&NK(HBB9MObp?CKRp+7h(W%$R@@~Dabnk4wagWsKdQq{|J<#lyq8F!I#3l
zjA>LUl;V5DU^~D=y7ktOqI<vF3uVTP^(3#W-7&Xf3I`eVk#Bh2nL%e5ezyO3huIh?
z6Uf*tCq|d;Um0K@YfmI3zZ}RTK@}%cOXJ>C$d;HQpDwTaX-RrXN<iU=!Wr{X=6yWd
z?^GO-@DJzGaCu)Q;U~!^*(Pzn@a&UnMOceE(}aAV8pOJwa)fi^xu?BHx_{^9n<HD5
zf2V9r2R+0%gf!&*8F`yM{|CFsOzwgTOi|dh^?{h>hdMv^H20W?&$6<^pNBQ9a*{Ny
z{M7Sj6}5M3$t>Fn_ovd$NfvO@{Oi-}zdNTp|F{WPC|sNf*tfWXesFXreSZH8c+TJ!
z_o(I8(8&@sXwhy_ehj|>k%mW?q3M{VDO4#0K>!)Uz_w-_J$}7tW<{4w+qx6V<sZ$@
z?kIvhZJKQYZKm!m*N{WO8JhjY{g8d+E7_}t{h!mP#)c?X@F87ho&$d%yrX;E6hwcB
z?NO^yhfr^bY6-6h4~V0=<hU8xOSuJ%|NQPvah7A|NN)0P`so&MZxlF>c!Rhenomvi
zNtf_^);v$SGH$$R#Qf)kQ!aWx<0k7S$);MreE+SyJvPnvu#X(_+^Ol@`=l1ElRoc#
zzRnLmQ=g{f6etv&7u3i%r0TOD^KkG)uzpXoVdb}&wSsV>bB}QwSb0yk4)_~knp4(m
zS~-ktpeIpAj1HNqRV!3IFv>GgGvOxbFfB47lpdAEm*Qz1*EHM7*WFY>YW1y_Etkzq
zj5xZ!Ma#F1lInz)#gq*?w;gLOHaOon(>X^RryXT35YK~-BaRP`Px;14{YfrJElJDy
zut>c~KqNfCdj4#MOa-b!%fewuQB88qAGci40Btwzs&c$?U9N5Oxb7e3Am(dkbSVxg
zsTh6EW{ay!Hg1#2{!${4^N5*-;+*c>ak<O#)pCCelcSY`$NtF{#HGTyV@LEB@iygj
z;^^GC^ip&EkGzSU8@m9FEAx%@_0!h&@rO&xvxD>cbA{XT^Y(p{HSFD*k==BbE}mYO
z_EV$PTW@`DIPb^jmkXEkvGdjAS8)0>?|S3$W;1jtv@1Xd1_-0&x9_I|%^$!R;3`@t
z8slFU0N2Iu|Fe>Ge*Q@CXqU2_vN|?^(vHtNy(xV&Thm;^T+3W1#ar`>rrMtX`;xQL
zvxl>G#IewM%mM0mamsNeRCbP|jh?oo4R)=!cTJm$k`p;tImJ0-lKhgxIXWM+u=^D?
zIo9<fZ6e<n(Bbtun#}dC#MHzL$2>YwIT$bX9)!hgE^qAi{**U-FQ@n?<Lo2bdk4vl
z<@X`)CBIlzD_kUOHE%W0Wz&_Y0BNF9IbA0ERKKe_Sb~V?nD}g@v|qO>e;<ByQ9Muo
z0^IIbef%Y<GN#Cpn#6xR2+r7V-A9;ww@<g<G9`Rr>{i$Mf@1qg{uBAn9)mHTkBE4s
zxL1fUfh9qT>@e&aW<sNHKFjwRY9uVRQ1?C(hr~Nc=dU+AM-6;ceEcAIkc#8&cHHIU
zC7R6D2fla}juA7Q(Y;uptZaV9z4!g$#p74yYEnlDA+;4<Lnxl3WE`~cQ(Sap7~~S<
z)ls=jw=C%j=`Uc5q^Z*UnoOJ!{8wJ$pQAsQfdh_^Za(zg>RsE6kdfh(IpC_h_wT0@
zI80<`raa~mt-D34Imr_Iwio8@mL#m2c(@OGt5Ti@2E}^x3~fz+e9m`1++m%^*XNVT
z@-RN@exz+tI?>iwesLi5nGYgg@-BKZvUl6LsK?c3;4XV#o>1CaMQ=V+KI2{zq2W@N
zT3O)0WMwnIFn3r`!EeA;Z+z)~;NJHD8QL4#LFFb^x4qN+P~5Cf`lYR+zxJEO=wg(A
zlm<7Po#h|v`X<lI5T*^LhWby|Hl=kXWq&>`sW%><-)tS5`CQ#s*@pa%z99YS{Mp(0
zBz)DW7}8R1+pvFvdu`s9({47FAb9K{e#_0%$Z5Siu%z*VeJ681MJ`<U>S^LL{W1$9
zgh1q7^_;&$v1zD9J;_^ARUtDyJ)gd?<Y4}kJ&X666wnd<;<Rft+%qGE5>v|iSy0;%
ze5QF`^|Cp+*+x^X0IpN8Yx8iN{B2eEG1HQt)ahX<^^AjNta^-$AK(7u%&p@xg!xX_
zym`;5>O6ioKcK_y#kq2{r0l%<c6-Np^(HCWfmEsjR*%nt>*^rYYRL+}VnFw_F%G;r
zJ4(mHZ}-ktur0&mu`i>WAI1fLiF%2lrNX0Q!*4%e!H4g~%AinVH!dU_okj4oE4U$I
z_4>%={*=5$mTZb#L!ip_%kA{@{(9zF=8f>j*NJDj2kWecE5$Zpt4w}@*X@e64(4n5
zgF|mh54JnUd4^35euEgV<puJ&*ERW-AASv{r;)42?x&Y8M<EI5ityjO-+PrlZQcFa
z22JmJ1h@qRe94R~TtG6k&q_^&YF&B<C5U@Mx&X*hQ2%+U>R&WgKo9$Zt^N~EZ3C_o
zVh9zF2Ze!pOZ#K3GAIT9bg0bTm{mkjAUNdHRw~(vB{Px0ImQYqT01+8?=*BL&HUP0
zXMb0h;-XP?1AsTPLdbwV2yqNvr=M2Y<F;mZjp3f>Fx{8Q@5;md4OzUim(~J7LE(M)
z`vJ&&d4Ki>I^Zo-HNl$lazGP18)l=gcE+a6t~T~>rJ<k%T!C+2ZA`&N6s|VbwjiLZ
zAl1K00N=j<O=h8@_*W6Il^~U-yb^`DouerQ7c(a_E0quu1qFqG<JWJ%FA|^rE&ldP
zkjfkkwg<AXxVX45yKpeuIhwJs@$vDou(GqTvopPwU;??>f{k36Y(dojRPvvCBuqgj
zju!S{3p-nizx5g!+c|*+si^)o^xwaK^fYy~_`faLg8psRn}IBUb6D7zSy}$S#K0Ec
z{(r>&=KLe}FT4I}PT+54KqU)TQ)?{=3ma2g(3@&PY;3HY0{?2~|H=Bln*NWd=KqMY
zvU2~g=>KH>kLX`rfQpV5rf=Q!w=;y;1X%u`w11ZuVENlq|I>5-49mY#-^N7<Nr2_Q
zV=RQ!lttqU1tkI{BO$8l3OLe(GgQ-<%xo05M?OL8%Vzp=@Cg|=>!f<Q*~W#TWpUZY
z<?vCXo_Sh_UMZL9OCF934J=|j2F1y5;nmiW;n72n^VrxCzhsZoI6hFj$Lc*~gl|`<
z!-z*vFC|V##OyXIdrIm$KiVcu+0a)Q7Z2+`4o<uigB2D9@b<4r1~$d^cg#B;9^s$P
zeKZrd9ky9^+$Z^+nWI#{q~t)&Pe&8e1*X_YNJ#OKT)!fJbN?gvChixH*vV?U+RWz^
zW+94MgBQ2j{u~xG-*i9SYC#<yiO7(;SpKgz{?*i43RP@cl8lU0{O{G6V@n_IvYs9>
zNdRl(|0u&-k4XFaDKO*=hXVxi76trzB`)qnx9$3mvaGPtOwdCetm$3DFGXZ>Hvf}x
z01s_w`U+kD>%4+KyK<0uj{0lZG}S!hu6WwS6!ovAe>D#Fh0^3xx=~T9uA?y0TxA`=
zyrSK$9GYQe0s0qZxaBELkmtRN%Ox1*Co6MzAr7xRn^8AwIbQmY0%sCXwS=^Jd*8l{
zG3Fa+BuKPjCdCqAw{`sVd3W)twc#n>O4ZpCFxEtU_ZZ>QaRj|RlKlX5nr(Cpue1*K
zr8Gn&fF59jZh!DJI5*`=e3w>Jl&_<18*?>1t@`=%XRK-%HovE=P!0;ApF9Q#u&_!$
zxNT^8dH<vyO=*8>8saXNfFr}7ksrZ0l~w#;Ww1|HJfHusN`pHc!hIcok|p-k@+GbV
zs<INLRh2BHVp*k`X=p-bOSQ!3=jW$uEmVenkKSkCqVOpp<+Xa;+P?YYx$Rz$&3z@^
zA?V}<k`Z_lvt>HJWWImoblj3YSZ-;EZP0GjMr_{LWFWielm|@SWD9v>s48exzX#Fz
z)S`wDgyS;MQd0-OqY#MngrFCGiXxKHgEXs=*k9qD$_+H_C}-4pu~%;Fn78gsT@Y2w
zIdlGd=6S=8-{y2U!Cy^f!e=*lLfA8R{mR|Gj_p-fsC@a7ccI_r&PHka<@0BDr-SJ*
zA|Bfjyqe)C6fXy|evi^0Ja!5W4h~|OO4^B1OHOloQo=8H)Tku9O48(YK9{3B;GI;n
zmvTSpscK#qcuumecSs^rPi}5*R~N%9D$>%3%l18}@fuTGIeRf!88mAU0p7XlrlzJV
z2><E$^_&5V7CbtcT#0&F&f;lf2HDGS54*3QT%kVXqWxgvM;LfC*Xgt5T@L~O^^9j)
zIs4T@^uLF9CdBuqYVXHfxgLWqJ~sB|$?4|iCLJZEXe765JeQ9f=NStv?S4G7BIOof
zev4y$d+V!;QkL*{eO7GscHP~bZz^Oyj`PKk;o)pu$oJG#O49_9Jb{+>pROD4D0dBf
zo)hs{^yLuH$?~i!+L9o^L&or^DBN3KqEJ9rrl7~(c(!<Xa}#6f1u4IC<&m5+F=!(e
zJu4O;kFOLo9n_e??=ngLdMD++mmQMFh)8S!g;E`h#z4-ls@MnPwnQGIc1p}`jp68h
zTsMbk`x=CdKdE8hB{?SeNaFRdUq}Ug-C6yKbX@)rzA1N9Dw-s&p3>{}<vAfe{b&}@
zOwMcHDVPBzNC9J`sHo_2h)ft376!iBQzk^QNUQJqzkLMtU~CT;z3O#K+Qr+lo9Pj#
zsD%8m|9H|8qrkfk`*5>px4aekwEb>`xK;D>MH1(j7q0q7cyx3Dt@Enwe02sERt&51
zS2oI%EL;Zln(M|S^^F=w)H40H=p<&H-}m*(a&r6@D2NC~k2l9xld>#fYW&8%h)C$@
zg-J|0lkz;v?|a`F>o<exqR0f(Uaks-l|#@-&0n7G#cam}Z%Lev{=_vq9e%o9@u-O9
zE0u{|{;nuQ=jL&9B(pgXQ>fSCJW+46xVQCPu^^866V}1OY}*eEO5Lf7){F4LgM~VV
zW$(vhG0$<u>t468PFFqvJRLRoZ4y&aQ|FVKr8~ecJ1^SU#!Kqh=PDsAoR4sf4R%6H
zM0!f|pZ8*ac%G0VPvrJ(#bh1te0n~ZDKYJY9(n81j`M!vJg>nJ(XLvHslB&}ilfKc
zDQbT}k9jlj&kmI}glN7R{%eH~v=iDIBlHmZavtL|9{)jh&*1d|zwPzq5$pB&c2z}P
zJt^I)sTv1yWN0L3ut*w$ki<+bBTgGCC@dU0YZv;~OOsnbYV0JC_dB+D7M7nfb+N%{
zPHl%ei2+=Z;~hRed^vG`qJGmA2Ex$UewFJF!A>ov!+7qG#|^&}e+pf#c$`iwyR0$=
zPUlD>6LDE4#A1Zrw-KIB1fUB^zfEGUy3_H@0>vN9fv-=OV^hd1trQmPnCn+JI(EaJ
zJe@7~J3sa>$Apu+0F2hLS0Uuyv|oRW>H9&wLh($5=Scb_bc!}pY=vRdU>yJ^oKKdt
zq`6ZBkt@?F@p<gK{NapAe|nrWO*cDPrLh`8dtLmdp*lbHdF78H<xiTeFkk_8eIL)4
z#qW-i^p%U8v~9aqpJ;d+)D4TXP24krN)ht4AUYVsnPN2tIy0YtpJB!1fHUGdMovyu
zR~VIg4l_tz6KFSleXh;J<=0i~B?P;Nj*(IBBEm?Q%xT5@G`G9$5gqqJmu*hPd2o0*
zS?=xVLtb@%Ea?u4P{*@fCems2?0e|8S#-udS!t_aWoBM^4vSh=aXm9MUN4=$MDEDs
zG8nojw&lC%W{pHba?7KflVf!Rzua#`u)H4|6Mki!I2ukq)Uj>Kw_k1d3Oed%`nr+G
zThEHjW4oj|csUnzM9=*7R%~7P^<GiNM57@=`1ooHsZb$<e)kBHRLfA&S{;i38)W?s
zzxs#v2Di<^d$%m?jZ^|;v(Yp)M6b7n((l@|kOi!1X*%;mAdjs!pUO|x*B-R>i1T|2
zH5qP*W%|~?X}Es1KZQKTw@Wes`cr8X<g)Cfkv-&pGB}1;)q9?m7yG*f!-ibY61*OS
zuTN`Zvcckcd_DJpg++nkYfds~hBUE6PPzAm0Qz71rz!*Vo=M$LxLsZFgybYT2i-8{
zGZ%Kl^!|uW8rEQg)vaH5XGQx%ngVeDYrXHVnP5$ep4jKlz}L=CtbMgsU6+|5^BeM6
zXt@YjjN1A{J43yAO;!<V7}uwBLA&4Psy;+9X_N~N9x$^EF*5X=gOcylX#}Y=#M~SR
z8R&m&qDDde6zU#IWcX#XSnpWwqlB;9QDZiSH;i>|pGs{A!3R~twVI<!=?>sE`Lcze
zSWOcec9{T3z!EP~WNs3r4{aW|lPZdWA3&&s=+CU@=(4v}QslV|6^-%BPYk`Ls0``9
zwRQsH@K4Y*4<Tn~J?O*G(0a#FoO_P<+sP5zOYL4B8=@hu@5bBvWbuaSU3&Rp>RY;C
z{Ct&({E;7__!@-&eavu0h=>^aK7Hk|RAwMd$0H!n{1pz<W8{b*XXy5RZ^=3L6Q)2&
zT2G!+s0?4)(;w9I_;{IlJ_JoNc(igTXk>JB(*_$xJ3b^cNxhOku|&AIA5tq>k#tHb
zn~97zXQQtEn8f^Ea+Ht=>@_MU0F=YRmY#XP?f*f6A`*iL-QG{<17T&~QcL>NS#{ee
zL{XvS0X^X$*b#Z*$D<lsF>x}Cw%~80X<@@8HtWhU7+L=4&>_e~HjNJlB|+1oM=6i+
z6U+wfOH9b1ZSi1~^*&IO0QfxjQxx&LCX;c$8&RPxV;v%$HSo>6*|0xLeP!Qq1q{((
zKLy}^!r2h|mS-mm6Nh26;<z&RANNP(n%cJ=@A(b}U4Q}v(R}S)QTLA^22Dy2_?w?0
z@#eKso}ssj{Qk+LonS<03SU?I=2*!+Ke*%@;4zx{+cM(u?qq@7&=#0NO#SUesGfd)
zROBlQ^kj7O&mTO|&-_V7kDOOY^;p)h5<fFm$;;*wkwuN6*{g{ef;*BD0?%dwAW&!N
z@&BsPXq^q*&-)IGQ-+a;Ad8>GQL4sx)J?*)<5`7>{FuaM*lB6OC`Zg`9*YC_F2^?6
zOeDYRwF&WSE&42X%Tk}V@blG_>529=yqmFN13ZcZhB~7GB{IByk4SlnoyMdT@E}Bp
z<J(AV7t#W%>`SeR;`cK1+f|<qYm2FSw^~I6mhePO&e+<&j%KjPC`HyMHFak^!P_U$
z37nDUpGc;*y^b!$vjXE$%t)!LDeZE(vi4UC(e;x%*aq}A&JNy5&C0J`akrkh-p|)Z
z-S?OHc#t0rS!V;}KFm++A>=-{qEB-MWAu@$_@{Vdc}%-M8myVO@G}ghm0kOAHE`IK
zhxm3>FdO|GpNCmG2Dx7Lmbiw_{F!BT;k4NsO70Z}ucyW8zkWcyzsslplBvNfOTw}h
z&u2ZdOhrn*LVPS_)}8#6L&K9Aw*0KTd_5SkjO2!ylF-+BVVbPBlT_n2^(`(Jv{;nP
zWFzxB=JV16x@p-?*C>}2>chuxb<~@5HA>A}k5MtO;b%E!`8wyZ9>LO1d+*jsd9Nny
zV#Lq(Z{L#}wzi{Rc}~{ogwQG;<4+B}Rd6RuE5^NxRk9}?v|CERjYkB2SO&W{be+{y
zX<*-P=r(v}+9a}@rE;By=;a}sJd#p=&AdwUI4Kwin{jBwB9n(#Ro}ZLQihLO_GrjB
z4Cz&0h}Ab69X7u*;4tcs>>5ihZT<e<H>uiGM9h%JMiYsj-su=5OZb>l6@UMBz+t$s
z*Bcw5;j<fk7`SNVP`5VW$78hLL(v*U*Rq#4>?2*;9<SnLz+rLg^4aPVvLTbexB>O_
zp`1dYV-;by%wuANJWmXQw)QZIglz>foEI!MPWp?%BSt148fz4+-3RK~^?N_6cNEwx
zw1%}m@92atl1jC?-{ia<vj$fgJa(CybAK%1A`C7gp#SSmEMSg%<E?0&;qpp8dZ`8{
zE}xAUyJN4&j~b*=4c2(rLEo3H*5<OZv-<;Ut+eO~f3bep6A!_f=W5Ns-KTwY6IFWi
zLUZ=aTV+P-q){$Q{}co^nd&<*Jvyy#sA-fJ=FsaLPJ+!^`z^?(;izs=Ag&2g<L=vO
z%lCJFXlC}a0j_g8v!8Dt#mQkmIF2>P?j%G!weBd^+ft$e_Gv5Fb*sudAUD9VxC3kI
za@p?zVC4UJ;W55utC2(kk7m7Y!y&F?zMd3&olvFB*wJ(up#pFcl3ejTLFY+ib1jYY
zVoOyfEwLzpvWAmg(3~SN-M~KGlKA(NqSAvA=o=Xp3SU6|R)kCyTculDgfUi374G|7
zleHvUmaQCUZl96GikEa}G)%K1heXp0sC|5YT8U&kK-f>3p(t0e;tX)YKsEt`bVMn<
zhYraN*#8EiCjP!PcC$!b@(Tu5={3T0jg!%Sn#v@2;WJZ`kxJUO3M%Y=YLP*5tjnSp
znp=UG0X#vm(fE;T&v}^uq|E>UBKxvy5i+4PbT|8GUNgec7_f{911?_cj#JW{W2ku3
z<X2Js)a*f`5E4&LUZ+WSPQAlV`V)oH!AWp@B?5&c37}-Uq0;@d)p_*>f&Z=wHrVmg
z9Q0WsBHaBZGf%ffL{-2x)7nUg&F5yd--HIKpbvy&)#GD7qT4r=$t*1M59(CP&Ghnr
zJ0>w4wleayPYPa7xO;9(H8-&5Z)>Ff7wHkgjw5&=w{Ns<JN4fO%<FZv7@F-AXX4MP
zsmZ9X{0CeYts<Vqv)dTn>n^3~#B6`it2x18<0tyZF(808rN*FzWq7a0humCU;4xpU
zh4xQh0>rb{sn%l3Bs61HYZF@jWZ5>RXb%4u@|#5a0&A}aLF1(`yv^p0EsoAtY<3}P
z=6^THzkqz20XD(sdhaC+)%!>OaBR88XkGumv)-^eHnij^f>9#O`UYfIaPa&QE2a=H
zrTpKMELfyX66$mSQNW!uD(!5HtllEX#o<s6+-6h5HS%ApY7p1pbX-ZnPcQG0tZ{H5
z$=(<IqfY83D*r8FPJwt9QDHhXZ-5_?=pqb)=^9A0_^*Cw(2^_|`~`McB^gQDW&dfq
z^E^c4_o|M-%N0-5e{FRSgX$>i_5bHc{FiZDuxC0EPV$A8QwWy_+zt9R_GuL2S*oxH
z3%6zE`zl1P7wtvvOZdsN&a#(LzO6-h>^Nn;A(G!9pj9=}M;tvU4HYhr`o+uUf`hVf
z-3s6aU|eHPRnnC!+3DawV9qk#0Rl2}mluYCG~1sXKCVrVxt%bc%4=+0<5rjo#;ja;
z?EDHlG*PQq8+caGiaDy9ECg02)Z?^`RspwCBOm<U6wdSa0x1J_dn$I@f!`khYQNQ8
ztq#w90}euG8yA(-6*a2&2eyXFbd+t18+t)=k@!dEB-OlQb*26LPV#gobgMdTM7z_t
z+gA&zC(|`K=aA~_W8FvkzFzFxhgp5A7)lCZp8bQ5L-0NKL4$*XS#Lhtmv7%baz)$9
zkuJDU`1rVvMDQ!LzLSKR<fI@oU_Z`c#ksj<P>>R0itvQ6<PFVHPgedSKE;+&YAQP2
z{po|phfSl9z{y07uXeYY@I5wG1ObgCw!Xn?E;^0VVq;d+Nz@xwcQe43H*u3mk8QG*
z7s%FIXS~HV3WGfz@kCE8Ec_E18hURqjyfSFMS8i##pQ4(;gLT>G?GG^#m1j(1``K=
zuj(&7qo7a_8j5JSSkDv`64K%@b(N5SgM^Hno03AnCuWw=#j)^)uU0n4VwyIaO3_G{
z+3#j^+K-N`CvaCoiase%3l+3Ym!z1Pn*P3p14>FdxO->-xAF=Kuoir8M3dmR1U>Iq
z>nvx&{r&wp7re&CnU@ro23lJMhDJy8$H$c{mz%lZ5D=2hIj+V%e(kQDP;THb*zGHc
zT^5Or0~~~(&H~na-q4k7{LqA_njm!QQmf}@fpodiADlUBS*xpa{?K~{6e)~aO<|KY
zmwO4y&l7!Tmj;8beC<9Y1CMf&Osxkg$U{x!x03F}I56)UA<s+f??K9~1x>883GteI
z+f)ccTf3KwInXfX8lKRj2KA{0nS$C2YK&bFB6jF<gBp4SXb6JSSf(I&PS0iH4csak
zc;A1}<J_il-_K7*%)lU10z(bPu#|h-m$74nc&5QS&T@_xS_~FiX!pA%pv4aJUs9v3
zCmVQU#?S8jB55lh!DLqw?v4?Dk*3K2W3^q+>RffaKF2V(-x+JyI7j7C#yAHmEZ2HL
zxLpgxp*CWrF4q@+2}A1A=Qt5Q#?tUsMLHeMPAt?}<->?Sy`iYR)z_B>o%$V>`67cu
zT)n(Y`gRuxc(BA$L@zeXOor|Gprm52YJe=aL*NO2p~I&mFQ8T5>sqb(tQ&d%u%e?t
zirg#V<zcR4@{OsJ2!cb#8-L@wXnI2sZN$~CK}pHGk>qf(d#f)uJk5V`^AEfB>>qZ`
zsrugcrk~|y5<LO|7?XA_$J}B%XUlHqefZ1GWtvs~Z~Vr`_lMKCx9}3tqB#E30|ThU
z+~aQ^?&sI%Q=k1{V%sb<QsDR-@gajQaONuz@pgR>zdHYINpUSaYgg#hL0R8!-`$5(
z9(Dsg0$!9wuX&nuyL6RQD-0XorWwgLW>N7N;t`xwwn~Xf!HZgi4jTzT?k<*hxY`^#
z7K31|Tecr2RM~&$2qm6dvh{@eet<S|wfQ+&BF<0v!@0=HM)ilO&qFhuu^eJzUy$^;
zHZ>@%bwMhO1kmsCz;5=PFhK~Mf`S=jZd;g^tJ#8rZ@`1ySV{`<5Ht7ojT%$G_$8-_
zM=)x&>+AXfFxWdtJ`0$<&Ylrya%;lDBH2(7ZyoZ33kB^3`YQakP^Lgjg59zjuXfj)
zpuU>&Rk)s3QOtL{+?n`OW%A)6H%2H&6b1nkp0#pEl}D2s5#kJ740kq;^^cZx5b>VD
zw^2c<OD_Pd#$w=qqRrjsmC~lrAq2dXD?mB?^t=e0o@%f&;6o$fjm><c@g{Ih)yxut
z+8b{QuoqyxGWLtH4}MuI5fbS7ovmg2;-ZMX><YiqIT(1J!!hZ%rr0*`e+-X_!5_vB
zd|3-XpColz5+(O}V&k%$9<-6yP*0v5+UJNAIBmUr8!)gmd`ab1MaPT#U)lwQ{iJD^
ztQ!=U5=$$!=k&(J5%D?Z<*mA`diislz?@0>T7MwKXn>cO(lYdI-hpH=tn#BMq;Xk&
zBx7nw&K}g3aAQLDRCDQd^L~xhI2E<HC9oI_IVBOJ{7wRo6h+LFWc8%XcM>|3358#d
zY;@nRCvn_u-q+7d#8nic`O}in%1djW4~Ga#&L)kgz~5Korm_j~&j-=B;iyWxmn%CU
zu~o_1O#SrHFwYU>c&R(f1U5?ivt?gs3d$%yO*?$dArSw>oP4?I0ho`?f1r|giV8=`
zrEAk}-p1v^*J9)}gw<UwM}n%fnEI&Q?#U<k2A?L`){xQWND!^wI9Ra+3T&|0Pp_NQ
zSX@NdS<|<qKGfST1ahT;Xi|%}Pc3Ly;b6XoMn08Y5~y0_e@DpiEmZw(vgfnd03I<h
zLm&Ymq0IQ^+Y-e~zIa=RBPV^l_uc6(CvKcy2Qlc7U8qBK13a_C2d0ShPN>^UDc+L^
zzdnK7-`MA+EfmV{g>oOkjrPw0S<1IZ^EG`NUHHy-XX~7{OT7EBMx;zy)e`nlnfAXk
z-{>mNH-@qcF$r&J+un;=yEfGQ_Cy|E*B-!Sv!HqvGy`896%p~>Z!k~hdtQJ90@RT*
z*;bIdANf$vV%4`%qJ0UYbw4O02WFl6Nap4}DoVIU9Z~x?o;X3Y>+apA#o#;fyiLs}
z$9&DD6v*96$f>CzRK~;AJ~fb!pChbjjePeR5Uio=5ERSN>kGE+cy{i>2IkoCthnY1
zct{Vdot?Ct7QFF_h$o$*zhU-gNXOM-F>qV4us_OSbW4zgV&$RS3S8JMwnu%6CZZc-
zoy^V6-EQ$aMS%tfMUbr$!+tQUC0u36<A+(uw}Fw_6rf@k%aqsM6nbM?q9DSro?UQb
z;~uANQr~G5lgti!(1r7u^_mB7tuJ>*r+q|x(!ek8y9ibi)k@TV*VNjti@AB*#~`2(
zP`GCacDj<G%PHf-BNwJShEGR5`a7H3uP8>944oT(VP{$-QWRbm4)fNo5329&S2<;7
zOBh(KF?<yPrl%_yjOoZM-hQ0?O#?18;5p9r)?1vMm_~VUUMGq^lsVSn!NyIhSe0qH
zA<v;JL@Ugt+rR2-RRgo0Bbx5wj`Pu=XJNa$BzZ=t+h+IZ3JGwgcx%-~X>&$r$rPgG
zr>M&}(VXYjMlz;x`QY~T(|nQ8M3g6333+g`V{u)R3f*DUrwKq3KH-57%p?b29d}!J
zCk!XOruSJ{%m-^85KVo_{BCWFz*=L7NDIB~=&&jKD+!m8NE2ZX1G6@lcRdh05OMr>
zmI?sSSr?*!XA1<EQ&0}NB`n9G3tq*Jl!@Y9tjWgsMiZ7_b_F2(rSIssZiW~tq=`yz
zt;(B%+aFK(Df#!{cvi!4hl5HVZx0oFf>FOi-oeG5pxlY6eJB#Z5MC&lMFm=5Py#1~
zpZ66fQ?to1_EZ#wB~AJxF{y+POKZ$`MpAR2my!q!v#=#-=33oAd}7S3UT<9Rek6wi
zK6^;M_i5WL7Cbkig@wh{8{a#Oss0`aZd95OrRuB!AYZ0~AaPBm7_`!`8H@s?6c}p}
z9)5ty>0c_6E=vuCneLwviA~uC34mXV5`uKW4^sv5xv0cEm9}PsOZ=tk7*GpnD8*Rm
zw+Jbn?0szm6tH;gtj!lg45n!K0U3m+V_Eq6uA=aMjWpx<DbVNw3=p@);=S#%Qt!82
z;ElZ8uO4Owp<AB`Kp9}Xx97V}2ldqi?g9>R*Vz0JV8#TY?R(a+?~G$3Jp4}q<)Z!%
zOTWklV?2VOPQyL__)k?j9jZU<^~5Z>`J(D>xC*hF!v>%E*ICcUvl<9^Er8R6ecExP
z+BEc>5|=<IAC+(2c7M{W>V5Sketf%UO6KkXU9G{O5BWk_Jdk$s`CocB8`Hnw8yJyh
zl`eM&*xNq3e(X}8Sg$qgQ^yQ#+9S#Q;l2O;=YC5f|6Xeq3>^baOr~zFiubPy2UXZn
zgSPM9dM(Rkow5c@1y_;QO)q1Se6=*|i1L}dk?_}%*_5vj>CVUe?=7qvP6{r`U(=!s
zOecHS+x8od5%!wUz2iAiQ1pK^`R-Ii<;!3PE4AQFOuvSWSuD@;%Di6e;$DqTj)LFj
zojD0Q!OO+TSgq}%t<2-Mm(R`HZE&2HA{vC8BYN1fPuc^PU2^o5!q?D#j#}e)@dwGU
zNr}-5eo#P6FmMlNeMM~Ga?!5i9iN}{dS<UVDQG(7C-As-D(_M(1W*D4AjQW6XSl4m
zi5Y6*z*u1cK-PlpSF!gJjOBjU=M_HBvRmIwzsU%JM~a9^?^4Y&WfmLklG!PMjg}=$
zIOqI8LvXC+eim7ul%8j$oTz6Ciz@QvoPke%ws^>p2t0xRn$dOFmu_8dc;d=tU&7F<
zH@^ojKIo;=-4G7Iqse>P{#fqHZfF`n;maa`e#Ys0Wz^*t`gnWFa$=;JPB9}I054O>
z?|x<O2Zx8w$bf;y=r(elBR&9y5*Q63zs!$C&k&WM5XDd#KqK9s6<(sBWjrW@Kt+%r
zd+u*1_bvo#NC={IlI};~F=H*i5v7s@6dU(|_VLm0)5R)0gWb=wr*NT2V=VCbjZy?)
z|MctjO+G20eV`d45c=}%Vl<4zFh&#+UJo%g!VJmbj@h*y?*7`Xr^!2y^|h;QZ@#3E
zAN>sY44yMY-@QY7*=F&{##R(i4qsd8j_^N4%j`Sf9GLoh4=4ju?)ou4KEBt)-wbgK
zzkL_6VaXl&?^U0_aQjc7eQdAgeSj#pPP$wt^6XJwL_d0h(M@A^+g?5kp0Xv7WheqM
z7gf&lvi_*B;WR_cMyI(|u7X4^r!nv=(%R`UZXtSh%x*<)gaWbXZ;RC0Q*-zXp@NP-
zCCPFmVuHZB{Man0gYj~>s8>tEzLOQjj0Nt(%2*0_*9(!f?yactOs3smir!+W0#MQd
z;J}wQdxo<6-Nb1DV0hWR^A(`wfujc0XX*2@h<mlAhW$&i;pU4o4mvGf+0u~Hxr+zH
zGR<LgpEJ13J+LxXr1>z4{C>n#wNaZ%=B5xpt;Fm<3xVQ&n-WerfIKL%{!o%xrcZMe
z4hf<miScP-OggnV5eiHKnv<Wu#s(+=s69NJ*d9VWH3KO$wrr*fqGI7MvU<K~7@BJq
z<#km{WW+XE-?Q^LSke?XtKaWEoJjA6p{c@LO)6k-p+1X@pF!1{uXHcR_2{8LPkc=1
zB5BfgqmaZXHb!M2l!)?0BO+x$#JV3>Z)`Nu>vj)fCP1VhKZBWPF!DF7FpiMscUyv)
z_H*5PCuqn;X_y7qz&1$u$HWqvlyiqa8~p&#zi`v~B=8Gi)<zx{<>SlalMkJ<Myadj
zTA1&lK7t*ANT+}B^*iX^EEro)3@)$)aqTj1aZn+FMlz(4hk{G<nt%kF1%m)yfIxF?
zUIbXcQg6L1w(5OZ7R#eMQCXXf4{vowvYxp{B$fBNj_zYGj9pw&|9g(>gzki6i(<_q
z==7IiCqsH%uwMqefJVxuROe;Ht`ZDuuLv|?jI3Kx`1yUr`dRwZ!yy*gASzC(tG-f0
z@PWNU2`<^#*T>s@ev7BrliJsDWnj1MF79LWWC5v%#hvd-0{DH9d!4P^gf$aLoXtPy
z(>i5B$_`Q1?cs{w%hL-qaOC8OiGR~Vx)5(VPdPBwt0hT(uZ#shw1l6EGxVn5vN<)U
zPiJ1PS3Z}zPNr2oFE-7dY($D&Mj;mj<lY8ApE4Sjf|`z#Guggel>e#xPQ<o8reEvV
zZo)v++}du*Bj{`?4D5VB0BI+u>^Lf(2?ST-Q_%Vrj)hy&SHmq`FUa&rWQj%eo>6pF
z_aG7(n8$YVItLi3MnU#lPCG!ke}1XZ5Z2|Yh#*vXKf9;0^zs2YJ<qwaR76OGieT_K
zfJTuEqAQwrF!3vm4!K}53Rn!d(1SO&9ZwdWlu#N$9e;~b1W)MA<zh1;BRTPgo%T~8
z09>AQ!ajr@Chz`GMKA<pI7pBH1@@5Q`?;>>p!}6L#EF19o(UwP>XqT_9F0?3AN3u7
ze=t@vwk6s2{QwPg4_qQ4<2~yp><tMFZrr3KJ{I-0J}!#G2LMIQ>Lw|OZ<P@6c<1V6
z{VeZb<U|xSYoIC+GZ8#RoX;rMwD{9J6S~EEzLu*_#l5~DoFwmJ=E1b$APA}lxKoLp
zQl7BwI2cXz`1cyKcvh-INuXx1`uawXTbyNeU0BRiCzfvd(!e&ad%!8iau|w)bkU#0
zajX$tTb)@GOJg;|!Zp`_TjvivjoBMPM?T58d@Nj*8SH861-(16k7jRlK7e{+8<$ud
z6MD41*AGZPw>D(f4Tvw%*SIPo$XyzeZz+QF=}RhI><erN>JEUR1CGZel`qo4lJ<`=
z)T`ce{I070qDJu(d7n*nLau+)qqbn?$EG<U3n#IU7>~X$kp$ho7PzNFxIk9%Kzuio
zQv^OAxq&R!%?1$wKcCvSI_y~=dr630`Vj2>ORKy+V$Su85~hA9z3(B~)*%~Avl4@T
zX>ij4OYl_|^Rf09%WvGI8=_F{jp0@pKDXi1c+1Bzlu)pDRrLJ4{IHG3hWB0D;aM5{
zgO&p~q*x)61{7bx3YA16ANN>e@vG0q`T23v0}x|_p9qe7xcL7<hsd~cU>3EA8*F1h
z6)wWpXk}p_RU=$RHCF{r(FS=U+`T=vu^L;cVi`If_Kx{Pc2`-4>x8j(n|oc0IwMj5
z4<Ii94Z~)l+Wcoc9g=Gg;#L?0cNR|?a2HL+q0K0@hD=xqtU5+aN{6@3)$UG0^9R$n
zJ`WJq>JP#g8R9lOm&XS2*&8BPhen2iH)9^MgukjwDe;-}FLnI^ZlO?+xdpq9U;ZBW
zIsWtY$;_-eBKA2#qtv7``?ge~-?FjuSsbd#h#p1-2?7NjSUyg8VjWw@(b)_}>tv<v
z0tGw)I|K70{4y6yzW~VW4>|IFyW*`W|AsiA`mYmq6}ygx<YwkZ(tLuP5={D1pP+7a
zbNGTaU+j-JQ$>N9lzYcZY)X2_nUgiu`?+w$d(Ve7lgr5&pIi)pnI|0=;D<xp!to<6
zhlHW6xhTD9kPA89A%P9F#GwiL7g}sSJS$4WxY^flO!?OiVbcwR$E~*_SYGv1nF{<4
z6m>Q;kyPE{7Q@-9xB6d|1Vi-$goQo$?#ltrI?gUWSUw5$r{T$84X-w6F3tIL#@hZY
zNBMzNB@j`MCj9!(!a<Bm0n9c!5-M_=tlG8iKf?1fJkT$ah_bC+(lZF4x4pj;08L;q
zDAid^_;G=b7zef=`v^}vPES}xHyV~4BSw0<9{TWbO1}lm;!(Se$eXYw!h_}PN2xlA
z2J|QSPg}n$q}n4r3*4GH3>ZOBGAQd4&84CtfJIFue08>-FI~p?BXLx|N^1(UzK#oM
zQ6+<zrZd$kotNR23l+w<YzI<i5sAkXZ=_4N*-xL3ATNT}EZe-Xmv8lXqCAXSll5z%
zzo3uP*O@wV*irY+l3(goS$%_?pHb(Ai*47CtNVA)2gva+`kyG(zni>}mGo6P62JF{
zf(|*+q<~!(MQpwxgkd;h3jRTCBTf^8zSEB>LSVmK0-<ejAGK_N#Q#F_*;=t5L%MLi
znvjx281d;g?x_hrHcTn(qcA(jSK0p?h_H(&;RlwB=-fuFhH9sfXC&%X1%UgyTO9=U
z0v5>t$3;h%S$XiX_g>yNPE{oENdyU$XaR3A<g9Q3kFYtgT}BAdc$;0MF<E2Kp%9tO
zarC?42-o+8hcVypSSy3(wnlkY!MmN80IWVJtjqO3*yVsRmUi)nbV{-*{Bcyk7~7VG
zh&M_~HuY6c=R4O;K7i5R$efdVYtON`0n*O+a@!tKwK(iHp5eLUte8!-sg|CH@I$`Z
zpkYDbS_2+SqV~XVqk3H|cLd@-{AR4r>xrj(HyrR6Bo0D?H_zYPA2za2&PRPSNiB??
z=D<^fw$?MBBIrq7Gw-9P+$U`my~H*jU9#lQrOdAj#E(9?ToYSZAAjUyGS~MKWDyG5
zO$8O1)|k6L`Ws!%HSCV76{6*od0?5lSyN?zjD^VvU?<9U(F#3QAHvG{-N?DZ5%baU
z?Xp{#3FN5}oC_BV)8&$1R;@pOOXjcF^lJZ#Y@;~p=+jV)s3&Py-|9pF==d-^hhJ|o
zpAPJ;-GCH><ugc$fR>tp2M58(=(a+rdr*~85*j(iy~|A?GfG~@B<Qd%EGgfah?!wc
zfdJoVoGmzfo_hOiaY-p!b)X9#1>rKpPXRCs2qj?f5&gRNejL+3Jxi*?`&pt~#V4$2
zi~NIy8L=|WfhfW;3WYZK&mg~Jue4Tc02my)clRlhq>K7W#QE3u#H2xTI0H_gza&3}
zvbB_WCl!mQFLkLoIBzgO^j#@qqtA?FvAfZD04KOeQ#S<4bLSk7aN6fB@<K(-7`pEy
zGSLrD8bKns&yyB8nX#3;5dpEqHHdAe-S6!^g;&>({EzK+vE74i4f;)C*N?uW(R-zS
zOeZDIOO3ZB>g5}Kz_2f{ph*G}F&@JpGjv{277TJ}_<e#<3RN`&GdEXIrQ|!EB}2YV
z?=`nMsG~DR5wo>$GwrE!JuzUW!3XaIaeb85SbQ=RGcWgO{D!s100DxOy_zrpayxz}
zl1=|D&KONQ4*}xFs6%r<;Ff5=vEmGI9Yznsms~*n&h~JL^WqSX%`glAIFo#2V=ZF#
zlmxugIL!&ovP8gN?{`P^UGT!|^WLnSd94t&#7w$X?HMWzn_TENe`B!gSWtxVa5fb9
zQ@wlo`8L|-z3^7qF79lUYi6_fkB$4)Ug}@9uG`-n#L-WtwAx`}qx$r8Tuw|QntU4+
zoJ1Tx%M8cDS-`kECE2KHw$^`BVYFGP`<ccajdRhb3{&r4HeapNPuJE`pSz-GB4L+j
z^5WUouW8wZJOXUkt)u(3&zaKT0tb)h;ino+N{k16=Y6{JLj;$~TqKWF+``_d_w@ci
z!S0?CS(INl{W1QO@YF4;8lt4$%wcB=siVG9$8)0QUECho)xyJz`{@~!(WJY(vaqhT
zqBW$UtpyYfZfM3hl`k;UAG1m*`AjRH$>Wvol$fZWW?h(mk)Hgagi+7aOG9AWU0<BX
z&S86EK6QYu$L&Pk+rq{n$tjcnuy};8{j+UPcCVz2MgIN{<n8tucrcMM;IJXr!-wOr
zzzQco9_8n6CZc}@^-#cWx8ME%Ki2BJ%!=8`0qdXi8#nv=s<4@UTvtF)cV%rlVD16~
z^nQ@gfZ*+Zc4`~&jW9O<qL#5-@KOwI12g^J{<yS9tFTaa>kTx@4rq~o6}OvFJCsU?
z&lB}YP(z6=Fz_%-&*Wc>;)OMEqF&}eb-0HsZz%tzK$W)_GaDeA_gXHmi^q;BaA`^6
zPCcW-u0BQH^&P>32*;pLvBE3Aq&;)sU|NkWh`C5AK%d{~It{XlJEJ(fQRG+`$&(>?
zY3`QL<u$$LrkHWfXUaRKtbV9Unr?HRaLib;&8essEotC^U+=z-L2I*awFlp=s^>6$
z`h%Z8Ir%BQ0JyP-%rM4nf&a_NH(lAx;XVhH^ebWz{6Y*I^r9`+xmH>BE-d-@r%IGs
zNx&$uUGirqJ4IIja&nST(O|TdStmZc=%s7HAwI0zR%@djXn3}o9@$MWz?mp?&XX1)
z6#^6(RvW0R5gNRl{Y0aXM(&pVqaJ;ZC>`jL$$weG7zLVrZs8p0rZa2fb<r0OsU9lM
z{1CnEY5O^WZWG#_&Us})GZW0TTZ*(@%%32YT)nU%t6_Jp@T}ZmM%K%>d7bH=G-dUh
zf&1s_?qsUQqCan;_292xYqIsSE*fPNa$xFCnDdn(*9dW99B~`;h_wqzukU8LB*$Q_
z@xEJ;;atQ6q_vnrYkBczj?oD?_gV8fR2;y^y_|s@tW_pE^cI@vl?&I1OA->-(Vp(M
zK97DkeUAgx<vG)tU4~_j6}Mvn4X<Hh4Q=l{x1saan<Obyce1v`>k*a2!|JW%Bz<jd
zHSmR6ed*hC%G<;phLv9d6#}?nW<XHH72~d3ROHIW5_I&rOw~?lvTPHQ)!IB60>Z08
zQjL)O6=TIYZxYYw58Xl%emhr0oYMe!#YODNvrH(fDoQ0;#G-3W*%|WPnQn3Wbe^th
z7HmK=dGm;M(!WFPvrZ@s(axJeES3u2H~7qnqh?5kKF+`0b$f@1Sd_1>n${zVX91{`
z<i;gSs79uip?*SJRa4qWVkk9m58mg_BU=!6EWrp%XUiHz#}N(KaM@cGe%l%!7b4v|
zI`3JE7_qJdEv-yqg)_Vs`$(+3|Hv2qk#i)L*)Lh|Z$J|&WhK~zM3BRZL;27iU$jTM
za*Y^pHL;iFQZV_Q2aZkj5n@R<K=bxSz#XhJPUPUpJzV?tV8L$_04U7I#~czKoMeww
z2u0hTOHISnn|<!_r)<SHm0T2XODx)PF)ns+E+t1C{L!n;X+_m>l(XaXY@Sxv{bt?)
z5ws<B4@Kt~*M?fEB&4Oez%pZ|&{q)Eb<PExD^2#N5rYe+1hP{8nJ%~`ZCKcX9*^^r
zq39Et!9NixBn+?%^|s0fWa}pR1LvCPp?oo``n%44WHC{!8D3Pr4jN?W`se(P@$c*q
zx@l1~R-y;<EZn1WE8>30(mOs0#T2+DISsiaf}gJ=UG(|K;#x|r3U$XoW7V1a?d2KU
zSGqCUpDM0HUDK&~9maVzKL6&70+Fd@lEoFUtCkn=#S9ki^Rh7T4qNisIb=F=#`JsW
zQ<FI$($6`mT~wIy+0A9LxBhlY0%azbmfaQC3P3n_o06RS`NrZ-+>RL(Ox^g4Q3R7{
zV$Ag0W^;!+>)@C0$H4NJk#leHFs5+^rxhGA%tR_~&Wys)qOL!3@pUP?2v6m6D!>Nk
z^x{+3MduLeNsKG+%_WYGU9Jn>fPzEiDS-+u{h0Pi2CP$tidp5j+@VS8A$R^cUcTzC
z($xqo7}obxcR=9O`&{Y@eGmR(fiX_I^OX%H$iG$y3qwUATIO74wZN2@9{=!u6IorP
z{^10Nenp1VSSy56a8AJeDsrH%V1I(J@O~I*sU-+B<=qt6b}ewzxAHbPZ=Y=2W>HM%
zh`H1~JQqkx8c5v{&>)2H?($6vR(SROVziS=%pSPdIv**SbH7T+K6k%LEI)^MZu8AK
zI+qeahnJBlFU&RZ{D!nb-mFZM`fFvT)Yw&ZxmRL^HJ`!75ca87p;>CUZV97cPH6)u
z3WkqC^f8%WM>S7<*y=w49t6-_!B8C^+WWu$F#JzM%iFu0_s}=RW1peT`u_8T#xG4G
ztCs{Uul}|APzbs?YoMu7ye>Gmk7HRUeP=Fr=iKT4@bt}LeZKGC%WZktwrwvgx0Y?&
zUan<Z%geTF+19(3ZS%R?=lgq(qrdK>_i<nMdGS17xFX%0H{D7XRJm;(Vi%};)3r>w
z_nPOo-0A3}S;yQfSl-DR`JOsYKb6!$Q8c2_J40Kks+BjzEOzDHR~?poQJ`USpM1|O
zQn`Snxx7C>FhN&156FA)<4=_rX#<*RyHk0UJauJ-$rMUg#iN(Nnl$4<BwFo6kXe(t
zless}=W$BArrKuOJbg)wAk5s`Z0a*%xor<EyO8%D^fm(T0#!1Qs!n+xiNxS^&Yf)K
zh$FnyYmS@yC$+4{pbrg;Lr6oIXtR~U>X!ehlMG?+A0Cv1rp}U*CF;9o>trlue)Fl*
z%X^D{*v?2#msVd|dJZNLeE7b%U)}N7_~akIFXtDmS@usuA0IF%D5!6el9J7RkkBh|
zQo~T+y+<G&0BJ>DSs9%L4!)RT?BCnz&_|c}a(;kVqfmrAI6j`+mv40HT1(AVXBD?A
zW+2Dto@o(It<(!^WMZP|v?XbQhOWP@)vK272K1KMBCMXRqogELy%m8h)H6nt*K3yo
z4gDfV>GWjDfO!jw01KatM#;iW)6hKIzuvV#2fMEAekQod*$}dKO)iijQgTywr)wu5
zQMe9Pz56y&Bkpj63~m|skHs?p4`xcJ2|{195>5|)N?FV0`5qfNayU80r2H>H=l((g
z9&?ndaEsrzY1#5m#5owQZqU@){{7e)0!)WY#T}Cqc4A?*pz{7FM{6Aq4GEmXdAN1~
zz3sqHm*-;>Q6k3nBabrJq@;!aC`&oJD8+T*xPh2xXnoTCqQ>ND;W65R@jGW{j2B!j
zo3!hI3yOd;!X(tn&*_;N@56-D)UQizC&j`|zTqiL6kNX_jnv)$`&4K!7kky!;BO9~
zPFuoqoq8!97Zj{eWpj6t<q~S@I<E&7DOp+aK2o$AOYD(h;W*IhXj*VyTnj7W9tixB
z=gM4tEWD-WK@1N|=6JO_K*#-{Q>2H;n?C$<@NO=d)%<iq@PejQZ`hQd9i+~AnTrtm
zq^*son#wj;&k=>*`Ba}<F!zs0CDbdL(}Tgb+DSyAHV)vzxt^yjvOr_d(CEJ4fBr1>
zG3+Co{xO!+HtD9Y$*W8#3Q8;*`kdt8^w()FBsjSEy7P0pSfp@H8k(O;FAWJvj8Bni
z9M*Ifa^Geh6Rc;8V+XtFXWa(HUSeZo(XdfusHump7X}D&pTRMgNVDhR7Va*0I;Wye
zR$!fb=OVdcoB?7rA2tn=v#@;Gu;V;>Pf9{ka6?EfooRFM-Jp8-{}^4v0YX8(bP&*u
zacqO7hDGCI^VK6P!RV1pUiWtPvY1TRJswch_<U|ZhIpcf8d76)<>aFJ0*;jy56AWH
zSVJonxBeJ}5pdc4@VS50WKa?UsMZDG6^qufSKMWKgTeh-X-UIh@W=x`%=!s~!D3X_
z@YxahX*5`g#md~r7ip0>i%8`64o?h9ni^QkXtz2Sg`UHj6FLcN`^e0PAW?={ZHJ71
z{0QUr<FokG)YLCZNgV4RPk1M=aBw?y6u%(oEM!Hs7mGppUzJ?b91r-Nc;>scRtIqG
zODEokn%^ZcvKqSo4>4>!JP}1JMUJ2F`keM?V!=?KQXigRU_U}ZLjDYT=^vdi8#`1M
zDINoe$R#rjd4&M4JPDVxtcY{nO}0$2DUY%BS?X}9lyl7O%o@<%sDye_Bm+Ej$F;tS
zFYQJbBxw&1MIyj3#daEV=A8Zk2EnaMMUF3(e`nez4e-G80b0!vZ;|jS6ja5-RlVi>
zWa*pd*K6CE76f|Dh6K4(HyqSXK>(@`O=5UarZbCq=D!mV0<=%L$vR$spHV;e4GUbA
zIhq|eT}&5RYc@{85RT^be*G%43B*t)Zy<vTA_||kVaD^ULza4Ih>u7z7miX_W~&LW
z?URLH@|lY|!+-0(U$FlVU&MHMV{l1C47O17zl?BZpl7k`5&s7^-@lc0*9-j#8D4?D
zUftQ{3chLlN3@Ukc}V-eqzk9#7PRC&?@n_uvwX#2@$x;cA{VA&a(nmv1Yc6+2zaC9
z(z&AI;t;12sFM|BWIPWSd_P3u3i^RBY5d9g05*Sox@Ldfsj7qa?d53w?JH##Thi-u
z(NmC6z`Zs7S;rMd{PE|Oi(O4~y5#j*%Bbm?X))Wu&fCM0V%yGFr#a<?Z_!!pDf@zs
znomG03W{D|AaAzssWG*CR9v7(Je5{YqhC%4*_<DDu6-H#q+1OP#fk>rUQ^WmMDyKp
z^4zt3b^4p{_(kwpW6?M3xu~h*toaNqjpOB0i`y{Sa+`at+J3#*<hj4vKPf4&JGR0C
zAS>+v4Ng@RY#%u7EoT;K*3(tA6}7kmbUgj8CsK{2$4ucE-#X6t)nv$iS}8+O_U@}l
zo<y|4Nc=wNi7?+LbEUSx3%x!(EO*XIJ>dB7W5@RN!EEQ75OHft%KU7Hs6<JTX`@_%
z8<+ARa)otMS{|;%%sRnavZp|kASyTAp_7X`B|guWXn{-9N8>45Hm^RWPrE@Iso1KM
z+KuZp&gHs|Nr>d+(}}9uy{G$B6#H3Dduw;!FgmkwbfESfj|g8SljSo1+@K=ys7&_y
zzM|5<Iyc8yFED7Ahz`irIqWzHxFm2uNHh&k@cMqH*KAHot4ik$;RjdC2=@ChJ<fII
zq*3oe3WYf~rrIB%IQ67L(pip33l{QzR0ejl1!P!w+5tujHyVU3I2*m^&(rQ!^dPSh
z>&*%|IRTo!7UK~UkC*y4W^9<rsXU2d$0E7e25tC)0^{?a7OyvC6q|6A^0`e-+VAuW
z;&y-ulGyRQ>B#dpFxQE=H6*>!teed9yNXipNoHE?5rru{;<=xt_tqbT>!l(>rK0i7
z{xJk?eeI&6q9Hymj5Kme!&A;c@Dy`VcVX<Zb5aS!nSM<9_^aNK_=2z$T9YA%tbr^j
zc%jS7PmA=K!qg=de5@ePkd;`9@DU%wBd^JvZjz@R)%BbOUGJbm`Sws~M_hoD_pKY!
zahtLIl4mUC0&&f5O?k7WGXaM9q!n;F+WDqV|E%aUZ%ALPr~E%6ae}{)p0ZXM6>c|%
zqf<PE%xGlarPVT798RtAN{h0zy?)4r!SCL$A4TejXdy=-40W*JdcG;m^nHGL+L9mq
zbeKr1TGh{=3G%svu(!oT!x$u?9W{Qs5F|H6KB=^#@AZD3)Fmj$?F|k;^4c}c9_*>A
zs<Ly5r)*X+s;$TQJWQCyDB)f<{b%(dwl}2zn>gMe7FmVhX;8oZgL_J)3%vu}_TxLP
z<!WmZw-eHNK>O|+*O6b4KD|a={u6<lB;A4TQorw&?85Zbn|CUY^P$LC8fQ`KX@~sv
zN|g`3w$D=k_43hKsB$^nj#RTmlF@(X%*hWZdLfQG5UaIn1rZNR5fN4t<?vDyqw$7E
z9M(%c<N5Q}%ai#-$)7R8^sAM>f9D!Ye_}lWHOuZMZEf96JFDsvs~qgdiXPDEz}~J*
z7sxolxC?N_#6?qt^YT)q94xJiO%^X?3#y@ac(15bOW|IT)Hi9jnys}svwSe?#&D|y
zdGDLLbULblo-#<`I)zq=))=%~hkjL*Yc`w@pV{dgwCnB;_uemLR%zfl?~AZyG+Hl2
zUAj5n>o>H)Tpx+Oz#!%a2Eb7BQl_tMre1foyDA=!XR^8J5%Ty>2OV4J%7nPZ;$Q@I
zmm}JCPj<hUPea9<&-{_Ci@f<G)cyZS(HjVUKjno=(J1KEd_C`u3qMfc#9(VJbM;JX
z1Mo<=S^)U|E$><3fSUl<MfDeZ+ll96!?c?hzJ@wn=~rgT%rEhbTp^7@+9cuQRVlxv
z7b=dy$8(8$gQx1G3(q-9k^+@y7ER$7cm@e7w&UH|uj`~KW~%;@23F+~&}~&!A-BAB
z3(iC?=zJy8ZyHsla~U`J{eNBnZ?aDQH!ERlr@(N=(RR2XYk538>PPQ%zM{ak67q%T
zscQeU9r37fMRP{^c11VR>R-`vE57s%z10zh|9OAC7;ZuWY1dkBFWd3cn$H464cBp!
zrfpt@c1yKs?#Cl8KZaBX0d4y^=bD=5<)ezCSW<~r?aNOk`2R;B2NUbE9jb8-qSs_I
z+zg*?Vu?Qd{6}g(VH-_-AL@?1%p8wd0xld)Gr4CGKSE4<u+@8ogSeq$twm8nM=$7E
z5@N|_4>J&Nn<e&{B|3}WWB8dx>n|3ho-pPi9@{-+Y_vm_fb!`d1l&FZP>Ca^PC+Kc
zQ)c=F215)j-8Hatei9DYu2yXZG?AO*;_aI5=#Rucxu0$w!{IW#S5KDvCp)|^64K*o
z!)L21ah!>d*IGlWZs6Q`T@Oeg5S!MoE*<)%K((Hn6OJL@7(o=!s)9~GI@Ii=*ysd~
zmP#?%E$6j1M<82+S(q~X#bj1?(bQ%eaDET>{cmaDLgtFGOX08g85O-hfmvvwl&I+|
zxQNP=LSciX{z}_z@E3g$_98TZ9Kis5h=iaokZ_l3o7*^s7Q;us12eoP2D2}!O|m!q
ztAnF9BeNf!7ZK)V9f39c@WX`*!`(J>wlLzQ2nL93SE|>63KN;gWKg*MUZ~+P$}PWj
zyQK{>4cgrd=8}|%00K6l8@!I_bp!9=d(@_%!?J)ZDslZi4AKu2CwkC_(q-WIghK|t
zL%uK7+9WI|705LJ115ot46C-)ZF)(HCZm;B;r>?+I+Z5Ze=>n77UrTDW+&r95@Ow-
zD3&4_adXzA$^tL2#32^R{GRJ5XnY)yjOiSqxNn@!gMon<$1zEyL2KG<RFf@r1pCp1
zn|6nOb<6M-#NyT#dd|522`3VQg$h1u1U-`An6}xWXg14jPG53a=wN=uh;J`^pcz;l
zf79+OcekJ2NC<aqzXft<E{|R3KizOd3o_3*Y@PA@Bk_gq7DsBWy@AUX^>hCcVxcvO
zoMA}qSPGi32b!(-WOBIVz^Pm!x?oOqi7nB4G)j!3PJMa+-oAA3-x=}~v4R!2N^y#@
z00^bn80qN(G5f&weaRDwB-Mk|-a=j&`}DK$h*?_i|0-CBB*1eR+u>@3uk>bZ2~ffx
zpVVfpo&W8blat6@8oz%<eyJfS<vZc@XF!s=VM5v+zW6FTmM~APztCH#5&vIi>I`Y*
z{kfH{_P#ucyV<Q#eCgU#1~Y7qN2KrvE?C5F&wUWhP|1PXC;7;G^s;+*U^kw?TerzM
z?)%ql8sZ#j`xh!!+VnWYqVp$C|JAb%D%m;|C-eQ;E4H=|&}YQ*vLoBNN5gvIEm@q4
zX{P_aiJs&GBd3lA`e(fF44jScgQ0A>0!M{SC+jmdHZfyziM4l`&%eXuAuBjfJ=N9J
zj#)8^6SvUsGxhVT!DmTt+v58F4&NH$Ic?kU>?2tP6+3^_ZvIbKA|(2y3$}$A<ZM~{
zFNX{k%9H>ejIWa@O}@7rP}>j#0bD~qYpH*)`@KIHC)Eq@JA9`9?G9z_r#5D2#r`jt
zA0TOJBu8Oe`~+EvOrLew1zIvY{6r1LIRE`f9Jy;G2OI)on0^JeWmRFWGlFRE_!tim
z9^~e9b^R(=5udp^lhX`;e*ptgOnmytOSxcBaBza9Whsi2c9Ug&4#XfgCX%!qBD?K;
z3INJl3d5C7|BG&LfRK)k068Ad@Y&XQk}7@joP%$=FCE;k$MmR>eDioJPVV#*E#I^H
z`gaYE1t!=ie{cI*jXT?fC?@h?3*GC@0HdXv8BiWYYue|cqx*uxXp3s;#-#RNV#Z|x
zOZ6271}f?3X4ucYjcd@KSYcjr9GT_)!+^snA9&({;R`8g4~=eKBA*RPm2L%(jcq2i
z4bX=OkbYf1kB2UU!)n_qQT$nvjP8f`WPM}@gd2wsl@e>%*D7kZ9c$_TMG#OY=|ld$
zreK!eq^F{?J1KI$e$8^XqxZDIcenUNxE~N*nbUGGr7F-zieyx>tRWs<kXRmWZXuj}
zgF0!ZE4Grt*hDBu`r~IqB?Cx)W(fG$LqhOGkV%jneazkX=0MRL_|2B=qPu%@TOgk_
zk8>Z4y~hQCX7Wu&wr-a@%Np>O`J5aglt?f?*85n(&V;-eK)B*2s6n-Ju0m?XJ?+AE
zb;y0W*%(g@_l4dX>0>S)NFstGSw+Qowjj?l=dWl9xX}jEa>NggyvQAMQz1p{&`G}^
z(H2sX!H8Hw2}R@Ipb|+HofE-6?(Ll*>`)o2{})1TNE)%p{XQX|_oQa7ROO@a&d!b^
zAP_bijM1O{Wi0IjCf<O&ku;WWwlZHX<G-}JbSZe+1{|CuGh3aEYet^5M^=q~62yys
zKmtcjz?xDIpsSw=W{~Vfu_uy?gt#D)+locnBf<p)L6Sw-XC0!31M=^B2iUK9R$$w?
zHsg8u@ZhF@z)cn1+_+BGJEMKntA5DwU65H!7_+jn<`yROPjwd4jf<I}bT^mTEo=x4
zA-P96>tT_(<q_}GLKdWQ6&?PZTYr58Nuf6q@$-wGib_h_*&C4qoHVj2Id6gQ{LS-l
z|H<1F!ePHJ_9OU<3_y>#JvCT6JzPsu0hS?UliY${@~)r@7>!P!%otoruY<V$xV`hg
zy)p*ab?#T<Ja4Nr<}WSmB9}2c@cR0H(Rz~1-M)~CiHkK4Aza9&bL7HCNeFS%;{qgh
z*)%&G!o&^DhS0)npJ%`K8pf}@ywvZD8i;VH;esS2{ySf)&;*Bv$3N3XdRjCZuclmy
z5-f-MNyJk`Qj?RXg4|A&i7SeW6^O6eo>ximwJJxxc;ZTM#v(y~lKR6H^2#MH#{Stm
z2J^s~e#4~+nmMS>XU666v`CE2^t7^0{|eDx49-EN-5yflJQQsJeH!U1X?oYXbyc?4
zyT`k`LvXAptXO`A2uAoynlCwEWL0z0E6V{T+C!=^*=sx|*rl-0coNAmSpkPI7NSOh
zQD87Y;hS7F!{><`y-EKy<a;x0>v&U7v7DFxs(^T~kXo+2^wHv9nk1|79=Z*uKL)Xc
z*{n1u51v$bp5_6^pBbzM3Vm+DyHO>l;l7z-vG78fn2}=B2_2^ydfyzs0O*+%X3A=G
zd?CR%wh)R8mMP=ZTtd1y&uzQUG&$SbMm!k_Ulgqp14g6pxMiw&T^%Sjh{!^skW}y`
z8UJnwFSna=YF0vt_*7*e5%7Jf?6~|)4rGjg(*$bi-DK{UgM|3_=$bZCNQ01_)jD%l
z^N?^hIP-;yOcK_JkN6P&q9Ji+{g=j0BeDxKOM6)ZJ2>H%ZQ8B3Xk%ZZeDLN;4%dKc
z$6?<F_^B_X+5(XqJm2j}xT$;CHvulLK;F9=&eHIh!`EJ(t$N4EUp?A)Ig%YXV}guo
z;<WQtxmjyG3Rs;<HaCwaPE3B)$9SX<!a|4o$kQgsdKa5246oMo?B;l4CoA<1s2Hc{
z0t}a~%_E7UYzPiQ(;ob`Q&OJ{wQxBd5ZaI{h0i*7gR~Mu9ADfDNp%20bQf1l%$F05
z#+;Z9qMwoBd)<R_hpW}vu@yuP$uM9w3ee82J6G)E;YZz0Le(LV=96#||KTJb{OX*t
zHjU@0Puf?xxtqUJV>aR%oJI=ERmg?*^?OhCCr_JZd-Vn0;-VT-+TZx!Z@eOYM93#P
zEfVqy6)g%Ty6To$CTao{@yVZ;NY>F?<FzM>CdV3A#c5UO@&?{+sQ@pb)LSMLUB?py
zr$h51={=siz3lyRPF>WvHNdxu|8ZfU#4|eU`X-r`I%??BZkiZyqgi5eK6H97Bh>+-
zyyYq%df7C#pz+QPaF0hp`RV$FbxH51+j!ybblWy@yAe+7d70I@MvzNL)8)FymNE{n
z4WIXQH+;*({7PU3(}$+Z-<HL?Z$4<4jp-n_7iFG=ltFVp7KNtG;nEV#y9z*)g6OeR
z@RkR7atyCN{R)Cpdt*HaPPaj!v*;ZLkA3{~H6(ia*ADJ}@W@2oJbn7thLnc#{rWpo
zr4XQUQDll~?ki`L1t0k97YS9`N9^2~p^ut(LN2gUG9l4qR|z5*^)_=_1X7gd_}pnd
z7*;&%y=Fe8>M1eTuK{6o9=$G?Tb!qC#z^9Jv3!GH)V*DDXhEU#ZR)7lWW@MLE)1xQ
zM!*k81O8}POtn!TX~~@b#sr0V_WaQCA{3#@>}0EYcI`VU@@a3q6k-yYmlrDB&rTJi
zcb~)_onQb58Af@A_^BC8>-Vhk9(D^sSW8U|=3^kX=g0hS;%2~pkIZTQOc&$OjCDoL
z&K?=Yl?D{CvRtgz$MKB?T<2rid|$QFE<n7S2GAEa%T0a+KHIh;M)$eU%-P{+pmCK4
z5WnX^Z0Bp{a)UK3*%P1UwkycFQf)sRlQDlU+dJ(M3G0JN(NRU3cxC&GfNTm=Y)8ri
z_L}cR=Jg+5*8LjViqCMJ&PN<hpoe&>h`q>0o28!YvFkxY-#z!OsOjd8$IfK)#~oFv
zkhdFE-O1nRBL`=1ULw%QwjHlHFE>-2ldKc%LPUo!XPqH|PC(%lP_0adPY9AiW~QqO
zRkl6<qQh!^0>R`fz1^X{0Tm5Tu|xmFw@1sjyrOJxzj3}Js}{XWF*cKJ1swj}FF5QT
z5pMViOvCQ$zcXYJcq(1+DNR_1^t<wN(NS;alCusdbks7}N7YBUF0_11IBt&SQvXC?
zk&&gu$5Wo_(DV9UNG;cRa|W?uo7B$vfUqe)+7o*}97fhToTylU>QL}`GDM1^@TII*
z>VA=r%vX!a)mf|Zc`A~a@8<}JjAE&EeVZ`)mepv--A^dF$@8MNz{lhL40|}6TOPBu
zDn<*dLlCnQrTyflHx)OY#U-xu4ar}Xo0{7EdZ!W2Y+Bt=eSqs{xO@y)PvywM%p$Ys
zwhn`OLy}6xinuI}m;y!oWol8xuLdjofiwA>Y#()DYfbj8k~q9&SEexNJ40IpB%!Ta
zf}Fe|b3P$rp1nF|mLGPAQfRpUZJ!%(eg^S9s!=SP0NZRE+?8^CiWu5)AXH3wnz&jS
ztdX5gx+z^r=^J(I1Yj&iwnpBunAOX7xnt#?#bp9nZ?l$^bb;qU*P5a4Eh1iPGS+|7
zZnLJ*Fetjuq)7wRD*Ge(4*Z9%r;2nXvvy_kiq)?$4AdJ9;t-8WVZx^?nopsL9|1w`
zl;>>m)TT!;?&F(|n@ZU-0e_3#nsr}|z~1WB5<h|PiNP{lSflky6p4toAf^jNQ8!eS
z@POl+k3WOqud~$xROe$fQBIH-E&t1G=Rud>i-ErL!79LZc+!$PlL>&y7CL7mBcp&d
zF&5Gy9Xj_SLL)tE`Lk|fRh{KM4C`^#d$zwqh&ffU_7qqrBsI1;ENg7(ddfIruD4#{
z^w4iQmCq_)h@j~*1-geIfxOe!C2ui#QCUXyjbRXYLu)zSWG&%s9o%CnAwK^5?1))z
z(u4bTFUy`K5@$IX^k5XF)@RD}v8M%pwviV>-$A9Zh5;|!Ff*z!f2MAzXlhPrq9BU7
ze19*9p}DGI!8UB`vYXBR*skT;KdjDKg6||EJlVsT={w|y-AKbbyoB3Gtm$YE*Rw8$
z8`w0vOD1;-Zb{Fz!c3>R0@JBFYEy;vtW0woMSdY$>0<$xokk;nLJ89dLb>$`UAgq;
z(ZKj%hxVdxIGR(m3pVx(a8`gW^u6dw0QuWWc&lK2-)ZApABxHXP}p>PZ7xt7RKw!1
z-#l>InOms2>Bm55#WwYRA%EG)eL6U~6G&)Q8#R^sf!DAqbgRxCR5Q#&PoLOeqaklw
z6YdV!n_0z5godLf>85j(n?L+^z9w$XECMQ!fI^QnfBCnw<tf&cTC$ZoWKwD@ad=%0
zu1_@TO4sDyyvjZ=CbdtFvDAE=2&!Hh8XUgUi+}?+Lz7*N8|?Hqr7sKD*G|Lq8k7mj
zbq>5?d&LtwUb1c|ni>`@$i8HZ(3XHUu1R=`qpl?8XjF0lgALOJ?0Ei8E|yBMRe!b$
zY!d{kGN$ytc@b$459k*;S?oYKSxXjby(6D4)_>`b4EOxRC%nykq9Og{Y-7xh>Qq}8
zNseFIYX7>{w&V1w-psdvD-H4FWa4j0A9=D~#Jm1!p$&d@M)=v_K|J;^UN79xqO%Sg
zDM`Rj8|~#QK706yo%}1uIO?Q|4pjmbOG_W(mya)=HSD-F+2bdgHR(J%t~s0Tp(Y}?
z0nOvYas2d)7@@Z$LT~$jVlS;IYwPj*ACC=028f_4PR6ZL@Aj8t&ng9-jgI&WogEKn
z^72O0^SrVNGV^u3IHT&5A#XI_aiT3uKN?gg1%)bPiroZKw^w?b1sji_<wHyB<N9}$
zVdMyREDaRhKO^Ch4DPOl9xn#CWpvb8V2%Qj@U;aPGr&FlXEzA4ye^#lkFZvL=@m#Y
zea-8*zkfOAv68!6d!x(}6c{dT*qh{cU6YgNzv8<&TF|7^q3iR<yS|Jm2mo_R+8?a0
z!8LD^<4GX;0*)la6wi%eXT9DLx!icxbput~Pe60?3-8S}WS?S6<~oEbeXU}@j#=<i
z&w8V6=cqIW6LCQ36oVVqr%xFLYX%lOeM+eC8u{MOMR1<rRcbUrF!<7{WqGOVqeYfQ
z*_1|*jkmU?9G66)m@Mbv>sM~}szzige_DrOSaw4pDm+t1t7|k>&0P;BrA{H*2>DwZ
zl3A*Z{8oMltZm~k7$yXj;)C%JQ%w=Snl@|-r{TNn@I{q7wf!Ifo9BhabYBAl=fkB9
zt3Y3L10idbPHRJmk1~rQA-^4Shxb`$k6fKHTc_7jEev~8E3tKr{%y7yZRgz^nS$P1
z<z$-dhJ$8T_%s3edw_jh@y~x%Rb{|zmW;d2f;S#>0urWZCU`OPdcPNG3f~nZ3jvL|
zDYrP6YhcW&V!TyA6!!6;X7cb?I0MQ;b!j|J3(6{Eu2PUPsl;hj_2tu_qe_&8>#uns
zGoY6c*zmGo1VZ7b&8>q|-Zvq}moo$$z8oZce4YrKmcJTO0v_LY8CjQVq;}?JCQ;uM
zk~6OAT|iYP!plT2t!GcHj9i|X9(M<{HfPZS&p+;XCJK_(eF$0yFh{c~-Q9<k%D9j}
zEzg%Ynl>b@OpT^yPh0!8DIMMekeb=@^+<_xI!7B5y&NALmR15hQPA>91U?$YZ$I2B
zg+skfeH`9LNOL$9#cU2Aw3Dp|P-g4xxA=YWSvH=y@lEcvjSZn&kL?Sg5Ezk&5Rkmp
z(5LNgjCsn8$xavq>{SV^1!0+ASXAB0k<V%yK|dT<abq|zQmMm;JE2!uw}rdfn1<!j
zy;_hxX?5DzqxV|Y+yl??%0<-))mm3~8JdY)%26SZ)MheU>XRP!(R2*K8e2QuC|`xZ
z_lzeb71<RK0wC~1h2*CsqBDe7g50$C3we0M@QmN93PQc&IZb!8l!*HglZm;gJq@|3
zZA@@ie_++{y&n=6LN&24SXCzc6Lg<DF&9s~zf0Qfjh~>Q&iD~Lj^wR2huFcK*2E|f
z)Ck{JX-)0v6SR8X5nLba=}yh5$`sU2aAzC1BmY2OAa&DJy(8c^8}3&!UnY+~n4OtO
zNZexVc&4e$I3;Gdv<LKOP<z>=0RgRN?Yd<fTCUy<rN%4svLY?}_tjO$2XB1B0KSXQ
zZVSq|b0y68Jo7~UeQ~&o!FJ#ecW}%qpF3ePzWXo)TfO|Z2MG?T(DT$&2%~b%{;52H
z^6Ko%9q5gybrc)MrDWg)v}KVaxn+ENERr0x+7BmIUGMc_zYM8C+54gQ^Xu9)#cZpD
zsp6;8BYr+E9>69JC3~c=)mXD^6v<He>d;wpvBpZh4r{nR4hO1Q))I;l{Ai_=cKwa1
z=l79XQjnN#0L*!NCVTed?I}fRm+RS@JfSapvQ6`&$h=><Lj}ZBf_5&MLWz0mvChQj
zI0$NkEKC*lQ&LzYS^LXstyY8ZZFIu()#hL=1`*k>&U0bHqKxxzMM1RYeUq<k<n(cI
zZtOf&SS(eI@HCfK!p}HA$Gc{uHXJ5ep=s3+qTIb=n5$s*qov7O$Cv?;99ODp*;RuG
z0ownt(rDEYj0UTzh_JqT*}}G%9MZm?-`}&+`(F*!WYpNhPrlkw2WaUN{|IGq%TidK
zr^8c$zeVgd2;!Z>o~-sC{7VtF>D{+qM+8CG1`id8jgC#OLVZcpWx(rp{)3Lla+NC$
z)3IOj#bQYRjP3Arx}cO!Cg28oX+HrDAn}9Yo`vjM!jqk|pd#BmgZO{pVg$3>tS+u4
zk%5x&2|JT{T#m^YJV)!d`bmk2sg4F#oTiO&)dU(#A@=O&lm?S@Ff=czpTXnJ>|^sX
z-R$9@xfa7CkCtH<muIuq>RF&Ra=XN{JhM98*thU0zJx)k=LO&9qKH09%c)JTKVQ?z
ztDj42rbyymCFR$;*R$+Ktv~8v+#G^p#aT-J5&+xBZ4$nxTY-xqPY-RnJRT?;`r?@h
zT*a+&ttkMrP)v~pb!$;Ezz7#}+DEfFOCYQM$9N`}fB6HkO~&~#zKqPT)Y`q;C;ouF
zD$Ocd9@PeWZT=Iy)H~n1__O_Aj+6?xS*YSE7YD9wajoc?Yz|dgTMu21&Qu3f?E+ht
zEw7hXL3l{#uMZ2LY#`CD%YmD~W^^3C{FPMR>bB!<IAy>8Ba1BqGr@WnY<L1rb!rDQ
zllWoUE$Ss;VsCPg*c<lh09KIxKJqgner^e7mYluk?abafU5;f@CcV)c#llRUWki_|
z%ta@MA%?c|P%5PDhpdlvGw;jxtRN&J8J@}bwIL#`%bn%8%H~t_Yx6WDg8u#nAFr#^
z;Jw+NztgrOv{TgJ7X1&QT)aVC7Q3j+(1o0xSm*~id?M8$?45c%Xn2|xbyqzi&^}b=
z-&Y2ocFMzV{B=4B1Eo^JT^fz^AuZ<`-?WX79h_S(o9%j@8;@`<iQwE7T&;tqVR3l6
zgEB^Kw5{}e!X@+$xFH&Nx=H$08E<K}1U_IMzXhT1d(9P{k_NZ({Wh!6Fh0oAKQ4&c
zPTn=^@`gka#kl1T*B(V;KSc#U6iny~AWI7A*Tg>d{uu9vfs~{MlTj*-?U|up-y?Pc
z-*h$zcSL}}>VHV;+0ZNt3%VY7<`wwMC)v#(+%XA80F@aM9EH^-BCuPjh<U4;$Ivu7
z)xe}P2+d!04v%H{3i=l`UC5}9!Vm(d(QEh=Jf?uBL30=3mr~}gy?ry^<blkGJIX8v
z`|=%a^Zrbip*n*#AI3RPnW4-68%Y~eUap?4Z-YZ6$yuJXNA0(UxSANksv#V5e5InG
z>ZHHYz7uW}mh$|W>!|tMm6>~4JIC)h4^XfLaGtnAYjQgUOK34+Npi`rJJj6L6pWA+
z4_<iuJ3L2r1?ZS`sVaE7pxU^d%%8P^(~Qz}Yt#~lw^W)s-WD{3l3=;}8!hMerS5#c
z){+6XqQj4XO18!vsVuG?9_NyLuF8I|gEMzu{!0EJ?oLWcM}T3<KeAL03==jj$lo%P
z2$(Hftvfr|j0s|R<JZ&MiAgHxXqgU~E#Jio8*9cr+6pu?{=o(8egH%zo8!SZNN0dg
zn!WYcB=z0&cM=(e$=@c_HFKqmLBA-y$xlRo?4OZ%j@&yMLuo5LMynjp@HcG%Wbq%S
z@cNG4yq#4qVEl$UVV@%TA4F+^4@SDL(Fs*w`auWJ@c$s4U6d}D(Vvi{`#*D(qc4Al
zuRKgAdCc-z{`}V_=TBgJt)I`ok)8xdD^0_;usI#t<J_KXo~TMZ%%x-eD>wrv00x-1
zD!7mChe`>T4zL;3vHr7(>%`v8BXV%8vA^i?_mR5+VG{RilYcL14GKD2@^wV?BmY(W
zH&TdV{1zySj0Vq`_Df@>OBesW!yQN5=^nxKd4H(8FYl(UexC0?QXDqesiQvD!I?-x
zK_rTkIxPDSr{@|qF-%6b4{Bv$|8N+<1vSO>4^Q>wZKL?)+^4q-YIwMQC!g(mD?fAV
ze?ZWh#E*sGL`(aWhCYli>dy%GX4|VjY&+Q3fDsdg4PKQ)`#B<q)<0>7{Xa|sc!~lp
zJ~;quR{96{m;Z|Fu)q^^;nJ+#@{JMeL+VfSbpN#w1B?!l_6(fa%pkna;?@Tba~cBt
z*~s{>eQp``e{?!>04BrrefuN_uKFu$`sc>nuv$VoqwQx}O-$1L=}D^(=5A)SwT{%$
zggAx=fO%zkSTF!A2|YIB4G)gGs8?->w_&teMLFf}j2`j18XQCnGzb6U5gPCA76wjG
zQn$i;d&w^?@}y=^)qVu5EVZF-Y?v4rGGNb#@_UYRLd4Z300=46F8srj?UfJ<OGp!u
zZ1^ZLog-|MA^MINf9ppFJ2`v6I$4r9P`=Ecj6tT+i({~k(S!7ku>Gc8GH%Rmdey5b
zRIb7HH#U?1lk*NJh2TAVe1Q!N3X;@a_@(Z21IJkOWmM318AIX;5$_j}+8TE$C@AbZ
z+Sbv3rlqX9Vb+wBt7y_p$Qbjeh<06CHhP~c8R0c{Sp$OK{Bkb#uc{<fq7u0!ux$wk
zXOW6Xn?e_(J)F!ZJhl}*#8pxqH%&O2t1Rt&FMf~&20{*@EZp{d_Un0f!W9Y-`cT`0
zmvJ?T&VLsauOz2P(3THLhT!T+H6eDS2X@ink5b2Ibm;DdBG{^FzI`0rBL{S8P8QKd
zsqPiJZv2>dCi&2!F<GKYQFD{DXc0kCqL;#<y=b}l`()HZp-Kmj#%Ghu8!W&~A2+5_
zGltX9E?6F2#!59?W4G_iVu#cftcY~#|6uL9)2q|i_HE>=0sX7J09}1?u=0N+Fp^l|
z=UvmELpoWedn}&j>&;RYw6f2_w9MS-G~tsO?$IGv0BKT@m6o=&53jrd|3Fx{!hLmh
zRSTpP;q3yIzhkGJEQ&oLp{=s!#QHuUH=2aI4(jQ8?OYm5q#zM2Q3Uz4t=N10uPKq0
z0bV01NPFGh@t5^7J|-m(Kn;;o0TB~yA5VA&zq~+D`JCx2H`zl#g+MArpYoTO*P29p
zMegrEiE}8|Y(&9Jm^}LQ;jt>=PPl~DBmKRr^<eR$0kH%8ns%__(yn3wERGTCXnGkZ
zEA!a%GpoBZHY_bKZ#a+Zfs|>MGY8=2Aq9)zUQLasLOu&#Li-@Bn2(Ou6&bNm<#+wF
zsGl5x!Nder)^UdsnLBjG(v+vnt<9-7TJW2oE@l-$@q&7%#?vIk1Jj~V*9VA)=a=V$
z5k|pecYof~mShLVZ=vY+sMjs^r3a6el{rcjS#lE51i96Ql#}^zluF;flX>3`4Sai}
zZ+wjnhpZaK138SUF(FQ(Us|$aF)vU&sx-cT4jg1gzFO*I7aYzkS8u&TO5suc?v00$
zV$kSNj&bs=!II9EqfyXDoJWxoB8pm|UOk2S=8+-rdJXsPs~!;n|7bsc=X963KI5C^
z5v9>+E^3Dmj+>I47?8ul!V(lSMHFLcXU7CUus?kU;YKvW7FZEZH<1B3VU09*`jx-l
zUmfUb|L@g}@O>eV87f|1zM~!Cb{#-z`L^swKgJ@BfP$E~`T6N(uR}MViHZHnqy^$x
z2Gd{=gc3(`<Pt<vZ96k%XBa!vPMhz1c)aeb`h@qMy)e%o%8)SsK5E&PhZ$}D`TVrH
z$~QbZn$R-rY)D@8U%?oFTw%fY8%l8|B?7K8jLP<6$`6chb~gOu{<@-&$3Oh;fjl9}
zFeqT?FrtYha3o<jzkEB+gz-XGUjC!|8T^3Q4=^6W{{jhy(*1Z)(J~g*UT%HT(o$-<
zQs1cTs_l6ORSoV>MI`2tOaMz9lcjLkKGDn_KePkd2F?2Mg%GAX47XhgI_{<3Ww4sY
zDNo)G1JujyIJk*q_1cc)^(>#lzW)B9$D1Rgt3uh&c|G&(o=BN0EPq0&`&>*tTFTUG
zHAudzwYnV8$fmQizBGl73=YNs6=NLRCdXuk>EFthOEt#f$HSBAYCJA1BB`mVC7UV4
zC1c;nnW+J;32<%Sp>kZ>vR0afBP#)TQfX0kQiE)oc^Uz~$77Zb+C5-J7qKCF?|KHJ
ze|fx7T|}vIyI_pVOe8;9c8%FiKpPqw;)v!eM&pA=!@wAtChr`4&fXgujLjQ;0KBJ0
z@kl8sRCrtti4<vO2LrdZh)KQy_8)*f_3g<@0f1$t71pu{jR^P4E5giaupgT#aE6pa
zkEla_jQQ|!77>iL#l<{YW2!+`)g;W*CX7OrZmc7t;AF^H>XSDFcp!y^TM}T>pE$ca
zX0(yhEgow3IotQO<oawz)I=tmLRE`L{q*5Umt49ZN#_ditlRd#8c%XvcbC?Ap15*Y
zrluSO?7Ab)E0iwU4ll!ZPB?XvRdrsoBk=h}=F4=-!81q~bQ}vj&NRu0D`LyEs<ohz
z_VbL(*;n>iJ5F{x2ebHryh-7<KYk)n7lS?_-KI%A>*;Rh5FHac_vLsddgrd_y%jF8
zUatp~yZP%g*QC){Br`?6lt}#NNX>7c&VycwpIPeySCCLh-nNRlD4N%TzE5MSHD93k
z4fo`lkH%L<dxZ?G+k@}m&v4<14l6rvYqWe0#8_-WTG;uwKHSbfFA7B|wcDwuX8n;5
zgEpndI?05<$rJ=(Hy}jh1#arJoG!>O=T~ekOHKWrw>qA7dcql!02}n>{Y3!UqDa>A
zNcDPqk%55nDDH646RJqJjzNRjfm;c<Wdze9r+DU&X1CdmINKqlu~;9w?{=$&!yHW}
z++&Ez6@?jA_U%yNskf$xj}la*kVz?iSvZqC6Y$>7_2sunYsmIF{7Aa}j&4<UWLWT>
znr3<Gj10w75_tBx?U-gfc;57Q4qM!mJ>49U0$ge~if++$T|N<&Vm((C`8LNrhRdyE
z!tK*mn|LIFG?I3Y8;tFfsrtO@<0Z|gbgm(;%93T(*L$T2tZ2`2k4sElrw%W{Bgz9o
zy&S9MCdKI)*Fgd6xM0&r6Kl5a0ZY{TlA;$CjFNpMd=4!+!7a|qqsOth)aH@UYU4l?
z7q$>zLBkfWr;~-t@h8HsMYrWU`SJ41<?sQ}NU<h|2WK-*ukuC>5osDN6^Us)kR#+^
zpNafLqdwHZ-x;nZ+qPU046W45PUQOG@%pr_x*P$v-7T(X6z{I?3?Sc>6TtRocz-Hy
zvhLUtt$YJoQ@F0T>>D`3mbLCN!0xtA%OTcyfO@Dg>jrnfxoIqr&+aG`yic>VjRBnU
z1}O=BZPMa-T~Bhy29}^dq$NyzN4ix*Kk8`lS=v!e>o8;^zT00?vT3>Scz7Wcxb4@r
zPh`dcQKe0>x|kGWwy*K^Yk7}3*LV-OEL9sOAFrk|^oB%F7T%aW>>gEKAMDZ`RE#Yn
zkGP!h3~tE_kP42bQEx?I+m7qUA(~lM$}S;qyql-JWqPDt9|?Bx+0|LE>i~uiay7NJ
zbssyd3`O&A$wjO5qp?p5WPartI_ae#wOb<&Tn-SLS`vEKlr3OD)Zugm=;k0XoIh&T
znNfFe7H0C4B%(h-nkLsfC=difO8$Vfi2ZPCoBK1jQ{9Z7fA6j{)->BkiakGlsxtoV
zjO}4N4=F#gV-B@kyPp3MJ|<Bb^Xo_wz4y|MkL{P`PNp?+v<N?bz<ue=_DBABh15s3
zFEE?mi)Gu9TWBjDYY*P~6{kWXd`uxj?|E%Isg<0W<}N6+tf1pgzJW#lyhJ!m<2rzR
zaCxMAxZXnAIdfen9w6ZS%Fuo+Me1ZY5Sa|*>%&iH9i(>_wfFX@@-dDR*>r%ifdg~_
z*z;`{Wt*g%91A{Q&^_qy%A|6-MqRl5O%;*9=!#ixYxcM|^I11d+n9>x7fr8}hRHh+
zVnVn54n3X2h`kr$ydDs0d$4ZdXY2l$cIRw9KEJSTHIv%Hgv7#wEccW%1rIDBz+N#$
z={;7zAnoPl&z&@+Gva$JW|>^?<wg+oFL)V3#;3Lo?5KAK60bM%?&q&hqk1M0;T}hk
z3#0sa+I3iEe7@sI;xNb|AGF~yHndhYG@VbXP<%#!NDVV>76fFZm40wJnb-d2#DorQ
zCcMvt!^_O92)M{IsOtEHJ=ZuDaKJcm$|DncpLcv}to(|nLk4Y)Z-4gUzmW3!u;E=8
zeZQ-D7K1LGEVa^bvfTkgpdkOC;r=`oBD?y6^sE%UAZs$7k^3?~F|-ZGI7M-!<56aO
zS=e(l*BV_n<Ap34@kbn$-Ku}z!mSmnc&?!I%pBHxZ?~jy8=IDaL1o<%Wb_5Ki+DCg
zuAQqZlqTWeDoL7HBEf9}k&vD+uOa*zy;Mo=CGuIF-&>b3NI*EZQe<SH*RP!@rn15R
ztnDOT%Njp%fcSmlE|cov70}=zide0)h%jSq93$@cz_WK@KvD&3bMg*9plY247}apP
zd=a&p)IzXD6A5@b=R+Y9h@}aI9Z9C2nOfl8K4}CcHiA5QVL$g>CMN47c)s4MnhL4s
zi3=!3Oos^+`Y?;ZC~Fs!<~61-WNbKZ9T-(6MFXawJQ|OHC@kMOy@950YFTDY@g2zD
zD&U+#*$E2jckuT(xqCigz#qJ+zu4UyfBAa)cy!{h`LzhEdYsW+8BU(#{C4V$&-oDZ
z&rCn9VXcWbBValaKt|5ae6ee!<@*WllXIuXVhfU1&8-n|u84(vy2t@X+;{A}y493<
z<GC-JDs;LoG0f*8Fv9{S9q{)%Td3se`$LUAk}J%cwX2r<(fL&we~0ms1H=x(N<eT*
zw+>bqWw_kqW4!ZGIVJ3rU)NvfUz{Kh`P0@roA_5(UoL5Y(jY>*fBwr>QT}0wk|2JB
zA=OHpKd%z&Wk{nX!x8jQBQIuC6LtBAR&A~Ij%jS&tU`PSBCWcz>C(dc=69k1T4=}T
zIXQ+Duh@&6i-h>Rmp_A7JDf8+sg#7OXOGI=uxAs6UdB2_J+%6=N@-FuUmf`ZQD3^(
z$5O~Sb$rWnZ1Hcke0wARJO#^gEIwMywbXMc4Wv`pFzuJWoSwH$ZD*EwkLx8=o_Xg9
zzQ#`!4lBtEn26^a26A)t5myRq&x%!HN@?Sz50L#EAVfb}U6jw9RTj$HUsqgw#iUD#
zss<W$s*Mp$CbYFy`RYqJzEXbw{wjP?*sLN(6@v+D-y@@iFn1M1^fxgN?PNX3^ds{Z
z0=FqxPZ!I!j$c8qx*2?%-u4Jmmq59mjhPfvXGa7l!8Yoz#Z?G@s3SyR$`=2g_M@D$
zKS%38e}6iQomOZ&g$n^w71F_lU2J^3VcJPGQr-iTchTFqyW1KU#&M4k+3o!zM^=5Q
z6<f8T!{;hV85x$m)~U@Oj>V-h@$s}L8k}%yzRt#|(bC|+xqw|*@8Z&VnvVRdM!lH^
zYJZ6GZV$O-gyRAmxnljM9wkD{k0-}Pg1VJYu(1{jLb1#wzvE1Fq<_kPN3q<vZWMvk
z{}6~p{MD3L)WgcKQ=8MC=OJ{hVKd@o5vFpE-VWLOj$<0Vgv(ISggxMg!LaPMSe5Mg
zDPI+)L0Vec;bKVlhf_9++Sh6%tWeR^#oGefOpe)IQAf^AW+<9Kd?bW<L`@xSx}(#J
z9ES0v|N5bY_=l%;zks9q%5SnsyIE#s6L*mSF1L6A(>YTDXi0Ml%4~Ft{CeXh;~Xx}
zPxFQd4UsP?(YOca>sCk1R$a4s&>9B}j$Y}Y<qcoFbl|oN&y|7x!t2P>+8u*R`c^iv
zwX$Zpb{qH&#jn6r$RR*39&K;<367sOiAN^R5c{Pa5AE!Cncb#;0YU>|G^=0EL($!O
z!|ubGtL;<fuc6JTM&sGJZ<#)*`@###2<J^elyAa*v@axCM6ID_h%Dv-#o+!F(J-ML
zm{8FnpJl1{en3YlRs*M{$;H{4!=fD*Xmu(DhoGLE8+=os8TObAi5sg+e4my*#ClN7
z8GP)C7;>?5hS}N-{fG_<pPZ1HZj2j~88#k!GWNa#XFXoXjZn9KY-WhyUbbLxZQg~j
zy(ok9rtoV~BKY^ipq<<29}^ZY^V6(laDRi*u|fjD`oui%Lase%p<3$359e?g(AsVj
zn|TMY|LRnJI5z?!f#?a|G_lm(thUU}>!f_QaC#t-fM?gc%jRuFHNV8<&1$-=Y7e2V
zw4=D{_i0Dq47E!P1%GYPYnatqqOk91p_AkWj?}HD&)G8T7MzZjhc$ho@M^u`sk+Wy
zjpX~ar+pDEV`b!3qJ{@vt9A10LDjl1z&ULw6Ow*w<3PA2z0bDIx%Rt#aCovp_#PE`
zr`s}8bELM6{F9%fTzmPMqmq8%4~%9~GNT&y>(iQX)7Ei|b`SKO2T{6Jn|8}g(_Qnz
zn)z`HFR1-AYM^Du_|6cUj(_@b0BWV-=_R>)c)$nOiU4@COQ-hoOLvlF2=YFjH*@z}
zOEiiVzuKwLK{>tRqikSLPkRlkVWW@a*S*y)&rXW(e}?riAXm<6!SCir`MKj_Q|V7u
z8kph@nsvtz64Jr(L#6naLy!XXrV~c_n{W2Z+<(6h2)`fbW^R>J%u{ih>5NOb(}&x$
ze}%S2g0*=Li)e5;<6g)e9TQC9p<4KOZpg;Ha>WSGj{CLb<<g7Z`!^c4Zvar3pDv%L
z2I%)=A~V-h^0}>C6VTD$D&>siDamghXKdbVJGrO5zbi(_-MhU$D9<f>0^yTbhCV9b
zh-UGpci`iV!NocCB->{qu+Qgwes*W|c>O02GzEU|Lj?F;><6e8fq9;Z)c27m*>wd;
zHJMfUD~)p!&YP9pH;E7YUrt63)@Fe&r$^|-RfjlJx4YvVwJ9KDnOr0WPPTy#j>7X3
z7g4cT4h3qNmR&W(WqS`Z^ySnAKdoCd{=>(ZE`3=d5)u)dBi>27pCTycpRV=2xxafk
zxVt}iRI|lUgxUKS@j|~hkjO8MI7U~2tZDDhem-@IMKeikq0oX1zgx?9rvN<@e7A7~
zXOD@bv3TVSZoKZ9MDZ=4(TMKgA1|sOUjnR#hKG_D7hxUO>E-j?RRy+7`JPdKWJiP>
zoPpZorpf#^@dQM6|GlOPR*l#u4$Zd1v&uF*6N%4_8Et>V3h@Xlf}&6QN>S133wIf9
z8l?pAc^|=>)<yEGzl;>1A74h~2_;Ju5%k$ZpL!?^@rePAmPg)@F~};0KEusLvi~>n
zgun?X6s!r@R-LzMLLNvOR2KuMS2xf#OM4O7>{TUT|BN*g{N5s>3wRItA+a9~9Ggww
z{XUyGSh{QLbzacotwR+@t2KP%L3iezf=*=wDT2>ExJpiRq-MiL*qh|m&Cy?l3c+PL
zV2<B^E{+r0GJ#k8a~Eje%RogH^M0G6larGq{)Tf9ItQl;ZaLKx<I!-%GGB%DCgMV@
zcxC`5)@CmJ3dbVXaR`-R0@wV@%+j@19MDrAK0;C|91yoPfr&=c*4A$KB7u?_3%v@@
zocn?M9c7I!gOVjDblOLczu!XJv{S9F+V?j6{UD&F?U3iXzJU^L-8!)=p+j3N8Srw8
z^=iLpdqo`mlAW1J@9A=uWKvSH`<H~DUz>sJPX2NqRbKk;lz%h;db;IGBYlly$+=A_
z!jTJ2l#76Ee4$1ckXCtJ4pFiIx0_+}x|AIYR_T(Edev^}y=mIE8*@eBuuCyCZGeB3
zl5#k_RM`HK{%;{~`1oBahgb{Q)NNFr|Dx&n`AVz#$o5VONEmiTN^}RYJNeZG9-V$W
zoh)n5Y^P%@8EiQf(x9`*P=|TJHZ2(n-s-C)!rlzuwr=MA`V~<WeE%oXTgP2dG52e9
z8*;>-NL*aaDjhX7j*8q}+cFmt`nG1EK>1ZxHtFVQet7$8JnpRHP4O3-fSh&HUI$Ep
z*cC>h)nc$=o>fA4o0yo`qV;iLxf!$2LoCfG7sIsL1<ObNR|)x%z;ADjUIFD?wrefQ
zHXRQpK)MzplgXnD+=|Dq%MDXU<}IGeY#5wj|A@_Uw&xD``g=A5X8#Dar4=p1=hZt2
zzHEQ~>%lKNZWlYQ{r&wo%%9L<Y-*U9t1oAwYj<*CP7^V8eY61sZ__{rKpI(Nu_LwA
z%&HBIKw!W(tBsBQo_8Dl^@kGwp`?_4G=?*l^JLrs8vL7Cp;0fjJN_^fs_lp_b-Yqz
zTx+#j)$LX^Q|SGk!6yU;ejzP}xg}JvkBpPW<s7avUr%$Ajf<CE6+o8`rTwxUqRzUL
zECv^u@@o~id~q0%V^Ra8xftL=MBW|a;`Xnyak2ui=fE|hMvrx8Mki_PyIj=NvXNcK
ztIbL(l^W&>^smOT0vV&M16IG>%Q=0iVA=WhNOlrZkTna%NEg|2tRWx2kn_lDXI-DJ
zX)?4PvnVxQTwF{8w+<>nSA+w%MUMC3JB~6JmgWIh4PL%qqShCN3T2Lh2qn<XWheMP
z^1mkv$=P&7%}?Lu;)+Al|1Oqng$?)v9o8j_^%4z~o0Ju`spI9izG~E&nFq293a*FF
z0upM<Eg;q9D}qPg1MW`{26^7$4-GC-=ZV8lQC!@~U?bOQ+CGG5c+L}U*UAef5t{fg
z=0)LAT<wlCbH442Bn=hE_HHi~WheYU_Wr^tuI`B%Mu8A45Fmu$uEAw+_uwIdJHdj5
z;O_437A&~?V8PvWaCeu$Am1U$^M3FB1MaQ5Rllk!sDU$c_TFd9>eZ{eyF%Xd0mcOF
z_2c?+bW98*kY0f9_xa}C`2#Hh=N;Y0*58_?4Y%Lt8Vy4zzuN2p^KheZfI0rSHG>Jr
zkj>^OO!CnZDA5>vi-5gF=@zM4YLD~NIE}&}g7~c|q&68b0tiCw{ary}I5*yP>k;(C
zmAT)V)}qLT9?Z6Ab%zRmux!1gPGaAdasp(;{Wsg`hT+BnN2EL8nx-6!rY}kr7F5W9
z0Z#@b1W<BER*>}{LOosjaR;d}Gj@=!6a*O>8Ofw;6a3o%v#^kwf(YQyj^D_)@YNi@
zSwn4SViMGiH#s^S&C0HTN#C&<5zGZjjyC`y;+IBgloV3LR2=~?V_}~mN(1!<Ymgf&
zQr)+XHy6&CSe$t6ju=S5kENl4&c&FH2mH{~^Bk*I?eBZ0tx;8vj(N`8eDYWq_t%RQ
z9?kpOJU5*|(JGF@N8okkb$N%KS?Q-R1U!eqitl5&39>Ocs=Gg-NA-u)H?DhiuZor)
zdq}|aDw=j-l+@JyTSF<;BjEg67?ASmNYs95gUr!QkJwp$)iA64jDX8!{QjeBoU4FE
zUa)Oy#W}bSr%;7kMBuRR`xJIUZ>6DZE|4TUK#sjsIU6~P(;E6A#B^TDEjx&0#+y%<
z<afh$hlV7MM1^1|D=_1Lm#+e;Ir_X7$a1o_VSFjJB8<T9(<h4dl_EeDEJID?;e8r-
zeb5(w1O!Iz8s80rd?-AOjQlV57JEP<*`c2-{QYVC@k-whA3vVZm;$Dcb0c)hOd%F_
z-Z#BO`vmCBlv(<ZrBhC)>-&g7Yh^Qbp5z)Xt0mgjhemBlA^}N!Q=!wN#Rj&o7h`7^
zRm?wc(BxVjV>!Ln$)5GJwYUmU6Z4OPB8*NkDI}8}0|z|4o>5guN1vv%;+pS_>dm(<
z$@}$Qj|GL_W_lT2ib?xcC(9wt`CL&s?D44@O=dMy%Ty9pTU^@!cm{wQ7^%X5m4U4b
zmYHg_BT%dV)`H0cIu<=CC-EuAFBCS&{9JrxwcZMu6IDkd5zTR)lK`YN){s_@j4K}K
zmuKW3RM}`z$%Cn_>3{C{ND8-JgcCvJotkYoew$#gHP72exS^fGWO)Z0w3jmRnlQ3`
zfVNEGI$m2^v;FwNM_OH?o>Qn5wdKf-u=Z*Vi;|03MXIpptCPzR>o<iHGS>2;Vp3}X
zlsuhzyB5cl%KO36MSl)r_kXssC=JGy7MA|=tj@sw@HE~&xx@9v7J(rUx)?m><46E;
zq@v)1a59%w>Cj@@m&^Xo-F#t6)?z|HzIJye`RJ6yyip_~hApfw^!=*wGBlP4v{<mR
z;9(y(jC+6~?8BSqcZV=?^`Ut*NIZO>C}I1u^G#Yonl+vMwlxZCX!fL7=<&c{LM8mp
zk2ji-qTZVLy-J{LMYy<v>HMc!3&oi&XxiSTR7yO|g@)qP*e(#qW0P!kDCS!;V8~`q
z#Fk}FVK+6{ZSot4SLy}G{WR~<;OHNhUWf$$aMviZFXL$K&M$A#Cn7b~wcm8U&ZX+^
zY(SI<KAsGap9`sRd!!Tc>HP?|43D312daFpFE!b9UZc}F^KJNTXT({r(-hXfWW8^C
zG1zPAhSMk>!}=ZVnAQL*-OB%p3kXpi%E!e_&-Q8LbvPpLk>_7RoxU~PmASFI=e^nX
zx$Xn%i!cr)bHoXyxs@(BL5C{eNqx)4yVF5mEc5By!nb0g=9T2MoHxG>JHMEsM|zyE
z*|+^<6Xm3HtrNjd?eKWX+1}IwBx;H8A#qWCa3664B*@C7(=PVL$pNo3hPv{WvCGtm
zg0tXVa^-r=%&sokT^;~T6KylhBlW(lsfHLx;BLtS6a%p<77dXh@=1Ea!<j9weomSx
zcgIZSnSefD0~{#mwB@${aRZ7sL8XF-yy!F|FfNZMx4Dh;E+CvJSL6EVY>S{QIci=B
zjbPWaLL-#x>oSof9-~Gr+m8T2UB|VK02001@-aC<aj5I*631<x5;a1!-Oi{sw8|w(
zX|}B8E_!erb7isdIub}dq15za$oiBQ2O&i7Rh-wY@HZfwCAr1Y(WV4a9aY4X#(+hg
zmYMGU;=G*2br!Q5(xJ=jIL-X9?UZ!2$o0JwlVan*W(21iX2q_!o7V=PnB`SWa-u^c
zs|gxK0xS10=b}d0auLp(<n4B$w`A2b#RpFH&_q_=mYQ(%o$=g|AjtvvB{#vfK#C2Z
z6l)~9(B1p)a6EeBG`si)<pn1Tr$4As*o^{X&rJFMB}ksp_zod)X@bziev%Ek)L6YK
zW6tWs&2GRX{e+=u-mzZEF4KPg3ytXJ5ZXcAeB`4N;MN=Rs9Fc>^i6YFxSDoiB(0=O
zD@zDOT=sCVn6IssHNqrdneGgM*0kbVyIdw>yuT2lXd|BWH@ZT)kl(jHA>jlnnNUPW
z5pzOd4Fk{Tz8LdNc<EDdwwH>%-PqWWX__7yyixA6OtqJOfjCR*Nipk10oOIByF&70
zc0^VaHQ6$JdNwsIsZduy@Zu<;UMN7|-JlkdWj8KqTy{Dxzt+X>TC+a=_je)BM3BgW
zcV769>XC?}!E#x<eC**w2vJKC<Gpi0WapOSfVo+PT@%ut5*4=LfLqgjMvRZo89M&h
zqBPGr%rz=E=t&)GEE#${F}9#y%0ojmhn7Od<oH{-mFEij!aC?pl0nil5>XF^=}OxU
zKG?~y0=^9D6uX0}OLTWtsq#yrCCtR+KZXOd7aelqvo)pvashzK^<qK(Y9bd0Xaw4M
zX!Twi%y_27qjSH7Wi?)|E$ka<Y)*y~*K)bB2RDifTR7$RT+SIzkP}<e&Tv+wSg15`
zmI=@}XdC!o=SBNuG5l=8K8Rin==>qBL2psyaj$AW8}ayXK<7qk^oJ>Pmdxyjvv6AN
z4t;DFE&na-v;bY$r-gVx4(Lz2pAix4KHEBlkjUU`w0NjLTBIDkS5@xvVLAq5s%YP3
zwfS>Cp;ck6S3fUkj~YSAJ*B)}-_vsowYg=V3^dqRKiObWY~wJAlb<Il--u1vs>}Z|
zSG@sqRr{08NzA0b36@%1-qA`fyZ;~46$buW#ATQYN}5#73)^}GUrV}=$~3Sb>+Dh%
zR#efGv1e0GpW*>~6|i|@J(sLlnGmlR-EODf(;C<U6caawcJ?Wb;iCofCn-|CW?dDn
zS>5i`eZTQ{t@+Jn4z&%cd%s>1$NU-i7qIlbcu8th%RX%?qytt>#pAS=V1Oy+M$(oJ
z4h#gHs~k_gWj~~s)AmGXag>4z_Z8`CmlrTuc-DpTo;R;+>1roOgmw8cUS#iAYCD<(
zW^YG|u!vriJB*CbQqHnd`MlZ^o{D<rYSfz0(QaY^y?TCYr#M-L`&rg`$u^wai4yq=
z20T)(8x6h_=E0!m^g9iv+QVm_VO8jGv$ckLM9?U7IG=U0S%=b!@Zb7rqwwvma#dBt
zk3nH!V||9fw(jTN&T?M)fB^}RgNiV>J}#EDYp7;)RHGO|avlwCQ2YC@Qvqxbv&iF>
z62V^%=dzbSE}7<C`g-agea-1&(Ep8IhF|qv&;PAl1+o(3Xqk*&(1j|wR%oz*IJR}7
zDZ>W=8z?sYpyaf0{#IwGVPYKW&9_QgbkkE3SVLVRZGC(Dc<@Cl&gFng>jY1$#y*1{
z4|RsL>d2#~jjgT0=3z>7Rr>nM?h|_;9ERzsjTfMF+?3@Dcr4&q`S>(i5o*MVopuDz
zbAK2OeF&pXckM5@#V+Ee2>+do*@6x>9<huOWM!3Z1x*dgWj8oYP@Cqg1z9+bC89CN
zw34|A3(+*#AL3Iq0x42J`r*eC*+D=J<8HJqSQwJ}Hfz#xj5UGVZ!lTy0c;rdhx54}
zA(y693d$v#ZvlaE^Tpnj#(>!YKTM+Uoq@XWMWf!oDJuepcoEaRx?tAvkc>S^LSFZE
z6Xm=n9~ZmL?*&e;C#+AXuHb2B_N`jC{T96xbL+(q*YnGSO546yH)kOuhTRvYKqvBU
z?FvRN`Nr8dE@!kkMHiZ-6xVq=n%uVvXf~Q1mRU3MHS?FTj{x7vTO1O|@12h8%~oc9
z=KblCsWLe?`V#e;=$C1{KWEa(A_UG9&p#Ie&OH+~CG{)%N;`;hkaD~Gby{60O{;WQ
zbDX;yvQC<J-S7$p#_)47qbH0e3>OEyX?|lh>njjUz{K0~W=c(n^)~>3Ies}GIpI9n
z|CBl@IV3kTVq5g@Pl8n#bf{YyG-&~6ut@3Sz)+srU1CM{<hteC1i%}a>Nb4Cc5`R*
zWngP4FSTyTQ9h;Sd=ogand+9E>dcqG(k;*}vrBJ+ff*fnjy1PKJC7*((z~i^iwWhU
z#&i37!3!og-N0xrZ8xRw=ifh{jBP9mrz}qlo}S)xJn1Cdi+C4Z*(!B}?)mdLo7n%t
z>PXLoCp^QA2SG$re616`H(C)x*_BOFrAjT&t9@;1Q;ouN>+$F~%`;wS<*~b%9YW~w
zOZrx#h?~dg&hb(ovUjGsyHJpQ@aeQOpQx<q>MLH}ve(rmy_AgAWqSU|Zw0_~Wdcl+
z^t+qneZ!q{uiL{-&b)=<Vu8vpr~2z-Bs^b>#S6AW^W0{mQd9NAGcw(#0qMjj8^s{k
zkFgwu<GFzZN(+iVI~|Od%%zB!@b#WU!ug~@*GdWDVZ>4qV|Sy*=&||p@^^@SA`Iu}
z=aWTYT%A4PX}VX2#@l#VR)uaezlqszs|h3|dVv5%IuiGjbWo`IPx(oWFBdx%-5vf?
zFM$m`fAm7cAX6=)<z7zkwK?=hNXV&nEv_P16#^Y<s|NGi91z}Hf)LW%-Txv%fF)$}
z0@j%V5;<boYi%|JmtDH<FT0H+E|ST;?_3k+-1R?5nI;5sz!Q3hpgKytAd{5R!zt*`
zu)As)ulPvQH{2f&Xw$q9!DcG{;^Lev+MMA5cNiNN7erK>zqMz6y|YBsHJhaUa8BJn
z{L3~YZGMA@BtsV=k}O?*0fFc7?*nv96wXbqKfD2jex>EJH|KI2m)xCVWmG=3h2~pY
zO$9chP;PnnCls++i4%IyQSzugoa9$+^vntEtdvcUH%p<<l^QYwoI&;2!&a79L}b1l
zj2d7bzr+uTN@6$ey`E^9YB^q#jIGPJn7~{ju%mR$xze(Vd7I%;NX#SYo~_6`j{0R_
z>bm+AALrSVp$5Dh(}Z)UP|7#~fs34ED7OqXA-kl}J@*I_u=F$r%@i?A9otRxC54OF
zd>xBkBKdGal(!mew(+gF>F8vDf_$7e`)PH_UIqmP1(mkDuNro@AfY&}{f}wXro42}
zLV70F>`vp6bSf+Gc@|zDTEs2jR0YH(U<IRsZ|iYofS7{LpoiFCDM3M6I*RWIEE_Jk
zhjg<u@s`bKkh_P;fbiegMSAuiff5BAtgX){^LQQU$rvU^>rkyg?Cc)_c}woIig^M(
zU#YO`wDpVoZ6Z_Cyc>d;kW6WU`@x+u%e=J^3#9#*X$SB_vyM9WLnFAqYpgpED7Kye
zXKZX<-U$Bgm<M=u<}y0hu-a@!friM`aJ-#8K;Vf8x*+1qDd}GQOh3rrkNg?G@V9Z%
zcC)Asnpw#bPk&bh-V>yLVwuh0GmU{*?GL72wKVXnogR*pI|kt&#{Ba`9}^wneQL|Y
zpUqcK7fIrsq*^#5F^ZFjhFu`#Ekq|YSv*u)x2W}wk}Q?$<($@9@E^3p)6PmZ^jbw2
zqHO;`bHHYNf(vW%2EK7ze&NcMG!sLBp!m0_`SsyBhZV(3$ccK?n|;m|Lv!<aw_dB6
zlF@mK>x#Q|7F-Kv|7f$52r+jDZ5MN<Cpz(|twr#K45P~YVge$M7fdCb67}ng`+*FL
zS8k3SZgK>O*0uW&r|oMCyY+ugQ(*tpCVii)v|#4|mrGpVisschm-m)=IBzxj&)0dv
zgN0WxuuYgVv(f%;x0LT~0M4DGC!Xr*w0k=6a*^L>(ualP{cAzy7SboR%)>xa@GoDy
zUoZW1Etp1>FI3i3MWr>gc|!kgBBWmZ7yuJ21`cH@N<3Ujd+TzI9p@C#z=kj-Nj$h6
zcKyRAh`F;txK+McO6bnZO2_6y%=}Mm;y)bpyEggEaX2*Vj>jF7G#n@t?`+LOd(<Hn
z9e33ybI$R){lJ;l`rSH-x!@yrRY{*uS2iI*fb{#8)LTD>8LQ6*(XX49n|&RR`xmG@
znxG14X8iIatc`<BOAq$eDgU}%m?E6}9G^UNmnVT)hYmRVba+m4J_3~qsc%jDT#cuh
z0<-vp;W1b2q;@>un@09nuQbXQx|4iw5jT^-rAgfw#^Ko|`$vxKt93&^WgWXXAFebW
zek?~lbj=1)*788+eHBe>&1SU2(^!;<omT|s@?(l{BT^=O8Uw%o@v6Pcq(+YYJc<zk
zZ{2;J_yPrGGaG$50U3*0dfEMcP;(B0?XK=e08d55%L+f?UuGQERQt05-17QsCl)51
z6hxh~!Jz(5PHzGKu&PaUJt<dT_q|uJzpN&>Mh*1te~uXpc67m}iB4|SaIS(u2^D%5
zV+LOUsoovSxeEZhCV&xtuzVKh@plP)O%={Hdga6N!^-}0FRoI*>pRbBXG~b6zL22F
zX-9EVC4f%u8NQ^361jxBgMT!mq?ffiKip*)E-mnEb%yhQ&$-xzjBNOQW74Sobnb42
zkaD>*C+knb`s>uWZa1O01$sqrUJ-Uh#M=*0H}AfFeKBz@V6{XT6cIARtb*MS6x_=V
za4-BG8~ja9E)?Z^&JE?(HG5tPx(zCkpr-wi+>E>7vKXv+I{P+_+Q~Wp`qWc43LpmF
zBo9I2MSBoU26=|ZRgiG89>uuW;D75H7~xO-KK{ZI;-E+%B2wC1uDBY&hNfZ_yZLUr
z9*=P<)qPD;5$ToEtt0%II*RuS=Vjdn_iA0|wJBDSoEDJ6`n-OV`@40v`<yT4=Ea!X
zQBtU^Zu7w269-VQ3QI2Aj97Jc18*8m{ml&T8|`lIx3$l1i<k$VT`v|5?K*WAxvNF+
z=-uIl>CgkvE>h_3$o5>o#I=}$nOV`Y`9`uTjM;K1QBYp+VMi<mU7MGfI(!0LqF#rI
zN=zVRSuH%c3Y3|20U`jO<Zg$zQ;dKP-_z^g6#kn0L|<K!u6k{4ZQ!m-OtA5Pc2zhV
z^H`*b5V!%S+V4q!zeA>x0rJ*;DRaj#s0$ASxPpO=tN@ZJ>QjT~jH4%xI!>D&)I(Jx
z{BK7D9)HNSobX%7yh-A5DFt8k%T^kX5GV241>am<Xn8bAt^J_L^?3C9zO|d*pPJzg
zO1A(MK>YUy=ii@jn7M%t7SGzlNl(=mFXscZnc{eKp(OId`NE!N8pS-f>oCCga%?OY
z^MbiW+}))+X}n(P+3t*o=gkpFaL;SYir=$Xt!5$B%ru4%D1w4mF=cC5;re8Gk$T;V
zk(zrU;3LgE+(Sc2Y4)z;SJm{tsmjO%-$8}SdI9RzfPXzoDlB@PTH!-kZ4%&Rfy3St
zO%k$758iTRXLAO09hFY!)aPhBmu55lR0*0)b3A^xNhO54OU(fbmt2m0H<G#lPm^k@
ztsuM1c#4et{Z|l8A8?N5yc?KAGA$uy0YeV>?+0_QT(bKJ$U}_Imy6zKH}JY`6R+br
z?2PuE`g%MDRBa6NSw=yu8k7*w@u(@n`9Juh5m@qDrQ+OH^4aeFKu5dnVggz0SI`b$
zZX^C;|D)Y&B!6E(ZRt3MVR|8EY;1^EA!ftU((F3OiUsHw1<8S2Kv6T*Z*S*?bjScT
z)BEG<iYwTBX?BbGqlJblN*bDh-v%_jfQGWP5r@pwR3i*V|9ukCq+i~#Kh?92%rHU4
z#p`AhSHV}r-26BG^PkYj0<_-Q2)BwfE0T~NbiV!ln(7MTWsIQ~I?F^y7Y!sd?2l1=
z)Q}A2m)RQ0potj~lG^&30UA%9hGTrbx$YXq-GT8RGW)3qr}qLRj-E~jkFISRj{@>#
zqUKb$&pD0+(m|*REI2l-fU7nuXwsk5t{U#C0<zEo4ViuW!<;%!r|byaQ-f||ibFnI
z79T)bOhQRN*wlxqZt3kjWVX@u*g_h1Nwi_PCl4r5XKtIfo1<f2GXuimJVn4BeA!JQ
zsRM$adb#ACnB1a2H4YRM9N5lqFLtt*)^sh#JOc>FuUJjPu6g><ep%+^v*EkLg0nUs
z^!{1v_03fefgP+bemd24y@b!64bMJmcBoK<(ELHa-;jKlJHwQ<FV)A!A;7l8{*~aq
zlTjU{k`<=H`p|xX2h`^NTnS)FId01z)nBLP9R~rDpBRt*_MOvVn1h_nZ-TPc!uv6-
z&FYDfNcvK+`or(0<)1J#yN}dozYWj_>J7p<%D9LGjEcdJOAubX{&Rp_WpRR*a8<u`
zj(s384S(Ffy==*|{5?q5`26O1B|U{0ik<ik3sKD?C65HL#|7pDLyLYFTT+%!8?}yY
zkoexu15vkn?%Q6Gv(}j<4(*4+IQot1<y1?UcE08G_`L184~L4Z=t$i$_9xbU|7{*X
zh{l`^4i1;11zk`OG8qZ1Thj^cs=%`IxlU-Ne5x%tIOiq8N5xA%BHtPrXaZS0#tPsJ
zNva(C!f!krLAO>lWPg3MxVgi+9*P)N{Q`$6a(AMI10CiWB6>V4et>8FlVEg`IqzMg
z^KKfSL)3bB3MH^{js<vXv3-1ACzh|!ts$un?vE>gN`-QNc=Za)a2;XeUbEJGj)5Wq
zzeL+M-S%L%4;9HrMbK^Dq4HfsnocCM&jm-3^`6A~-M91zq1$p4*GkRrbJ)?j=;S6m
zx_`}Hz-dnoQ!?1s7YCRPZ0kbF_4%$31>wOD%9bscFQrG@H2?~bTe)j!nAX2V+p!Yy
z(?L0L_I<z0l$nGLYaTM=q=@#ce|h&#ped>#a3q@Y>F7lL;$4eW#!*+!3KHW5+k`!Q
z1;6sM#n6BUYx~W#m51H8fYAnfEl}^g4+A?q96P6}b<_n)uZ*)pr;3z&OL+HZu@vt$
z)c1<M%qn`77RW|#{&kLe3dh0YKNr>|(|;0>8)rDlJQc2Ph2E14xudRloBVi7=u<=L
zjiE;P`i8U+>0Q8mV4ZbTRH9!o=%rg1?uDQ0y8v)+z{RX&8!ueH=*hDG2{~gYwi9OL
zn@1(4@oY_VvFfpmFe50C#zjg8n@=tOj(<2*HJ_Wn_D<}{xTbvX1D`2<lG#B_X=LHO
zvWiUudcN*vfI8bhFu<|q&y7Upi~YmM4@=fu?DeXW!D4W682vOq#wUXOmd3sa3wR`2
z?;&H(iwFUP+QS_S0^{>v)EgZhDa8AM0rG)8ylW^gUVIrprP&p(wcd)Oe_WrdY<Obp
zo_6(Q(x;8Djtqm-aR7rQbW4!In|A}PI*4%F&*m48x`+_Na0HFWpGK~z!A<+T^mtvj
z{8mlx$|=!A|B8bPO2t>rc?p6+a$7)py)9OBYr^=1R|#Lj(=B!$3OWU{!ylGo7+(kN
z@^;OkBXRwOuV4LyYmh(;0)&1C-}v*@8wwpU{x*jW>nEpIX(biIU!45}waJ9N?B9R;
zZ^eMcJmC)08Z)W>;p7#JOkqCSdeJ{E6oy*@uD(*x8h!QW>tJ7fLwcV{^jh;t=K1tG
z2CjC=XEH(lXT5O)Ap0ds=@Y;PUY-uX)y*Gqs{iPZ0Zc{+_u2&UxyoO3_O6W&xO%DJ
zh5COtdkKqD?c+`VUrUI9tB)t2GyZq80GQ|VBJJ4!T5|GqwZoow{C_ul>PY4a%D<L4
zK3&acCnEdb&HmSIU?l$cwEwQW|4njWk^OIN|JlX<x264WC;#68_P=xc|J!iID-Zz<
z-?0b(|G*teT_o|>uis!k{|8x~C}rRe2bYP`pn!h{%{$T`O4+m@{@DOeoU2#h+M0eu
zlDN%3VB-nT9h@@r7jOaed8DxKx7T%uMSj##fBrV<0EhXD`smgj?d0w+R^)%@DZfBm
z{5o0uAI3}l>HB|wUR()t+2=~Pd6e=G((-avASI{HQxcGBoA_%?0<aG=&}1-32CPC~
z9r&lAnM+tJ;#8LpuSjA3!ZYSqE3}r((<m0?fA-j)*8tS}|M)k68!MDeu>N#ixS2-S
ztMobn2KFzOa|Gnl^C2~&DSx}TCjdC9n_J<L{&B@2z;|gEW6%F>|NCQr$lbrE5{CJU
z8?`9`#HwF1O8u|(ik@&<$IP&Be~0jd96*gYW`3OiM#ly2^^UU#GR8l^iUWLCvnqXc
z(0{$k6rO>~dcyo|2>2ZUF}u{W<p193G97S}FX_O+|8eM1u1ElQ_5W9076+M(W-f{S
zH{7pI@Vx@TcW`BM;x7N@1@K4$BiEcq{%icZHXC?yeS>TP<JV|^9|}N0DUklCPh_%n
zYejN=_}i%^iZ-Q%r6Mf#|7M4%*OtWJ4g!knr?J(|{WmjUUu6oP<Nr4`(Sdg^<sVF5
z{hQ72Go8@>gXW09unMTY1^pdXPvH515&ku^%?Eh*f6vC(Cfd*bHidFU1Q=0tWfb{;
z?S(}FmHnAcz&%e$fd`35|KBu^gn6F)e@$Xw{`ka+#{9d7C)|+PfA$YB`{54TWwNCI
z-9y-Gi{t;#yGJUDkMSpf;Ayx$XOKYE2plHDxwQ=S{~4u?<hqxt&l|m7<KV~w321j@
zwB|b2|Jv%nXJRotnYesur2sy8qm$bU3oWQrL5Ek>sr`ziv<7SM#y@#D<D=o3Uo=fD
z=%Kd0ZeYM_{a`$;jCaN-j>NnbI-8YaonO}PoN4fUep^sd;`FF`wRGmoTshUk+5H66
zD!|3vYkWpL$txVoM8}S}iFcr~*8igsx2eU=gRBGIk=>)M_CjfK^GQ_LOF%+DXl@$l
zO^z@APG7VbXC&s|N{tk5rig5yks72u(szsZ;|p7XY8<Pc`2Od<Q9xF`7szx*m7eal
zfWKqZVsHBWfA-MKX{6aB!=m2YV-ZNAI=dg@fAi@Tl4P6H5ZwVLLA%VwiaQ9~mks9S
z(2IwWx3zukN9gh0LCieyh^(VI9loBAmxMdX)%jo7?-IP$Dn_(>RO_7XW-2V6jg!`&
z-(1Ds?=!t%J#w`tg3{9=nqrtcJ;>@5cbma46V`zC+=Fge+Lg;)ARdc(A_$#vbrvX$
z(gAi3>gEXv%R<9K&3uBhyl3zz@5-_YXLJjMp&5x~ci$g>EH}aiej>MOc#aqZ>UnV*
zYAup!B_KKhVZctpqh0dIc;u9`JMO43_h@lTVC>!f#)a%F(e~I_Ig_S^KsVTZ!)!6H
z3&pfrznigGI=gC`fS19MnR_s-ud{G}%#}Cr2&h+FBgT+92?|`A5S1g5Nea+NE<b8_
zKBI1CLf79bjn>`w+zx+H9p;Agu<PoAzI3dxt&JYLL_}h~xOJ`*pVM;_V1ssxGcl^f
z9J|K(OUTgk&?gh|-N&@1gHt-TDQ)qs)hu2#qzZ-}1^%{^9%6D1YWfJz=DY#fj`~XY
z6G#Um<7@j|(_diZc!3SQR>NcCTrgZlWmw(rvwYsW>&7w>B=h?37`2FpZ+cP}T<2oa
z=(`Zh>->Gv)kHNzDOcSr1Y(<E?jrV<9{2M=bLlORQ<M7%WvG3h6<?uVj;-agOmqrm
zqS#6w|3YwqJw$bdOddw);vkh@t;)UV_0i%!UxNDYIil!M8TSA*3X0s1(D-o>&seHI
zbZJG9dHJ}?i;(-9FdJJ{PPqw*CCd@zr8^Pm8(Oy{7aLG`1#w$#FY&ICQB2u<K`(KQ
z*yJbimWg#b68F$-x6*jNfvjoTd}kfATz<)?OnJ0Kw*LE%-_7UJ;wa|kZq(II0dK*l
z0wi*;CI$_>qx&N_?qqoqlY+5&+^Zu9bCOGC?mH`m0{N6gH%^{l;cq%DvdVXK&;2CE
zOKb>&l-~u?qgfirT>G~gF`mSQiRq5xfLm)FH_OJeZ8S`ylI5&lk}%l(#_U~4V+>Kb
zqa%XUuz0UGO<VjpD>ZfrBQJ4T+^Ug%<Tj_sG>3n5Twe0IZklMAv2bp(?E!xA$G2ZW
zK!J7bY@?cu1g#wcY7Lb@z4P7iinwaaG0=*@vj%Ii#j-UpBcm8Tmu1d%0%gqf>n|ZS
zxCg7{)mv)p3#N<E1=IVPMMy3GK~?*aO~STz-EO}|;{@c)JGbuih-#dUlE3X>+C^hN
zT+VckoQhQOTEOvizT|B2hn>Gw&Tx&FN<iws+u2j}gnQ@0dIW2&lKDzm>X(PqT9CZk
zL|C!R{kLrm1YR#$ODH@sS{4@Iq%Goe)@EphE2diM=?b%)FlN)!P5Fa-9n)01J~<X#
zUaif7IkYlngTLrzFpa-&o|}JJ!8$hn?og|aY)B3U3u|#!PX$tY;uydL>k_e$kDhPl
zzDTD<24YMhYNYuz5Wnt#w5?ZD%S%bsDXnR4JL=M1s-+grJyV$!FuAJEsi@?&MAdZZ
zHCBy5Y>R#sH1aa-x!G{Pyky|oXNs$W_ftI>6F;-QY-0CE3~<R5@>WTovfgT{u-VhY
zljfGG`9<QUGl=S~YJ2IbTT2p6Nd|_7MylRNZQ{I6>QHkzs5s>0pN%hg8_u0@nQpO{
ztTu1Z4g_I~SZa$1YnW~AFkF5k*Ci1+M?sl#d28P}r)>~0(V%?Ypep%x9=xckG5WpQ
z1*Uz8;^6eaUSv#r!p-Q~1}|0Edzd$=Oab3})A*yt2#bMY>6dLBWcaTh*7vWCS?0=G
zA@w`7eWTM`0z5YeG51;;Mw^U7;#8}9^i1v=tXpq|QYqq%<&ms$qf9+qkATQ@o(!_U
zfW(wc1a*zYT{Fw(NkNb`d}Ym6_)s*u6r7>E)mD#sh)}&4_RoDm%z{?22{8VKW~fh=
zrWny7QBI<B72l4)tVE`&fRWAO4|#}YRcY^SHA=~(hhv*0jz~Qj1A3$Rs^DIYM^Rgc
zh?;D<;nnj-47eNtZimaGf<;8{y_&RKr#Ruh<C2%9#$~SxdYPbnppE`@Wo=Cf#De@&
zugJJLl}gN=c+IlNhAjA3r6{^PX3E$(+_683b~W#swV`4{vF}HxI|76`w19$&kzWO|
zIuas_lITK;Uc%*O*LSoCi;cj{2m<kT<KyFB#+XB<ju4D|A>~<OxzaI|BdD2`@<Cqk
zbKRfen_r<zV`KOIc2;Oxeo;_jHt06gG=uK9hjf4RsivwzvwWe*Dse?H07_I_L5z)!
zeFZzZp{-#@SZl3kNb7_y&<Qw76F?!57!{1G`5pm0E$pbqYA76bh%+;@;QRD>h%w`f
z`#tj=G1c$NS=&XEJSC5IK7)xovQnHhJKydZfT{&0m^(7q%0o#9=xAM*%Pm@f1JKI-
zo5fW3%R`7+hW(d!=&ycy<9DkL84s_471|!1QLgcAbRgU+O+?kH(MZ=mg)YsdPHNDB
zDvF(kxP-TZ+;v1Ra2TVLs*Gf3n9?p8V+et897FiqL~DZ_jhWKCFAle7FAXmXz@Pw0
z&4M=NFU+$b*}y1C-g0{qUv+j|k?!BHhpmfcr%61|Kjc_}K+~}O?cJ|mn`-AEcKF|V
z`dSMwAy3DTmJNSEZ+tWSLr)A$H}y`6%K+Zdz!X=lC;;8r|0>|4swypW>sg`ZRRYBD
z@d!k7AI7yvo}gnNWV<uk&QG-7$E{la8G|7mDxFyf|EsyXxPFaSsvIIR@HVJ-Xoy49
z2Q~qa!cUBi8tULwZ{7^&+s5ZqLS^;uKlP+_&#%kwx_FiYVX?m(&bOr9-CGC+oU6|x
zSDy|*XUik;sp=LBjpREPD9v02h1M%9tX#A0;b@=;mf3Vk%v>W0v0Z+6T255U*(M2)
zkB8>DQLG>W#tryrc2<?*=%_mDtg;wxv&NcsKyAjCqo+_G9iKck-|D%Yc@#qr>X8w`
z^&0l)S>Fa`mPSGKhW4fEPysgi<)Wn$QKAV|sQ|G+*@FO2vDuHGHexP6=fS0!Q)@{@
zXQRpy8u}cwi8Hx5p4<a@%9!Us(ow_R1_3dO4viB@otyU}`h=x&+$K^<s@IYw7b1|5
zER7i^@)+u55*+?<<q~y#4MOH63pK{ljuvlkxQ62g#0@KlWvWHztGFpDxWzm%6{iy~
z=te+>do-7ho5XyzDI@gyn2XqsF}YVPO1Kw(flId<K}0nLbUO6K*Nh1L2jBQat`?+L
zWWX0!+vQ$<-g#2_YEPc+gH^Ie>%PKn;nK>(GpJpsjjv5io!{*G{BqOcaclMN0`yR@
zsoHwBb`@gP8Uy5z<ADpi$0i!sDmlun!Ghy6KGN)92NG8}UmgJIR?sG#a8V2=wivyY
zJDB!9U+*j}ChDHgx%9>}YHT#43&zLBemUQxyXxub+UFrQBo02fLF7}^(9S%svOWUW
zHnGz4X;fBK=GyHmE4#sAD`i7N?RPH|b*goe_xXN7F10RnCfE#9Q8<2eA2w|q;>m8r
zQaBeH%)B=qh0xGM98i$BwyH`r_d1RzcD-5)9oPs=Kg@B+SKfL+l^B|C;B{B872!1g
zl7!bRr!IeN@P1x1{4P?Ci$?0MhOqN+x$Ne`j+OuY@1<ccKQiCZ8g5;^Jrv~%U(c@i
zMN>sWt{^?JfSu?3pZrmYDXp!oC5z44eJc?fY7fwLHw!;Yrl!>G>N5FyEI73CpY0g1
znfD6gu{b6Ure2kRZ>BY<X^5G;IV$Rdx9E^3kzrlrnY9|_{6o3bnOZKsvp+m*6}yNL
zyuN!e-lD~qbk>Dqcu;jSU94sxzICNx6`SyIt>bhV_t;m_6B=W=*tiRi-E>Kft+r)k
z^g`sO7PV=_BgoN3=v&Vm_`&+<aB}jKK^>otRte->+)N#CrrM6@<&FPvve|{?N3a$|
z)xPfT>FFCK^T}!YPX9>++4cxJwI4Eu{Q2Q{18ehQIh8s;{d?u`B?d607ZnBcsjVqq
zk2eS*FKih$YV55R>Xlk<j`%KF+$Or`?;kd2x@*&aV9G;4XcZE(b;q7xa1J=Cti2{u
zmYK1^I&R}p%~UeS?X!p#gP+mCDosXgnHm~u^<QJ|jQcg6tZtbl<$BO}nfk29x@DJ(
z81YUjqYwwk8A*D&Pp=BTL15klN>Q$j6^92YN21H`xX7N(U2rr^3hpGMU5U=+D7HYx
zYoXP+G^GKDb4B@rjD_#^o#i2z2MmYLms)j%+OdFI6gq%z<<66kOV7LSDO3`#j4MC>
zkhd?n#%u@;1s&gUL~(IPx9hvm)1%oZYsYc{_OUMmWknlA_YncBO%Kiia!G6wr7e3h
z1`y;Pk}?C4s~vcvAj8h}8m^^Sm!tatPJ8)_G#~A4<NMu+vziCNcm^%H>~LNgnup%8
zEeMI>X*AU<A|ea$JWx;<mo+JW$-&YxUEFkHV?^k&nBB3fPnsr;cIb24iHpz7%_Y||
z3Nbv3&Q(QEI9GbZJ)=U3pw`xiPNpa}y+KcS6i_}8moM1XUKoTpV_1I8zR;jjqRrS^
z7_d-jD9f|!i$$sM9FMbO7*MrHXDl@v&Xj7M&BZbgx*a_#@bsbLpW}!DMGtytaMAHg
zh_GUNuoML-APxsWnCd+4Q;p+>Hb{6xM8cBuvYfOuEAA+M<)`)Wi>2h)MBSqTd5+;q
z&HSMQv*}WHM)ziyOSY2u{pqrV%>k8U=fvFmt#66n+$K%m!+H+2JPOKwh}Jj!ay=cL
zOjs84@i5Nu@<(fGos5D&VFc>#v}B8Bxw1M(duX)2(JtL&d^(AWr4r-Y_`@a}Lx0Wy
z^y4Y*lx71%4Wm+9voy*@NUqGs#o=M*NI$dMe*X&wys7+V!uRM-W49JtzjvC5r|Pnc
z=c38>YmH^-1s)=gET{zYqH@d{UVupW9r-CItFzyL*=z8>4!Dsiq&zf(FNa;ux)O8-
z5_H@stXi+V%oiJ{99~0vKcV#$%VAzgaak^?CY>H8gmY)(eJkbE*^S+ft~G52&CvXI
zBwF#;^?)(*@p#up0lzXPk~7v11Xvjl{9dQV8)&&TO17P3eVw4?T!4ya?`yR@vy5wP
zpYqb$Y5P7Rj749l_7v(F$p6sW!6r<iimB~<gWa(GfVlZHiekvV)!ogot3S@@9>?wD
zvtPG9D2_ehM4K%E#Box@E(>z4A@Iy*OCJ0ukrz8-S`v&)j#~o>%v?^bzx50GFGi%k
zBywVjfx`KA>m(B~koBxGwL@{>sP|`+T0ROsm<NM@pA|{UeXPkKK4AS$@JtWuGt2f)
zN549@^c@h29>z*^{qnkbjQ^nN$ZIFQt)Y9z2mKe=NoasMB!M=+bV~!C#N)Q%stamF
zd$$EKrK_c{Ms7~wtU8W$SOT&Vp|HufP|bU@?FW$LT0l7S(uM9_gRf$aS@y^FYAD(y
zHR<h$zTM*PmmAa#UzPwsZ1Q9G-C{PPEvMV){$(~nVq9_7^dnQ60g?O?(znZ%Im`J9
z4a7u_*a^w2=;^n}(aE?J8tgV3F>?ckm$h2s6;9Ei1e2eWO&%`_hxl@m+<SLsvlcI5
zm89nPZ_wYvhEJe-ZS467H%(IR=E`sG5Ga09^2Z5ZFPZs1Z?eGZ(}*OQ8t__%=sYqS
zO2g(h8rQVZ!N(?PZft0Xrx!A*;36jz;a)7`ck)temFxf=L8x@{)3Rny$eVj|uAP<g
zvV8ZWjQ|`^8h41thB)BS=NE^WVJ|hjaCw04=5K6iSj9Lj-vBCVLc`)a>j#vZt0q%6
z1&P<~jBjQoZHn(L*0#dV%Bx$$z+iqnev`;lr!BnsYKWY_NgcNMm$6?G-4MU+yKS?w
zn4&W9IBMwLTz0-3_bv#~1@6}@v&&K|wg``Q&MTzMVSdx`RGE=%?plw?_`?4&)RkCZ
zkM>-$i@>Udic8ZYO?uy|Xig2$gN>bih(2536X^7$Qc8oovRV<xI{@lq$muvL%s$HG
zwymI+=?aw2{V6}s8s7CT;242nCLqNmt%~FzfkBOqA{>_qkU(*`K^#YuTpyhB4w!gh
z4uR7>)({BtCS@e}C3O2UDldb;Z4u);<9I0hZ>650P#))M_F&iiaE6ScOWQT%9<z_G
zR)9P`-JatmXRRl_c|noqx>)AKr%#X2P1oiJ84`WcB_%WpxfnZ<zD#CRVzIW!5>@OG
z4!ZO)+3CJW;=@hK!~CVR5*>F4_~W$s(5TTF`8}s-4ufX1gz`>{9p6=N`hqBrySUZv
zJe!*Ps8gkjy*Zgh3RQpEo|1#bgk0?oqKLB9KrFlD^>oY8yPFZ5R^0X_uuViNZ()Y5
zMVx;B*B?XM82gzU{o=mNnt)w6B|Mb*%T4H~z6BgXE{?G89k+3K=ic++78d5`vna>U
z^n8~15ndANPJe{h#scMw`*n`%KYL*K3<{<Uo1dT~PqKJ@^O&xWCj-J``Rw19)n$O8
zS1EaKozJH&zIR40jZ0aLB3*SKK+}@7x@E&gQ*y)VtZ8v{wnf;FBFTI<Z7i5{YQEN-
z+8W=T!~oe5tmM++E|2DGP0f7a_)b{TQ!&aou~S-3&Z%{1rKP2*8Tq?pnOb@S7Zint
zloCpF<<f3*!PgIn^C04)XXRTwK69kLxI629o<?rAc8nSoA0EDK?T$A&F!wO<4`%M-
z$?{VkE+pwSBC^odW-Ysn1y3%#IQ8^Czjt~N-JPkcv#0p2PCY(F-|fUaK2v{YM@kPq
z7ihYEXEaW1)5<GJQfWlbRec4-doF=IC<Kz1R&`3%s+39mId^?NP|P)2q)^g85nkxO
zXP8~rdvU4ukt}uom!1Cz`_=yFg6s6FnGiJl>T72raU+Cpu&D@vb&AH~?&>uX$`*^c
z@^f$V-nvYBGDZJLzd#@0>~E}I+>^i=sPJjRjaU$bS*a=2;-%wfr&pZkP>lDzgviJ6
zb`nx_#nkW+u3jiLhXq)2UX04Gkqz?h5gWD1W$;ip4rZ`fx4(+(Q!>g%$*vdUOKesX
zo_tju(S76fR@VjVt$`9PK^75jY;-E<O45($#Ty0|D8%8Yv`o%6IzQcUl7F#7I~Dzb
zJyO^L6Y2VEhuv3+wK)$V8ixh<l<NIS`8+ph4M@TAEl^Q9!K|!Fg!p0GXZ(jm2wT2a
z3RD;y2~<VC@}X`9>M)T<fR1thqi)GP-^p!rEre-OgdMk!e`J@$pXSs1$m6?~Ri!n8
zX_NG&A`0vC^RqBFT9TfsELh^ms_`74O!-zj?6X9srVag`34bD!;R{hu9DY^AMx(t<
z9><oG$dFOy0yv;*d?98B8UbhF?9~)By=)oxnL+l2>*6(j;CpY*fDG3)WPfR(*1GM<
zGzfdx6<fh^-tn@~t5!QFIcgPy5-c5^nrhCnB2r|xKiwUZUbfcqrH_qA0x^|iJb?V0
zlnzHXuJD2sv6C-P{AK_;al;MdeyTy-LL{3G1w#(}YAVYKi>Fe@xNjU?b{4`gj7KIS
z6zhAegtN=xtCIg72=F^vs0@02u*ghMUEs3X2)fZ<b>^{C<-%L2YIcv{)k>z3=<Qq;
zFqCcVE}J8l-n+@8?AqnnP4RI{bDnSJt&VixlU{e+pRkuUxSYq-ow2_>SihXbWw<Kp
zwt&PjBHv<$y3vhKE5yt`Dq=Iw;FC~p)z0)ZY?NsynxKdYvp>ImRru=t*UvKLTx7GJ
zB5xJ>Z(<u9$Ljp^xcDvB$U4%PBAY+gP`poCkb<*>+tf0^Foyi{abGigaIIl33J1HN
zdN3yea^2P&fAGWJz!t*8nn$`rvL+c}ugmb9N9@PphEJ88q3k}<@7wz0iZ*bGvb{v4
z_&$d|T#h~i^u$Knb*pa_7eLnQb*<R3K|JVJ>j=f#OBz;SY9Mo-B@ym)*Q`Iax#R6(
z(~Y*ouQs`h6!NwSpHWg(=%D0tkA8zsBGccqtre7Yfh4$+l0YN2`10O*L~vT8&ul%g
z8c3$Nui~+Luneu3LL7Q?*2AZ$_d0zBy5(h^vdTz)EEjx~G6fYyWjf)5$;vUTPrPQr
zJ*TDkJq`DZJ|rfc2CjD4R{z%BExRtvPj?#*<d~JDyN<twLD)ia6eunK5=m5w#jpC=
zD3AT4s;7{ycATfu9L8|TuFJ;IZb;3@+zeOvJ~BnA;;0oJO(*9xv*}@+e^-l3g=7--
zmb;d^tfriS(|U@Z^AfrB?MYOOj>#Shr=98IWZ=!VjY=Ol4DYN-PfL!SS3ARd^v7GU
z6m*O2hXdkVF?o8N$`}62#oNqLejbsQ#8zbzwrjHt+gRr{c}m5Uq17n}qVLHt-$l_!
z5}hJ)Gwc*YW+PCT-r6%wRmZh9bjLc*Dbm@8(qLJ7X{9OpEbnKl(!@gI{CesU%f=2v
zm4$5#k}-gJebQtTG3fSC(DP-jbA5x>f_G?CM10xx#*ZD{%OeXbTtNBZ``Fy~DUO*w
zAWshKP^O~bxs}s{AI>LXUgV{$=AGz)jquhbD&utb#@$-y-LA*pPUN2CAEbpQ(_KSY
zu;_ImICqpTl~+4*8d@8>#_4fQ#|<jY>mi}DkEg}-hNr(w=eLu|%fPqEs6Y^xHuSiP
zx6;0q|8Y5C11OWnAQjFnI(i)9KH2zEImcRYXA+3-d)(4!)&a4lzWj+KdKX+B@%p-+
zFs(et&w0`WuI{G18Wx>VZH~u&f`KNKgob&?>3WR6#MYNv(xUZto*-|IkA_PsrDUdW
zwn8f9!2^ubqPAS;FKjT$74Dbkz>k4OIIELq;sC2{AyKy`ihT}y5B=)Ye4#Pi7oDC?
zCNz{p?}LCE**%Z)UIlgrnV6c?-ii0!zA!lxAs7-$MI7iFPbS#<EyL+KU9Gh*<|yrF
z1F%tz?II^np$87p>LSFkZ)~1<u|d8tXWyZq?x>&j*Rq(v25@-Coz4p_HmYH*`(;}Z
z3@s$)n&-cKZ&vElF}=5A@ky!rN`QGZ?<hv<Dvn+Ozx3G{Tdvv%uqpZD?e^!Emcv&~
zX2Dt;R0-NnID+QsvA9;DD4W91=VN_BMqOc=Q&9!mf>lTCZ$t5JtLr*7t3AWj>_*|?
zG0mq6;|fr({RoOxQFE8`g%-Fc?mi|LUPR9n@J_IYS)5wu`moA;M9{86e-(JIE>)+{
zvf_I4dp&~cvkqE2+JJwsxh=#CJ%#2giKIlT`J867Few}^Mod-=ceUvzLEBDC_ua($
zEeI=UC+r#5nut$8FVIGPZ9`FYus6GCm*tA5*Y^TWl5D3bZD?<Z9nuT!+~81iT?7UZ
zb49+(*Eg*n6<CQmwV&e`a@{kemEyp8wQFvtJG3Yik4;|Sa49RI4^19U*;Fmv?PN!A
zu7y4*gu+WX%mA6KQ}PyoRJ?7WJN|BNHPVj1SG+2}wTrS7oxJ5`Iq#*AO8mYeay9A@
z4B4M-LfX84vlv=?e6fiB%9cDzmrNE)ie>9tR>P&rd+kn0!cI{;4aG^W;VVc8QR!oe
ze1XcsOW;!>8H#H;J`0|<T&|qG=*dP!5`^2MR66d7qO06t@BY+LuVXp>=7nPthGjKN
zn=&fEcEO0_Gom>fqWlQ=%(HUchk5rl&;ter6-!!N<dfAv8>IW4)w&vx8{x#C+V(=W
zZi?DwKP@E``))2D9sBv72z6(|rfJeTc-+BwK%J=GPp!TG#fj*P8t~Tq!a}Yc`{8*Q
ztNcho<3XObmCB)Fw<p5|eVtXh{#wjMOL{^2A+N>P?p`xc#ClC3(fmPZ%c>FYE;9e2
z{B7{0`JqSm_0J(t*8Evyp>-mi?TtTZ{kgG8vvEOw*c(ldp_qp9o-iAH=*jT7mAciG
zmtMhF9U1*p=d;`L2K$uZ5Anvn&E)9n^6ZA|gn)RQT3#-rmU!qF9pW%CQOVNEwgi1}
z%AUk%i$zEzTNZfH<@;b?4(BD>1(H2#op9^f-u@OclUl}6Fg7kz3+Qm0*L@A1r{#-1
ztIH|^Jvy|i(q^b@jDKnd(O}{>y~b6el|h4M=n}agSJ~ue`%+Hi!!shP8-g?t%<56=
zy%vy1$lhlCm%Rk%n(4?do$@bX)l(^7zkXb9L)|bY_4<aqlB`o<6oX1KIq}6#$DqCc
zyUqwFn&nD;K~veP@b1FU24|U8JWc@UVe`f+n+k0y+C!KZzRuzZbo6~;ANYC6cI~sd
zPs#BoJ?Ean2P3zMX<O6W>k$7vc|Ux(IlY_AK72;xS~b4+^TN=(2#bO9<%q+xGZjvz
zQR}<wO*3|<Jd|(y@hymw1Xf?)?_=84o8K!Z-Jau1j~W?sfJ}ryM{y=b;ZsIiS+|8T
zNxwdlh>rFgG?BaJijA;1A@z52RO?<UORHF06z`Ho197b5H@sam{lWvrS)3s~W(~N0
zVFskyQ?IrXEuVq>dH~ax_?0fAqydG8cW?_DEteumBr60@G6cuuk!w6#h&L9dNsrz4
zp*q`HT58JYY_B^$2t;scSMHxHgmg`15ffKuyZ$2erQy0T(t5Qtf?~{;W4XF?7SB)c
zE<zNYF3Zh8H~j2pPLbytxrE{={s{e2dji=Wd7lTA6%-usjq@L6KBJv7M?ff76iI!}
zP-o~Yk5uOg;P^qskdzj!TO4%Ey8D*tq7KgfN@D8TMQhq;kSoX8Zr%rqS*WLJ|EH$%
z!(l5DLfsgTRDn{)j(Ag)mzRo2gQAT6c|Jtt$d46AwOHACr_0?MmYmG-EqAKtn?1>B
z%C?asT*-4>f-t8Tv`C0&J~-ZtB#`Mhj|R{lGLms+6=7-YBGI|*x4aaNj*pJP3ZmW?
ziN3iWEO~qG;vx(Lrsvg{x)r|VqLD)kx`oU^6`1})wXCB|Z<P^;3%*gb@gb<Bko1Vz
zI2l}mE%0;1TvNjtdUn3YVolJ_m-pyaM2g~p4LL>okG^^!aoL#c9zGwfwa~DLM;5#;
zlgEjkf_(++V)EvB@4>uZNaM%+@U7NG3lC5GCa|H;9$OCBhow{-^JMXZj3UpZ87h~B
z%i;VoPW<nP`>Q-{_3yjM*orP6>mZ!ZYn2clAlxp+x(=#lJ_44Rl>;GFJueN_h_1aO
z!`Ih>&ZWv-4;uxnuy(Hze|(HCkwb-_MOf~={9xR(2&d;XX8^I-=(1j{{oO+r@zMB7
zcdBu6-OTA>rtFanWBGm4$LL9jz3ZWHl1yagCvk{P?WP``B4x$)F4k8Kl3U&E?fs&V
z=mLI=?r5q#SkpV7v;+e7P?7SIpV0gl^<itNh1G_9d~inA$F@$RM~hj-5FfwjE8WB+
z%}uSgBimtTPq6^^eucNNDhJQQUUWG)-OzFCuEFqyOhxWhQVE|fNWi@s=6G{Zhi%>}
zr0r4#tR#!rRi>WOl>KEY7S0k6yv;Zw+Tr+P9fiz8wrdGWq;Dfgv1OIeJB#yWrm}_i
z6Y&Y9Y}T8bZ%3ANtr02gH#k+_7`H0o)WEx(SIg4)mBxN5bSnRL%&b<YcIO94s|IsB
z@IKlRHdZ>x4t!^r)Us~|agHYMa}-5ap~n{DU#;qYQy881zdeDH1=!N2EDKq4q<L2$
z8=4|PTE14cJJ>!@dBF%7Y8zndys?x#x(v2qlb}LgsYRV^!8o9{SVz}R2IoE}Ooefw
z3r0^ZI=YJ2{TVvgZn7*+l^1#9<?k|$7^H<pTv>SO7+FG=Zf;0V-no_(3V)Fmg+WLD
z-d`#3x~_1Eovw1XJc#CJdExk4;o!)d^%=U$Px{YMwJSJC8HzgOH22&P1?4CHp8(4R
zH2Os1in4t;=r6D~B8}TtlgDL;jkD>nZU5V3HjUlJ(xfkmz_HM`hF}?)4gMj4N)o{J
zWv?Y%TlTkLue(6kq&<|4Ls|s8?c4HQyVz;UvOAFu`><V-p=4oFIP1FNq%$$T^fulu
z5#?St+a-D3>rR@I6=xfXG`P3Ty8f~Iur&WmcDR3s=3Za{n3Br=u~Amk?RMEz+_Kl5
z?+MX$vn@em>%x*U1KD)Lf4_~d4@+E2Acfy=WjNrSixN&1XSWrER}nDX8iKiT)bJIJ
z<Jub(CX;s$N+~hkoQCbZZ>%HkGWAt31S`}&NIqEZJa!#RO9Dtt`jUNizdH@qZ7}Ie
z62VsVpJA3Byeo+J7ZEHwn}<shsEC05MK;nAt9VBfueadZve%Nm?%da>f0;JU{><&R
zO=tG&PE(fMsY_?OB!fGjvmPKHemFMXE>Wy|-E1RW$xd@DY$F1}?)Pmuf1P-n#FYne
z=6^{d`#Z#Y!@2sNE9L`7u<Xo++4k9ifmr$adquEznGOCi1i;PSgYn5vOy`Q=<_Yxn
znvGH3NCWo`qoWa=de(&XVIAj;*TtYqm<%PlL<_J#)Zo*vl8ZXjOqh5BBMH-VLJ)Vw
zg_=LyboRp7m6@gU(eBepRm%T%X@@o~j6kp7xXm2O<`4I{l}T^JSsz{&E?FzdI_peQ
zLix5<<`~RVKM2^LWsJ`9)KVw%U$}IgV3MFf1E}f;k<iZ)j4+|bqNQskK_|ArZ!vK2
zNlJ23g5ds=r((`<FadiH#XI@gx%uVr^yO`<(_wbg2}X8g<(v15t)p~s$%pSAoHHD?
zbY;+2KLCO$L&FUXep$ArI58n!+N-FA^5m!w11242T-l}5sKJxQi`(|eDO>|WNsk*9
z-dV$sE=5nWu|A0edoZy3v+%jG^;^u$FlO?Bnl#XL68IoMfxZx*qBGWX?bycm6zO{U
zbS32~2~<b`mo2V;T-WP1Y?B@Otz2CHx}(Cp^*I3q1v9WU(TDkNo!XcQNbJ2K7?&Is
z9y5EB{)QP2CSdsK)tIdJHas*2<7xL}zUn#4H^_=jJB>(}`qu}SeK_tx_c1<m*;hZn
zF|<cJGpm|qQ_=Y%9VRMiuz2~}VobZ&zD;u#-taC=6oRQY(TwC|wRe<?ET|~nRSxb&
z5NF(&eD4HSl-U=LX2G1?JfD4`WvOB+Jg5{KJMA=h|KHx(?L-IzQP@kbyz%|tPor+!
zXuL9U=S+LdgdZs&TecjM4F#st_S=?$mQIoPUp6bXE4m24h+vo}n{5FZB#_!6+)O^?
z9<0)Kh_`MZzVisCJlux{lWO^7D0{jG!{C_bt=wh(SJBBEFIH!(v*3E9%^#|*z;I;^
z*QBrkWKzO`271+c&@kxtd2FX7(QC_~{~ujfwYJiyrCRw@y0=4sbqW6E=lGbvof2-B
zQ?e^b0ljT=+<lhlJfaK@5?-jdrt%Rvu*`GnAmd<f-Q@G$nq%a>hXJL=hIE(yAvN-=
zH1|&c?G)9yR-N8Ip?(g@tL1xKztsCVlZ-U(g(*+i@i&&sEb4NQ89QeDs4s?joqOuR
z@mP51T9h5q#d9%k%*R?=V4lQc5^aTRHOyM+w)O9+G+hFztv1|Xy9Hi(EM6-C{zLS5
zFD$9Kl$qKyYm~!r4D&ko@!D9pt0T%$PgiE>e2f>%A7!V)H1c7Z)l?K+7Xc9v0TB=Z
z5!jjlj68leL|`kT*hgM;EUqrJt<g)r2#A0Ph=2(63DEvxmK0Yl^QlO0r?X2heI@TF
zr86QR0wN#+A|L{#1ZaPso=@(WD6eMqbNBK2<vJd1VRL*&AN$cul}k<pL_h>YKm<f!
z839ZUetCU&uXgyj&J8r?s$u3Jj5Ivyz)Khgsb!>>K~^jg5CIVo0TC!A;P%!GE{2-F
g&G{GRjl(Wq0Q73%un}8LB>(^b07*qoM6N<$f~^R~6#xJL

literal 42899
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
LwN*+Uo4xrT5_9Tc

diff --git a/docs/en_US/server_dialog.rst b/docs/en_US/server_dialog.rst
index 4016ba6fd..bd57e68b0 100644
--- a/docs/en_US/server_dialog.rst
+++ b/docs/en_US/server_dialog.rst
@@ -170,7 +170,8 @@ Use the fields in the *Advanced* tab to configure a connection:
   `Section 33.15 of the Postgres documentation <https://www.postgresql.org/docs/current/libpq-pgpass.html>`_.
 * Use the *Connection timeout* field to specify the maximum wait for connection,
   in seconds. Zero or not specified means wait indefinitely. It is not
-  recommended to use a timeout of less than 2 seconds.
+  recommended to use a timeout of less than 2 seconds. By default it is set to
+  10 seconds.
 
 .. note:: The password file option is only supported when pgAdmin is using libpq
     v10.0 or later to connect to the server.
diff --git a/web/migrations/versions/aff1436e3c8c_.py b/web/migrations/versions/aff1436e3c8c_.py
new file mode 100644
index 000000000..7a7c3017d
--- /dev/null
+++ b/web/migrations/versions/aff1436e3c8c_.py
@@ -0,0 +1,27 @@
+
+""" Update the default timeout to 10 seconds instead on 0.
+0 indicates wait indefinitely which causes trouble when network connection
+to server is lost.
+
+Revision ID: aff1436e3c8c
+Revises: a77a0932a568
+Create Date: 2019-10-28 12:47:36.828709
+
+"""
+from pgadmin.model import db
+
+# revision identifiers, used by Alembic.
+revision = 'aff1436e3c8c'
+down_revision = 'a77a0932a568'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    db.engine.execute(
+        'UPDATE server SET connect_timeout=10 WHERE connect_timeout=0 OR connect_timeout IS NULL'
+    )
+
+
+def downgrade():
+    pass
diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py
index dc39a1393..a813f7a7c 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -28,6 +28,7 @@ from pgadmin.model import db, Server, ServerGroup, User
 from pgadmin.utils.driver import get_driver
 from pgadmin.utils.master_password import get_crypt_key
 from pgadmin.utils.exception import CryptKeyMissing
+from psycopg2 import Error as psycopg2_Error, OperationalError
 
 
 def has_any(data, keys):
@@ -58,7 +59,7 @@ def recovery_state(connection, postgres_version):
     else:
         in_recovery = None
         wal_paused = None
-    return in_recovery, wal_paused
+    return status, result, in_recovery, wal_paused
 
 
 def server_icon_and_background(is_connected, manager, server):
@@ -121,19 +122,21 @@ class ServerModule(sg.ServerGroupPluginModule):
         for server in servers:
             connected = False
             manager = None
+            errmsg = None
+            was_connected = False
+            in_recovery = None
+            wal_paused = None
             try:
                 manager = driver.connection_manager(server.id)
                 conn = manager.connection()
-                connected = conn.connected()
+                was_connected = conn.wasConnected
             except CryptKeyMissing:
                 # show the nodes at least even if not able to connect.
                 pass
+            except psycopg2_Error as e:
+                current_app.logger.exception(e)
+                errmsg = str(e)
 
-            in_recovery = None
-            wal_paused = None
-
-            if connected:
-                in_recovery, wal_paused = recovery_state(conn, manager.version)
             yield self.generate_browser_node(
                 "%d" % (server.id),
                 gid,
@@ -151,7 +154,9 @@ class ServerModule(sg.ServerGroupPluginModule):
                 is_password_saved=True if server.password is not None
                 else False,
                 is_tunnel_password_saved=True
-                if server.tunnel_password is not None else False
+                if server.tunnel_password is not None else False,
+                was_connected=was_connected,
+                errmsg=errmsg
             )
 
     @property
@@ -352,12 +357,16 @@ class ServerNode(PGChildNodeView):
             manager = driver.connection_manager(server.id)
             conn = manager.connection()
             connected = conn.connected()
-
+            errmsg = None
+            in_recovery = None
+            wal_paused = None
             if connected:
-                in_recovery, wal_paused = recovery_state(conn, manager.version)
-            else:
-                in_recovery = None
-                wal_paused = None
+                status, result, in_recovery, wal_paused =\
+                    recovery_state(conn, manager.version)
+                if not status:
+                    connected = False
+                    manager.release()
+                    errmsg = "{0} : {1}".format(server.name, result)
 
             res.append(
                 self.blueprint.generate_browser_node(
@@ -377,7 +386,8 @@ class ServerNode(PGChildNodeView):
                     is_password_saved=True if server.password is not None
                     else False,
                     is_tunnel_password_saved=True
-                    if server.tunnel_password is not None else False
+                    if server.tunnel_password is not None else False,
+                    errmsg=errmsg
                 )
             )
 
@@ -409,12 +419,16 @@ class ServerNode(PGChildNodeView):
         manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(server.id)
         conn = manager.connection()
         connected = conn.connected()
-
+        errmsg = None
+        in_recovery = None
+        wal_paused = None
         if connected:
-            in_recovery, wal_paused = recovery_state(conn, manager.version)
-        else:
-            in_recovery = None
-            wal_paused = None
+            status, result, in_recovery, wal_paused =\
+                recovery_state(conn, manager.version)
+            if not status:
+                connected = False
+                manager.release()
+                errmsg = "{0} : {1}".format(server.name, result)
 
         return make_json_response(
             result=self.blueprint.generate_browser_node(
@@ -434,8 +448,9 @@ class ServerNode(PGChildNodeView):
                 is_password_saved=True if server.password is not None
                 else False,
                 is_tunnel_password_saved=True
-                if server.tunnel_password is not None else False
-            )
+                if server.tunnel_password is not None else False,
+                errmsg=errmsg
+            ),
         )
 
     @login_required
@@ -949,19 +964,33 @@ class ServerNode(PGChildNodeView):
 
     def connect_status(self, gid, sid):
         """Check and return the connection status."""
+        server = Server.query.filter_by(id=sid).first()
         manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
         conn = manager.connection()
-        res = conn.connected()
+        connected = conn.connected()
+        in_recovery = None
+        wal_paused = None
+        errmsg = None
+        if connected:
+            status, result, in_recovery, wal_paused =\
+                recovery_state(conn, manager.version)
 
-        if res:
-            from pgadmin.utils.exception import ConnectionLost, \
-                SSHTunnelConnectionLost
-            try:
-                conn.execute_scalar('SELECT 1')
-            except (ConnectionLost, SSHTunnelConnectionLost):
-                res = False
+            if not status:
+                connected = False
+                manager.release()
+                errmsg = "{0} : {1}".format(server.name, result)
 
-        return make_json_response(data={'connected': res})
+        return make_json_response(
+            data={
+                'icon': server_icon_and_background(connected, manager, server),
+                'connected': connected,
+                'in_recovery': in_recovery,
+                'wal_pause': wal_paused,
+                'server_type': manager.server_type if connected else "pg",
+                'user': manager.user_info if connected else None,
+                'errmsg': errmsg
+            }
+        )
 
     def connect(self, gid, sid):
         """
@@ -1078,6 +1107,8 @@ class ServerNode(PGChildNodeView):
                 tunnel_password=tunnel_password,
                 server_types=ServerType.types()
             )
+        except OperationalError as e:
+            return internal_server_error(errormsg=str(e))
         except Exception as e:
             current_app.logger.exception(e)
             return self.get_response_for_password(
@@ -1088,7 +1119,7 @@ class ServerNode(PGChildNodeView):
                 errmsg = errmsg.decode('utf-8')
 
             current_app.logger.error(
-                "Could not connected to server(#{0}) - '{1}'.\nError: {2}"
+                "Could not connect to server(#{0}) - '{1}'.\nError: {2}"
                 .format(server.id, server.name, errmsg)
             )
             return self.get_response_for_password(server, 401, True,
@@ -1125,7 +1156,8 @@ class ServerNode(PGChildNodeView):
                 %s - %s' % (server.id, server.name))
             # Update the recovery and wal pause option for the server
             # if connected successfully
-            in_recovery, wal_paused = recovery_state(conn, manager.version)
+            _, _, in_recovery, wal_paused =\
+                recovery_state(conn, manager.version)
 
             return make_json_response(
                 success=1,
diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js
index 99fed949e..843794d53 100644
--- a/web/pgadmin/browser/server_groups/servers/static/js/server.js
+++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js
@@ -292,6 +292,10 @@ define('pgadmin.node.server', [
 
           // Call added method of node.js
           pgAdmin.Browser.Node.callbacks.added.apply(this, arguments);
+
+          if(data.was_connected) {
+            fetch_connection_status(this, data, pgBrowser.tree, item);
+          }
           return true;
         },
         /* Reload configuration */
@@ -732,7 +736,7 @@ define('pgadmin.node.server', [
           tunnel_password: undefined,
           tunnel_authentication: 0,
           save_tunnel_password: false,
-          connect_timeout: 0,
+          connect_timeout: 10,
         },
         // Default values!
         initialize: function(attrs, args) {
@@ -1273,7 +1277,14 @@ define('pgadmin.node.server', [
         }
       };
 
+      /* Wait till the existing request completes */
+      if(data.is_connecting) {
+        return;
+      }
       data.is_connecting = true;
+      tree.setLeaf(item);
+      tree.removeIcon(item);
+      tree.addIcon(item, {icon: 'icon-server-connecting'});
       var url = obj.generate_url(item, 'connect', data, true);
       $.post(url)
         .done(function(res) {
@@ -1287,6 +1298,40 @@ define('pgadmin.node.server', [
           return onFailure(
             xhr, status, error, obj, data, tree, item, wasConnected
           );
+        })
+        .always(function(){
+          data.is_connecting = false;
+        });
+    };
+    var fetch_connection_status = function(obj, data, tree, item) {
+      var url = obj.generate_url(item, 'connect', data, true);
+
+      tree.setLeaf(item);
+      tree.removeIcon(item);
+      tree.addIcon(item, {icon: 'icon-server-connecting'});
+      $.get(url)
+        .done(function(res) {
+          tree.setInode(item);
+          if (res && res.data) {
+            if (typeof res.data.icon == 'string') {
+              tree.removeIcon(item);
+              data.icon = res.data.icon;
+              tree.addIcon(item, {icon: data.icon});
+            }
+            _.extend(data, res.data);
+
+            var serverInfo = pgBrowser.serverInfo = pgBrowser.serverInfo || {};
+            serverInfo[data._id] = _.extend({}, data);
+
+            if(data.errmsg) {
+              Alertify.error(data.errmsg);
+            }
+          }
+        })
+        .fail(function(xhr, status, error) {
+          tree.setInode(item);
+          tree.addIcon(item, {icon: 'icon-server-not-connected'});
+          Alertify.pgRespErrorNotify(xhr, error);
         });
     };
   }
diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py
index 2a17b3a2d..67dce0942 100644
--- a/web/pgadmin/browser/utils.py
+++ b/web/pgadmin/browser/utils.py
@@ -17,7 +17,8 @@ from flask.views import View, MethodViewType, with_metaclass
 from flask_babelex import gettext
 
 from config import PG_DEFAULT_DRIVER
-from pgadmin.utils.ajax import make_json_response, precondition_required
+from pgadmin.utils.ajax import make_json_response, precondition_required,\
+    internal_server_error
 from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost,\
     CryptKeyMissing
 
@@ -377,11 +378,7 @@ class PGChildNodeView(NodeView):
             if not conn.connected():
                 status, msg = conn.connect()
                 if not status:
-                    return precondition_required(
-                        gettext(
-                            "Connection to the server has been lost."
-                        )
-                    )
+                    return internal_server_error(errormsg=msg)
         except (ConnectionLost, SSHTunnelConnectionLost, CryptKeyMissing):
             raise
         except Exception as e:
diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js
index 42d2eca4b..6e466052a 100644
--- a/web/pgadmin/dashboard/static/js/dashboard.js
+++ b/web/pgadmin/dashboard/static/js/dashboard.js
@@ -543,6 +543,7 @@ define('pgadmin.dashboard', [
       );
       const WAIT_COUNTER = 3;
       let last_poll_wait_counter = 0;
+      let resp_not_received_counter = 0;
 
       /* Stop if running, only one poller lives */
       self.stopChartsPoller();
@@ -563,7 +564,7 @@ define('pgadmin.dashboard', [
         /* If none of the chart wants data, don't trouble
          * If response not received from prev poll, don't trouble !!
          */
-        if(chart_names_to_get.length == 0 || last_poll_wait_counter > 0) {
+        if(chart_names_to_get.length == 0 || last_poll_wait_counter > 0 || resp_not_received_counter >= WAIT_COUNTER) {
           /* reduce the number of tries, request should be sent if last_poll_wait_counter
            * completes WAIT_COUNTER times.*/
           last_poll_wait_counter--;
@@ -571,12 +572,12 @@ define('pgadmin.dashboard', [
         }
 
         var path = self.getStatsUrl(sid, did, chart_names_to_get);
+        resp_not_received_counter++;
         $.ajax({
           url: path,
           type: 'GET',
         })
           .done(function(resp) {
-            last_poll_wait_counter = 0;
             for(let chart_name in resp) {
               let chart_obj = chart_store[chart_name].chart_obj;
               $(chart_obj.getContainer()).removeClass('graph-error');
@@ -584,7 +585,6 @@ define('pgadmin.dashboard', [
             }
           })
           .fail(function(xhr) {
-            last_poll_wait_counter = 0;
             let err = '';
             let msg = '';
             let cls = 'info';
@@ -613,6 +613,10 @@ define('pgadmin.dashboard', [
                 '<div class="alert alert-' + cls + ' pg-panel-message" role="alert">' + msg + '</div>'
               );
             }
+          })
+          .always(function() {
+            last_poll_wait_counter = 0;
+            resp_not_received_counter--;
           });
         last_poll_wait_counter = WAIT_COUNTER;
       };
diff --git a/web/pgadmin/model/__init__.py b/web/pgadmin/model/__init__.py
index 629e98f37..b22868fbb 100644
--- a/web/pgadmin/model/__init__.py
+++ b/web/pgadmin/model/__init__.py
@@ -29,7 +29,7 @@ from flask_sqlalchemy import SQLAlchemy
 #
 ##########################################################################
 
-SCHEMA_VERSION = 23
+SCHEMA_VERSION = 24
 
 ##########################################################################
 #
diff --git a/web/pgadmin/static/js/sqleditor/execute_query.js b/web/pgadmin/static/js/sqleditor/execute_query.js
index f714c2b50..63ad7721b 100644
--- a/web/pgadmin/static/js/sqleditor/execute_query.js
+++ b/web/pgadmin/static/js/sqleditor/execute_query.js
@@ -12,6 +12,7 @@ import $ from 'jquery';
 import url_for from '../url_for';
 import axios from 'axios';
 import * as httpErrorHandler from './query_tool_http_error_handler';
+import * as queryTxnStatus from 'sources/sqleditor/query_txn_status_constants';
 
 class LoadingScreen {
   constructor(sqlEditor) {
@@ -83,7 +84,8 @@ class ExecuteQuery {
           self.loadingScreen.hide();
           self.enableSQLEditorButtons();
           // Enable/Disable commit and rollback button.
-          if (result.data.data.transaction_status == 2 || result.data.data.transaction_status == 3) {
+          if (result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
+            || result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
             self.enableTransactionButtons();
           } else {
             self.disableTransactionButtons();
@@ -123,7 +125,8 @@ class ExecuteQuery {
         self.updateSqlEditorLastTransactionStatus(httpMessage.data.data.transaction_status);
 
         // Enable/Disable commit and rollback button.
-        if (httpMessage.data.data.transaction_status == 2 || httpMessage.data.data.transaction_status == 3) {
+        if (httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
+          || httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
           self.enableTransactionButtons();
         } else {
           self.disableTransactionButtons();
@@ -131,7 +134,7 @@ class ExecuteQuery {
 
         if (ExecuteQuery.isQueryFinished(httpMessage)) {
           if (this.sqlServerObject.close_on_idle_transaction &&
-              httpMessage.data.data.transaction_status == 0)
+              httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_IDLE)
             this.sqlServerObject.check_needed_confirmations_before_closing_panel();
 
           self.loadingScreen.setMessage('Loading data from the database server and rendering...');
diff --git a/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js b/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
new file mode 100644
index 000000000..075264296
--- /dev/null
+++ b/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
@@ -0,0 +1,11 @@
+/* psycopg2 transaction status constants
+ * http://initd.org/psycopg/docs/extensions.html#transaction-status-constants
+ */
+
+module.exports = {
+  TRANSACTION_STATUS_IDLE: 0,
+  TRANSACTION_STATUS_ACTIVE: 1,
+  TRANSACTION_STATUS_INTRANS: 2,
+  TRANSACTION_STATUS_INERROR: 3,
+  TRANSACTION_STATUS_UNKNOWN: 5,
+};
diff --git a/web/pgadmin/static/js/tree/tree.js b/web/pgadmin/static/js/tree/tree.js
index 33397e80d..e317aeb81 100644
--- a/web/pgadmin/static/js/tree/tree.js
+++ b/web/pgadmin/static/js/tree/tree.js
@@ -9,6 +9,7 @@
 
 import {isValidData} from 'sources/utils';
 import $ from 'jquery';
+import Alertify from 'pgadmin.alertifyjs';
 
 export class TreeNode {
   constructor(id, data, domNode, parent) {
@@ -261,6 +262,9 @@ export class Tree {
 
           const parentId = this.translateTreeNodeIdFromACITree(api.parent(item));
           this.addNewNode(id, data, item, parentId);
+          if(data.errmsg) {
+            Alertify.error(data.errmsg);
+          }
         }
       }
     }.bind(this));
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index 9d9ab5c84..8f5897f3f 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -36,6 +36,7 @@ define('tools.querytool', [
   'sources/sqleditor/calculate_query_run_time',
   'sources/sqleditor/call_render_after_poll',
   'sources/sqleditor/query_tool_preferences',
+  'sources/sqleditor/query_txn_status_constants',
   'sources/csrf',
   'tools/datagrid/static/js/datagrid_panel_title',
   'sources/window',
@@ -52,7 +53,7 @@ define('tools.querytool', [
   XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, httpErrorHandler, FilterHandler,
   GeometryViewer, historyColl, queryHist, querySources,
   keyboardShortcuts, queryToolActions, queryToolNotifications, Datagrid,
-  modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, csrfToken, panelTitleFunc,
+  modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, queryTxnStatus, csrfToken, panelTitleFunc,
   pgWindow) {
   /* Return back, this has been called more than once */
   if (pgAdmin.SqlEditor)
@@ -4182,8 +4183,9 @@ define('tools.querytool', [
           self.unsaved_changes_user_confirmation(msg, false);
         } // If a transaction is currently ongoing
         else if (self.preferences.prompt_commit_transaction
-                 && self.last_transaction_status > 0) { // 0 -> idle (no transaction)
-          var is_commit_disabled = self.last_transaction_status == 3;  // 3 -> Failed transaction
+                 && (self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INTRANS
+                    || self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INERROR)) {
+          var is_commit_disabled = self.last_transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR;
           self.uncommitted_transaction_user_confirmation(is_commit_disabled);
         }
         else {
diff --git a/web/pgadmin/utils/driver/psycopg2/__init__.py b/web/pgadmin/utils/driver/psycopg2/__init__.py
index 4b3e2204b..94dc2976c 100644
--- a/web/pgadmin/utils/driver/psycopg2/__init__.py
+++ b/web/pgadmin/utils/driver/psycopg2/__init__.py
@@ -14,19 +14,21 @@ object.
 
 """
 import datetime
-from flask import session, request
+from flask import session
 from flask_login import current_user
-from flask_babelex import gettext
 import psycopg2
 from psycopg2.extensions import adapt
+from threading import Lock
 
 import config
-from pgadmin.model import Server, User
+from pgadmin.model import Server
 from .keywords import ScanKeyword
 from ..abstract import BaseDriver
 from .connection import Connection
 from .server_manager import ServerManager
 
+connection_restore_lock = Lock()
+
 
 class Driver(BaseDriver):
     """
@@ -80,21 +82,30 @@ class Driver(BaseDriver):
             return None
 
         if session.sid not in self.managers:
-            self.managers[session.sid] = managers = dict()
-            if '__pgsql_server_managers' in session:
-                session_managers = session['__pgsql_server_managers'].copy()
-
-                for server in Server.query.filter_by(user_id=current_user.id):
-                    manager = managers[str(server.id)] = ServerManager(server)
-                    if server.id in session_managers:
-                        manager._restore(session_managers[server.id])
-                        manager.update_session()
+            with connection_restore_lock:
+                # The wait is over but the object might have been loaded
+                # by some other thread check again
+                if session.sid not in self.managers:
+                    self.managers[session.sid] = managers = dict()
+                    if '__pgsql_server_managers' in session:
+                        session_managers =\
+                            session['__pgsql_server_managers'].copy()
+                        for server in \
+                                Server.query.filter_by(
+                                    user_id=current_user.id):
+                            manager = managers[str(server.id)] =\
+                                ServerManager(server)
+                            if server.id in session_managers:
+                                manager._restore(session_managers[server.id])
+                                manager.update_session()
+
         else:
             managers = self.managers[session.sid]
             if str(sid) in managers:
                 manager = managers[str(sid)]
-                manager._restore_connections()
-                manager.update_session()
+                with connection_restore_lock:
+                    manager._restore_connections()
+                    manager.update_session()
 
         managers['pinged'] = datetime.datetime.now()
         if str(sid) not in managers:
diff --git a/web/pgadmin/utils/driver/psycopg2/server_manager.py b/web/pgadmin/utils/driver/psycopg2/server_manager.py
index 8ae46c2ee..1676f7e38 100644
--- a/web/pgadmin/utils/driver/psycopg2/server_manager.py
+++ b/web/pgadmin/utils/driver/psycopg2/server_manager.py
@@ -25,13 +25,10 @@ from pgadmin.model import Server, User
 from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost,\
     CryptKeyMissing
 from pgadmin.utils.master_password import get_crypt_key
-from threading import Lock
 
 if config.SUPPORT_SSH_TUNNEL:
     from sshtunnel import SSHTunnelForwarder, BaseSSHTunnelForwarderError
 
-connection_restore_lock = Lock()
-
 
 class ServerManager(object):
     """
@@ -292,80 +289,79 @@ WHERE db.oid = {0}""".format(did))
 
         connections = data['connections']
 
-        with connection_restore_lock:
-            for conn_id in connections:
-                conn_info = connections[conn_id]
-                if conn_info['conn_id'] in self.connections:
-                    conn = self.connections[conn_info['conn_id']]
-                else:
-                    conn = self.connections[conn_info['conn_id']] = Connection(
-                        self, conn_info['conn_id'], conn_info['database'],
-                        conn_info['auto_reconnect'], conn_info['async_'],
-                        use_binary_placeholder=conn_info[
-                            'use_binary_placeholder'],
-                        array_to_string=conn_info['array_to_string']
-                    )
+        for conn_id in connections:
+            conn_info = connections[conn_id]
+            if conn_info['conn_id'] in self.connections:
+                conn = self.connections[conn_info['conn_id']]
+            else:
+                conn = self.connections[conn_info['conn_id']] = Connection(
+                    self, conn_info['conn_id'], conn_info['database'],
+                    conn_info['auto_reconnect'], conn_info['async_'],
+                    use_binary_placeholder=conn_info[
+                        'use_binary_placeholder'],
+                    array_to_string=conn_info['array_to_string']
+                )
 
-                # only try to reconnect if connection was connected previously
-                # and auto_reconnect is true.
-                if conn_info['wasConnected'] and conn_info['auto_reconnect']:
-                    try:
-                        # Check SSH Tunnel needs to be created
-                        if self.use_ssh_tunnel == 1 and \
-                           not self.tunnel_created:
-                            status, error = self.create_ssh_tunnel(
-                                data['tunnel_password'])
-
-                            # Check SSH Tunnel is alive or not.
-                            self.check_ssh_tunnel_alive()
-
-                        conn.connect(
-                            password=data['password'],
-                            server_types=ServerType.types()
-                        )
-                        # This will also update wasConnected flag in
-                        # connection so no need to update the flag manually.
-                    except CryptKeyMissing:
-                        # maintain the status as this will help to restore once
-                        # the key is available
-                        conn.wasConnected = conn_info['wasConnected']
-                        conn.auto_reconnect = conn_info['auto_reconnect']
-                    except Exception as e:
-                        current_app.logger.exception(e)
-                        self.connections.pop(conn_info['conn_id'])
-                        raise
+            # only try to reconnect if connection was connected previously
+            # and auto_reconnect is true.
+            if conn_info['wasConnected'] and conn_info['auto_reconnect']:
+                try:
+                    # Check SSH Tunnel needs to be created
+                    if self.use_ssh_tunnel == 1 and \
+                       not self.tunnel_created:
+                        status, error = self.create_ssh_tunnel(
+                            data['tunnel_password'])
+
+                        # Check SSH Tunnel is alive or not.
+                        self.check_ssh_tunnel_alive()
+
+                    conn.connect(
+                        password=data['password'],
+                        server_types=ServerType.types()
+                    )
+                    # This will also update wasConnected flag in
+                    # connection so no need to update the flag manually.
+                except CryptKeyMissing:
+                    # maintain the status as this will help to restore once
+                    # the key is available
+                    conn.wasConnected = conn_info['wasConnected']
+                    conn.auto_reconnect = conn_info['auto_reconnect']
+                except Exception as e:
+                    current_app.logger.exception(e)
+                    self.connections.pop(conn_info['conn_id'])
+                    raise
 
     def _restore_connections(self):
-        with connection_restore_lock:
-            for conn_id in self.connections:
-                conn = self.connections[conn_id]
-                # only try to reconnect if connection was connected previously
-                # and auto_reconnect is true.
-                wasConnected = conn.wasConnected
-                auto_reconnect = conn.auto_reconnect
-                if conn.wasConnected and conn.auto_reconnect:
-                    try:
-                        # Check SSH Tunnel needs to be created
-                        if self.use_ssh_tunnel == 1 and \
-                           not self.tunnel_created:
-                            status, error = self.create_ssh_tunnel(
-                                self.tunnel_password
-                            )
-
-                            # Check SSH Tunnel is alive or not.
-                            self.check_ssh_tunnel_alive()
+        for conn_id in self.connections:
+            conn = self.connections[conn_id]
+            # only try to reconnect if connection was connected previously
+            # and auto_reconnect is true.
+            wasConnected = conn.wasConnected
+            auto_reconnect = conn.auto_reconnect
+            if conn.wasConnected and conn.auto_reconnect:
+                try:
+                    # Check SSH Tunnel needs to be created
+                    if self.use_ssh_tunnel == 1 and \
+                       not self.tunnel_created:
+                        status, error = self.create_ssh_tunnel(
+                            self.tunnel_password
+                        )
 
-                        conn.connect()
-                        # This will also update wasConnected flag in
-                        # connection so no need to update the flag manually.
-                    except CryptKeyMissing:
-                        # maintain the status as this will help to restore once
-                        # the key is available
-                        conn.wasConnected = wasConnected
-                        conn.auto_reconnect = auto_reconnect
-                    except Exception as e:
-                        current_app.logger.exception(e)
-                        raise
+                        # Check SSH Tunnel is alive or not.
+                        self.check_ssh_tunnel_alive()
+
+                    conn.connect()
+                    # This will also update wasConnected flag in
+                    # connection so no need to update the flag manually.
+                except CryptKeyMissing:
+                    # maintain the status as this will help to restore once
+                    # the key is available
+                    conn.wasConnected = wasConnected
+                    conn.auto_reconnect = auto_reconnect
+                except Exception as e:
+                    self.connections.pop(conn_id)
+                    current_app.logger.exception(e)
+                    raise
 
     def release(self, database=None, conn_id=None, did=None):
         # Stop the SSH tunnel if release() function calls without


^ permalink  raw  reply  [nested|flat] 7+ messages in thread

* Re: [pgAdmin][RM4818] Unable to handle loss of connection to server
  2019-11-14 06:44 [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-15 09:04 ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
  2019-11-21 06:20   ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-21 06:28     ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
  2019-11-21 11:18       ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Akshay Joshi <[email protected]>
  2019-11-25 07:06         ` Re: [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
@ 2019-11-26 03:37           ` Akshay Joshi <[email protected]>
  0 siblings, 0 replies; 7+ messages in thread

From: Akshay Joshi @ 2019-11-26 03:37 UTC (permalink / raw)
  To: Aditya Toshniwal <[email protected]>; +Cc: pgadmin-hackers

Thanks, patch applied.

On Mon, Nov 25, 2019 at 12:37 PM Aditya Toshniwal <
[email protected]> wrote:

> Hi Hackers,
>
> Attached is the updated patch to fix the review comments.
>
> On Thu, Nov 21, 2019 at 4:48 PM Akshay Joshi <
> [email protected]> wrote:
>
>> Hi Aditya
>>
>> Following are the review comments:
>>
>>
>>    - Update the timeout in the comment section from 30 seconds to 10
>>    seconds in aff1436e3c8c_.py.
>>
>>
>>    - Asking for the database server password even if it is saved.
>>    Reproduction steps:
>>
>>
>>    - Connect to the database server, saved the password.
>>       - Disabled the network. Try to connect to the database server.
>>       - Enable the network, try to connect to the database server.
>>
>>
>>    - No error/spinner visible on GUI when the database server is
>>    connected using SSH Tunnel. Reproduction steps:
>>
>>
>>    - Connect to the database server with SSH Tunnel, saved both the
>>       password.
>>       - Disabled the network and Reset the Layout.
>>       - Expand the Servers node and try to connect the same database
>>       server.
>>
>>
>> On Thu, Nov 21, 2019 at 11:58 AM Aditya Toshniwal <
>> [email protected]> wrote:
>>
>>> Hi,
>>>
>>> I forgot to mention, I've also changed the dashboard code. The dashboard
>>> was sending graph data requests, but when the server lost connection the
>>> requests remains pending for longer time. Because of this the server gets
>>> flooded with lot of pending request and in turn slowing down the entire
>>> application.
>>> Code is changed so that only a certain number of requests remain pending
>>> (currently 3), above which the request won't be sent.
>>>
>>> On Thu, Nov 21, 2019 at 11:50 AM Aditya Toshniwal <
>>> [email protected]> wrote:
>>>
>>>> Hi Hackers,
>>>>
>>>> Attached is the updated patch to fix the review comments.
>>>> Please note, there is some problem with psycopg2/libpq where it hangs
>>>> when network is lost - https://github.com/psycopg/psycopg2/issues/561
>>>> I've also changed the code to make connections after the "Servers" node
>>>> is expanded to fix - RM4933, so that the servers are listed first.
>>>>
>>>> Kindly review.
>>>>
>>>> On Fri, Nov 15, 2019 at 2:34 PM Akshay Joshi <
>>>> [email protected]> wrote:
>>>>
>>>>> Hi Aditya
>>>>>
>>>>> Following are the review comments:
>>>>>
>>>>>    1. The default connection timeout should be *10* seconds.
>>>>>    2. In case the network is disabled and when we expand the
>>>>>    "Servers" node the database server(for which network is disabled) should be
>>>>>    shown in the disconnected state.
>>>>>    3.  For the above case when you try to connect to the server and
>>>>>    at the same time trying to fetch the properties of the valid database
>>>>>    server, it takes long time to fetch it.
>>>>>    4.  Case when the network is disabled, the database servers
>>>>>    password is saved and pgAdmin4 tries to connect the server, after
>>>>>    connection timeout, there is no message to the user, only spinner gets
>>>>>    disappeared. We should show a message.
>>>>>    5. We should improve the error messages "timeout expired" and
>>>>>    "Connection to the servers has been lost." to the more meaningful messages
>>>>>    like "Check the network settings, check the firewall status."
>>>>>    6. Install database server on Windows and Enable Windows Firewall.
>>>>>    Try to connect to the same database server. Spinner is not showing, as a
>>>>>    user I am not able to understand is there any action started at the backend
>>>>>    or not. As a user, I'll keep trying to connect multiple times and after the
>>>>>    connection timeout of each request dialog pops up.
>>>>>
>>>>>
>>>>> On Thu, Nov 14, 2019 at 12:15 PM Aditya Toshniwal <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Hi Hackers,
>>>>>>
>>>>>> Attached is the workaround patch to set the default connection
>>>>>> timeout to 30 seconds instead of the current value of infinite - 0, zero.
>>>>>> The input is present in the server properties dialogs advanced tab. The
>>>>>> workaround applies to the RM4724 as well.
>>>>>> The permanent solution would be to expand the nodes asynchronously -
>>>>>> https://redmine.postgresql.org/issues/4933
>>>>>>
>>>>>> Also fixed a bug where sql editor is not closing if the server is
>>>>>> disconnected in between.
>>>>>>
>>>>>> Kindly review.
>>>>>>
>>>>>> --
>>>>>> Thanks and Regards,
>>>>>> Aditya Toshniwal
>>>>>> Sr. Software Engineer | EnterpriseDB India | Pune
>>>>>> "Don't Complain about Heat, Plant a TREE"
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> *Thanks & Regards*
>>>>> *Akshay Joshi*
>>>>>
>>>>> *Sr. Software Architect*
>>>>> *EnterpriseDB Software India Private Limited*
>>>>> *Mobile: +91 976-788-8246*
>>>>>
>>>>
>>>>
>>>> --
>>>> Thanks and Regards,
>>>> Aditya Toshniwal
>>>> Sr. Software Engineer | EnterpriseDB India | Pune
>>>> "Don't Complain about Heat, Plant a TREE"
>>>>
>>>
>>>
>>> --
>>> Thanks and Regards,
>>> Aditya Toshniwal
>>> Sr. Software Engineer | EnterpriseDB India | Pune
>>> "Don't Complain about Heat, Plant a TREE"
>>>
>>
>>
>> --
>> *Thanks & Regards*
>> *Akshay Joshi*
>>
>> *Sr. Software Architect*
>> *EnterpriseDB Software India Private Limited*
>> *Mobile: +91 976-788-8246*
>>
>
>
> --
> Thanks and Regards,
> Aditya Toshniwal
> Sr. Software Engineer | EnterpriseDB India | Pune
> "Don't Complain about Heat, Plant a TREE"
>


-- 
*Thanks & Regards*
*Akshay Joshi*

*Sr. Software Architect*
*EnterpriseDB Software India Private Limited*
*Mobile: +91 976-788-8246*


^ permalink  raw  reply  [nested|flat] 7+ messages in thread


end of thread, other threads:[~2019-11-26 03:37 UTC | newest]

Thread overview: 7+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2019-11-14 06:44 [pgAdmin][RM4818] Unable to handle loss of connection to server Aditya Toshniwal <[email protected]>
2019-11-15 09:04 ` Akshay Joshi <[email protected]>
2019-11-21 06:20   ` Aditya Toshniwal <[email protected]>
2019-11-21 06:28     ` Aditya Toshniwal <[email protected]>
2019-11-21 11:18       ` Akshay Joshi <[email protected]>
2019-11-25 07:06         ` Aditya Toshniwal <[email protected]>
2019-11-26 03:37           ` Akshay Joshi <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox