From 3477d98a53d1470c6cd0af945d0b11fd6db883af Mon Sep 17 00:00:00 2001
From: ivan deng
Date: Thu, 16 Feb 2023 22:37:14 +0800
Subject: [PATCH] move and update gpt
---
app_chatgpt/__init__.py | 5 +
app_chatgpt/__manifest__.py | 50 +++++
app_chatgpt/controllers/__init__.py | 5 +
app_chatgpt/controllers/main.py | 11 ++
app_chatgpt/data/ir_config_parameter.xml | 11 ++
app_chatgpt/data/mail_channel_data.xml | 31 +++
app_chatgpt/data/user_partner_data.xml | 17 ++
app_chatgpt/models/__init__.py | 5 +
app_chatgpt/models/mail_channel.py | 145 +++++++++++++++
app_chatgpt/models/res_config_settings.py | 11 ++
app_chatgpt/static/description/api_key.png | Bin 0 -> 79757 bytes
app_chatgpt/static/description/banner.png | Bin 0 -> 267229 bytes
app_chatgpt/static/description/chatgpt.png | Bin 0 -> 5269 bytes
.../static/description/chatgpt_chat.png | Bin 0 -> 110090 bytes
app_chatgpt/static/description/icon.png | Bin 0 -> 90186 bytes
app_chatgpt/static/description/icon1.png | Bin 0 -> 102963 bytes
app_chatgpt/static/description/index.html | 176 ++++++++++++++++++
app_chatgpt/static/description/logo.png | Bin 0 -> 90415 bytes
.../static/description/main_screenshot.png | Bin 0 -> 176349 bytes
.../whatsapp_delivery_integration.png | Bin 0 -> 175234 bytes
.../whatsapp_invoice_integration.png | Bin 0 -> 196171 bytes
.../whatsapp_payment_integration.png | Bin 0 -> 176926 bytes
.../description/whatsapp_pos_integration.png | Bin 0 -> 167162 bytes
.../whatsapp_purchase_integration.png | Bin 0 -> 191253 bytes
.../description/whatsapp_sale_integration.png | Bin 0 -> 195419 bytes
.../static/description/wp_all_in_one.gif | Bin 0 -> 516929 bytes
.../views/res_config_settings_views.xml | 30 +++
app_web_enterprise/__manifest__.py | 4 +
.../static/src/scss/views_style.scss | 12 ++
.../static/src/webclient/navbar.xml | 21 +++
app_web_enterprise/static/src/xml/base.xml | 18 +-
.../static/src/xml/res_config_edition.xml | 20 +-
32 files changed, 554 insertions(+), 18 deletions(-)
create mode 100644 app_chatgpt/__init__.py
create mode 100644 app_chatgpt/__manifest__.py
create mode 100644 app_chatgpt/controllers/__init__.py
create mode 100644 app_chatgpt/controllers/main.py
create mode 100644 app_chatgpt/data/ir_config_parameter.xml
create mode 100644 app_chatgpt/data/mail_channel_data.xml
create mode 100644 app_chatgpt/data/user_partner_data.xml
create mode 100644 app_chatgpt/models/__init__.py
create mode 100644 app_chatgpt/models/mail_channel.py
create mode 100644 app_chatgpt/models/res_config_settings.py
create mode 100644 app_chatgpt/static/description/api_key.png
create mode 100644 app_chatgpt/static/description/banner.png
create mode 100644 app_chatgpt/static/description/chatgpt.png
create mode 100644 app_chatgpt/static/description/chatgpt_chat.png
create mode 100644 app_chatgpt/static/description/icon.png
create mode 100644 app_chatgpt/static/description/icon1.png
create mode 100644 app_chatgpt/static/description/index.html
create mode 100644 app_chatgpt/static/description/logo.png
create mode 100644 app_chatgpt/static/description/main_screenshot.png
create mode 100644 app_chatgpt/static/description/whatsapp_delivery_integration.png
create mode 100644 app_chatgpt/static/description/whatsapp_invoice_integration.png
create mode 100644 app_chatgpt/static/description/whatsapp_payment_integration.png
create mode 100644 app_chatgpt/static/description/whatsapp_pos_integration.png
create mode 100644 app_chatgpt/static/description/whatsapp_purchase_integration.png
create mode 100644 app_chatgpt/static/description/whatsapp_sale_integration.png
create mode 100644 app_chatgpt/static/description/wp_all_in_one.gif
create mode 100644 app_chatgpt/views/res_config_settings_views.xml
create mode 100644 app_web_enterprise/static/src/scss/views_style.scss
create mode 100644 app_web_enterprise/static/src/webclient/navbar.xml
diff --git a/app_chatgpt/__init__.py b/app_chatgpt/__init__.py
new file mode 100644
index 00000000..8a67bc5a
--- /dev/null
+++ b/app_chatgpt/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020-Present InTechual Solutions. ()
+
+# from . import controllers
+from . import models
diff --git a/app_chatgpt/__manifest__.py b/app_chatgpt/__manifest__.py
new file mode 100644
index 00000000..509a2c27
--- /dev/null
+++ b/app_chatgpt/__manifest__.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+# Created on 2023-02-016
+# author: 广州尚鹏,https://www.sunpop.cn
+# email: 300883@qq.com
+# resource of Sunpop
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+# Copyright (c) 2020-Present InTechual Solutions. ()
+
+{
+ 'name': 'ChatGPT Robot Multi Chat and Training(Under Construction)',
+ 'version': '16.23.02.15',
+ 'author': 'Sunpop.cn',
+ 'company': 'Sunpop.cn',
+ 'maintainer': 'Sunpop.cn',
+ 'category': 'Website/Website',
+ 'website': 'https://www.sunpop.cn',
+ 'license': 'LGPL-3',
+ 'sequence': 10,
+ 'license': 'AGPL-3',
+ 'summary': '''
+ Multi Odoo ChatGPT Robot. Integration All ChatGpt Api.
+ Chat channel with several ChatGPT Robots.
+ Whitelist and blacklist for Users or IP.
+ Base on is_chatgpt_integration from InTechual Solutions.
+ ''',
+ 'description': '''
+ Allows the application to leverage the capabilities of the GPT language model to generate human-like responses,
+ providing a more natural and intuitive user experience.
+ 1. Multi ChatGpt robot Connector. Chat and train.
+ 2. Multi User Chat with ChatGpt
+ 3. ChatGpt Channel for Group Chat
+ 4. White and black List for ChatGpt
+ 5. Demo Chat time for new user
+ 6. Easy Start and Stop ChatGpt
+ ''',
+ 'depends': ['base', 'base_setup', 'mail'],
+ 'data': [
+ 'data/mail_channel_data.xml',
+ 'data/user_partner_data.xml',
+ 'data/ir_config_parameter.xml',
+ 'views/res_config_settings_views.xml',
+ ],
+ 'external_dependencies': {'python': ['openai']},
+ 'images': ['static/description/banner.png'],
+ 'installable': True,
+ 'application': False,
+ 'auto_install': False,
+}
diff --git a/app_chatgpt/controllers/__init__.py b/app_chatgpt/controllers/__init__.py
new file mode 100644
index 00000000..dcd9a093
--- /dev/null
+++ b/app_chatgpt/controllers/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020-Present InTechual Solutions. ()
+
+
+from . import main
diff --git a/app_chatgpt/controllers/main.py b/app_chatgpt/controllers/main.py
new file mode 100644
index 00000000..e85192b4
--- /dev/null
+++ b/app_chatgpt/controllers/main.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020-Present InTechual Solutions. ()
+
+from odoo import http
+
+
+class ChatgptController(http.Controller):
+ @http.route(['/chatgpt_form'], type='http', auth="public", csrf=False,
+ website=True)
+ def question_submit(self):
+ return http.request.render('app_chatgpt.connector')
diff --git a/app_chatgpt/data/ir_config_parameter.xml b/app_chatgpt/data/ir_config_parameter.xml
new file mode 100644
index 00000000..728f78cb
--- /dev/null
+++ b/app_chatgpt/data/ir_config_parameter.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ app_chatgpt.openapi_context_timeout
+ 600
+
+
+
+
\ No newline at end of file
diff --git a/app_chatgpt/data/mail_channel_data.xml b/app_chatgpt/data/mail_channel_data.xml
new file mode 100644
index 00000000..f56b40d1
--- /dev/null
+++ b/app_chatgpt/data/mail_channel_data.xml
@@ -0,0 +1,31 @@
+
+
+
+
+ ChatGPT群聊
+ ChatGPT企业内部频道
+
+
+
+
+ mail.channel
+
+ email
+
+ 欢迎来到ChatGPT的odoo群聊频道!
+ 欢迎进行 #ChatGPT 群聊.
+ 向ChatGPT咨询你的问题.
]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app_chatgpt/data/user_partner_data.xml b/app_chatgpt/data/user_partner_data.xml
new file mode 100644
index 00000000..0071b111
--- /dev/null
+++ b/app_chatgpt/data/user_partner_data.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ ChatGPT的odoo机器人
+
+
+
+ chatgpt@sunpop.cn
+ chatgpt
+
+
+
+
+
+
+
diff --git a/app_chatgpt/models/__init__.py b/app_chatgpt/models/__init__.py
new file mode 100644
index 00000000..381d5ad3
--- /dev/null
+++ b/app_chatgpt/models/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020-Present InTechual Solutions. ()
+
+from . import mail_channel
+from . import res_config_settings
diff --git a/app_chatgpt/models/mail_channel.py b/app_chatgpt/models/mail_channel.py
new file mode 100644
index 00000000..0dd713c6
--- /dev/null
+++ b/app_chatgpt/models/mail_channel.py
@@ -0,0 +1,145 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020-Present InTechual Solutions. ()
+
+import openai
+import requests,json
+import datetime
+from odoo import api, fields, models, _
+from odoo.exceptions import UserError
+import logging
+_logger = logging.getLogger(__name__)
+class Channel(models.Model):
+ _inherit = 'mail.channel'
+
+ @api.model
+ def get_openai(self, api_key, data, user="Odoo"):
+ headers = {"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"}
+ pdata = {
+ "model": "text-davinci-003",
+ "prompt": data,
+ "temperature": 0.9,
+ "max_tokens": 1000,
+ "top_p": 1,
+ "frequency_penalty": 0.0,
+ "presence_penalty": 0.6,
+ "user": user,
+ "stop": ["Human:", "AI:"]
+ }
+ response = requests.post("https://api.openai.com/v1/completions", data=json.dumps(pdata), headers=headers)
+ res = response.json()
+ if 'choices' in res:
+ return '\n'.join([x['text'] for x in res['choices']])
+
+ _logger.error(res)
+ return "获取结果超时,请重新跟我聊聊。"
+
+ @api.model
+ def get_openai_context(self, channel_id, partner_chatgpt, current_prompt,seconds=600):
+ afterTime = fields.Datetime.now() - datetime.timedelta(seconds=seconds)
+ message_model = self.env['mail.message'].sudo()
+ prompt = [f"Human:{current_prompt}\nAI:", ]
+ domain = [('res_id', '=', channel_id),
+ ('model', '=', 'mail.channel'),
+ ('message_type', '!=', 'user_notification'),
+ ('parent_id', '=', False),
+ ('date', '>=', afterTime),
+ ('author_id', '=', self.env.user.partner_id.id)]
+ messages = message_model.with_context(tz='UTC').search(domain, order="id desc", limit=15)
+ # print('domain:',domain)
+ # print('messages:',messages)
+ for msg in messages:
+ ai_msg = message_model.search([("res_id", "=", channel_id),
+ ('model', '=', msg.model),
+ ('parent_id', '=', msg.id),
+ ('author_id', '=', partner_chatgpt),
+ ('body', '!=', '获取结果超时,请重新跟我聊聊。
')])
+ if ai_msg:
+ prompt.append("Human:%s\nAI:%s" % (
+ msg.body.replace("", "").replace("
", ""), ai_msg.body.replace("", "").replace("
", "")))
+ # print(msg.body.replace("", "").replace("
", ""))
+ # print(ai_msg.body.replace("", "").replace("
", ""))
+ else:
+ _logger.error(f"not find for id:{str(msg.id)}")
+
+ return '\n'.join(prompt[::-1])
+
+ def get_chatgpt_answer(self,prompt,partner_name):
+ response = openai.Completion.create(
+ model="text-davinci-003",
+ prompt=prompt,
+ temperature=0.6,
+ max_tokens=3000,
+ top_p=1,
+ frequency_penalty=0,
+ presence_penalty=0,
+ user=partner_name,
+ )
+ res = response['choices'][0]['text']
+ return res
+
+ def _notify_thread(self, message, msg_vals=False, **kwargs):
+ rdata = super(Channel, self)._notify_thread(message, msg_vals=msg_vals, **kwargs)
+ # print(f'rdata:{rdata}')
+ chatgpt_channel_id = self.env.ref('app_chatgpt.channel_chatgpt')
+ user_chatgpt = self.env.ref("app_chatgpt.user_chatgpt")
+ partner_chatgpt = self.env.ref("app_chatgpt.partner_chatgpt")
+ author_id = msg_vals.get('author_id')
+ # print('author_id:',author_id)
+ # print('partner_chatgpt.id:',partner_chatgpt.id)
+ chatgpt_name = str(partner_chatgpt.name or '') + ', '
+ # print('chatgpt_name:', chatgpt_name)
+ prompt = msg_vals.get('body')
+ # print('prompt:', prompt)
+ # print('-----')
+ if not prompt:
+ return rdata
+ api_key = self.env['ir.config_parameter'].sudo().get_param('app_chatgpt.openapi_api_key')
+ try:
+ openapi_context_timeout = int(self.env['ir.config_parameter'].sudo().get_param('app_chatgpt.openapi_context_timeout')) or 600
+ except:
+ openapi_context_timeout = 600
+
+ openai.api_key = api_key
+ Partner = self.env['res.partner']
+ partner_name = ''
+ if author_id:
+ partner_id = Partner.browse(author_id)
+ if partner_id:
+ partner_name = partner_id.name
+ # print(msg_vals)
+ # print(msg_vals.get('record_name', ''))
+ # print('self.channel_type :',self.channel_type)
+ if author_id != partner_chatgpt.id and (chatgpt_name in msg_vals.get('record_name', '') or 'ChatGPT,' in msg_vals.get('record_name', '') ) and self.channel_type == 'chat':
+ _logger.info(f'私聊:author_id:{author_id},partner_chatgpt.id:{partner_chatgpt.id}')
+ try:
+ channel = self.env[msg_vals.get('model')].browse(msg_vals.get('res_id'))
+ prompt = self.get_openai_context(channel.id, partner_chatgpt.id, prompt,openapi_context_timeout)
+ print(prompt)
+ # res = self.get_chatgpt_answer(prompt,partner_name)
+ res = self.get_openai(api_key, prompt, partner_name)
+ # print('res:',res)
+ # print('channel:',channel)
+ channel.with_user(user_chatgpt).message_post(body=res, message_type='comment',subtype_xmlid='mail.mt_comment',parent_id=message.id)
+ # channel.with_user(user_chatgpt).message_post(body=res, message_type='notification', subtype_xmlid='mail.mt_comment')
+ # channel.sudo().message_post(
+ # body=res,
+ # author_id=partner_chatgpt.id,
+ # message_type="comment",
+ # subtype_xmlid="mail.mt_comment",
+ # )
+ # self.with_user(user_chatgpt).message_post(body=res, message_type='comment', subtype_xmlid='mail.mt_comment')
+ except Exception as e:
+ raise UserError(_(e))
+
+ elif author_id != partner_chatgpt.id and msg_vals.get('model', '') == 'mail.channel' and msg_vals.get('res_id', 0) == chatgpt_channel_id.id:
+ _logger.info(f'频道群聊:author_id:{author_id},partner_chatgpt.id:{partner_chatgpt.id}')
+ try:
+ prompt = self.get_openai_context(chatgpt_channel_id.id, partner_chatgpt.id, prompt,openapi_context_timeout)
+ # print(prompt)
+ # res = self.get_chatgpt_answer(prompt, partner_name)
+ res = self.get_openai(api_key, prompt, partner_name)
+ chatgpt_channel_id.with_user(user_chatgpt).message_post(body=res, message_type='comment', subtype_xmlid='mail.mt_comment',parent_id=message.id)
+ except Exception as e:
+ raise UserError(_(e))
+
+ return rdata
diff --git a/app_chatgpt/models/res_config_settings.py b/app_chatgpt/models/res_config_settings.py
new file mode 100644
index 00000000..c7fcfcf6
--- /dev/null
+++ b/app_chatgpt/models/res_config_settings.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020-Present InTechual Solutions. ()
+
+from odoo import fields, models
+
+
+class ResConfigSettings(models.TransientModel):
+ _inherit = "res.config.settings"
+
+ openapi_api_key = fields.Char(string="API Key", help="Provide the API key here", config_parameter="app_chatgpt.openapi_api_key")
+ openapi_context_timeout = fields.Integer(string="上下文连接超时", help="多少秒以内的聊天信息作为上下文继续", config_parameter="app_chatgpt.openapi_context_timeout")
diff --git a/app_chatgpt/static/description/api_key.png b/app_chatgpt/static/description/api_key.png
new file mode 100644
index 0000000000000000000000000000000000000000..43ddb0369bd04b6b3418bd301b28445aeeb0db29
GIT binary patch
literal 79757
zcmZ6y1yCG8+bv82fgr&lxGwICdvIIa-4+N0cPE74?kpPI-Q8tz2^QSl-7oL^-|yaA
z|5R5^PfxYZ^wZ}&eL7T0LFx+<0TK)h%oiDHaTORCxcBJCZ=d1cZ&-=gv+p-JCs7%-
z&+nJ_XK)A%3>l1!xQLp2`tgdJv;LsZ{?i$AA@}vF2s+$n%wu_MD&-u{YOrpNnFUq#
z7J&P#{BCe;SlF&zI4-%>pvKYA(e5&?RVBS|MWdd!I;{OG4B#_*#(w+O`n8j*hab^T
z32QPc?FP=Q`famxr`u!5VlDUGv-zzxltUity^jA0zNN*6&hQDj3YC+qq;0Kg`ZP~VJ*
z9Ag!7B6wR6kOV}RE4KaS=Dc#6=uY0nfLUP;8QA=Pa|>~&7G%>76H6t?&j2vPx9XNo
zc{hnrgYXZCdnRxAeeIkU=xA9)l@qCUpd4dIPpuDcYl>th(_A^ZgwRewR7m0j)P~fx
zPk;z@%bv&AjPf)bG}ARH1<4W~UV9yLNUcDPjXgCR1M;)`&^Yij30xjGZa5i~8$&<*
zRHE&Z@}M?@{cnwFK?MV5%0^OLQJ(eO@A>OCO@Ln
zW|y{=tF=Ym!N+0-l58?Fx+TKC9K4q-F}G*(=P+A^{e
zW4Dl`$ryEHAoa#i(qn`4Im4}eQ}3kRA0J9e!<1}G-rU_&lYTgr>Fd9ijzwFdpHE8ac
z#B93gzgg!r!ZMYo2&@G(a{l+{A<-j4-+pecEz@aFO;1lpSnW79AtvOu5m!H3UYm3w
zmY=U)-tqdmI``xG+3yuyFq<5DDewPtTToS263OpU(=Y6GV?Vw~VhWWRj7~5?T{x9rAlUr)hhLtgLM_
zS&VDYu6tW2C#d9DyJ$_oCVksM>-3tpk)P>feeN?c?b{?U=NO$Q^@1y934iS_1%t&y
zEHU5*$79o)QPs8o`DlvHq(CysIhk-u`)l%SlAO6Sqyg@G?Pz#-M14Ds%yb*A)!OBH
zN2lhluBZN)y>}B6SER!Ch{*(m#ro=EmX>U1KIi0qcXw|?i3R+mArb|aag(;u29N@1
zZ0=yQ)_hkzZ$>O^F9WY2K?S>+Pq)X56SEz3AkeNu|-Co|}J2OY(7$7X2bMfhCQXg1mFk;T%-pZ^LeV-iWNdno{ng&m7m4i+FBpv|r?@`6`qlN2pOhJG>cMz?&V}lY^<%o=
z>^E`t?uZ#3zu1ePx9c8hS?hmeVbe?OXl|iMu;%bf-;W8rik?4$?zo-uy$-V*I}@R5
zZm>_NS-H7(*9}{(*g?3t56c+0q(Z^Mu1^nTQWiWO4F^dRyOMkdY1eBsKd5yC`Vy}S
zA)w3>@jXeN+Y8@u{R8S(R)`PG#=!?>4%fBI#qVzHrvCiGd}aiQsS3o|UVP8ZyK?`r
zz#WXBnY`@mOrNJ)r_K9NgjHW(-%K>&<+1DQYeB!{$U}-~{h_X87
z1>A@R)8K&v25Jynq}S?;p`tJ=|5)(bEt>c99NOYjuHR08-;3Ag)DTl=GvNx{3QRbP
zZ5njHOhoJnyVl8RbbK7h&mUf}^0w+?Wfc|>998v{+kSn6R^_%Pg6i#^GF6?wmK7DP
zxbD!p*x+(?^Hxw$c(8w*Q&@PGxn!ji6MBG*f?ChcD;OYAKeNm|{;;bsEm#arYB|6^
z&CWi+TY*hZURER_BHFBc-92k^Eq{6yHu&@WkoESEwRVKiQgOAF)!x6bz~gs~(5ZMx
zEH#ike&U*4LQkx(f8Qo_e48)9jY=#eNrt|z_YEdB7?S)=jlnQbtdz-P6ix*pBe-xtGKm0@Q
zHT^J5FIzp##!Rv>mhD8Gw~ezE_mSvnUq5QrMO6vXjrRIzh?km4(_Z%zx=NC>K{u|S
zVLaH7n9k!K5%y07)z3a8uKozW#gT-)9nPyN8q38;ZLWe!xL4k-mpte%X32C;x@G2{
znj9E*zLCWOHkDbtj#0*EF@4YvSL*?R6G2t*J!73g%QvqzlmlK!-!8o60iKDu711$W
z6DHPshtq?04GJVZ_wmA2l9ENeOo=mKXYPTu_OyJ&U%q}nBAlmvsKM
zF6$myjnshGB*KSA05y;2y+Ey#$aI)WbJZKqmeYr0eC;MRd^aojsS8`?IqqrhLmDO;
z;$mBBE
z%p$%((y~Zb;8n;Rfv>pLIgnT0tl^1X-ex`pO%lIpZeU$4C1MnG9a@@xtXkwMZ_kt|
zArlnuZXYzz!sj^{0Nyn-u>$fgTEZ2=H`{MuzKBs4;rHj^tEP7@gsfG?$L}`Rf0Eec
zb+Tvq!UT&wXG=B)uc=7fqhb)=c?G;pN78frUF!1nyX_e@X86qPzfrIj1-sxUN}!yR
z53!&rInW6h3i_htR_%Y*}Y2=p`1qO-&O2Lx`YhKf@V@jCu)UgQl63tMQiq%1Bj
zmix!`j>ztwcpWz379rXwXwfkcNT_j&R{7kLuU#rNu6p~?(8IzyE%BG~vgNka(YANX
z+jru0HGF5VHys*|7u4Ob=W67(`m*LHHh*B%HU#nM1OVqE2Y1K>XXOQWdhZtixTS#!
z5sZ0WWm2p{7SogQ>r1-MVKZNX%*{UfqjNSRz5`QM6l<;}eG7g@KKFgvvyRTRsp@T*
zfA@WGn!5jD0Fc>Ija8>5iR4NS)tIco3Yx4xc}*d4n-t@jogr&ygFDWb*Q)$y22oJk
zfx#9;nvdTl;YK2&up?9wPIKFaCCD(pX$a;mT7R#mefY#VbooMBS*632SCCiLW`fVP
zG;RKG)eXLjWz{!2+~uaM%s}La7r({0{`zP$a=M_O|3xU2>ICfQ7#2IlCMh|HM@%@#
z(S6|TnEycU|IJ>;QmbxvE^b>`Bl4P4WM6|!!lwWPZG
z<<*tD^Ai_LNofflK5@I(FY{l>c5lcug+2*9@DIUfX9ZW!zP{e~1PnhkV|N>jufSE7
zPa2-LuRp`LVvo{fYXYZtN@Jg*F2lF<>qzg(TbD2s%*5|sJ6}`eXxy9}hXxvMW*2bm
z&68`6AcN2wozL*1DY*QO6kYe**rw#
z3h@ApHoD^N9h|ObIC5A~%9RDjIQxMqXj)L)+@II6qX@{)3fo<^?#d`
zOrjixh7)h&fE`ZPjemK@h&`dcFIucK+KT#5Fq#U)<_pr~OM6`~14}ISW&ni-?(X9F
zo4&7Us?JFRa>=-tu7S#L0wBghdcGXGc3nBPMG5WAY5`FYP#7q9|D=eRd9tbE~6bVPCPFtV4a>-_!}$l
z8iq5QvSV_^8KUTzZ3^V6+P)
z#I<>N!mbKLqAx08>@JX>o?JznQYPS+O2M->8-*cACbVCP|_gvNhvl-pKo4ANMoj=_amzV(cu(irvq0T-HvDpiMj1BV5A--;(ww#Rd=3n-1*px?O%;
zjYFzYO$S{!vTPq=YVv!^XbD=c+z>G!*~00l&a_?EH~g&p=^QP~2ozDhV;qs4;c>l(
z>uB?aXU@vDa||0PjM{26GlAIb9M575co9I9Yos+Tczkz}KD^P|2yPkeJ9BbkJctuZ
ziN)8sM8}1Isx02LYr?~;N8kaX&J7$)+c!YL+}b`1uO{G$iN0Bbdu7#s_`Ww1jY9f*
z=gW@YRz~BR@nVfx+vC5|w%gfxS~@!I>04D*)#t&xw+z3x*G@_qAWPddg==dD>Fav%
z^HS$4L$2HYJfqofUXt*wtlO>YmW9{NEilgZ`Ag@$)GoC}azbTuu|r-q{B(q6*zkzE
zXkiIws-#VuTU};*;nDs+p^l37
zw2CUUwb%3*YYQtPQjxJ(AZyo`2AhPc8#}aV{2aY5;we;IY=2*mFd9ALscON;$V5c?fFxYyz3EX-`@x!cV**{$GMLe{5m%HRkuc}tn!mWL_Z`ISP0rYxPmxE3T;d(}%wy@JY*e$atjSQl1@
zUZZcP1%<{JmLp+{7FOP&;TD9r6psi$r@1zl}G+at;05o8BlY{0Cf
zl{q!ZQzY%S(i-~g(R@u!18%g?h#pzgSel6T1JY%g@~-@+(pk?JVf8o%K4S4-Gbj<`
zWDJwD3osSf6jvWUzH0BjsG>Z45zQ5An(^Tz+$oMS$+o)$)jteZ{K5kwjhKsag{%a^kk}Ns3)ne2P~!p%+_<3>9ocjbc=wn
zRGh+!iYovZ=~TwQ#^OaaBngrN+1>uQg&am6(J>A8moV!kVKY2DXkXXYVN4raug^V8
z$tz_T)YP(9!PLykc$&j2j6@C<(?P-8*ebfU>F3KRxng45>a#Uvc`(WPk{9Oj1rzo*
zU|iMkNp2okWnqU|DEP_DoTwi!9(EMvc4L&eyEA!pE3+$V6MCmtmV
zwCSLWk52#yiMHOOVX4M+wWG(kq|4h*Kqn>a69$IRRKiKbotxuU<+uuJ&!Gpb%;Tk}
zup!j{&`?oH4=`hU>ShzY{b*H^q^gq;nDY-hqL5wL
z9v<=`%rnXOk<4@%!Dh4IvebZRMTM)a#wT8{ig0OncuJwc
z+0rX-XJ&D^&M;fN{oQHOL1KL3t+ltS!FPhr=#lnRA$~Ww_JsO&WY{qgbo0aG6r!({
z)YQ~9rZKymqG6m$yxLa8fB#*cZ+OW!F2K^q)X65Bo97++bZ931Bj*uV2
z3>{Fa^SC|Xg+{$yT11>YcmV*cE*vXHY_54)*nr-yEe9ay0Zn=;S)T5Yes!pDG2>?P
z+pQwe=rb`2yC?@{KZUNe_||CTwTZdf#X9J#`4|&$<2u*VVj!7i^K^AcF;Wu({d&HI3__}^WP+POBjug?cPL^cXL3YV4
zn^lc9EiMAP;2tYVhC2X6YZb>VVTqqY!(bEUe?S}cEyaI|`TAOxq
zE{eW^%ik!^xZN)9FHKYmdq88O7!7$qej-3-^{-07b~#2LVqH0^m~WDjTrdDN
zd{8(nCI-b6&&IdU;UfV|T*K+Y;tfn5m)bgL@@6uv+)+TKg`rk{=G)f5hVOn{!BWB*Dl?icn&Q
znZWNUA1fH)0^S|=(6$St#Wd}5`tFC%4iderAQUD^X?E>~4TtFg&wKkd>*qc8)h&j&MeB!JSf0x(ST{I6-fbX>&9Vculn
zl(S7l$rpX@@glax`l#vQz(BOW-VgmyO
zNmQ;_OxRSZ`-n
z$IsE`iCr;b`+Ni#FH1{~|9sfxBm?GVRtNEynRoK`-q_TPED_#N*>KUHETj
zl5v3d>0De=V($L^v$h5vDPeA1T|&<0W~;SRmbm=4Uzdp^?w3asj`ta`YIa2%vuEw&
z{BPGYREZMn<4s
zcUnDt31H6`gPJzwbgrYgkC^PWPIdKetGCVbN7*eUmmSgQ-Z~_W!5zMkS7U^$R~Ubu
zztMdTk5ZuoT;{oah2sd?5W^sO7jhZ7*5cubk)7zb^H%JyIE=h3cTAQF3S4VX<7bzh
zuRBi*Wn8X;H+_Ykc3?)_-1>6Z=y@>@?SnW<-RQH0@w>MxssC_Vml4UH*v|;ULOnzK
zcnqbQ%TBu5NwG~n>!nr_RKaMZ`OOdX&CR^lOD&Lt1N_?);h}hb(oQj1)UaChaSrFJ
z@~>_e+;7)kkNdY{E8h^8lF~R{C;T?v`0g;GJ8$_oM`j)tg`d$dXDHhq6QV!PGwxNQ
zt|o;`8F)u_zCOKmd%$WO-xJJbZ$0-uSwPTq@6F8-8I}W{cMP9}y>HMud(}*dXVd14
zBht6p(Nbl2kfF{N%DQB=XYGwudDxfUz9fkBi(b#LIx&ma%cbH2UOb*PBrEYFThUB3
zzz8`v^ae|P{}{J%1rr!L4O;4rdG7Gf~5_Uo2ait)rx+_HhPlo97B(s>f*r^dc3~=l=|>V={JA>TJN?C+Rf~MOpj_?X@}H!FE_l@
z>^!iadL;54S8!d=R>T@D<22h7L5=W$xJ1*B;~)|rlf4_A+6Bgif@z-iJ$-B@*`26l
zD9gm3KOfyu9UC6}T8K-S!gozJ7fw^VY@j9M=E&)?5;g}jR4jm@;r}J@iBU_?A*Ft0W{ytkdRvd4x!q(FO2-H9Rb-TvjqYR#6Kq1}%Rmu?&a`168f)tZ{5*3auw=TA
zd?HrAP_-0B`$4A;QM6xTVK!fXy4HP#+v0=hW7Q8?j0o8zq?CPc_bBYcdFZ`V}3Yq3>{?Qkn0s>E?szki5zuxVL#(dfK&etqM6>Xt0Jt;#g
zp{rPPZ-__J0Q|Y4c1Ws5K_P6D4I*GsfrnM@>~~+1yczA~^heCl-vj4EpPP9X<&bbc
zNbh2bQWscGFU?P&`8})p-nn&1Xj?+#FgxSt8eC%l^vRlk1iq1VbI9xHEMe}QLHUa~{WjzB9@7A`
zzHj39ii@iM4O~Q^uA!hDp|+v9WlL*Ml+pmh{P{r;m-ExoC{+b0KcnYsF93Yn#v!#H>
z0+x|TQ#CG@3aeMTgN3uXJ>42s8gB~yDi&^IN`o1tsO|cg8hb_@IJR`@HL`|$lUsz#
z>g?S6O(QP%C62My9zBLN{!D*1XB2_5?^!JUJKj!WrBGzaQI$OkXhu3o|Gj8dDn#v%
z`rOLc_#jwVM6>Ky7fNl#k{lxf_!i3?MxywoBTf%gmIg~zIaa|1@s+CJWYWrl&I@#6
zPaMUvaY+p|Y{ZDP%Us&5XN2*-$@raks)NUec!5`_r=l-Hs=1yYfR-1FQaftf4SLBC
z_S;yN76^5vlPL=ORY3@CVT(u`&)8lIvZP=b&ZzV+2({gpt_fqL`Z}py#sb+E7NQ2+
zWm^s*TT(!!<2+u7)c%5(xSFSez`TpD&b@FlqUy7{Te1cI#y@iy=j0sc;&N7fLAH8W
z@irPs5-{KXL$!pEUtV6ko1Vl-7GFOf&6Vp;b5(0az#^b3>8s0Yd*H*qz;bYN*B%|{
zyB*`{l;c|Cj_5xrMHUj?AG|%0BKv&YdZca5p~WlkU)tMIe0zQCOZL4}@OC7OpKEcd
z%M$vj8cj|Iyb4MjWAO{f38P}E<@csf$%%uz>dpKqSf7f8
z1+DOE)vko!>-FP*{O|IFa~F~Godc)Qw~m|J_y!&ipGdr}W4&x!_Ys62>E7Kn@~iAD
zlN?`WIH03L>z!{mhN~{R`r%jMXwi-~vNDqDxv}Xq=TcocSSr5I!_kty*r-HN{-(^0)NRxCyAll2e++0g91y;-Y90X$O
ziNUGn?uy1fjkrZr<
ze!83!l&sJloqv(vBRySL(`QKCG`T5YN-*~lPX4qgsv3|kIR9;^PNmw4ayB25wbo;2
z{wu15o#T#0JP8MFDa#|BDEZ6eeuuYz!v&l!$%;adoY}LEpjbkUulD0!V(ywwfaZi_
zwG9A&D(R$br8?kp)T?ts^S?}bVt$iy#dnZ}U~I}89(
z4|Pz`!X^4P+WxSY5`Y=X?|UXEw^2Nw)w!n&gF9kE0H56@@GdHmNpkS;=2;<$$$PqO
z200mT`)v53^lsCfxmI;Z_MfOIt0#_*jy~NYZe74#U0p3$YY32_bsL39bBKmbG;T{R
zTUb~i2Aw`1nyRZ0wGZkb7gz#$3D*ms4j{216bnYK5Ov
zSG`{tp6d;alHBKPXRDa_EoDT{A$)jCXW
z#QwM>nH5yh-^0TbWVOmPu-W2R{-cKKoF#H4EXjGkMRk8o1)7^%;F{c81DWfncVZV;NKk*?($dDln_Aj_Rnb)go|A#$qUEgS^NYo?91hG+@HSQE
zq%;5%4^7os6%OYAD+W$PE5|SZ<|hS>g_@4g-t1|hp`T$33=E?{xJfD=a=0G8n--DM
z|E?2mgF6W>tn3fH<7N4G6Li&eIRcpfdG+2R7DDw1U*!Kvzy8zZ9y{Tim8^{CoU8w>
z2m5d09!Suy?Jj&g;QvX?s-3u_3iv-6e~~@w{68u$IFWnI|KFoh=RV4RO8akk=8~p$
zpk|kx`rAj`smYlbaiCY0dZL-mE+UQjf3;%26`?UG|L9rR;%1`h@X1zQ3867V5L&Ry
z2rgLlVbK;c>6d+fBeQ4SY#YDIRzOEw(}*}W?9$O%~&Woj|5m^!#ERaL!A
zyFG{vyoOgq%IoJiKuc_AG0FarnPy^jH6IRT?D}E9kSv$xy1H?TTMQdzV&abNwN^rl
z>IvxKW`beje+KyT9koo8H|nT#g8k@y8D{@ZeXbEYN+0X#6h^(87fJksF77tLl6nGK0alt`~CN>We~e5rIZpF3uEx@zu&z*#L>F)^FmxHvhOW$tg%UcTamNOi*b0L`GI|X
zWVRD6C?#_H>b$;oC7$+Lup>(O1$+!C34H#@Qf-9&Led}4q*3Fv(kFT+9Myo$LWQqk
zzPFWSWAGoyx*-Q%Y~XBr9U#!qEC4#%M0~s62!JW+?H*=gaDSb3vGyzbb)!41T}zD?
zJq9)hN;4Xp4Dq%1+stRZxGmNc%NzExkGQSJ1RX@c$KZA_oEZ9-urQIWL!rAnb~eU7
zE__oDWHYrG)^tK8^SJR@^lS_4^4CIlT5dT%M1IvGutlQRSWz9BNr0#%Kb~V7j>cM
za>5R8$`=uB5BiM<)<;aV(mX9X=G*nGRyX0P-J6(=Sj6D7nKTu~?QO4+Pj>B%wVuo1
z{F2|IZU&z(uPEqnk&pyO*9uWdX{}B7;V)7o1uC)$;X|7w1q!k)saq?w`YwPHGKsxp%#=o`DpCsTHwONFuZ|}DOR)%L!WE#
zCmBW(ZU)Ugqfg(cJ4;fYueaeabam*D=J!mWevzogr5m^kwSKG=ggCf~d}wvu_9=Lh
zW*XjtXmVfvjW=s5Z`6!o;f^0P)R`!?v)(MuFl+J)j2412qY*Y>Z?uVZ28`u^Lm5Iwn-t!Z;B;#gET8Te?O1YUGZ`l_sd_>l1AB^?*|
zk4EF_FiqEe>#p&to}2sXP%cqx)@#0X`?`7yinM&kTh3(r^#^w{WARB|0&Yz;-^~Z$
zf0vh@oSMiHx{14(L)8?#bYs5nF-aTwR&rF$s|cN0D%PkC?RBBah7|>QL%}Tlq1^p4
z8p>SJ9Zmk41{FPC!Gy=v&7QB1m%^8G=d7(jD>e!=p)T^pbZZ}1&VD-h!BxRQ#ZJF4
z*eBhEm)>`#!!P@KDBEB+?o;H}D%I=r{gDVYI3r?|$Wcxc110c#8GnCqxXX2ezKN{~
zOlz;Kr3bGEFJx2-6KWK&7;Q=IwOZ5Loy$^|Px~^keOWh6k@-(MY{kU5e*oyHQVveo
zRZa5S`{Tco);&%mcUEV+$)xw-VXdDLb$DCj;>9+uxT;Bqn)!6AAvV^uM|@%|{MtBStO*chcY+(m|0w7RV(MNve#s>+9vODu
zsz(|pwKk^zzAjfw$r98DKvYkRh0&j9Ly1vCUVJD9HI-?VIiQSnow~%w+nCfAOQ(uZ
zU=*J8aDpg39O+8ZL8>2BxhHK2GULIB>ap=__|z@tMjvY^-bqEupC6Bfqz>xV0uS|(
z(mw4R>4XD^ReGeK^p}&f5BA}uYa&`Ef1&7il8mXSebR1;%{ubn0AZ$vT4@(C*j(f|
z{wUxUYK50mMEHt8p@r>ZoS>q!FfJ~Kx8N2NV^`nsdr`QvGM@qxfwqB@G$eYZL15W}o>$q<01pWz@w~cfWFlgcHbrB*EgjbF`K3X(>^yTL>*uuH
zMnB!%(E8)CiVRrZ(RZ|J|Bh?6crNIP6EqXnZ=UO|&er^h0*mnYA@HA6X_2#n!-X@;
z-YuueA+@?9PRvm>I}g5C_z{^LZ5T>HC_qNK=J#yLpEYM;=cV=+pFAcOa|uhnsCr%$
z5)$#?qdObia7Q2bfk>gqP-DQ^4({2(;1VA%J!C)p&I{A6NlI0#nJc)XMKb46{(<8Q
zfDY2pU(&Vt@<4OukAuK4{}ss3Dgp}6T`_k34UnM?_hA(D$a;c4$%QY;kEIF>EDff}
z^?m=IY0(>GEg2o@*vLPOpbKjxfzKk48I2KcfB!-~*U^>}n
zDl9z6YH~v-;~Wg;5QH{6y)=Tuo2=hf^V)tQo9cc^(0LgJ-aJTw_8pk;0
zTorYTe(!kYez0WQ!t6>;hjf&+`mO&S`{`)c!&VN7)OVpb*Ki5cK?n#JU8;sxFoa~A
z99cC~j=^YC3kkieTpt&2>m#=pzL-BDEci9Oi(VB?M@Dxexvf}p5nGr!l-Dwh2E%{Q
zDKr`lhsrJl
z{7t|h-QPHV$Ud@BkHfKYvoSIaM1~EJLtvQ#(p?R6b8RMal(|A49^i0;am)uj?p8{%
zt>sA8ip((~cxDqUx-plR9uAtkwvCAuGm+_*;pflXjj@)qO2qVENHcSddj^gSnRdEZ
z4y&<~FGjcehr&kf#jt`2DBG@g;oEA)#Wh)iqgnL!NmLd{DTox%!wyH~$JvAmRI5#4
z`RDIHgT@>;!DywfWz;ldL0oea6Kf~nm67P0if{cfI0L%;3x3WaIQ;X~)yp!B`+K>K
zx|M}zBP{EXz2S?Nvg`DYzA0*0IV%E|j_SbfU4EaxM0qeG4FrE0<|fE5csG!;6)X+E%rhbAgw
zgQI9WBBBgv8Rv3paR|a$(yVRgO8m~#l`ROnFvISCFeVj?U9@DVI8qhJ{RYNz
zfq?HQ`B?{Tq_L+c8te99siFhv?K)s*2|6za7BD*b>3GzXq?nm3R&X<}3@*@n?
z4%NZ+Yti8G9m=(gKW4yR{W}{MnsdtA@fUY!_U3Sxnk;*fHI8|cC|;|rq6@M8$cDvz
zdo}F#7r@}7+#&j
z>&qSREdlGpLz{ticKK(HG&D<+9;ay!S_+Yvts`G{U_Zeyx-zU{zXO~y+)v5#q4OUU
zg2Uu%H{=~+lrZO|c+br8Ohce!g!j8?^?&t=a{P>vq?gIs%YL8yXg_}2P#)-^XYsvr
zm{X6ouR)d;=c#VZobxBs(WCV8A-`((c|QMI-p3h`;=7d>2M+wpfgJp5BfN42JThG9
zX^;xTbFWNG9n`E|CSD(WTk{ZY3Fdw~qE6R0Fs_XGuJc*CSyes+<*F%cj+6?!)lz$D!-sn;s
z#~7vCInqUHuCdtoW#?9HtV*IORFP}3+Rfe3OtfYs3~>y3>9jWQA$?NIcw1sjA3&`P
zsHpvtZj1B|g0RjqCF*(IZ@ki=O8gGZW(2o-c}&)OfnOPh6w>|_^+{dD@})io^lfri
zAY4)QdY|Vi6KQ|)-f9+&;<|}{Up>!szuX59>_qR-MB8|==)gZ`@vbK!*C4=!uLsva-Rj4$t9q$h5ImneDDmwaOBe$XqP(NcJ6nX5*|
z8@}$*?P5{42nOzta!9SV{#McIj;e32iySqMp190?`~Jts=1Zwn4StbaW*TmCTDfj5
z@8yhY1l*VFrXc5M;0cYHRhIt5r6>zimXFN434HZ?-!9>+I1;*kxl1?*5Zcf9MAi+@
zRUL*oE1_Mp43gb+JRUrRZ!=oLy@-&pF~*?!
z^r37BU0e$4_Aoh_qG=G=X+|eV2@3%3eGYu?Ly=CCQ3;CtxZi@nfV=ZOYkXRQTyo@y
z$E_+Y42SdkW8LX~Lx1tRUc#3LR8`^c@j#dPbQjR~g;3Fe3YsmF`P$8PIL~Zxk)r~n
z6rtCT7kCN?_-m^*d>Ke}oZj^K+Vo3;BQfvcqWS}pCL`D&GOIz0B;3l`;Q6%`AYdkN
z(Tw!1TlnTDwZ6`Xez~phg*8I>nW4O@DG9Oa(af@~N&u|2S4YO9d^w{HeSw=>#n+(1
zuHaOKc=;u@%1k-sx@b~CuXmv+ou#Gmx;xF%>Y-^rW#g0@7FhF%wezu?R>y$X(7OzE
zK2~A$dqQI-f0y+3%UxCA7tT=@>8lY^q8?#C@}m+x+OSY=_Hne=9WswEUj(X*nRD&X
z;_wJJZnB6dOcr?V+1f;wOJsNHePGOSV1}qwA|gR1X484K@Uc@e&Me}l+A11x)v+?8
z;vY@nv+J+V(I=jlP;tw@gKu6&v^jal({vS81RB!?^i5BPJw`tW(5tE8{Be`$b{HzC
z%~MH6jkD3sQ_)62o?IhTcao-I2W;7Q2!gH-1)e{!I2~T`v|nN8#-h+>hU=eTnPN<5
zn%gc-cE$F-piot2d^4s7LKtnc_~-MNf>QIZAZhp%%9wdM4gLrvR&?j|?rqIz!Dd={
znD{vk2$h;t*huS!%|BJd$R~1h4hYt_FIn(VJrZ}y3=P8vx3as?4snE@Vl#aWo-I>S
z3p`JoED#5dRncX*0X^*)Jk=FjbAB$81JYsnWRz&S>`GVXG8_WvPpvmy7c`E
z$$k<%{5fkopUGSs{RsUKw)j#GHa2(tI-kEf=UPK=jmv$u%In2R2<&ipD
z?q9we0!E#D7eo9+SI)GV8H{|f>qoSlsTsL8v*_Rj}d%DqjSKw(B0jzY!@?`
z?z#IF;9>RypNYnO?VXLVvpss{!<15c85SA(zFCLuCf{kgghF+kbc@DoXN5`PeW
zz=bqYJ9Z6(V=5uQ%_^eRObd)j_lU4nMvJO6t<{yfW7hN{^z13X9W+$U2BeOSN1st*(|xp_0xVgXo9$?EH_{r1*r*8hyG1p+#>Cx7E%ul;D}r@->kBim
z^rw!}il+ApizcOxcKg9o_Qmk8n`Bl3!&(A&UeXtFrJ4g>NHmiI56ugq@goqR5QY@X
zo&84cf#cKXm^|V1ewfJ>#-*yCk3h7C9gm3HV!ir_By`cwD
z@Az!}6SO2P;jD#!+7`#0)m1RgPR_1&aBa^J>82J)^5RfeQvNvt456}kTUVLo5Ma*u
zZG+`j3SdVJny8y1lv6^VR1OYysG&m=eHf)fofgUg0%IwTX!EA2d7885N=`qr_bzS)
zl(~b2@|oQq%0K5b96E|s6jsY4_f{d|!plTRh4g)~?!p;eQ8WWmV_`W6%#!@-_rTWt
zwD^oDTp=KQ5cPw!cDjImITV}fOMhOj_HKjPq*qV3%m7}-XwIj|kyEV5G8u26|Au>&
ziZ;a*%8kKS5Pw30S-gw|ewuWxy-o+8x_VbbH8Cyy1?K4qRYu2k(i=i~PVfxAY?@+hDx}W`KiQ)M
zoNtfvRSgVM9Q)j`2D`#Hy+P%zb+|=>OX6ezcmyFZtOEAG7lwG|)YR9WFj6gv#yI4O
z`XdYInm7XME?zD2vG%;&Pc0B}%Ts!3{M=9n4Od562P-hlQ~j&2DEHHnCzV#j?(7MY
z5ugnKRKR%FLjjS%20d59XXA!86OMRd
zg`Xat5^UG=9~KF)cA1Zes$xf&zYr#yc>VA+LCSQE|X0NlZ^F))^S2L>#PbTfR$L~`{=5J
zjB1-c+{A7aF;;#vS31p*CNdCO>Ai-RLa(l~xQ6)RNMuhW&Np`cc=z_?u3J301lC^B
zzRA0`+{XCgmj$1M*EeBpg!-_YpKbzt%?9$vWg<@Rq&7gWmQOxN4MgL)8%GYi?CxtbMk9ymjIcrUn=H|Jn6R#~uUKXoIf
zq|Knqo+ztF?b)nKM^XU??pIT3)y4I=c;d~B4a4%gbARovRsQ5=;8(oiV&x`%IZ=&2
zNeit)oS{ITRK<#o+8p22D6U%yfe%Zq6!%9zzETxXnJ{0cje>PFzhp(SU|T
zgI=n;1L3x=q%JFoECF{PZSiEc#r^?fseHzdLbyh0n1zVac&8+}!j@l(Gv`sF_@isf
zVlxsSDhoj$>C*aA5<@<#vK(up{j_8vdPSdR;?}MI?C*e5D`(iu$)ueK%0?q5GTIB@
z5{;-^uF5?UfdiE8<5jfJjITtOn+4cpw>U4Z9c?;Ez+DR0e3QVL&jpLSZ}cfotvXl1
z4ES-&pPx}{C7Go}-2A%i{|ud2=3D9cZ5Ej^P|LcNVvwRH0?e6EL1SV+2cKDU5@%(>
zFzcYR@^H^HB`D5d_pL>^E!et0_pnpyI`uon5yQH&-a_v}KmpGLXLrHr=bl#8t=7Af
z8L%pUj1o$k&2|hmw;>H*`Zmp~KN_l6GfYKsED0Xf-P>KNQQ}?-PuJ_qb&A|>abN1ujk#0`$=60w_
zMJ54hf(#Ga7$n}M2pmD|#OMj7r8(Z~NGL3;&QXFhch>F>mp!*ie+Y}d9G=?xh8tM}yu{cgK#=z0xLLokoCDHzbv;2Z
zd(I)?5W;RmG3nYh+)XFAn>U9~>yw_Nu379PcY7PWLLJ$7E~dL!xz0<4?+nsQE(VVV
zE0kw8zwasO<>iR!BO0tW7Q-ig0;-kk$a=$mbHW2hObKS67cpDsR-mcdWD2RGEEfjNYfp>KRu9%^6Y#l8McJDIMS0abEZymSR
z*?kKrD84U=~xmE1h@*d63rauw}9Vq
z5xjL%V4pcn&0}^+yODx_8+iM@L|XvvavJz-RDoC#_fZ(r$l+a2^~@zLk89w5=_#%X
z9RcV-c)q{hdj+Y$iGTn^gRnDIX$W;mfCwx?39vE4^N=%8zQ{VPXRhjc>vBxIo;4bN
zn|fj}mwp)`CI_+_(r9sqTtDNgus&W7koDianNi#iNBi}qgDkMT1qgFlq^SB%iLik>
zLu@!PPBMDJ`Q)_)yG*}>q$$#;1Gb~0{M?@t_DIlRwuQ?_CJy#Un-V+_NTTIdG~&7Z
zEtj_~zCvxU+u=e^s$Bg=Qib(9UUZYw6B%9;xzh=D4#DQsf_60pLnj_?rzbY5r#7V%-L}vR970acFdHf!
ze)G%qJ#Lm|@ASk57uF{(pVF4Ztl1f_Yng@|H)sleM^vy*pNYWr&eFM?YE-++_o^7I
zo;SGBUOOoFQLbn5(TPVt<~cpL>3uI|eA9r3)?ICfOsD{_jcZgqfTFo}&G!epimoba
zr^Mj+(DUmGlu2IGnrlC720JE-l%Z@o&HCqId5TK6Rv!Go|)k)>5Ff-%@RIk
zF5xA71m=a8y&O7st2!yE;r!YjK$~2_}lI
z)(;q$E@O5SAtg3L7TB^3aN4%sbi*xTTvl5ShZ@1|tV_+{oIMOb4X%aKpr4aJh(eBn
z7!H_-6Mfz~cDS?hw=d=FRS%juR_M@};Zp^R*|zZ**KjqLe;w7DsxMnVH#cU($@*#N
z#T2Ay#OQcwC~(t_Ut8q-IhZ%+?c0uo?Cq$48lZvI6oCX&Ph=W0g89{V3F1g8DHN>~E6@v^h+
zjk;!wz)HFB(gSUQm(!I3RHOT=f+i=drQX{7j1cXFDeFa1&+$4-e5z!A*S5WKO+?kH
zADj;0*)lnu3Y?@;@AK4!{Gc70!l+0C-a;*=?j(A%EE)u+L}{*+;pEfF@6Ga#ez@dD
zBW@(~df=UjDz;sf_q&r#9Y?Kl#}Zsd*@wz|I!eGMtZGfdXbH-=CY3peC@v(-Ue6H`
zP+BLhA5OH!o_y>*okt?hH_YCl|28&Qi}Q7l(go9YCo7pp3^|vai>5JTZ=xY+iW{knb4ugll%hq-~u
z@p`(7x@#e9ykPUjE$Oq4JX^Yc>jOtuE5gsu-1OPm*(LgTT*dht
z&5BfURxgchOr;Ti*@rYy@m5yajdtlSXU+{MYA4T=JMA3ds_*76CHK0|b!FHa;=cRRDHvw8sRTzt64W19WzS~chwmB5I2p&7zWrcVU5Z-OvpcpKnER-gtpj-dc
zU97@Z6KqcZ)!s%V;CUB;H8n~HP@J9aya)>73GNyU@SZNSrdWf)+`GrGN7P`U4o#DH
zGqJncIk_R!d$(Lu
za@CwvqIoB#{I_}93l7RI-VQ-1EEzA@n|IIVURTpl;zW=}EX=^o?ySHhOj>_z0#Z@2
z^N?1yZSru%Z3v2jZ$4>a=v#=;()KCXoubvp`7gxom%$V#i;sOF=emX0?
zM_wdunf_%R0^WUO3A=A9H?E~!Iwtz+`1Hr=0B1m@I%5+0y`31@&sb`S7!jx!Bh2#N
zx8*+}ssuvxIY&1jc;hkljIkmBzE7~c0MX&4hi);`n5k*dz=@3N_`J+@?Rr&JO$*2uE6h&T|L~?Qj3I#B!0WD$=fGjP>Rl=Rm_C_l
zf0a#a)dDr}G1GPs(7CPny+>ptMF;thz>wUEmQTEPN1l*+jBHwgM`YMRRF(@o-r{ih
zuITdOl{V7OX
zyXNup!)Hu@WFIvv7OFcGszb}~>R5J*GK!O?kTRCVQl&(LUw5=3^=LaEl={_*;eT?d
zC?
zHpXF8$d5jxP!)u7Fks;7<<;}tdYehU_s0A3f!d4T>fVy|-!GXfs9f|?bD<60Y+S=w
zXgWgt!xY_berTFLsJo~^eJOvkJ3|%r3EKz^14)5n0)ENs@&kS>)rS}83Cs33pMeHr
zT=h&3yBw#aElQW&P;bg~zDSU~AVOs5K#w|J2Q&`{jqml9S?Pa{2!S~BzhM_3>2V;6
zkcAMR0AYiBWb={i8N`Dn@QLuv-o^Bd-@$e?J{Z17TwJ=K9yrD0Ymf
z*dc<#=8)oI%ZsP-Tl|zvUmn?6*bHV#cXxcKXmKj^JUjDm5qW4dG+E`Xiouw_
zD_uRSN$|CxWw_g6@d#7&FOAmpmCHsE$Dcv$aX5FnxaHL_URN8O
zH3CGxWiAs@QoXpiJWqkG(nvk$xh2A6w_+n|!IQ}YE5SCXxUmtYbn7>+@Swu%i
zm5=PBBQYHL7VutGl|x6O?}IqhpH3_*WrHXqy|(Kq>>gB5U)o*3>jdF@!i|!5k8lTDElu6HOK&A=7hT#<$?cM5S)oyVLYF0IKS3Lf$(iS$9^-2gGZg3L|9QDG3z*cE&SZ&dv@I66_>g6?wF~dseicM#*XcjKKc`Z)2Nqs
z&4QbOD(2d4fL617hW>baz~lHS(XNc%3!9jcwuY_@+^%vzg~6tD`Z(vSToON!Qfj7$Jd+`|(;9
z_#50FaoE`LyW_&N$AsYg@9u7wzv5*WTMI-MTVUbB0$VsY&+%ws6xZSw^(F>TJ>VtC
zDX_5Z$RNCAfTedtVH@M)X<
zsVe8l!;}8>D5d9Auqntt2~GqeOXz3N$+;qq!`4@;LV9JTE5*Wn!%ZPoCHP%jH2c&d
zhbA`cJQ&=7Gp33RhiK*oZKY0ifjZf|+*~v3C>V-k
z!T2h{zXWAG^$9%BtZm)luIiJ;<_;us=gf?}13)0BPq7WkiwRi_s$nU}W(h0t+r|WE
z@gB4BOzJ0<&T4BXoj!Z_!QB4AWSshP0D@3Mc&{kZFjQZ?;&c)v?8R&UZ*EwN<2N<6
zT%8*cT;Azc!N7cdwPc}*8Kb%yGetoJ0cVWuQjor#F3y_wpyF6VD8zNE?zN>7)P9>
zQ``uy%6?G&5;+>;c6_Jj(40?H@pHXIqm!HvM^Q^BoZcg_Amai1&X&83(5|34D}BD}
z_w5FBj-|e*=wk#nZh$QRR9qIKrP{-!=Vsew*mH6KV<4Dqb&%b~>zE-qwx
zlTAa=w-c{|rGqC?sHmkXqv@9sJLIvejvK=%2O6@H{N<`xXG|WMXIp9=TnZDEH?!WB|)cOJCJV?wo>*%d}c2hBon}(r53XE
zgr3r-_@~x?XE$iN97{qRboZ-qdn0qSdhcxBs}dbi6I*N$t*NF8y^l}J=_JfHC8q4ueKdKgZ{1F?~j`~*1J-G
zctVZez3*@IWkoi`FOA!CPUrU4A#48fWPe{n>;Q;4`G_M0?nY9ea1`d@!X$^5HT7Ya
zJK28^S8>D>>>R%%o||D)ar(}u?$y7Ed`d>WgxaiXMX*=;Vv!jcEa-Y8`sN?R3HQXO
zGWVCC_zA0;7v0R(;IFI_erP3|F3rlbq0n?;2)&46w&)%2*0PR!9mNOSPu1Q@Jk%*qdG(Kh3aU`^a
zAxBqRc@nmf(@Os=ZaiG2#JX3R3=n+WUXZtaS@zhCzv~>SyxH+4;$;szIcG6j@R}_v
z?js@H>C+=7i&Zpf4?-HT9%0
z9UbV!k2WdyNVXv#73Byv*8fif0aEnOo>f1*Ob!Fppk>c+bWx`i-c>tuZbGjw0i;E=5VD
zdjxh94vE~I`N8Az7iG*$)XV&x_<3LLT_Z9eG+@IgpM!;ospDbT33erX8{$Q!kY!S&
zrNrVW7-?S1pYZi>1nenU5|}@3YjZ4Rwv@r;H2Nj*q1ruxxiEg3Y3LDcIGKIlN%;%}
z_dITrrkmXsg}9&9SEE)_C*qUtZ)$j=(#jaw4znc}BMkP7FL<84mU>mH+koMmoftqp
zmiby*qskh}XoVW6&X`|5FEW16^F0gZ8^-Qgn0&3jr5ck>cgY9i%9H?`y@7mc*3=7&
z&(4w(!3&Q2SP9I%AP?rjeU{VKD=L^E>{6{+|F!syfpS443TuLt#7XVXvW*RKTRKn1
z){!tWiBlR0a8Vyzm)`Kf^`CEtnCn!BdPU3ao%f^?b8AdD`zIR;PjuA~S@MVDFqmBx
zi{09JEsOj!%53rHOyIvT@AnMm@AFKK9*&b{l?cB94NW>b@;=O>iwEp5l%BIM@^=Ov
z80Z?I7ZNbalpF}miqIXt=NcUhFq?0viR%Fe3u^!X?`O<41VZF)%C=FTx0%G(cn6A<
zwl)pPai~jfH7cu<9)xRR5(rRr9-`Sci#A<5TySrM8e=7dIueGyAgINrwFJAJIhO46
zuXbsSG&e>j!yqsFoJw=m<2aNXy`F+vIW;?2gj^w5kP~Rii&9S)_6NpWj)^NQK?Rq6
zv;;Y?x?ic@=SW?*-qFRSOB0kx1FbTf+NNhYGXweE+}H4r2GHR6;Q#?5aEk*}kfD_4
zs)#Tgn!(@uS;Dgt^Xc(d)A4JWk~1ruDQXQCWrK8gQ~L5)X*!X+eFU21@S$S5NkIws
zr!&p>loh%DP4ORA-Jg(ysi#tTf!{)7C7ff%m@~Y?a-mn?){GyDlq@ZW@vVi&I^ANU
z+A3-ey%L%+B5~{6#he_z&8^M{QLD%}(~!!+7W~r;z0S@$$(n6oeqO=ci-Wa}Xs~cg
z=%fJg3Sq9ZCVGf##_o@Eo^UnQoPH|ag*4-?SOHP@3EUDFoY}b$m_I1vz`e_bQ70ow^(jp*qUIcf@<&`)dABvCUcwU)c@O%TnK
z^r9uy&tbxo)>^;JltC5%C;>TW@NPiu4_>)pX2?Wh1=;oKeKP8bd&$NW(8R}2wYD0=
z*}F|xaBV!|peZvCT6+3!;La8Z8Iud*B`g>b5qQ46vlXjJ{V)1AH#0$fv3By`>v-W(
z5cc+eOn?!vmq3Pz)_g$*a#mhT
zI1;F-UD9H1&kN+D7_3pGKYQ!};LXQDrh1_kxSH}HxsoBpd~OZm5H~^BV~&6C0x$$^
zIc}wkiKyLp3{q`spv>1x2^ef%$?}VVg7azTqojwE`J0TC@LP1fW44}*j=YYYqtfv8
z-z9fDbSi5r7!+sp6g1P6XN0W5)SEzjcq^Ze~t8U@kK~QXv(DM(2yZ!a&7h>7bHqEQsE)
z7Wyp2n!ye?7Ss6SxmFg|v!7>8aA;q2w?}mVSUJKVp)1sBu8S-;Qyv~3p%Uw+l~rGq
zKAV6>E}~?)JIgw;GJ1afhGB^cJuF6&ir2+Bkg{Y~SyQPudlt4^XCQ_W*HMd&;6;{^rfAw
z_(!C@*VvyD_E>~i2Q?_9EW{{PclsK!erO9NjJ-LVj3U9|nnRGMwCw&ZSh^4a
z`;&@r#!(aGbZ@om&JR7pq6(m(DcBwpcOh$qU#>O|kV=&QaR6I~JPs>Tn69HJJQv>*C1?Pww@8nH+%s4)LydW9ZZK+Kkk
zEC(rez1xwGUVO$>kw;(?-T)iDWEUYPXkbv5Mr=PAe5V%lwWm9rh;_LNT<;(IDFRo7FG
zJ;JBt2L8LqXZxo%*`@|x6|SSsH`jzm6(+g-CefmWSVH7${5u|<=V&3vSgRPvd
zWVM&I&;9$BJF+8jGxU9sbc2{-IsmTnYP(}GP9?=JQd$BOUUV_}7^&P-8=PW5HS
zw+5-X&=s?4U4;BTqGl>_yOP{}z%A-xvDxc>O)y(kpBLj))ZMj}CTc&?+z5pg2}3_y
zJ%*WI)fp*MvKzyg!sB$ralECQfTNm;rE)gCcWSm4N_UB>9hEFP%s_sM7PJY?Sc
zjAzAzHH)&2;k#bO;RG6k(F9TWkQjEU{P9+A*i_(dy&}P{P22C`%InaoIlzr~2-+-W
zPtY16sKDJv02M;R^A9Ko
z+S1O;xbY<7wND^@+*(rC&i~0Llz}J*O>Y%Dq;dO-q&f@>mxQRri$tJU?wvtqqt5F#
zg7ZNqTP6^y-sUQvFlLNQ7dl_MXePUQAeI
zak2)PTdwpJarm-RADjo$BlgKEQpiMt+H0+M9x?XSfWfi0t7cl11r7J*i+sWVO8yP$zctU{a#o8
zR_r#inMn{}Jw<`uB4Foh$mYB-E>7pjO5PsF`F%wGaMMP!H#;%$TZW`gQ}eG+M(^~&LIkpY}tZiQR?tvo_?{mkHJ~M+>=phWobg67F1NWG8SEY
z|L?tx-z6@;W=92#RCBkZ;kpHgO~ZxTx^Vsr;0aupLO(BlsQojM2Hp@jqDixxe)9Chp&wF^`41`q%XDWqki%pZ@P3gk6pp
z@X7rwOzd2AdYyAE=`MFUR%?&>QGOF->@-^@$#R8*kJ~REpqA<>!eU2?5tV#Djyw3PxorEJ!S^h9-^~
z0&>tnB9s*52G({^SpuiBD0%<1(@3bv!kl)w?+d@3W3e5-QPpKf7G2m{U~4OxUHfCV
z+)}#%9uf-5Crvfi88)-A)GW)BWqPI>>l6(EDFdIgFAu9>%Z}Bjk9~4m^+w%mbvzvJv(Mz^>YaF
z#`xRLp{Rxq4j0M8S8IxbfsJqTxihB*X)JmS3mf1R&WX6x=ajWML`N%OJM|~gIOJzadxkSh3+W>Cb&jc#xg$6T;TH}e7O!`IIc2yey-@~d5!|sGtjl4fd4&hDHn|efCxXTs#-7g
zbBx|_UK4{MG)P!GJ+5Dv=_+!n2T*m9t&NdS$KJWbX+IaWKmko``yY~bXABi0HdL7Odp2P|Que9La#RB4=#4}~
zNIhQu*#+8^zCK-pcx^l|d&=F#RXmrF^8$o?Y+XBz
zzdwDuZ$2;JUyRt+9)S8WJKMkZw6X?uR%YiNo{)f}k0S!OxD+VW)C~gX$ay-HXkUAu
z2%A{y*T+7Pgi_bEwmdK-mAVIUhDVc&DbX-6(*|I^1sW;J3|IT`Ed+o*|%%JRtiZ&|CHM}GtvqNP*%9W#)ctG
zZ25BWa|u2gOjDv2HLfRW(dQ6hO(f^Y&SsA`CHv}HMd*taeWAJW=mieK@{cKRPyo24
zNeLgic-AXfSdVls`gyOuNFA#DW8V)tl{mcP)H`cYd^xTMNi?poTtI6V
z2e|2k3UKu~7}w;hiadS%Igeai*BD#XF2Cs6op}&QXPKn@IasFc+6@!ThEI&5tf3j@
z87!ilokLFJF1GEdGnX~1o)Cpnb=9X1p8{dgXpc5=7Mt@XRHGWZR@cq-9?5mzIbNn6cK<0QO<1dBpCeyZc>5`}!3Vy7K+)d$(omTO*8S)*n!SVJOA_9066sUm^#l^)-0E;o19Mj@
z&+wG6Z%n05SDfA*(Tq=I8}k!fPZqMZ=8U96X?TXo0+myWWDvvL=LTblvB>DW^qMuX9IK#Y{8zbMV@Zq@G8A
z!AI>)9+VkJoJv!r(EE?`9=`-I<6%!vtjLX8=H1qyZ?nzjz4tlr86^*kWX8;uBug-
z)5)I34b6!nIjXIOzl<^qy9Mlcy1tdm_nAYkjp#HJ@Pz#I`%q2@7xalMPqiJYjz}EV
zG=s5}QmhX3m=PZxcKi-ScTO&ru+?lu-lScX>zq7nHvTSymdN3wgGy&Dn`nrq+uhEb
zg;o_x%N|);4(&&0M9rm7V_^Ysyrl9<_wwKhJZE+{z`#9>qc+JyyrFJ!cTwDJQURoM-bp30xh
z5b0r+&+rOSVH2l{Tb~Zv>IJ10Njc#$b2PSu4T^|bx&fKco
zH)-#mkm)@r`1WpZ%(=A*4&r9G1zyBrs4*~XmF@X3~Sxy6r32J5-#mu
zGHee%ByJ6t7_E4r3g0cT6A2LJ7uX03d+us(VmF-cC*PfxblL9#@7qQn7a()z=89%(*2TzpM#1&ic#Vbbn|X`tj`m2>r$@?QWt5^Um-d$)(yFa(GBH(0a~jl7
zpXNTct&S_CuZV9XgPS}*d`%dQt}=-U!OieYsO(7JU6kgsxkGZ#fx8{7`FwysK6X+X
zHk=#xre7SE$NgU5Is4-#v{_gqeWOti9jK0mxve$4+FeEi!q|Jv?TW$q-VwLb=aRTo
zOHl;e-muRqt+BK?aNvE)h9);v{~+g4_Q_VS1GE@R2HJ#N