flask模板注入

参考链接 从零学习flask模板注入 - FreeBuf网络安全行业门户 ​​​​​​关于python魔术方法payload:““.__class__.__mro__[2].__subclasses__()[40](“/etc/passwd“).read() 的解释_沐一 · 林的博客-CSDN博客 目录 参考链接 flask基础 1.route : 2.渲染方法 3.模板的使用 模板注入 1.xss注入 不正确的代码如下: 修改 2.SSTI文件读取/命令执行 文件读取 命令执行 例题 1.首先确定有没有存在template 注入 2.探查可以用的方法 1.找以下 ,为文件读取做准备 2.继续找,为命令执行做准备 3.获取flag flask基础 先看一段python代码 from flask import flask @app.route('/index/') def hello_world(): return 'hello world' 1.route : route是装饰器,作用是将函数和url绑定在一起 样例中的代码就是当访问 127.0.0.1/index/时,flask回返回 hello world 2.渲染方法 flask的渲染方法有两种 1.render_template render_template()用于渲染一个指定的文件,如 return render_template('index.html') 2.render_template_string render_template_string 用于渲染字符串,如 html = '<h1> This is index page </h1>' return render_template_string(html) 3.模板的使用 flask是使用jinja2做渲染引擎。

oralce 处理列转行的三种方式 最后生成表格样式数据

【背景】 项目需要把数据库里面查询结果提取到表格里面来,区别日常的数据提取,本次数据表格样式复杂一些,因为涉及到收视人数、次数的问题,处理起来多费了一些时间,大概需求就是下面这样子 数据表的查询结果是下面这个样子: 看上去感觉很简单,但是之前没接触过,拿到这个需求是一头雾水的。 看看解决后的效果吧 【解决】 网上了解到了有三种解决方法,借用别人的例子,简单记录一下。 namesubjectsocre小米语文90小米数学100 需要转换成: name语文数学小米90100 方法一 使用DECODE 函数, 这个方法plsql可以直接实现,但是我用jdbc无法实现,一直提示decode方法的计数方法有问题,不得不换一种,在解决过程中发现如果查询结果没有数据的时候,就会返回空,plsql这边没问题,但是在jdbc接收值的时候可能会报错,所以在查询的时候 每一列外面套用一个nvl()函数,可以解决这个返回值为空的问题。 SELECT NAME, SUM( DECODE(SUBJCT, "语文", SCORE) ) AS “语文”, SUM( DECODE(SUBJCT, "数学", SCORE) ) AS “数学” FROM T_STUDENT_SOCRE GROUP BY NAME 方法二、使用CASE WHEN 最终我是采用这个方式实现需求的,虽然列字段确实很多,但是一劳永逸还是可以试试 SELECT NAME, SUM( CASE SUBJECT WHEN "语文" THEN E_VALUE ELSE 0 END ) AS “语文”, SUM( CASE SUBJECT WHEN "数学" THEN E_VALUE ELSE 0 END ) AS “数学” FROM T_STUDENT_SOCRE GROUP BY NAME 方法三、使用的是PRVOT函数

Docker安装Jenkins打包Maven项目为Docker镜像并运行【保姆级图文教学】

一、前言 Jenkins作为CI、CD的先驱者,虽然现在的风头没有Gitlab强了,但是还是老当益壮,很多中小公司还是使用比较广泛的。最近小编经历了一次Jenkins发包,感觉还不错,所以自己学习了一下。网上比较多的教程都是在Linux上搭建Jenkins,小编经过一个星期的探索终于完成了在docker中进行搭建。 最终版就是:通过git上传代码—>使用Jenkins构建自动打包—>把jar包打成docker镜像,运行在docker中,Windows下进行访问 主要记录一下一些踩过的坑和注意点,让后来人能够跟着小编一次完成!! 二、安装Docker 安装Docker 三、linux安装jdk和maven 1、下载JDK8Linux版本 官网下载太慢了,小编这里为大家下载好了: 链接:百度网盘地址 提取码:ov24 2、下载Maven maven3.8.5下载链接 3、使用xftp上传到linux上 4、解压 解压maven tar -zxvf apache-maven-3.8.5-bin.tar.gz 重命名maven mv apache-maven-3.8.5-bin.tar.gz apache-maven-3.8.5 解压jdk tar -zxvf jdk-8u333-linux-x64.tar.gz 重命名jdk mv jdk-8u333-linux-x64.tar.gz jdk1.8 5、配置环境变量 进入环境变量文件 vim /etc/profile 添加jdk和manven配置 输入i,进入输入模式 注意自己的安装目录,放在文件最上面就行 JAVA_HOME=/usr/local/java/jdk1.8 CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME CLASSPATH PATH export MAVEN_HOME=/usr/local/java/apache-maven-3.8.5 export PATH=${MAVEN_HOME}/bin:${PATH} 按下esc ,输入:wq保存退出。 查看是否安装成功 java -version mvn -v 6、配置Maven加速镜像 cd apache-maven-3.8.5/conf/ vim settings.xml 输入i,进入输入模式 <mirrors> <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> 按下esc ,输入:wq保存退出。

正确性与健壮性概述

正确性与健壮性是软件构造中一堆很重要的概念,它们分别对应着软件设计中的不同导向,指向软件设计中的不同分野。然而,一个优秀的程序需要同时具有优良的正确性与健壮性。 健壮性(robustness),指系统在不正常输入或不正常外部环境下仍能够表现正常的程度。面向健壮性的编程要尽可能少报错,将一些理论上不合法的输入合法化。而就算程序在某些条件下必须终止,也需要通过一些途径向用户或者系统进行告知,从而达到“优雅地退出”这一目的。 为了能较好地进行面向健壮性的编程,编程的程序员应该假定用户的输入是不合法的、模棱两可的、易于引发错误的。然后根据可能引发的各种错误进行分类的处理。而同时,为了减少用户输入错误的可能性,返回给用户的提示应该尽可能地做到表述清晰、没有歧义。 用一句话来简单得概括面向健壮性编程的行为规范就是,“严于律己,宽于待人”。 而在对用户的可能输入进行分类处理之外,健壮性编程还有其他的特点。其一,封闭设计细节,限定用户的恶意行为。由于在前面的论述中,我们已经把用户设定成了一个可能会在各种程序部分中以各种方式产生错误的存在,因此为了防止程序的核心代码在某种情况下被修改,我们要将程序的核心代码与用户隔离,以防止像是你家里养的猫一样的用户哪天一个不小心就直接把你的程序搞废了。其二,我们还需要考虑各种特殊情况,不要忽视任何的可能性,在已经将用户设定成你家的猫主子之后,我们的代码设计也应当有相应的调整。即需要考虑一部分代码遭到修改之后的处理策略与处理方法。在这一步上,我们应该多多学习运维工程师的职业精神。毕竟,你永远也不会知道你的用户会怎么使用你的程序。 正确性(correctness),指程序按照最初要求运行的能力,是最重要的程序指标。 没错,正确性是要比健壮性、可读性、可复用性这些性质更重要的程序指标。如果说健壮性、可复用性这些性质相当于无数个零,那么正确性就相当于这些零之前唯一的那么一个一。如果一个程序无法做到正确的运行,那么即使她再健壮、再人性化,那也是白费。如果说健壮性致力于尽量让程序始终保持在运行状态。那么正确性就应该是致力于让程序的运行始终保持正确。在正确性拉满的情况下,任何一个小小的差错,一个小小的不符合规定,都会造成呢过整个程序的终止。以看电影为例,在正确性拉满的情况下,即使一个电影的某个画面突然缺失了仅仅一个像素,程序也应该立刻报错,终止程序的运行、终止电影的放映。 在程序设计中,对外的接口,趋向于健壮性,对内的设计,倾向于正确性。

【环境配置】MindSpore GPU环境配置

文章目录 前言1. 安装NVIDIA-docker 2.0(1)若是以前安装过NVIDIA-docker1.0的要先删除原先的版本,若没有,忽略这一步(2)配置依赖包(3)安装nvidia-docker22 拉取镜像3 启动容器补充参考 前言 最近参加了CCF BDCI 2021的一个比赛,基于MindSpore AI框架实现零售商品识别,这个比赛中使用了华为的新框架,MindSpore,这个框架的环境特别难配置。CPU版本又不支持调试模型,GPU版本的要改底层的glibc,gcc等版本,要是使用的是服务器,这些也不敢折腾,要是改不成功,服务器崩了就很难受,还要重新装服务器系统。因此去网上查找看看有没有比较好的方法,能不用更改这些底层的东西,就能很方便的使用这个框架。 于是发现了docker,下面简要介绍下docker配置MindSpore1.3GPU版本的一些步骤。 1. 安装NVIDIA-docker 2.0 我的环境是Ubuntu 18 LTS版本 NVIDIA-docker是docker的升级版,让docker可以只配置宿主机的NVIDIA驱动,然后在docker容器内部直接调用GPU,可以 使用NVIDIA-docker虽然不用配置CUDA和cudnn,但是NVIDIA驱动是必须的,首先看下驱动有没有安装成功。 (1)若是以前安装过NVIDIA-docker1.0的要先删除原先的版本,若没有,忽略这一步 第一步 sudo docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f 第二步 sudo apt-get purge nvidia-docker (2)配置依赖包 curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \ sudo apt-key add - distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \ sudo tee /etc/apt/sources.

映泰Hi-Fi B150S5 主板来电后电脑自动开机问题

当电脑交流电失电后,电脑关机,交流电恢复后,电脑会自动开机,此时因为开机设置中:恢复交流电断电后状态设置未开机,更改方法如下: 开机后按Delter健进入bios设置界面,选择下方高级菜单,选择ACPI设置选项,将恢复交流电断电后状态设置为关机即可,保存设置重启,重启过程较慢,需等待。

快速搭建dvwa环境

本文章仅供学习和参考! 欢迎交流~ 一、软件下载地址: https://download.csdn.net/download/m0_58489132/85248733 二、安装环境: window10虚拟机 (本机也可) 三、安装步骤: 1. 将下载的压缩包进行解压,可以看到文件目录下有三个文件: 2. 安装PhpStudy2018,路径可自选,弹出的其他窗口忽略就行: 3. 直接启动: 4. 选择“其他选项菜单”,点击“网站根目录”,会跳转到如下界面: 5. 将dvwa和pikachu文件夹移动到 C:\CTF\PhpStudy2018\PHPTutorial\WWW 目录下: 6. 进入 dvwa的config目录,找到 config.inc.php.dist 文件,复制一份,去掉后缀名dist: 7. 打开config.inc.php文件,将原来的用户名和密码注释,修改成新的用户名和密码,保存: 8. 找到“其他选项菜单”->"打开配置文件"->找到php-ini文件并打开: 9. Ctrl + F搜索“allow_url_include”,将Off改为On,保存: 10. 打开浏览器访问127.0.0.1,页面出现“Hello World”,说明已经成功一半: 11. 接着访问 http://127.0.0.1/dvwa : 12. 点击Create/Reset Database,出现如下界面: 13. 使用 admin/ Password 登录: 14. 点击左边目录下的“Command Injection” , 输入127.0.0.1: 15. 发现乱码了,可能是编码的问题,接下来通过修改编码方式来解决乱码问题: (1)在dvwa的includes文件夹中找到dvwaPage.inc.php文件,打开: (2) Ctrl+F搜索所有的utf-8,并替换为gb2312,保存: (3)最后重启一下phpstudy就好啦: 16. 再次尝试注入: 成功! 环境已搭建完成,可以开始实验啦 !

python pip国内源

python pip国内源 1. 常用源 清华大学:https://pypi.tuna.tsinghua.edu.cn/simple/阿里云 :https://mirrors.aliyun.com/pypi/simple/豆瓣: https://pypi.doubanio.com/simple/ 2. 使用(不改变默认源) pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple/

ElasticSearch中refresh和flush的区别

注: 部分概念介绍来源于网络 一、数据写入流程 1、数据写入buffer缓冲和translog日志文件中。 当你写一条数据document的时候,一方面写入到mem buffer缓冲中,一方面同时写入到translog日志文件中。 2、buffer满了或者每隔1秒(可配),refresh将mem buffer中的数据生成index segment文件并写入os cache,此时index segment可被打开以供search查询读取,这样文档就可以被搜索到了(注意,此时文档还没有写到磁盘上);然后清空mem buffer供后续使用。可见,refresh实现的是文档从内存移到文件系统缓存的过程。 3、重复上两个步骤,新的segment不断添加到os cache,mem buffer不断被清空,而translog的数据不断增加,随着时间的推移,translog文件会越来越大。 4、当translog长度达到一定程度的时候,会触发flush操作,否则默认每隔30分钟也会定时flush,其主要过程: 4.1. 执行refresh操作将mem buffer中的数据写入到新的segment并写入os cache,然后打开本segment以供search使用,最后再次清空mem buffer。 4.2. 一个commit point被写入磁盘,这个commit point中标明所有的index segment。 4.3. filesystem cache(os cache)中缓存的所有的index segment文件被fsync强制刷到磁盘os disk,当index segment被fsync强制刷到磁盘上以后,就会被打开,供查询使用。 4.4. translog被清空和删除,创建一个新的translog。 二、refresh 最原始的ES版本里,必须等待fsync将segment刷入磁盘,才能将segment打开供search使用,这样的话,从一个document写入到它可以被搜索,可能会超过一分钟,主要瓶颈是在fsync实际发生磁盘IO写数据进磁盘,是很耗时的,这就不是近实时的搜索了。为此,引入refresh操作的目的是提高ES的实时性,使添加文档尽可能快的被搜索到,同时又避免频繁fsync带来性能开销,依靠的原理就是文件系统缓存OS cache里缓存的文件可以被打开(open/reopen)和读取,而这个os cache实际是一块内存区域,而非磁盘,所以操作是很快的。 写入流程改进: 1)数据写入到内存buffer队列中 2)每隔一定时间,buffer中的数据被写入segment文件,然后先写入os cache 3)只要segment数据写入os cache,那就直接打开segment供search使用,而不必调用fsync将segment刷新到磁盘 将缓存数据生成segment后刷入os cache,并被打开供搜索的过程就叫做refresh,默认每隔1秒。也就是说,每隔1秒就会将buffer中的数据写入一个新的index segment file,先写入os cache中。所以,es是近实时的,输入写入到os cache中可以被搜索,默认是1秒,所以从数据插入到被搜索到,最长是1秒(可配)。 三、flush操作与translog 但是,需要注意, index segment刷入到os cache后就可以打开供查询,这个操作是有潜在风险的,因为os cache中的数据有可能在意外的故障中丢失,而此时数据必备并未刷入到os disk,此时数据丢失将是不可逆的,这个时候就需要一种机制,可以将对es的操作记录下来,来确保当出现故障的时候,已经落地到磁盘的数据不会丢失,并在重启的时候可以从操作记录中将数据恢复过来。elasticsearch提供了translog来记录这些操作,结合os cached segments数据定时落盘来实现数据可靠性保证(flush)。 当向elasticsearch发送创建document文档添加请求的时候,document数据会先进入到buffer,与此同时会将操作记录在translog之中,当发生refresh时(数据从index buffer中进入filesystem cache的过程)translog中的操作记录并不会被清除,而当数据从os cache中被写入磁盘之后才会将translog中清空。这个将os cache的索引文件(segment file)持久化到磁盘的过程就是flush,flush之后,这段translog的使命就完成了,因为segment已经写入磁盘,就算故障也可以从磁盘的segment文件中恢复。flush的时机可能是1.定时flush;2.translog大小达到阈值;3.一些重要操作;4.指令触发。 translog记录的是已经在内存生成(segments)并存储到os cache但是还没写到磁盘的那些索引操作(注意,有一种解释说,添加到buffer中但是没有被存入segment中的数据没有被记录到translog中,这依赖于写translog的时机,不同版本可能有变化,不影响理解),此时这些新写入的数据可以被搜索到,但是当节点挂掉后这些未来得及落入磁盘的数据就会丢失,可以通过trangslog恢复。 当然translog本身也是磁盘文件,频繁的写入磁盘会带来巨大的IO开销,因此对translog的追加写入操作的同样操作的是os cache,因此也需要定时落盘(fsync)。translog落盘的时间间隔直接决定了ES的可靠性,因为宕机可能导致这个时间间隔内所有的ES操作既没有生成segment磁盘文件,又没有记录到Translog磁盘文件中,导致这期间的所有操作都丢失且无法恢复。

Sectigo证书价格

Sectigo是众多CA认证机构中比较注重性价比的一个品牌,旗下的SSL证书在同类型SSL证书中性价比较高,更受中小型企业欢迎,所以经营了几十年,受到了市场的检验,市场占有率也变多了。不过需要知道的是Sectigo原先叫Comodo,是在2018年改名为Sectigo,改名之后价格没变,签章变成了Sectigo,今天随SSL盾小编了解Sectigo证书价格。 1.Sectigo PositiveSSL DV单域名证书:PositiveSSL是Sectigo旗下的一个子品牌,旗下的SSL证书是比较基础的入门级SSL证书,Sectigo PositiveSSL旗下的这款DV单域名证书价格在一百元左右,可以保护www和@两个域名记录,也能保护一个子域名,申请也比较简单,只要验证域名所有权就可以在十分钟内签发证书,是比较适合刚开始建设网站的个人或者企事业单位; 2.Sectigo InstantSSL OV通配符证书:这款SSL证书是Sectigo旗下的一款OV通配符证书,价格在一千五百元左右,可以用一张证书保护主域名以及主域名下所有子域名,对于拥有多个域名站点的经营者,通配符SSL证书节省了管理SSl证书的时间和成本。不过这款SSL证书申请时需要验证域名的所有权和申请者的真实性,需要的时间比较多,一般会需要2小时-1个工作日才能验证成功签发。 3.Sectigo PositiveSSL EV多域名证书:这款EV增强型多域名SSL证书也是在PositiveSSL旗下,是比较基础的EV多域名SSL证书,价格在两千元左右,默认保护三个域名记录,如果不够用还可以付费添加,多域名SSL证书可以保护多个主域名也可以保护多个子域名,是不对要保护的域名类型做限制的。安装了这款证书的网站还可以获得绿色地址栏,并且在地址栏展示中文企业名称。

mysql DDL 建表语句结构导出到EXCEL

工作过程中,经常需要把一些sql的DDL 建表语句,导出到EXCEL,或者表格文档中,当作数据字典,供其他人员进行查看和分析,对于在 windows 或者mac 环境的一些mysql可视化工具差异,导致有的可以直接导出,有的则不行。为了导出DDL,还要安装其他支出导出的可视化工具, 甚至是需要破解,成本较大,故参考研究出以下sql 可以直接查询,然后把查询的结果,复制到excel即可,简单方便。 SELECT TABLE_NAME 表名, COLUMN_NAME 列名, COLUMN_TYPE 数据类型, DATA_TYPE 字段类型, CHARACTER_MAXIMUM_LENGTH 长度, IS_NULLABLE 是否为空, COLUMN_DEFAULT 默认值, COLUMN_COMMENT 备注 FROM INFORMATION_SCHEMA.COLUMNS WHERE -- 对应的数据库 table_schema = 'your_selected_database' -- 对应库下的具体表名,不加 table_name 则查所有表的字段 and table_name = 'your_selected_table_name' 查询结果展示: 然后复制结果,直接粘贴到excel 中即可。 文章来源:https://www.csdn.net/tags/NtTaUgysNTU3MTYtYmxvZwO0O0OO0O0O.html

STM32F103单片机温湿度光照烟雾监测—Android Studio蓝牙HC05APP显示控制设计(完善版)

本次是接着上一次做的,因为上一次完成了经典蓝牙模块HC05和STM32单片机双向数据传输处理,但只有一个界面,在Android里,一个Activity(活动)对应一个layout(布局),不满足较多数据量的需求。综合考量,采用在MainActivity上加fragment的方法。类似于微信布局,可以得到多个界面。 废话少说,直接上效果: ***视频链接*** 资源目录: 说明:因为前一篇博客已经介绍的比较清楚了,这次程序有一点改动,但主体不变。所以不对关键程序进行展示了,有疑问可看上一篇!!! ***资源下载***

网工必备命令:思科、华为、H3C交换机巡检命令全收录

当我们想要查看交换机配置是否正确,不可能将每条命令都看一遍,毕竟数据庞大,这时候就需要精准使用交换机的巡检命令,下面我们来介绍一下几个常见厂商的巡检命令 思科 1、show interface stats:查看交换机所有接口当前接口流量 2、show running-config:查看当前设备配置 3、show version:查看IOS版本信息及设备正常运行时间 4、show clock:查看设备时钟信息 5、show vtp status:查看交换机vtp配置模式 6、show vtp password:查看交换机vtp配置口令 7、show env all:查看设备温度,电源和风扇运转参数及是否报警 8、show inventory:调取设备内部板卡出厂模块型号及序列号 9、show spanning-tree root:查看交换机生成树根位置 10、show cdp neighbors:查看邻接cisco设备基本信息 11、show cdp neighbors detail:查看邻接cisco设备详细信息 12、show interface status:查看交换机接口状态是否存在errordisable接口disable接口 13、show interface summary:查看交换机所有接口当前接口流量 14、show interface |ierrors|FastEthernet|GigabitEthernet:查看接口是否存在大量input或output errors包错误 15、show processes cpu:查看设备cpu负载 16、show processes mem:查看设备mem负载 17、show access-list:查看访问控制列表配置及匹配数据包数量 18、show logging:查看本机内部日志记录情况 19、show ip route:查看路由表 20、show firewall:检查防火墙的工作模式 21、show conn count:检查防火墙并发数 22、show xlate count:检查防火墙nat工作状态 华为/H3C交换机常用巡检命令 system-view #进入系统视图 user-interface vty 0 4 #vty就是用telnet/ssh远程进入交换机的界面(虚拟界面)

基于MCAL中API的关键字总结

因为要做MCAL的测试方面的东西,所以要从Driver层下手,因此对自己将要用到的API做了一个总结,后续还会去更新一下工程方面的东西。主要做的事下面的这几个模块: 因为是测试,所以只是总结了set,get以及初始话方面的关键字。 DIO:Dio_GetVersionInfo:获取版本信息,指向存储此模块版本信息的位置。 void Dio_GetVersionInfo( Std_VersionInfoType* VersionInfo ) Dio_ReadChannel :返回指定的DIO通道的值。 Dio_LevelType Dio_ReadChannel( Dio_ChannelType ChannelId ) Dio_WriteChannel:通过服务来设置一个通道的级别。 void Dio_WriteChannel( Dio_ChannelType ChannelId, Dio_LevelType Level ) Dio_ReadPort :返回该端口的所有通道的级别。 Dio_PortLevelType Dio_ReadPort( Dio_PortType PortId ) Dio_WritePort :使用服务来设置端口的值。 void Dio_WritePort( Dio_PortType PortId, Dio_PortLevelType Level ) Dio_ReadChannelGroup :此服务读取一个端口的相邻位的一个子集。 Dio_PortLevelType Dio_ReadChannelGroup( const Dio_ChannelGroupType* ChannelGroupIdPtr ) Dio_WriteChannelGroup :将端口的相邻位的子集设置为指定级别的服务。 void Dio_WriteChannelGroup( const Dio_ChannelGroupType* ChannelGroupIdPtr, Dio_PortLevelType Level ) ADC:Adc_Init :初始化ADC硬件单元和驱动程序。 void Adc_Init( const Adc_ConfigType* ConfigPtr ) Adc_SetupResultBuffer:使用将存储转换结果的组特定结果缓冲区启动地址初始化ADC驱动程序。应用程序必须确保DataBufferPtr所指向的应用程序缓冲区能够保存指定组的所有转换结果。在重置后,需要使用Adc_SetupResultBuffer进行初始化,然后才能启动组转换。 Std_ReturnType Adc_SetupResultBuffer( Adc_GroupType Group, const Adc_ValueGroupType* DataBufferPtr ) Return value: E_OK:结果缓冲区指针初始化正确E_NOT_OK:操作失败或发生开发错误描述

Mybatis报错mapkey is required解决方案

Mybatis报错mapkey is required解决方案 问题背景解决方案总结Lyric: 几天都没有喝水也能活 问题背景 因为使用了mybatisX插件,导致检查报错mapkey is required 解决方案 1 关闭mybatis的检查,ctrl+alt+s打开setting,Editor→inspections→mybatis 总结 莫名出来的错误,之前还是好好的 作为程序员第 159 篇文章,每次写一句歌词记录一下,看看人生有几首歌的时间,wahahaha … Lyric: 几天都没有喝水也能活

recv函数和send函数返回值错误处理

本文中分析的都是非阻塞态的socket错误代码,因为阻塞态也不会出现EWOULDBLOCK错误。 1、recv函数: 返回值<0时并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况下认为连接是正常的,继续接收。 当socket设置为非阻塞的时候,recv返回错误时才会有 errno == EWOULDBLOCK || errno == EAGAIN两种情况; #define EWOULDBLOCK EAGAIN 因为宏定义EWOULDBLOCK和 EAGAIN ,所以二者等价; EWOULDBLOCK,WOULD英文语法是表示过去将来式,表示本来应该。。。; 放在此处的意思是,本来应该阻塞,却没有阻塞。(也就是并没有发生阻塞,原因是设置了非阻塞态,也就说这个错误是在非阻塞态时才会有的) EWOULDBLOCK的意思是如果你不把socket设成非阻塞(即阻塞)模式时,这个读操作将阻塞,也就是说数据还未准备好(但系统知道数据来了,所以select告诉你那个socket可读)。使用非阻塞模式做I/O操作的细心的人会检查errno是不是EAGAIN、EWOULDBLOCK、EINTR,如果是就应该重读,一般是用循环。如果你不是一定要用非阻塞就不要设成这样,这就是为什么系统的默认模式是阻塞。 int foo(SOCKET socket, char *buff, int length) { int nleft, nread; nleft = length; while(nleft > 0) { nread = recv(socket, buff, nleft,0); if(nread == 0)//对端socket调用close()关闭 { printf("%s", strerror(errno)); return -1; } if(nread < 0) { if(errno == EINTR ||errno == EAGAIN ||errno == EWOULDBLOCK) continue; printf("

如何设计安全可靠的开放接口【番外篇】--- 对称加密算法

文章目录 【如何设计安全可靠的开放接口】系列前言对称加密算法特点 常用的加密算法DES基本原理算法特点 3DESAESECB模式CBC模式CBC模式的特点 【如何设计安全可靠的开放接口】系列 1. 如何设计安全可靠的开放接口—之Token 2. 如何设计安全可靠的开放接口—之AppId、AppSecret 3. 如何设计安全可靠的开放接口—之签名(sign) 4. 如何设计安全可靠的开放接口【番外篇】—关于MD5应用的介绍 5. 如何设计安全可靠的开放接口—还有哪些安全保护措施 6. 如何设计安全可靠的开放接口—对请求参加密保护 7. 如何设计安全可靠的开放接口【番外篇】— 对称加密算法 前言 对称加密算法是指通过密钥对原始数据(明文),进行特殊的处理后,使其变成密文发送出去,数据接收方收到数据后,再使用同样的密钥进行特殊处理后,再使其还原为原始数据(明文),对称加密算法中密钥只有一个,数据加密与解密方都必须事先约定好。 对称加密算法特点 只有一个密钥,加密和解密都使用它。加密、解密速度快、效率高。由于数据加密方和数据解密方使用的是同一个密钥,因此密钥更容易被泄露。 常用的加密算法 DES 基本原理 其入口参数有三个:key、data、mode。key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。 算法特点 DES算法具有极高安全性,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。而56位长的密钥的穷举空间为2^56,这意味着如果一台计算机的速度是每一秒钟检测一百万个密钥,则它搜索完全部密钥就需要将近2285年的时间,可见,这是难以实现的。然而,这并不等于说DES是不可破解的。而实际上,随着硬件技术和Internet的发展,其破解的可能性越来越大,而且,所需要的时间越来越少。使用经过特殊设计的硬件并行处理要几个小时。 为了克服DES密钥空间小的缺陷,人们又提出了3DES的变形方式。 3DES 3DES相当于对每个数据块进行三次DES加密算法,虽然解决了DES不够安全的问题,但效率上也相对慢了许多。 AES AES用来替代原先的DES算法,是当前对称加密中最流行的算法之一。 ECB模式 AES加密算法中一个重要的机制就是分组加密,而ECB模式就是最简单的一种分组加密模式,比如按照每128位数据块大小将数据分成若干块,之后再对每一块数据使用相同的密钥进行加密,最终生成若干块加密后的数据,这种算法由于每个数据块可以进行独立的加密、解密,因此可以进行并行计算,效率很高,但也因如此,则会很容易被猜测到密文的规律。 private static final String AES_ALG = "AES"; private static final String AES_ECB_PCK_ALG = "AES/ECB/NoPadding"; public static void main(String[] args) throws Exception { System.out.println("第一次加密:" + encryptWithECB("1234567812345678", "50AHsYx7H3OHVMdF123456", "UTF-8")); System.out.println("第二次加密:" + encryptWithECB("12345678123456781234567812345678", "50AHsYx7H3OHVMdF123456", "UTF-8")); } public static String encryptWithECB(String content, String aesKey, String charset) throws Exception { Cipher cipher = Cipher.

如何设计安全可靠的开放接口---之AppId、AppSecret

文章目录 【如何设计安全可靠的开放接口】系列前言AppId的使用AppId的生成AppSecret生成 总结 【如何设计安全可靠的开放接口】系列 1. 如何设计安全可靠的开放接口—之Token 2. 如何设计安全可靠的开放接口—之AppId、AppSecret 3. 如何设计安全可靠的开放接口—之签名(sign) 4. 如何设计安全可靠的开放接口【番外篇】—关于MD5应用的介绍 5. 如何设计安全可靠的开放接口—还有哪些安全保护措施 6. 如何设计安全可靠的开放接口—对请求参加密保护 7. 如何设计安全可靠的开放接口【番外篇】— 对称加密算法 前言 前面我们介绍过了token机制,它可以解决单点登陆、跨域等问题,避免每次都需要用户登陆,不过并不是每个对外开放的接口都是需要用户登陆的,如果是这样,那我们就要想其他的方式来对用户身份进行验证了,一般我们会使用AppId的方式,实际上你也可以认为它是一种token机制,只不过换一个名字而已。 AppId的使用 因为AppId实际上就是一个标识,所以一般只要能保证系统内全局唯一即可,不过,为了能够防止有人拿着别人的AppId来请求,所以通常AppId都会配对一个AppSecret,可以理解为AppId的密码,最终的接口请求内容会根据AppId和AppSecret并按照一定的规则来生成一套签名,当请求方带着签名值去请求提供方时,提供方就会验证这个签名,只有验证通过才会继续处理。 AppId的生成 正如前面所说,AppId生成只要保证全局唯一即可,所以这里就不过多介绍了。 AppSecret生成 AppSecret的生成也很简单,只要与AppId能关联起来保证唯一即可。 PS:AppSecret后续会用于生成Sign(签名),因此一定要注意AppSecret的保密性,并且不能在网络中进行传输。 appSecret生成代码示例 public class AppUtils { static Map<String, String> appMap = Maps.newConcurrentMap(); public static void main(String[] args) throws NoSuchAlgorithmException { // 方式一演示 buildSimpleAppSecret("abc"); System.out.println(getAppSecret("abc")); } /** * 构建简单的appSecret,比如:使用UUID * * @param appId */ public static void buildSimpleAppSecret(String appId) { appMap.put(appId, UUID.randomUUID().toString()); } private static String getAppSecret(String appId) { return String.

LeetCode 39. 组合总和

题目描述 39. 组合总和 解法 这道题超级简单,如果你看过 LeetCode 77. 组合 这篇的解法,你肯定知道 backtrace 时 i i i 都是从 s t a r t start start 开始,那么下一层回溯树就是从 s t a r t + 1 start + 1 start+1 开始,从而保证 n u m s [ s t a r t ] nums[start] nums[start] 这个元素不会被重复使用 // 回溯算法标准框架 for (int i = start; i < nums.size(); i++) { // ... // 递归遍历下一层回溯树,注意参数 backtrack(nums, i + 1, target); // .

Vue3 把实现双向数据绑定的 API Object.defineProperty 换成了 Proxy,出于什么考虑?

核心 主要是处于性能上面的考虑。 如果对象有 100 个属性,Object.defineProperty 要循环 100 次来劫持每一个属性; 而由于 Proxy 直接可以代理整个对象,一次就可以搞定,免去了循环100次来劫持每个属性的性能消耗。 Object.defineProperty对后面新增的数据无法实现数据的双向绑定,而 Proxy 对后续新增的属性也具有响应式。 接下来给大家从代码,详细分析下两者的区别,性能提高提现在了哪里。 Vue2中的通过Object.defineProperty实现数据的劫持 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <p id="oP"></p> <input type="text" id="oInput"> <script> const data = { name: '张三丰', age: 18, }; // console.log(data) // 数据劫持:就是把数据都变成 getter/setter 形式,能做到对数据操作的时候,也能添加一些额外的功能(例如修改视图) // 对象、属性、描述/配置 const copyData = { ...data }; // ['name', 'age'] Object.keys(data).forEach(key => { Object.defineProperty(data, key, { get() { // !

数据结构2023考研笔记(自我理解版)

文章目录 2.1线性表L 前言2.1.1··用到的单词缩写,函数2.1.2··sizeof2.1.3--typedef的用法2.1.4--指针变量2.1.5--c语言动态分配空间2.1.6--参数传递:值传递、地址传递、引用传递 2.2 自问自答2.2.1.引用调用和调用有什么区别和联系?2.2.2 线性表(Linear List)是什么?2.2.3 .数据结构三要素2.2.4. 线性表的基本操作2.2.5. 顺序表 随机存取2.2.6.脏数据 2.3 线性表的链式表示 顺序存取2.3.1 相关术语:头指针,头结点,首元结点2.3.2 单链表 2.1线性表L 前言 2.1.1··用到的单词缩写,函数 LOC(L)---location ElemType--数据元素类型 element type,不是关键字 ,比如typedef char ElemType;可以提前定义,也可以直接定义结构体时不使用ElemType SqList--顺序表 sequence list malloc、free函数--动态申请和释放空间,使用到<stdlib.h>头文件 new、delete关键字--C++方法动态申请和释放空间 LinkList--英文意思单链表,通常用LinkList定义单链表,表示时强调是一个单链表,与LNode*等价 LNode--链表中的任意结点,LNode* 强调是一个任意节点的指针变量 2.1.2··sizeof sizeof(int)= 4B //B是字节byte简写 sizeof(char)=1B 2.1.3–typedef的用法 见这里 2.1.4–指针变量 ElemType *Data; 类似int a; 只在变量名前多了*号 用法见C语言指针变量的定义与使用 2.1.5–c语言动态分配空间 L.data ,在C++中是 L->data (ElemType*) 起 强制转换成指针型 的作用 malloc(m),m是 整数 哦 2.1.6–参数传递:值传递、地址传递、引用传递 可以看C语言函数参数的传递详解 我的理解 值传递 调用时把实参传过去,函数改变的是形参的值,但是不改变实参。 引用传递 需要把值传过来。 地址传递 (指针变量 做参数)由于传了地址,再使用*p就用的变量值了,内存地址上的东西变了,也相当于改变了实参; 不使用*p实参不会改变。 (数组名作参数),传递数组首地址,改变实参 (引用类型作参数),&j=i; //&j 会跟着 i 改变而改变,j和i是用的同一块地址C++语法 引用:给一个对象起别名 2.

如何快速获取数组最后一个值

在不知道快速获取数组最后一个值时,我们的写法是: let arr = [1,2,3,5,1,2,3,6,5,4,1,100]; let index = arr.length - 1 console.log(arr[index]) 我们需要获取它的长度再去减1,然后通过下标得到最后一个值,本人认为这样的写法会比较麻烦,其实我们可以使用另外一种方式 = 》Array.prototype.at() at() 方法接收一个整数值并返回该索引的项目,允许正数和负数。负整数从数组中的最后一个项目开始倒数。 方括号符号没有问题。例如,array[0]将返回第一个项目。然而,对于后面的项目,不要使用array.length,例如,对于最后一个项目,可以调用array.at(-1)。(参见以下示例) const array1 = [5, 12, 8, 130, 44]; let index = 2; console.log(`Using an index of ${index} the item returned is ${array1.at(index)}`); // expected output: "Using an index of 2 the item returned is 8" index = -2; console.log(`Using an index of ${index} item returned is ${array1.at(index)}`); // expected output: "Using an index of -2 item returned is 130"

Python divmod函数

目录 描述 语法 使用示例 1. 整数参数 2. 浮点数参数 注意事项 1. 参数不能处理字符串 2. divmod函数的返回值类型是元组 描述 divmod函数是Python的内置函数,它可以把除数和被除数的运算结果结合起来,返回一个包含商和余数的元组。 语法 divmod(dividend, divisor) 名称说明备注dividend被除数不可省略的参数,可以是整数或者浮点数divisor除数不可省略的参数,可以是整数或者浮点数 返回值:tuple,元组中第一个元素是商的结果,第二个元素是余数的结果。 使用示例 1. 整数参数 >>> divmod(9, 5) (1, 4) >>> type(divmod(9, 5)) <class 'tuple'> 返回的元组中,第一个元素是 9//5 的结果,第二个元素是 9 % 5的结果。 2. 浮点数参数 >>> divmod(2.3, 0.2) (11.0, 0.0999999999999997) >>> a, b = divmod(2.3, 0.2) >>> a 11.0 >>> b 0.0999999999999997 可以通过元组解包的方式分离出整除结果和余数。 注意事项 1. 参数不能处理字符串 divmod函数只能接受整数或浮点数类型的参数。例如当参数为字符串时,Python报错。 >>> divmod('a','A') Traceback (most recent call last): File "

MySql安装+测试连接+常用终端mysql命令(超详细)

MySQL,本质上就是一个软件。 主要有两种版本:8.x和5.x ,一般使用 5.7.31版本。 1.下载压缩包 可以直接访问下面网址进行下载 https://downloads.mysql.com/archives/community/ 或者进入官网一个一个点击,下面是详细点击顺序: 进入MySql官网——downloads——MySQL Community (GPL) Downloads——MySQL Community Server——Archives——选择版本,下载64位zip 2、安装 mysql-5.7.31-winx64.zip 是免安装的版本。 解压zip文件将解压后的文件夹放入路径(不要有中文路径) 3、创建配置文件(my.ini) 4、初始化 打开终端cmd以管理员的权限去运行 输入初始化的命令 "C:\Program Files\mysql-5.7.31-winx64\bin\mysqld.exe" --initialize-insecure MySql安装已经完成。 5、制作成Windows服务,服务来进行关闭和开启 5.1.制作服务 "C:\Program Files\mysql-5.7.31-winx64\bin\mysqld.exe" --install mysql57 mysql 5 7 :起个名字,因为是5.7.31版本,所以叫mysql57 启动mysql: net start mysql57 关闭mysql: net stop mysql57 5.2.我的名字叫做:mysql2 (因为安装第二个版本的mysql) 要在管理员权限下打开cmd 5.3 也可以在window的服务管理中点击按钮启动和关闭服务。 任务管理器——服务——打开服务——mysql57(右击开启或关闭mysql) 任务管理器快捷键:ctrl + shift + Esc 6、连接测试 安装目录有空格,所以要加上引号 "C:\Program Files\mysql-5.7.31-winx64\bin\mysql.exe" -h 127.0.0.1 -P 3306 -u root -p 本地主机ip: 127.0.0.1端口:-P 3306用户名:-u 上面的命令可以简化为下面的命令:(默认都是自己的主机,端口3306,所以可以省略主机ip+端口)

React项目实现导出PDF的功能

在做web项目中,有时候会遇到pdf导出的需求,现根据之前在公司的React项目中遇到的导出PDF需求,整理一个demo出来。 导出PDF需要用到两个依赖包:html2canvas、jspdf 1、安装html2canvas和jspdf npm install html2canvas -S / yarn add html2canvas -S npm install jspdf -S / yarn add jspdf -S 2、把导出PDF封装成一个公共方法 1、在src/common目录下新建exportPDF.js文件 exportPDF.js: import html2canvas from 'html2canvas'; import jsPDF from 'jspdf'; /** * 导出PDF * @param {导出后的文件名} title * @param {要导出的dom节点:react使用ref} ele */ export const exportPDF = async (title, ele) => { // 根据dpi放大,防止图片模糊 const scale = window.devicePixelRatio > 1 ? window.devicePixelRatio : 2; // 下载尺寸 a4 纸 比例 let pdf = new jsPDF('p', 'pt', 'a4'); let width = ele.

齐全且实用的MySQL函数使用大全

目录 一、MySQL函数介绍 二、MySQL函数分类 (一)单行函数 ①字符串函数 ②数学函数 ③日期函数 ④流程控制函数 ⑤系统信息函数 ⑥其他函数 (二)聚合函数 三、函数使用示例 (一)字符函数 ①length(str)函数 ②concat(str1,str2,...)函数 ③upper(str)、lower(str)函数 ④substr(str,start,len)函数 ⑤instr(str,要查找的子串)函数 ③trim(str)函数 ⑧lpad(str,len,填充字符)、rpad(str,len,填充字符)函数 ⑨replace(str,子串,另一个字符串)函数 (二)数学函数 ①round(x,保留位数)函数 ②ceil(x)函数 ③floor(x)函数 ④truncate(x,D)函数 ⑤mod(被除数,除数)函数 ⑥pow(x,D)函数 (三)时间与日期函数 ①时间与日期函数含义 ②now()函数 ③curdate()函数 ④curtime()函数 ⑤获取日期和时间中的年、月、日、时、分、秒 ⑥weekofyear()函数 ⑦ quarter()函数 ⑧ str_to_date()函数 ⑨date_format()函数 ⑩date_add(日期,interval num 时间)函数 ⑪last_day()函数 ⑫datediff(end_date,start_date)函数 ⑬timestampdiff(unit,start_date,end_date)函数 (四) 流程控制函数 ①if(expr,v1,v2)函数 ②ifnull()函数 ③case…when函数的三种用法 (五)系统信息函数 ①version()函数 ②connection_id()函数 ③processlist ④database(),schema()函数 ⑤user(),current_user(),system_user()函数 ⑥charset()函数 ⑦collation()函数 (六) 其他函数 ①FORMAT(x,y)函数 ② INET_ATON(ip)函数 ③INET_NTOA(NUM)函数 ④password(str)函数 ⑤md5(str)函数 ⑥encode(str,pswd_str)、decode(加密的字符串,pswd_str)函数 (七)聚合函数

html从零开始——为网页加入樱花飘落效果

JavaScript代码: var stop, staticx; var img = new Image(); img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUgAAAEwCAYAAADVZeifAAAACXBIWXMAAACYAAAAmAGiyIKYAAAHG2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXBSaWdodHM9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9yaWdodHMvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NDFDMjQxQjYyNjIwNjgxMTgwODNEMjE2MDAzOTU1NDQiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDozNDVjOWViOC04NDc4LTFkNDctOGRjMi0yZDkyOGNhYTYxZWQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6YjAzN2ZiMGItNTU5Mi0xYjRkLWJjZGQtOWU4NGExMDJiMGM2IiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE4LTA1LTA5VDE0OjQ5OjM3KzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOC0wNS0wOVQxNDo1MToyNSswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOC0wNS0wOVQxNDo1MToyNSswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjEyMjVlZWE3LTEyY2QtMTY0NC04ZDAzLWFjOTE2ZTAxZDQ1YyIgc3RSZWY6ZG9jdW1lbnRJRD0idXVpZDoxRDIwNUFGNjZCRDlFNTExOUM5REMwMzg2RjlEQjFGNyIvPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDphYmMzNjIzMy1hOWNkLWNiNDQtODViYi0zZTgyMjEwYmIxMjYiIHN0RXZ0OndoZW49IjIwMTgtMDUtMDlUMTQ6NTE6MjUrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6YjAzN2ZiMGItNTU5Mi0xYjRkLWJjZGQtOWU4NGExMDJiMGM2IiBzdEV2dDp3aGVuPSIyMDE4LTA1LTA5VDE0OjUxOjI1KzA4OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+XCpBoAAApBxJREFUeNrs/cmSI8u2LIipLnMHosnc59Z7jyxhjSg1oggn/EWO+SP8B34JhRyWCItk1at7786MBnBbWoNlZm4OOLrIvc8+t45bCjIQjibQuKuvTlUpCdva1ra2ta3zZdtHsK1tbWtbG0Bua1vb2tYGkNva1ra2tQHktra1rW1tALmtbW1rWxtAbmtb29rWBpDb2ta2trUB5La2ta1tbQC5rW1ta1sbQG5rW9va1gaQ29rWtra1AeS2trWtbW1rA8htbWtb29oAclvb2ta2NoDc1ra2ta0NILe1rW1tawPIbW1rW9vaAHJb29rWtjaA3Na2trWtDSC3ta1tbWsDyG1ta1vb2gByW9va1rY2gNzWtra1rW1tALmtbW1rWxtAbmtb29rWBpDb2ta2trUB5La2ta1tbQC5rW1ta1sbQG5rW9va1gaQ29rWtra1AeS2trWtbW0Aua1tbWtbG0Bua1vb2tY/3xr+o7+Bf/2//z/+1OfPAIgJErGbMj7M8fue+O1A7LLjcxyw+5hwZMbgQnLgKIftRsgMyYUjBYNhOn6AADiMOGDCyIQBCflwwNEdw24HHA5AzhjHJxyQwZTADLgmHJPhDRnfjo6PlPHbNOJDGZgEZsIgOAHPR/yPwxv+28MONOBghIEAiXce8LkzuAG/vRP7o+EzAcMRyNlxoJByxj4T/8su4+UgPE3A++jg5yfe/lvD73/b4eVfM17/zfE//y3h6UjsJ8f/9N8m/Of/Cnz/d0cegHES/t///Q7HHfG/+/8JT0fABGQTzIEkYMyGf/0vBh8N3/99wv/rP/1/sDs6/i//+t8DZhCATOFwzPj4/R3/MhkOmPBz/47dB+CY8LZ/w/NnQh4cu88dppSRU4abQwbQCRPhdDx/PCGbI9f7JLXbRfHpYw+n4MOkPAAUSacBmfv30f/rf+f+8m+GpyPw8Zrhl0IMAmK5KgAOWCY4Ib6r8pO+/hiV/5c/LyyVe6g8TnH5P/3f/q8bwv2zA+TfZ7HtvKbY4ScCOxCU4EaYE04hxb0hOYgEATAJTsGYkP2IQQBocAkkAGMBQcdgA47HA3aMg0cQkhmOGRhEZAMoIpdDhiREQYzXJQBDSQwygFGLdwET2/3c2luLx9fXzjhKk4hs8QTmsd2OAiHkIR4wZmFKxNMRGI7C5xPxt3+Lv+0GvL47/r/fBgBCJpAcYPwVAICbsPsE/v0VSJl49if8+/C/IEMwCIQBcCQLUBeBlOOFi4K5wanyGcgAiPEe5XSApInJsllCQkAVQNFStpTcUjoakxtNZqJIwtIx2XigpUyaG2xSdvPj9/+aPy3zoORuorKVD7OCoZfLxAUgMhegrEBYf1p8x2pYdxUKITVEXIBhewFit21bG0D+HWoQDgJwiERSAF622CFNgpsh5YypHPck4S7YEEcjQQhAsoRj/ixARHiBOVpAhsthNkCKPZwCvNvTB1Ugi7/dnpunr9mQYJjoGGWLOooVUAcDbAWV6CleN9sxJwzOeE/lczgakQ4OkzCNhBuwOwo/n+M+u4Pwsbd4dQLciJefwvR/CLDsgyWVP+SMxx0HgSCe8h7/037CwY7YY1cPeyQzwAxe3j9FeBKSwOf3p7Q7cuQ7d0oYCbPkifvDnqaULNvOhAE0c7p2ACEbTBwIjhCMYIJhAJggWICsMuQTnEdCB7m/7f6rv2XLb2781ITP6bdpSgcrgNhFhTqJChnv9eGosILijKAnCIvlxQsQbwC5AeTfM4IkACdhHtHUlBTxjYSjEYMATxHGEQyQK5GFlZ3daOWsLxgjyiphYAMVJIv9XsIC9xgHg4HIDFBzUxyM5QCUShxBYifDwYSXErlkCkmEkaAcEDFRERUKmCxA0ARMiIN5EHBIcT2JkapPgmVhShHRjZOQU5xExqPw43uNQCOqffp0iEAegDShe9Nz4DUcK6Aa9nmACLylT+ynXYlwC4CbYWLGHoTJzFxj8rTfH8ZnE14pfqP4Ctke0EBoEG0gMJLcK3J2Lx9XIrFz2kjBIhSvpx9NgI6QPgR/B/Qu6YNIo8kHTpYcU0IWcRw+NJ9HIoAjIAroTja/FhWeRIblUoGQHShSZV9J3A7bDSD/jil2xHQgiOTCNJRoToISW9rYsi2tnMZZ7ieHwSINhSJyYyBc7N8J7hmkAS7IAhgFYRRxNGFww2SOEQm5/e2IVZ3AToY3HiEMEfGWtJkIQGRJgfsIEuU1wAzKGUmEM0oHgwMYo3aWJuG4B3IidlNJlQnYFJ/JNMxvfXcUxqNw2AHjJxalgPbpuDAchePOsJsGJAz4Mb7jPx2/zyUAAPsUibbD0+v77nlwvEJ4pfEbHN9o9h20AEnoWcQe5FgvRrIU6wSjCRzNbIRAQBmug9wPcv+A9A66RR4vp7vk7hIyQTc3pckwCjo+C26atIj3r4PhalSIdSBswFeAsAEiojyjRGAgfGQ5LRBRTdjWBpB/F2ic910i9r1oHnQ1vpoml9splFSZ7XkC/AxZ7V5wCAMY4ZviEDMLgByGVEDTYSQkxyji04BnByY49khz8bBEgBkBkP9ucSBaV9+K9DRenxuQLeqC9TnqfZ3AWHJit7IBBmYgHQU8AXkE+AGYRxS5c4AufO6Ap/d4CB14+hA+98Tr74LXskWLeuNV7Y7A5154+knsfI8fw0d/WjIAw+uwG7lLT7T8QscLhb8B/AbxVcI30r6J/E7yReArpReSexhHGEeAVivEIBNrBUWYIP/UlN/o/i53wN3hzHBM5UWCJheY4cwwy0lJOEKi++dTdqUOIS80TuZwv1z3C1FhD4g1KjQ0AFyAoZWovfyhRYq/rQ0g/z4gyZq/IpXTfyYxOqJpYRGZycqODUDuYBoiNS6NmkSDKyOVWqXkAIeIIl1wd1hKyIdPjGNt1EQEeSwR5E8DkgyfzC2lriktSp1y5ylSWyqaQl2xoDaacgHI9h47gFRJ+02R0gNAAiEwABJAHuMPDpOQzcBJSBn4fDK8/MzwFK/l5V34t78ZYHMzCTWYKwXO3Qfw/h349jux0w7/y+7f4HASHEzpaWB64WivML0y41mO7yC+B0DiheR3AN9p9h3CK4QXCi8AX5H4DHJHlWoHlAMUNcl1gPs7MsiELKNzQgaZReS4rwQgR9GYmcQEV3bQkTnZu3Y05fyEI7y8rXujQs2NHdQSiUWKrH0PhoASAwgLxrfnyIiGliKjadu3tQHk32upprGtURN1O2SWRg1hU9QFkUsTptQRo/tNTCU6nKYJYzl8MoQdAJiBk8PlGC1hUmnBqEal0egZakMFbMEHu2OwrgSDIeqMQ9c3NtROdjwyW3SAWdPs2jcuzzeUjj0AmBMTiXSIDnNOhEod8rADcIiGy/ue+M/lL7oRr2+O//9/SS3qHnwZmTuF/Yfwb/9ZSJ7sv3x8p/yZlnZ7s+HVYP9C2t8A+4aBz3A8EfwO4G8k/ybhO8hvAL4B/BvEVwLfALwAeIH4VEJ2h3SE6x3SO+QfpFPQEbIRwo6uSWY7yI9AGgmMyvkIcgA50JjgHEEOFAY6Bk5INJl2BubrjRMuosI5Rdae0EmKXKcJILXHm6sBKaVF/RGurUGzAeRfC5Nexm/MgamOwCgiqADN2qgpoz4EvKS50ahJLXIKkPNlJ7uApTpYLt2Z+LvluKpZcWaN8ro8vkSVgwxHCs9eRnvK7cYAdbQ6ZAC+swSjJYIUHENJ6VVGdI5G2NEjrR5YGjXA23O82vEg/PitSzMNeH4XpgRMI8AM7HNL4xlRnWhZ9t/9D3gaNDz/H//tvzxZGp990Ctov8HSfwbtPwH2G42vAJ8B/Bbb8DfIvpN4AfgC4hniC4AR4gBglJQgOOSfdP0EPcN9kvMIMtFsiHOBEpgGAiZnYsTAiZCJTIASYANMBnmCmQmeIA12QMInjWU0oQGXz40zJEI7LFPkRMhWokKP/SoATw1UI9LUIgI9LQWBceLa1gaQf5dlAHKNwkr9Owk4lu4t5ZBx0XwgCLjXqnzbgdkQyBsaqTRqWhWfAZju5a/WbYzu+ABiStGVzgwQy2T721agdSfDkRkx+CNMc5INenRUss3znZlzJ9tLFJmc8DKuZCIwGGzKSEchjwZPMf9Yu7fjUTiOpVFTXs/uIPvb756ePmT7AwgyARgH8WV0vg6y1+T2Yjb8liz9N0rDd5l9S7TfSuT4n0H7TzT7DeQLYDsAz2B6BflMYF/qi0NpeZeOdE1bBbgTriTCYJYAGKUksv6eKCVQJiiRGkQNoCUQA+GDkBLgAwYlMg0gkkEDMAwpY0xHHc2RwZPGyVh+TwgwPI0Kc9lHSorMRdSpeZi8gqHmUiYsTlK5wLkb4WkDyA0g/6JKpJMYSif7EzO4tC5wqQVaS7GWjRqQIC1mHjG0TraBoAWo9o0aszEaNXUApetk77Ih07HDUEqkpQ1T7r9TwrtN8KlEjCxRbN+oKSMp9HJQ1eiSbI0aMUoHqZQOWDrZ2gF5IMZPlXonbJxg338XRRikJHBH4uX//P/ML0jpGbRXks8mfjOkvxntO5L9zWz4jTb8N0zpPyGlb6Q9C/YK8jst/Q3kd4A7gClCdMb+a8b5xNNNcdaB+DZuVUYFDAMcCcYBsARggDSUKsYAVyIxKvuRRESgwAhwonGQ5QGZOwAThR2TJhsxjsDgUx4+/xs7+rNpngo4AcNpJSos6fHNqLAAbE4xUuY2/+zvvKXZG0D+5SuVs/rMDomzd40ya51IcsASpEIFhJCY4HKk0qxwCKmM4sEFV4z6ZJ+Q0q7UIR1GQ9aEQYZPAs9u+BimBYbXCHIisHNDLiwTw3mjxrpO9pBxdlT27JpMRK1UMaRtk0MJOOwN40e2//SveXg62n50e/6XH3pS4p4Yni3ba5L9C2m/Uek3Mr0AfKHZNzL9C8jfMNg32PAd5DeZ/UZL30R7htmOiXvQ9rUBTVr5cNkiqPa61b3D2qwGoUhLCXII0NOoqCPumHiUcwQ0wG1E0g7EBGCMuiMGug2QBrmPzDiIHAAMoAYyJQMSpGEEh4MVNmUuJZK+cdJHhX2N8hQMLU5W2UpU2IGhuomFuRYJMKul3zWT2dYGkH/n+LFSDlm6hsJkjPGW0pCwfEo5VJthrBGb0TB5xoCumUMAaaYcjmnAYTqU7nZEmQMNDmAsqbFhnXJYj46xDMNlRM0UXce6drLFZSe7giJKpgpUiuPcyXYDhk/x+aenl5++e/7g0+j2bEzfEu03o73S+ULwBbDvNPsbLf2NKX2D2Uu5vIL2HcbfmIZvMPuGZM8wvsDsqTRFDMlIszLmwnlWc65ZtGHyGh/DS4W2lTe8zICnAe4DrKTMZgniyKwjqAGmJNcAq80YT8hIck9wGSkTUjIyRVVYKSJaJINScqTxmBNM2bwUiqUrUWFEhEolRbY5TZZhmSarn4EszRmfh9G9AGpO1kB1WxtA/l0B0k872Q5MKcI18wDI4QhMiWXULiiHaEPlbNxqz3OjRpVewplyyDQuKIf9wWU6jfQ0N2G610sQA6JRM2ruZLNUJU872T3l0MrQuiNqnUcDMsRxorl24/P/7Pv//f/ozyBeYOnV0vDNLP1Gpt9g9g3kE2ivMH6Dpd8wDL8hpW80vsLsGcZXpHJfS68kn2C2gzHBzFCH560Dxu4zmqPIOts0b2ojRLWhYdZ6IDGFj1ZzFDxF+J4S5ImUyd1gTCUFTyQTzJMcieSAXMBRiQGSyaCo/KWjp0xnPVedNk6WtcIZDE+jwqhNFhAsoFgJNW6lLpwMuYIp59Es1Kh1WxtA/r1hMvrOAZCpKNO0up/ZYgh6QTnEspONQuhgNyvMtoPPB39POWx8aUUkN1mkzo16eEI5FImxNGqoITrPIeew6GT3jZqpNmoATCUqHR1042hmuwTuTXjmgO9M9s2Mr6R9o9k3DMN3JPtOS99APsPSC82+I9lvGNJvsPQdZi+MKDHqkSk9wzjAaCyt/Dpu1MqK5Gl42803laICT0QjyvuPOcHCdnJHNGAsmjXuibJSK1WCEF1rIkE00VNoXdAgJgJJ8ZEnSoOSBiolSQNTSiYNhog+RUxrjZOzFPk0KtQ8XF6jQt+xpNlzvVGljlxPoOYqDR6169vaAPLvn2KjU7tx4DCUtFkq2++jHAIGyWFIFyiHgplFo4ZWGjVapxxS2LcBoNJDL42avQw/LEMeZYHcQX0cUGyNGpsbNZRcTjBDu72npxeMLzbaa4omyyuZvtHsN5KvoL0i2SstfUeyfynp8zONLyC/YUi/IdlvTOkVtBeQe5IDzAYYU4sEO3BbhLu12cE5bZ5BspxMvBuuNLaTT2OXKNJsmgFSIpkUnE6L35XgSKIMYoJ8IBlda5bGTulNCxpgliANMB8BO0ApUT6kbImUvX/nQgptnmOMhgxPokIZMaWICltkyXlf6zvcdMHc599PwXDLrjeA/CtX7SgndTxkYQZPLaXRYh4yaIOlxRCMGnfQUmvUNMqhA64TyqELSoKRIYsm4pPAixsOKeOpoxzWRk1QDhMmO8QsZn2Na5TDMr5EIhk5PCENL459Srvn0exvTOk7LX1jslcwvdL4Cto3pBI9WnSckdJvNLZaI81eo76YvpEstcX409FgYddUWUZXC0mcpuZhC5qINPPHu43dvFUB0FrQcxjkA+QDwSRwgJDgSjAOFEYJRzgToKF0vaPLHcdLuc4EMoE0kAOMiWZmE5MdkXiEcYTbpEXjRIz6YB4rGJ5EhZjrln1UOF/O+lEzAHtXm9wCyA0g/8pGDYqSD4r02Th1jRpFo6YBkgtMaKl4pRxmTaVRE3VHcACNsCy4hJQGTIcPjIzmjVI0ZhzCrlAOq7pPTzn0bvRo9FSkttY72RBwHIRjgo0TxidPz8PA55TshUwvNHvlkH4zS39DgF13YYhDmH2LdDkAEuQ3kC8lWnyC2UjaGKjcNVWkReS4TJuxLKrWcSl2qKD+ffeqOZ0ihs/RKI0xhOU0CKkOiUseMmcOA5noPihAb4CYKCaZDYAKmHpEvuIAs5Hyg8xGmI3GNI5HH3cfPn1KftwRXrQsaxe6jwpbp9sjyrWabnfzszqNCl2LSLQ1fFhS+cEi1t3WBpB/9+ixUuhOKYclovREpOM8OmOIiI9cUg5DG/LQmimqrBkGBFbKobyqPtY0PFg2qaMcLnDg5LhIMRY+Uw5rdAtgkNnLgUP6tOF5sv3A9C1Z+s3S8MqUXkh7jXqifceQvsMsmixM30C+wvgK8htSeiH5rTRkvpfbngAOJAmjtWix6zjXmmKNaJvAQz803wPpXFxdnrUUz9X6NewjzWXXO05UMsBGSCNcx4gUbQS0g/sEcgI5wmyEYwS1I5QV23cwTnBOJOu2PYEsINNsGvKQn96P+Zjgb//ZcprYGicBgL6MCCsl9TRF1gyGfVSo0vDRYJGKr4z/bGsDyL8kgmxipyVKi8ZGZUIE5TD4yx3l0NXogbVRQ1oLlAgid5TDFg0VdsxMOZxfR22keO2Ol0ZNTzms0dUow4GOZw9Gt4MmID35sN8d+ZxqpJjSb0zjbxxS7TTXkZzfmNJvsPQadcUWQb7C7HvUIUtaXSLGYJ90tUXyvLi4YIYQ6IByrvXqvKjGC8U2dpVilU+tpuOpfFjugJkRGuW+gyHTLUueg96ECVImmSXlKNsyI2jzU8AzXULcJmSILjED5jRNyZV3U/KXn9nfPvRBufrGyXpUWHjWJ3xqWVAR887K6A9XGz3WcbzNN7GKDSD/Qpis4rlDbdSMNX32og15QjnUFcqhO5g4n/g519tUBqPdc6TSRRuyNnJqJzsJmOgYZI1y6F1cupPhwyYgJ9t5SkTaJeNLYnrhzl4taojfYKk0VNILaS8FAF+R7BtS+h6pdNlGey2/RzptfCK5g1lapMEATnL7lQinn6w/AfhirXAeWhXw8/qZnQBph43tk6c3ewtAA4CnUqrNJF1kjujRIoRXqPqAnGBWwNK9gOZUznnRYyMdNAc9w+B0aH9E/tu/Kr+9+lEzvT5q0bk0V3yuJsRMZKTHbkXG7OQz6wGwB0V2Cj7asusNIP/SGiTqzFmk1VWlJmlGBCLP0l41XSwNnBrZWaEcsnwNHkUwGAsYJsHSCeUQYQDmcOwq5XAyTCaMLYWtaucRNO2VeKQncngelJ5pw0tKqTZXXsg5GsQwfGdKtab4DNoLkn2D2d+i3sgy5M3XEjGGlBhhTXGjfUxcDfRaCl3nWQwz0J1OVGu2mJgbTDYDXzoJx9RHp/GZN8ohu46GEZANkO9Bc8AzaBOoDMKjIMiQOKsgWPkwpIPI7ScoEi4iB5Aym5lrUt7/nqfPQZ6TJssnUWGaxSrWUmSqsLRWokSsRKGN+SRujewNIP8xVqMclpojywFAzLYF9QCt9UMWyqEVyqEtKIcxGM1JrZOd8xEp7Zp1A0lkBaPm3YBnGY6cFplnsXYwN/LZx6fvenrGwG9mwWYpIFi6z/bCxG+gvZYI8ltJoV9gfIbFSA8s7kOzVwD7Uo9LbXrbeAEI+0YLunpi1502Ow8S+yutR8MFcAo6p6csOj5YgCWWQEkQO6iLBJeXDGACmRURY+hE1u3ABDBqlrIR1A7gRNok00TDbsx+fHrD9Pbd8uGbCcLVFPmeqLAHwrO3j3Ppu21tAPn3jyJLSpQ0Uw73uQjjJoKFctgyJPcYncMsLZaYcPTphHLIpk6e5dilAdPxs1EOM4SRhiOEQdEdPaUcgjAmSwlpN5JPNvAbad9Ya4fkK0qUWBoqLzD7VmqPpRljESEanyP9DjsDGF/Aop7DhQrHEhA5lyPmkIjz9M5ippHLuqL6dPvk9xMcpDpFJMxNn/aArs6rOvJTRY2NkGigxgB8ZJBHEDuQE8Bo3AQY7kBWwAwbB3CkcZRzB+IIsylE5tNIYGfExGncPR95PE4+fRimlNF8jf6IqLCnltJLXdznz2VbG0D+3VfrZFfRB5872dGoCSOq44Jy6G2HtmLb2iiH5T5tjLu5HAo0a5TDM7DWMtjyoBymIY27RD6b2XMRh/ge9D/7RvKlpcelpkizVyS8wtIrLH2PWUeWYW97QeJrqHenl7Au6LLeKsWGrhlzFsydjuU02t9y8PviGel2e7Y1d7qm1VyILN+DV0Xuyl2y+DKlAbCR9AFmO8EngCMzR1kBQnEEeJRspDTCtFPSERk7Jkwi9nTPgE/FnWeitMPAPDqm17fJkVxTQvC0L0WF5ReufA5trLOPOisYllFPT8S027jYG0D+hRFk7UnX6mFSiOdWl8PJUjBeOINH72zXLLZoHeT2CuE8mRMMgOUJIFXKYTYVN0Ifnrh/5pBezNIrYw7xpUSKdfzmhbRvAF9h+AZLLzP9j9+Q0jekcjvtOSJIfgP4XCInsAcq8nK9se9anwAie5Ds0+/TGuXiOVdS9v6uNtcYAwwLCFbZotoeVjdyZARgpuwjyD2gieSoKB9kyjKArLBoyCHxWy5uOWZ2zEuLusSGWWB8KXSHAb4/mPBD+v27Phor9EpU2INhBULT/Bm7ET6iSfp6whmne1sbQP5lKXbTdsRMOawuh30kdY/LoVpbZ6Yc1vk+L3ax7jlYN61+WcRzRXyY8zXvxmEYnxKGV6bgPAP2EmISjHojUBkwpdGCOvQdQ93G11DcwbfClnkR8EyzZwCpAZCwmk7fcWa5L2rsgXIBnKdpNpflxh5IF4SbWUC2DlbLrEz1lNCLGmC2j06ZZkNqoa8IYhYYK3VKQTPfvmj4EIGMQax2Mnki8+5Af/7wfNj7wa14KXaZQANC74oTVgBwDBEUH9CJU8yPpUfcSg9bXubtWN0A8q9OtcNhCUlx1OXSlGlJX601VkrfCeXQgRn8aAvKIYvFgmvuZI/DALqCUUMiy/HkRgC7JxueacMrWSLASKVfCLwUEPxeosbCcLHXoqzzjU2CLH6PemM0aEjuEPqHJ5HahaLgSTFiFehqHH62eQU8yfWI8fLZa/X5iE4+7EShe+Z7awQoSF7a3oI89HRi3CdH8E8HmNs2WgYxgdrDFHOVhuICzgnME4H9IOSnT005MWvQlKYKvWWkp6j0TEPRgExdQ6ebHaMDqdIKs5rqz2nJZVsbQP7ljRp0LoFT8WcxlEaNF23Iely7Qna/iUlUvvU55TDm9RS86zRgmt6DEyNvquAC0rNsHDi8KKUXtHlG+4ZQ2SlyZEV2DGVMJwa7X1qjxkKyDAwhW6SWUu/CyuDkzZ+2y09T7AZyXZTG7raODdNG4XtBitOU+xqAXsJmXkEKzlqYsBApDqYTCShSbbMM+QSzHeWThGPpWGcQI2g70CeQR5K7YNRogjiCGgnsREwghpmVo3Fw2+0/NHFPPz7Da91QaaW7XaPJrPaTroUv9ql5Ysdu3w7UDSD/ARo1JUK00smuHO1shOXiKV2sCrIcAzsPmEI5nK5RDov9gjT7ljhE0tLTsHsysxdZegHthWTrQkcEaOHqx0inafY9utB8IdMrUv97F0HGY8e+C3yxccKVSG8BZNbV/dCJTixT7kXz5ioYnozqXIs411g4beZydu/pRTMQJcORKHVIcoK4I3UUORGYRI4gpnafUIkbFaLrE4gjYBOJUcQuuuOaSB5Ndtxljdkx/XiVW52uLN40lmd1cKtakDinIZ6CIRfSaZw52tvaAPKvadQAPeWQjqa6bRKOZhgVZl81nawmXrXmGOm01ZnFmG9slMMyDK04gIOAEY8fPA1DGp4xpG9geo5h79qd5rfSkAnQrCl2cKWDAYMuqmSpSSa+lLnIpwhh1wDn2jYsGttL5e9+5OYEKC81b26B5KXXsjA/6wbDy3fULILMolzRasZR02AEvSlAkVMBvSOAEcQYGj3sxoBahLiDFCNAsB2gwtu2oCiaRkA7unKk2j69f/rEo2T5clS4PA9xtlhozZslGHpRIs+77TjdAPIvhsnwoTEM7kgSDmVqBPKmvFNtEFpXeiYglqeZgbBu9drAqdqQlXKYM4dhGJiGZ6ThG9MQqTLw2mqIQKH/pVdCRZiWryC+weqYj9VI8VsnYPuKiJjGRbh1Jz4uDmNqCZK6kvOuNG/OQPJiyn3ltdWZSz9piplDnfBDWFUUcKwkd6cBGIE6D1l+kkeA8zbDEc49SC8d7glmR7jvC1jGdsOEzBxtlJwJ5HGCf/s3Tp9ppiGupchtTrIAYT84HgrlgO/QLBrax7YVIjeA/MtrkF0SlzyuT12jpkrg991GnVAORcDKrGOl0Dm8MWrC5RBIw2gwjmm3e0EaXsPyFKW22NLpnh/9ihpVlq513IbXIlz7isqeIZ9o3M8E8T5BXQO2C+IRutSn0QozRg8UDnUmc3b6Gshz5K6iwejEMNpAO3UuylsRMpBogHEHVaaMjgj2UDBsGj2RXpo3s8BFNHWmMvw6hdhF5XnT4XTA8tM7nvKLNCUdZyAErPiYz4IVRbNzDMk7txNBI3UfE+fHbGsDyH8YxKw87GzAmJeS/wvKoQNMbJRDVZdDz0iaxXNHFGUeF9xz2j+/7DkML7DU6IEgvoP2CvC5a768wvgbwDnt7uuLxhgIJ56RUhkI53DWjOkaKOuh2uXq7Hz1iv9oHyZWoLKV5s1a9ElejmJ5GuWrWGRrZtAUqbgFolQQrq8h1G1HsIBidKy9ux68a1dwtWdwzIXYlGH0xuUuEmmwlAFOnPLOsk37g46UT5aL9m+JCqN5M4/znEaFvTf2ormDUoPcIsgNIP8hokiiyEfkuVGTo5OtRNh0QjksNgs95dBgOGqmHNYok8k4piGNaffEIYU2YwhEvBZ/6W9zlMiQJwNLBGnfQMQ22jPIb0ypmGgFU4ZRb9xdjgZXLFV5IfVt7L5LIzxYkaY5AUlcS+d5IejklUbOaWNmQVcJ/ndhOHXacUFBdAPoBtoOVqTOqAKMjPEdZybtKPqudLOjgSMbI/G1ifQRxCgxapXhwR12ssQ4HDlOxun9VUesRYX9V2KnJwGe8LUFTw4fHJ62Ls0GkH/xuko5LC6HScCxWTkXymE5SGfKYSqUQzTKoQAmS6Ol4cnSEGM4xm8QX4uvdIkWESk2AijJ2pCxlmaTpcaYwiYhHmv7JiPUj+rwJBLkJYZMB0Z+oeh1rX64FkneYh1eUgVae23dnUktM/MEMBtkRYzYS0Rpc/rPVIRFpKRozIwkByQOoQKkncyOSBopHlWoiNHZxgjwACAFKGIs9d0MsyPkExIzpMnc9uNR+Z3KVDHOxAkrBh3rprxEN4cPOQCxgqI5VBwqt7UB5F8eQVbKocpIT4BhoRy645gGjNVfmlpoQ85DJmod61nFkUZyZ2l8YhpeYYVPXaJFNh41OhC0l07l+3uxO4gh8Jpip3AgLAerLWt8p9YHvCOFxUK/sfeROcNE/YlfxAIQT8d65hdXbW6logvpAOhBpIkRn/iubCZ8SiRlIwyjpFAYN02QTRCiW610hLiDFOmzsBMsQ17qjZhozIJN8LyL+iUUabjnQZaf35Q/XvUZNPK5BinTDIJddOjmjcpawkeYE2lKSNmQctoO0g0g//oUu8magUgufFaXQyxrQ+oyO501GaJjrXAZtKe026dhfMUwvIDptYsOq5rOa6UPkqWDDb5Eio0XgK80fgfTS5Esey2jQK+IjqytR3q4PHR9rdzYOtUn4KhL5lFdmn2JSrhIv3kHOHYAeVKTa7NYrnn+0dTKruEu2LhN85sTUeZ+UmvYBKI6pEwhS6UWaa66Pc50RY08OtlBIqSKOvnMxAndJ+T9IU3TPk+fTz7l8bgAxUVUWJg35gZza2AYF2sSaNvaAPIfDC1nl8PcXA6FUNPyNlAemKBqP9odlobJJ9sPL3sbdt8xDNFpZhn2BkrXGt/mSBKRTgNl3KfYrLINfL8Go4ZhhQDu7qJYPCJ4cDev+s7nuxXFrgnytlopz9N/aT5bEUAimHMrj7S/Ue7DaqpVO9tWJ/stIkSVOmTxD8SsQp5BTbWjXTrWRR4t5iIJTTI7AspwTlDVkfRxEHYvH3b8/PbpP//24Smz2MTaIipM2WCeELfPJYaqi6lSQyU3Js0GkP8gUWQ9GBvlMAG7Y2nUcHY5TPVYlYNIRcNHcDjHYZfM0pMNu1em4RuQvgF4IYpeIxAdaFhEiOQrYK+lKfNalL1fmSK1jm53BUd7KjJlt6PC0/usCVGcguKicX1aT7wkNtEB1K0Zx9XIdm2SWkuwXESf9W/5PPKjlaiVWvjoFM1IIIulNDGRnBRd6bEoHO1ozPI2EjQWDvskaRfzkxoBG2m+A+woaAyQ1L4qmSdhennf+TTiMOSkNFmLFNE1Ymrnmtap02MDxQ0g/wHXrMVYhFClMOwCYS54MlhxOURxOcwusKj/JIHZOI7j/gnD+NpYL80Eq7BegjIY+o1FiKIo8lR71dqMCRuEVLQcgeewL30AHO850IRVIIxSAWbb1VvqPfdEoLzyurjyuk/GgNqoUKcRWcewUJoz9Jmb3eYnuYxKCaSgH2Iq4rpTaL+HwjiJ4GQXaTQVNXJAuejdldS6EAhpcRYtRWk69fJjh/Ew6v3Fj2U4do4KEeImVUVq/QvhSclhWxtA/oURZNOGZIx5mxcwLLWtnIjxEATdefylb9SkYbd7Kt4v6SXmF/FcGDABkORzEY94otkTyKcSMbYLw02w3GbxO7CH2XBTBecRYDytPV7CO115XKvx6f5UfK0Jsxjb6cDx7KEl6gqD8Koc0qjYdQ4ovpvz+ZpOAZMQRgjPBCXWVgpV/gjn1L4PaRWhKFQKoYlMZZzLqRD0cKeihjhm+XGStOPxelTIJpnXAPehesa2NoD8O8BkjUas1CEnq6M/wpGz3L/OFBmQOKQnDOMzhCeATySfQAS4oV7nHrQnxvYKkPvycwZN4xOMzzTW+4wXI8YzrcV7osaTIfCT6FG6cL9rKfc5nK2MDHH9PRjvfOm9M4SKnWy4UM7q5mi2XI1N0/4O+lpkgrAvJkNFOBcOMxQdSQ/JTjljLAGKAcYio1Z/0ilJpEOMmiTcQU6JmJ4n5o8xu6g8fwbF5eK0KYXzkQFtEeQGkP9INci6i6aCG9mAsUnrn1AOBcidwzDuOe6foPwE8Bmw8jOiRViAJsBnEjVafAIQ95nB8gnWRZSw5wBVcE2k9zoonk6F6xzoFpHfnbJkZ2bQddDpWk59X6Tb61JcfHg/62mITlpPOaxeNdWeQZ2orrMMlQcmKhwc90ghmkshy92RKmumMGrkEySnNAEaIeygdJS0AzxHJ5zHYOxwB6RQ/Uk8DoZx0DRNzA4mXYoKtdgHefVr2dYGkH8tWrLrZBeAJBQuh4U1MzqQzEhLe9rwBOkJwhNoBfgUUWMAYWyjngtQ7su2JxBPjIhxD+Kp+FI/wdI+6HEFfR4p3J+msTrpYtwY2VlV4lmjFN5VCL0PHMmVSPNarVKlzGEsNgy589U+oRuiu94MvwofUCKdOxknJAsZNGmibFRSKP84dtGx1g7QEdIEYEdogjBJOsIVohhmpeONEQyfmx0sS8c8UVMnhHceHZ7Ul0UCmyfNBpD/eFFk7WTXRk0Rz7WgHGYL+4RkaWTa7WGpRIn2BHBPtNR5P6fZ2JWO6K7wgvfRNcUeZjuQeyQr221fHPkSfrWj2RcT9Ug4ogduuqNzdNqEIdfvwJO6JK5Ekb14BZfgR2cwbIQyN1ll0Agli3YMPRRGwpU7xHGFidKk0CuZypjPBCiLHt3qiCqPMWBuE6ESbTK3pg6UBTlhnkTfHZWnYXJPJedfqKDXRlPvrU1shoYbQP5DrUWjxkPZJxo1oTnoyTAegUMyaBjsWWnEYPui2B3gZngqPtO7th0FCAMw42K19lhA0Qpg0vaI+44Pz3vwxhjP4x/I1Vrlw6+HNyJHPlBH7SNNI5AtZrl7S9iyrbf3jT5LQBeLwK6QEsE9oMzEo2A7Vt9sY0bmBHkmkVXqklFv9OhsU2WbHJSzno0IIZkAaaDpRaY3TJ9ucNkMiMBS1acGwEmcDb62tQHkXx1BqmvUpFKHPDTKoTAl1mkSM3EH2r6lywX4iC6tZkmnWaLLmGOMNLs1ZSy61i215nOJLtOXQOgWOJ42YLQEPOlK3fIesLr4Oy6o93AdPM/ENFaA1oN2qJo+O8NeFyp9EsyptJe5SYtZRJrHXCQtABNMwLAHsoMUphDlgXtUMkXCS2fdPQDQoj2DuJQPrzPPiYF2FWEnH5h8T/rbqEOmWn/cOjBMiJ+zS/hWhNwA8h8sxe4ph+ooh3Wa91nDSKUn0BrYRW3RajpdfscTWNwEaxMm/GXKOE9cgmfNSifcL5TA7wXEe1LtVXC8kguf1h9P/bFPX9OqVezaS+f1qPEaTbKl1/PraWZZsJB2rNlA0eFkituoMEqbtccK/yk63gS0K6QpaHAieNBOZJfMm64d4YAcromQwz1LyARzKJBjAjDBUAbQ46fRxh25m3TMWT6NMMw0bJW2uWMqFh0bOG4A+Y8Jlc3EK3bQyYB9Lmf03TBEGpyekCLyK9HiC/uZxuIjQ5b7lJlHptLEKVFjzDxiX67vL36XjwDjGUPm/gNt0aC59LgL5cPrjZcr4HitVolrf6uOJ6JjzljURtrrLypFVjjZjjbqQ5TRxdo9T6RgI1xOYBI0gtgh40hpJ8dU5idHACPoY2nYjNGw0RDbWTxtNACFpWMYAe6MnF6AacoH/7Sjq8WJzfyj+alb+betDSD/gaLIGiSx2bzmcsMoJRuG6FqHx/QeQp1ZrHXIaNCgNF/M9rUpQ2tD37sKiESpTQJj0Nh+sSuzNrt4mlqfDHpLK4+/ixlza9ToCqrySgR670fApYDunKYzxnhaYDin2oTHPKOV8aRUHucRFNKYxDQAGEmNiu9lh6yJxhHwSW4jgVHCDtIx5lQ1wRXsHARoAtgXm/QJQBYwkbYbwEnK0xEfbkEuREKCgTAWWKRFOcA2gNwA8h9uFRMvX7gccnSOGNK+RHq7SKWxh7iLg0HRfY665J5QgGMZEI/HcNcAFK2bXZ+TFwGHJ3XBa3XFS2m0n9NjzqJFfaEBczNy5PUI9FdKCD0tEaUeWecdK+HFBPqsGxnzkQZZGbQxQVMZFzKBwgCkndwnShOYJtAnuU9AyjTV2ccJ0qRo0ITIBZSLj01QEUNQPsMQXW6ji/DBzJ+y54Hm7MBQRrgx9jnDNii+AeQ/VgRZlRwr5TA5cEwCmEYwBZhJT3O0aE8kS7OmMGWMzzGAXJkxFg2ZiBqfYfZEoDZnngt4jlebFOgpkV9Io3+VR32j5ngznb4FhsbHQbOfyyzAyPJcKu6SoXbGAnzsZiDLeUIxRM5kwc7xQsFh3pE2KTxpJpBOs6yoPZbh8RjnobsQoz+5FDWn+KrowfVGBjGRFkBpdHLIrwccPwb/zKlojZ7MqVrYr29rA8h/pBX5mpMYSh1yhCUbUpl3tKdCHXwGbE+zfakxPjcWTEodMNY6oz0h8Zm0+b7RvHmOOtVpGZRXE1VV0PA75hUvAKBuWbHeDZzCXfOPi0j4D4gmyeUQfN9EKr6vKCK66lPwWoP00GhsdcrUE4VSAn1PegYti8pw7MOIQxPEDCGLmMpw+B4qTRpoV8QsolZp2JE8hlsiM82OSBjT8Lwz/8xZ05QU6XUCYcUJc2NibwD5D1uDrCuJ6bc87Gcwq6wYhsJOFaGoTZiIEJ9BvsR1vlZzLsaIT+lWl851FPQXbBleAged9DUvpcXSn/8p3RMxPqrecylKvHeUqXc3NBYaYh+SYaZJ1qaNGaDcGY7NlgiiDTGwr0ziKCuRI0LlB9KR4C5Sa2RJRxA7gsX3JgbNy8B51CeNGYk7GDOGNO0nTfspTMSKTBAiDFULcv+2HZobQP4joqUIe9W4DwFbe4Y6Yy3wmSygSQT4mT0jxTaWn61RY71ARTBuYqRnNq3mIynyqUDF2u8rXtX3l2EvRJe90RTvONvwESfFC6/hEkieqpV396vU0LaN8/OEgpu6Jk83azlbnoM0KnMEfQKwD+Xx4q0tZbhCNDcEdZ3QMcCwptUMMI1tU6TXlklGqk1mI48ZyO/5cOizBj74UW1rA8i/WxSplmYPg7E0WIT9TBG0ffhP2x7GPRP3SGkP2B5WWDRmu5kxgx1phWbIXYx9cFd1rXhvSrkGDg/nYV9kwdxMq08Ebe8N0/mYoMWq4O7C0kHLKLcqkPcMG6F0h1WMvkpXuzZ15s+WHNIAZ4jhSjlSawWLxqIG2eYeiX00aJABHEuDLsNKoyaAMaLICp5mu2Q22dtxIgsNkdVJZwPIDSD/QWHSgDSkFNEfuINxT7MdaDskq6M6e7JQDYNPvWNKMzAad4TtQOwa3xqoNMT0JWB8NI3mWp2yalpWa9o7sbM1jHkZ9b4kqvGF2gdPJsd7kKzvuc5F0os1RklcC1cb5mGlES5fpbFTHW87NQ6zEcl3yB4ptWOS5xj1gaLOGJeJqKM+2CG8tUcE72AE609O7THSjsbjmIYj5Idea4PaAHIDyH/ICBI2wHahqMOSInMPS/saHbLOMtZo0orARAx+72gFOIsoBYAAV+OeKEIUD4Kh1sDxFqjpNNqcQ0498jwXwYz3RYf31BxvDoavxKsNEM/rlqTmURmvwGjFilWAF3YNZtpigNMchRYBIIMwyriDa4JppDBA5SdUZlgxgRyg8MsGkOKnxhJRhpd28HkSFD8lDQOYMBWieP06pPVG2rY2gPwLAZID0xApdNrDsGcKYIyOtdWZxT0shWdJ4pw+G4eWRofwRJ193MGwK+A43AuKvxRN9pqPq/Pj/PMaOuSvF9F4DnoXn/I0Cu4iTJKhCVlR1LumjSMUfur8pDSfRBbVAhvoGgAfBA7wAnQqP6kBYgrwU4rvWAlCApliOl2p/NUymEQrKrwGJpMmyiep6vVK2PrYG0D+dWDYFeQ1p4+WjCMtjUgWF9oA4xjgZ9XgaYQVsCMHoPwkRgL19qHwqseiCj4ATOCJOu8jlcNTJsw15syqWvgVHvYlZfJTIy3cEQF+iRXz+G1nJdhe7d0Qw9+Nb118bNgJ1KYaPWJm13hRK2/lhyInTiQYE91NNKNkCoBLpS5DiEbQQFLu1kqJhEVxWzMwtt9BDoNp+jT/OPjSqGxLsjeA/ItCxWkAfIwJm927h0iumTGlAWkYkAL0aBxBG2EcCyAmsl5HEUrFDiw83SpQgHJbjHiMxa41PRoU6FKkeEuxZxVBrmznZdsE3hzVeSCVvicNP7mdVx4X5ly87o1TGzRFeYRC4WHrZHCcMQ95irphY2nyGFLkbOBgIK2oYaQicGyAjMYKoFYiyfgJDfU+BVwHGBOGXfJ0mEArehobOG4A+ffAQi41Wi0BBziOuwQfDGkqFLUJhHGHZDukQhlkAb6oHwXgFQHccmmWoQCLKG67rT52BLhjPP7XyLVfzrhOGjN3p7+88Tt+mT5+Czx5x99r7oY1NWi+NCuCwU1jt+hEOtbl1RbMzBBPA0vKzAJ6YJrBjgXwPLaLA6VB7kOAoyLLqD+BYU7R02jD7pjH4VgkNFone1sbQP6xZS9eEK3uliGMPlnECmQkiB1SKkK3KOM5AXyo3OngU4/dyM6+AiKJuRaJrvZYQZNXmGPSdSy8Gj1ekDKTfg18O8vXuQTY6UX20mP1g+8z8YfNxPA1K9sSPXZVxw4IOxvbM+/sApSmog1ZIshqs7MAyJgcJ5hgSJJGOo6CD6XGOBY7hgG0AEFogDCQHKTSqFFr0ARARkaRICUKw8jBIHn0kTaA3ADyF6PC0+t34UBT6FeR+AM0kLQ0YEi7ovK9Y9QNd4sLuSOxn9PnqsbD9jgQI8wWAEnw60o9a3XDi8PfXALm4ml0OQLVSV5+Zs71B5y57gXpC1Yt7L+8CyB5cUeRgn0IzN40laZoRPBYeuoiAjQbP5qIaNEHuI2UDjAkRmNmiGgSg4SBYhJLFGnZICa6EsTQxJ3rltaiUiE5xAFmyDmMa7VpQm4A+WCK/Idkc4rOJeUNA0amMcAxOtBRY8S+ixR3MIvtZmNLrc0GgANrysSqB9jqlQPjerr5JrsDXGu3XRwKPwFFnYeDelS+rOLkNQXwRdj+i8C49hx1XOfK61sC64qxWKs9ls0dSBKaQdDURYroxn2slzwiYEmUQSpjOrWu6AmA0d0AJXoy0Q1uBriF900YLcDNBI/naPVLkEZzIWE6HsGNib0B5B8YFX6lIkcBYwYSaGZWO9Q90M21ImAgNLRu9HzbSNYuNUMgFYxmjWEHcQcrvtbXIqCLDZcLmo6n97klcnsRhGrNYaWux2vK4Q8yYK7dfmV+kvfc/+SxrWnTK483OmEAYz0zUjOaVnzkqUZmD7gSaR6gFl3qBJcBiapGN9HxNkZDx1TVMQxW5KJsblGrXI+fTAkKVd+tgb0BZPcG/s7voA5Q2OQYLaV5DKcAnjCC6tPkWdKs2ioUx0IBT5T2MDyXbVXt5xnEc6k73QRD3QOO9wLrCtjpUpf3KjCuRYg36H+PjOzcy0rUHRRGnYIkTmwjsBCl6BBxlkqrVUyd2EzMNxlESgrZHclAFRsuWknkQ1ySMe6D2sQJDmupenO5LVL0xGFIPljxscWfGyVsALmta2l2MgJmI20oplpVrYcBbGG+9QyEYo9gz6xKPuQLwBfAXsr9Q9ACKD419sx4vuER0NaltHuOYG7XKq+A5EMp96Wi4C997idAJ6yn7F9J17lSp23beSKHdgKcpuUMJbCsSc7fA+GWSJnkBi+D34YEZyJkmoEwle//jDnTmjRAbeiUcR8bOOwM8jAP29YGkH8JPgoY05CQdk+0IaTLtJAvewaKbmOA5p5W1Xj4VMy1omFjnJXBg01T2DYcFuhSDzZeBrbFMf4IFXAVYR8tcXwBCPkFIHs0erw3vV7ch3NTB7boSuuEU77obosnNcyz8wVb53nuQg8dGI5lznEGR2ko87ED5P32erFGPwQGmiVNPgnaypAbQP5lywDbFwHbJ0j7rimzbyl1a9hUr+syMA6OIV6BodALB7BrzLDOx50cuZcGtE/51l8uHOhO1HxQoeLB2uHN7V9t6twKaO00NT4X0uBC/af8Ts5Ne52re/cKPyUljrEdMIGNUhiRYwVQ1rlJWLGGteiEy0p3qBhzK81VH4cEunubpNrWBpB/fs2x1sRn/2VDSkEFlAojJlgysZPTQCaalaYNE2gh+wwayaCRkWUouLgvRWXKVg9jPhjp3dJxvJom8wFQvXHbvdasX603XhCiWE3L7wFldrYUXAHW03lNzEDZmuF9CHmqOVlmuCkyOtp1XKcMjKr8XHzdbShTi9NhdCPLrJkXnrhhom/1xw0g/xQoLPtVB4ZsvvJRfspAolk545ezeJjKtR29zqhJhBnLfYNeRrGMZ3B+DIJjrQKY/Bpj5o8f7tAV7NXt9NpOo7A/MJ0mb9+NvBtYr95+OrzOlQ+9NHfOt+NUBINoTyMJjIFa95i3JCGSgYrtxCyYAe5xCoV1NWUS8jKWK8BlFGgubVXIDSB/JSyctbhXgFAUvOxh6lhoMXRBErQQFKgRISsoVtCLCFFIhWdbo8WhCBeMUTdSAi0Vb5lyPz02p3Ft0Plsu9aBULeB8XrN8YKT4iPp8D3p9DVg5BfHh8g7ouprn/MMknM0WbnoPI9mibC89Fbu5Dw42g2kspyxFyk1SroNwj24CiqD6xIJYcj4k60zNoD8326KjCUYegHDyhI79XCqwNiuG81gg1TmG9l3EzH0Iz8QhmL6XpV5BoEDIzVPqCl4KbwTLFqAN470K6Hi8qYbPtdn2++tN57pg11Opx+NGB+sL/KR57p3jrSf1TxLtbl8rtNJgf57WB/SVzG/nOV2GkUHlPt8ShYgiY3DqFhF7LFPe+IOwxA6P0cD8nFLszeAvJYir0eFqiUbroBff8x3B5PIJmYwZJjYgGyUOHKuPRZJMo6k1WHwrkPJgf2wONBJoDVhitvptc4P8NU5yNUBcF4AO8xNilMwuUgb5IoSz+m2B6M6PQBsuNF3+cqUEU8+5C+m6GcBec+o0QnALd/n7DfLk+InSRpNDkIl3fYyLG5R1yYH2n4H7HdhR7utDSAjQ12PCtu5+VJUuJDbZwFPzqDYgSMgmhfmy6z8XJkzvTx+6jrTPasmGjhWbouIMYEYCKujGnb3kXcPg+ZWqtiGn3GiIM4rEavujE7u6SzrHHAeALaH8O+ujjgvn4luTBEsyjenJ63ZZpYldSak+GmVHWOxzRHy5aDRRLkZVIbHi2aajISMoUOJMmAOg5HcDxS5dbE3gIx1HJcp8mlxmheiQnRAqH57N6ZBAKmoSJvLQvCspdKJxjTLWC3GdEpUiQSL+iNtTqeL1NUQ4MiQ14/n5FVQPEv3tLR17g/GPqpbOYjPUsirh5TuRCWtp6fXRn7uif5Wosi7qYRfHiBf4VaudbYXpmOYudv9/qTF37NyojR6EG+KmTUZ0kAsjyNoRnoR5ymm1yajF+YNW/sw6pIpmaaJG9dwA8h5t+VJinwSlaxFhOJJSFBEpM0FK/oDptn8aKKQHBYAaKns5DHH2BTBm0J4iRyt/R56joWvzSJYYZzT686p8CwK5LVj90KD4ZKd66Vo8lFfmVtAdJVeyMfCwXsbMw9NJz0CIPfRLBdNlr5hc16LtK4OWZy2C32QNBiIXFzDWFNoI1yRSjsMFg1Bqj4WRiKBljrtoW1tANkD5bWocN7RKcA8GomnQMgTycIWLAikONCsT5lDXKLWGFvKXRR4qPn2XsgCqhYLJaLkWNRZ/rjT/urICW/PP+pe2s0VsLiHT303mF3zkuHjdcIvf8KXBukxa1+e1mD7z9JOuYow0AymBIGwAoSOUPThDHwwhTQakYSSkgtGIUGWGIrk/aiZxQGwoeQGkADyMNxMkXsgbNRZ4YxxIK6DTXIlkDtBA6WhjeXM4DgCGJt0mTQuQJClo92zZsCui91Jml0DKd4ZMX7l2OdKREqe1wm/0rj4EhXxzsfoDpDmpajwkVoq7wRPXa5Hxv5pkKWoM2IeFu91Ho0JXsbGWHxoiKo8Ps/gAjXKjG2EGcyU86Z5tgFkLLdo+FEFDNEBoS5HhdeODXV1S/OJgAXIteaMauQ3G2+BdXsFvXkUqHa40XFv5/pjHBiXAO6s06uLL5h9HXIBdDitgy2FFewKcNyTxv5BPOqz90RexMA/Bowvdfj5hcc/9Ak08kDQCWmwwqxRFwkGOLL9nEE0tVTd0bTtY04SxLSN+WwAWdbT8Twq7Hdd8fZxeP1go4E2AJYgjFKbf0yd5mPqQHFu0MxjPgvQnB/TUnTe9QJ1JeO7dbgu5pD14AdxAzOkP/6AvJZeX3xdj6TVp/Oc94Kj7svAL/9ZFuZURH8qHOsZFFmHvsvJrvpWnEvhVtXezuZVBhzp3AByA8go7+jBqPCBIEcAYSmBqZgkoShCl2gxmi61ez2Uxk0vPNHVK2v90cYSPVbHwvRYoKIl6i/k9blus3Dtg5BWZiVX/rBuRGePguRaNLvaqeb1RtXNCPfRbvUDe8c1kY+T5vb8aTbB21rADAa2Y/4ioxvOLpVe/7wXX3yVIaLlTTN3A8gvR4VXoKAOkTvisiMY9aLqIseRxgp01dq1gKLNzZdeJTy8sUvE2SLHoUuV+Hj6ttJ51pXHPDIzeZaW4yaQPYota4rjIq+PJf5qTfOPqH8uPi9bfkDsPzeenzSk5dxEhIg1mmQbEq9CAIboXMeJKWYd1aXntTZZapJSMYkQaLOq77b+2QHyUTCsd6+kLqEMl+O81O6CJXBUrTHS0gx0HNFqiJyFTsnOxlPWakPzdjuPDPRARrfWkOHSJfAMYO7kG6/1Gppg7B0D6GvVQi6UkC5yp+8Gx2sR62ogrMeemFfS7TUOum7UPU6mCBimg31qXT4dUqYY41EXPc71x46euGDicI5LCZqBoHKeNnTbAPL+qFAnoLh22NTj2CTICIrE1DyNizhplSsDQJiExFm6qqn7FJv5viBfo0VbKPl8hRN3j0DFPbKNq7YC10B2BZTWbBZOwfFugDulOGKdHdlTIi+Bl+6oT34Jmb9Yt7l8X56dmYoMRciZuYAOMpuquc+WOL04iMXsubtv6LYB5BIHBCBzmSpfih+s7VMsx7Ha9O5hHLH7PMIMJlZA88Q4PacuEizyZEyFDdFGNQTYkqfdUqOTbXdENLoNkjc72NeA9e763BdrjJcaLpcYPmtR4d0iu3du/MPTdD12xz7gLkXI9rpcVRCX89kr2DSEF7k5XiiJOpMl2++f8wZvG0DiwPuiwqYt1YFhm4sIBYD2oB/jC/afR+Pk0b1m6DRKlbFQ5xlhbGl3qz+WGqSlpbshRzCUxFl52v1efrXWt5L7drOLPB3z+VLEswaouCNqvAaMV8DxV0aD+IvRIHm5pnpt21dwUme/Fi72EiVrs3px0psp3IRbFH1IwJqlrOYsoLowpqZfsa0NIJG7E2kfFTatUVRAzFHJlhpAzjvtfDCYVIWaDY4EFukyVNWdWaWH4A7V55rdIDg4kph9sVGvY8fZ7XBYrQmsAcDpAX1Bv1H3pOE9uko3gOYXOtO883638OxeaiAfiHLXOvlfiW4vPXYxd7oMgVnGcjo6Q1ghigyd8bIne7FwDXL36Q67/GvdmE8VDMKWYm8ACQCJpylyiQyltl/VfUtLg86L2LH/PNBypQpyrBauNNsBCN8Zsxn8gF340mBPYA8rBlzEvt2/XcceAay8O51ezEKuN1x0K6I5HeW5ysZZYc18RYX7RmPmLNW8P2e+oXN2B1heGsDnF+rBa6UA6kQhafESy47JdTk6dc2Y5rsQE0FyoRfJbT/bexDhkvKWYW8ACWDHY4sKy+n0fjA8jagAOA1Pb5+jkPYweyqgtouLdqAVUNSumHPtYWHa1UWHBTzbTGQqqfUsiXb+p3EzT66jPLpR/bo1C4k7WTtfSalv1R1X73sniN2FXbz/5hO5u19aC7C7cPJZloytT3xQxyCFogXZCeqqbicj2jx5N2xpE2snG1sXewPISIn95NDnHQWibla3tmbUthHwofKrq64j4/cdemZMa7hYKIWH7Fk1dK/d6jR3wUHQbrdpz7rJt7UJL+LqqljFhbGgPxg077ZD+EPAsRmAX3+AVj7TSxMBX0fL5d9YNsy4SAeqsk+Z/xG7HZlGmLMIWbCNCVVVn8rL6XdgiUyJrfa0rX9ugLwnKqyKugsgXMPMODCsqPDOIraVI1tNucjEBnizswhqx7tuJQkjgyXGfrznygtYi8wYrnUV1E4aCGemh6fNnUuKPmu/X/0cb0WCvI1n/IWvc7XWqMdS6z9zXfp8z8evoj8YquBVAr9IniHEcOmEifQQk2qRI0m6OH/tZKMq1hkgS3bUBpAbQK4dOeJ5VHjxroxR7sL+EoHkIkWr6Uox5uIcAVZV6AKYpBGsoz7N9rUOlbPnZkc0ao+hRnnRlRxxqi94r+nUQxHiHSn4nZj5kMTZ3f7W/PPB8F7q5EWlcb/6RkPbWTXUbj41JZCs8va92s/SETMAc75NRUKNSjAzsw0gN4AEil8WT/jJK5hZTszhT3MlvpEPQNsxh9nUvamGJ4KpU+cJebPmca2hVwwXMYRgbk3NT10L7ykJ4Ob4SK1irT7naqNGjxUF76xD8lfS1EugxDsB/HbH506Au6d+eSGj5ok82pmKSnUshAXf2sIopPqlCwZ4YV3V7QrFHyBhJiWksu/V/bPN6BJIiXMLfFv/zBGk22pUWCNC8Xqoo05SyzwTk1LImFnQC10JVpwIyQHSKGKg2PxoNDsczp1vFWEKYWw+NPPA+OMBcg9w0nWsWHMrvGrt+ovRxq1o6+8WzDyozMNTEMPFsaKeP64awbMpRMzbVofyT9TGVeTJWKiq3tLrsAaGJdDjpAwZScqQiklXCnJse5FF+kzsMpxC5trWPz1AeloqiF88dDh7setCWsmMZMIoFFuEohAuYmR0pkvDxsIywZpi+FjmHMcmacbF3GQ19Upf1hpcUwk/w6EiknVmWK91Tve90dZpFHTP4PZXx2UeCvluhXRrz3+RmnM9Ib7y++WXd6kmiSpO0UWDpc7YG7abAgtZOoq0SN2tRJ3ejQN1zSe5/lCB+g0g/0MHkHYeFTb/64f8i5ico2wItR40t8KRVbexeV1rDMmz4o+96GxjBsTwu65GX8MsWVP3ZrsJemcH1+nBfNKNXoBk+1M8twZYmkrcD9r3sGp+ZWD8y3NB9848Pj46JF0GHOmKZ40uRKuVPCNCQYid3dfqV7XouGmefGDYxrJeiRfnZUaoDEIKWZuazwaQAGRcgOJXFiWkyQdkjS2VXgjhdhcV/nWzcsWsCr6sVyY2znb5yXs7rTeYHbr1qD461B0NnBuva9EMwtd1H/jAjOKXc3R+3ZPrSpAprZ1QrnwYZ/Jz5xlAU7qdwbDTV5EroNJBeCGUFnkBOtpj58fEdUqkMnxDyA0gC0A+CIarx9Qhl0J4a7DM4MYGfkvAi/GfVFKg0rjp71drRqj374I3XbVhvr3tRm2xDZX/icfJWnPmq6K6X8mwLz7HtRT8yoe+ep7glRrnLbDvgHQ5dtPoL6IVcJMHJs5A18bIPdKOyLBNwYf1yBZK7LiY9fKA0G1tAPkYEK6AjaQoZwtUdqNZmVMMYCRP/ENYZcpi7ILhIpfa0DiUoBjtERkD5EAq3iI3lLmvHP2L8Z4HdB1PZ/CEO8ED66rdX60xfukxl17PtaBXD551eAEd/6D5yiage8auEYxOD8LgLGWG6heLMuRaxAHiu6dFbAkxvA1rfbkSyIwCo7W9rQ0gr4Ph6X4uzYopXUOYkBmQZEWZp3aohehYg0Mx6Jq71IV6qHAzLE0dVvrhrt2XqmwcnqdmvP6ia71SVw74K6r/NzFHVw78O2uHD2XFd4/x3F95uIbv94ejK9+Fvo6JF6PJWXNzKT61vNYjnpbbOz4tIYii0ZVLHRJFCy2I2FsMuQHkBXAsALgAwwXIsDPOJDD5oBCcGKHCsxYHUDGmEw2bHRoQYoxokWnuWvdpOVhqk0Nzp2slpu6o46zAcl/080gKvlK7/MU0+tJLeIhSeEkJ/I8Aopugtian/EAn/JGywZlljU7UfSpItp99XdEhOUOYJzTGQcHhkBykg/BIyymaMkSX3CHP0M2hjm3900SQfh4VLk++TWm5sGYsrrNofrvMjrl4zqgyYJoPMecmTKUZ2syWQSKZYDSYRb3RYqCcjVVTa5RXOrvU3Zh4KVLUtcaO/mDQ6UDhvDFzi5r4R7sfXgLGW2NMt8YGTk5e7GuJuuN0sVbWaFe8NVoIDyJpAT15Ab8KkswQPBo0AY4MSy8XrQBmbexQ8vi52XZtABm73NSFhyWLlYWoaBsaZ9fpLjtq7f2Zy5jdJBqNQ6EEhgCFWYBfAGKwaKzUG60waqqALjqmDdmeo/jXnKo3rId7l2qEPHEt/DNt4R8Yy7kYOf4ZPtlr970YMfL8hgVWfkWk4/og+fl31mcK3UmbnKNHwaFIjVnEywCbz/i19lhri8FOjG3mdQBIceYPnxBCFElY2tBtA0hAA5dRYZWw73ZslsEIkxfR3Dk1H4/ZPCPNEV9REDdLsOJIWMd2mnpPsX61JmjRHAvZ0xKtWTA8UFC748B9NG3mFzLIlVnGi6rgizHDP7E9cFfPhdcdHk8/mBrxrvgG19nHanFwxqY5+6iW85Y6He5fUnYCAJtu5On303X01LFkmoFXgceS6TSHQ0shZDEMG7ptAAnk3XBWj6Q7rIBgD4YrxwddiLTainyZMQFWALPUGclEa4yH1HnP9I6GBhYvGslmjZ8yyc47wFEXNuoLNcVrA8w3QeNPSodvFjEfuvH6+76HT306m7j4CHgGlGvguZpWN5nGc0AlyXK9eln3dq48uZw6Gp46YgZQxnhQsfqSYJTn6c/MMzaA/I+yzL2BYAXEi4d+BUvNdi4MSleCGZGSlf26SpOxjfbADLQibmZF4ac4fs3PVpV/ak5vV6zfrwDjg/7WX6kl6ko6eepw2PHVV7FngREX5NOuzUBeba58QXziUvR8IRXnH6L9+Gi9YAmG0upkeedSLM0/1f+eQTgc0bmWe9bkRz9s4LgBJDBMvgqEqNFjtzuKgFI0ZzwRzMJwFGXNuJ3hXMim5QgjaVX+DAajFVwttcnZxpWzrWvXwb5w1FxNlS+RrU9mGr0eSbrjWDxt2PDOKOtGtHaNYXPL+6XXS7yKhV+YublBtebf2dRqEXESKjaGcSEcKqZJUgE9eeEhZoV2Wq6/g20UPDMaOJqfR06XzLZJyA0g16LCCoala+1V79FWSnBGkyE1KalZt7E2WWIQPDKZ2qFOMzCWbjaaDuRyW7BoLqerp34li1rUyTykLoAkihL12X1XuqlnSHEqvou7vF5KRe48FD0zqlrDuC+6BT4KiLgs/vvXCjm0dnjpSiNDyCRdXoASZZyn3E5Et1qUR+OGFUgFg+hwGRyCi5JMGLYmzQaQsbsJSCFt5la71idgWDvWJSmJpo2DjgTHrBzulWddtqnxsZv4RPzUiFD8GcLQCyOBHVS8a6CxGHqlS+DYWXqeBHo9YPIc4NZEc9GJVKxg4GVOMK9ni8Kyr3B3VFnPUmvOgCcozF8MY3mlhoq/Nmq88AF5ix5Jh6uY0eCEl12iwlJX1GJESJWTXW5D7YoLDplxS683gIw1PdnZuRmO0qRpu9GZcTZJ45SHxpqpA+DCDqoApzDoUpEuqw6Gdai8SpyRO5jV7btuqJxtwucKW0+6lnrzel2yA7MFSN6Vyt9Rs1yJKolbKuG8An4XwPFXxn0Wf/NaevsPkvOwgOL8ZblqxNgAsESKrdZYLl6hsNYiG4hW+HRgA8gNIMuyTt+kgeGlslV/3TXAa8SHoA5WjUez6kg4CtzNWpDYlVnHIYCzsmwwRByLENlVEca90qOYfy8Ubd0ztHwFxNaz4a+B4yob8E7zrlVWyVdMsW4p5VyLcpdpfnzW1040f2cAVQXBGk0uBI57hk2fKFVQVJ8WqEalNS1nliH9uSIlG0D+BwLIw4V9fKV7qTIjScDsU4OEwrFuQrdBIZRi7AelPknFthiwTC0F78cupNLcOTHl6pBxrWcxzwI/AGjSdcuFtZrlnRxo4lFJssvAdFY6uPakq32Yex0KT3FVN17jX5thY71bXSPFHiAdkAvKi/ucAmywbkJ6xSUdPzd03ADyQgbaWS+0znWvE0GAWUxZqUmYVfMttmZNdZAraj5tdIctWLE2lF7+ryOPDYV5T6S0ihu6JFfzgHzZmar4bYxo9gFNE4G3Azud1DfuPTRPRojuxq4HS5ZcZcTcW9/kymvm+kjT/ZWLXtOxASJJV4seC2smrCyjBVc711oAqkhIEEhTONeEqt7GpNkAcg4+yNnW+oa5VN3FZXUEh8V/2KqBfMhH22JbBURidjhsQEhyHuSdx35mhmFpTlzPovs0esXLpAeUX6UbCqtU5dP65UWgXO1IzyW2i5YHa6B4ExzvFLa45Fe2qgauO2qla5kIV/je95zxzj6HCoTxzITgJbKMlGJu2BTAZFE4mzUi6/6nOssbFgyWaC/fsXGxN4AEAORhvTOpAmxVtb6Zc5FIx0N/pHGOJGcv64UWZBGdYGXNWFUUX3Cwa0pe+dxnB+Tj/RLhTyNDXO35PKD/eM94zb12rldT+A7R7xkf5Z0fwrXONtd8ePQ1YDx/iVzJCrrh8YrGoRYpNJvXer/Um71LKrNsAty3GuQGkCtgeGLepc6wqqMsIOUc9UMVIy0plfQ6LFzFkVzImI0hfMulCVf1p0Hrco/F9vVB58Lbhlz3HXwnXexbPlX31h5PRR74SO6LFVWha6LAN/723X+aVyLHa4B/h7/u2gd699mvKegu+dWz2+HyzlqJn7VA1tK1DkVy5UnyjI1luAFkiSCHhZxir+NiVcG+bScsHxOFQUxhzmWMBg05NqtXY2ynjZ1d6wD2ornVpIvVqKuyZ9KXHP1upmZ/wD5/BShVHOlPr68Cxa2Gyj0WOLwRYd4Lwv0A/NX0erVDhou2C3fVQ0+sFO4CyVY+7LQgq9CtuvGdnlqIbvynXTKADMil+AnPDmaBxy3F3gByXuatldzA8HTyo2mgOA2OAMcqU2YYGghajR41G3KxRpJVvWc25wqFn6oPaamfRr7lVKC7rBF+ATR1AZUu1etuiWjw2vNfaQRdA527mjT3AKge17ZY6+4/7AqxpkPKi1+I1M0uFoADCl2QhU4YIz25aD2WrjVDIDfmHHOhFQqkk3A4Y5Yynn9bG0DGGl0LMKwsOy/FbHG+mDuHrEEqijxmiUXDMWiEmPUeOdcbuRDJpVWNSLYOeDP3Cmner568V0HyJDzWSqSyBpT3AOwvWRXgPGy/9MRnKTrP8/9HP7Rbc673ft6/XN956ENXAFvpYFfuC+BBNSwjO0AuXe4MZ24CFV7AUl0nXLEKrDozvXIUtrUBJICiNlophuyzHi2yGicBVxOZYDRkAtwC9NhGdyoQVlfCyr+e5x+LU6FCO7JSEzmrq50yZVaZMxfrdHfWLO+OLrl+261ZSF5Lp7+wbS3l5bUX9PUD/SKD5lpK/+hJozfbuvn9UXFqK5FhAFzhxhRlcK/pNWfjrn4+cp4pnS0aamqefaXTvq1/aoCcxhUwRG3YpKYs7pbw/O9vJkcqQ91prh0yNdtWIYGyMjgeArhAgntEmVbuAyWhCO2q528vpHqv49rdncYb4HnLoEuXcYf4RRvWR2urWukc64Fojn/Sa730XGs1kdNm0lod9MJ3q8aG6QAOHVGQlYKoZYtG1air/ITUWjas/pwSubVnNoA83elood5DK9dt7mq3QmVEj8xuIge4AhSNEQUCBlNv1Tor/Aizko8asNaa5BD1TMRjtHKQ3Eu/u1cX8lqAtsrHvvYUus2e+fIXc6mm6RdA8o/A5Dv9cPilJ7+vPnHxxNc1XNTnNn2jpt5NfnZ78bDpeKnqTbw8IeeKrAReN3zbAPK4f17OPCJGeSw7UnaknJGmHDHl5ElQbbQEGNbmTHSyB6KCXlwEVMAs9ymKPlG/HNs8pJgekoshz4Vp7wHD01T8zwgX/ki8PIu0LoS1d81T/kGvlV8BxItpwFKeTteUiWs6XJ5IRf9xaQMroNYdUW+fa44sgOheFYEESSSzAGXiLo3mbf0TRZBpygGIU0bKcd2yN53IMh9JuEZZkSkjB0ZKPDQPmRi+XUaJqBJo9fZmuVAFKazjZl8cX1mrP9JOJc/0ZcDTFx94V/T4q0fbaf2SvAGOXwPGu2qOvFAGeMhojJdnO9ttJyZfVTGcFOSzOk/cEh1rMFwN4wWFhSuQQTojN3e4qud1GfOBE8hyd/Pso4JUswHkBpAAgO//9XfQQ0GqORcWwdxc0m2RGPKUMJWxHfWeMq12WFJpW6TXxblw3lYEdTtzruZbczP6wGXxmzYhYl1StSaa+1X5skejPq78fknz4dG5x7UH6aSW92DOzWszVbzzS3gkqlwTO16tvS46hl2HujZelAlkkRnS1EZ9oAyyiudOAiZIE8AM+YT4/SjpCPcJ0zTR5WmDxg0gT5enqEF6cTaUnbFqOExT1BFDFDeRNszq4JzBLrrSQwd6qabfkUJzjjgDHOuw+Fm4yFu83e7IimboykjPpZy1YUh5vPqaol2sNfaRJq8XJ5cv/StjRLhQsjtr62NF8fw+pfObUeMtcPy1guf8Xio/+vR9zL8L0gQhLsAE6AjgWMEO0BHSJ6BPCAdIB7gfJB0W24RPAAep3N/9U56Pmw7kBpBn6/N5V8Z6Ouvp6iBXJiaSaMhIcnXWrR0DRphTbHbWC5I1a9e5822ts02VIfGiAHTxOOSN/PESV/tC6NYrj2vpvXzRAqcDR+JP8q2+67n460/+iGXtrzZ/bllE9Ldbdz+enJ0CAD/ni39C+IR0EPAZQKcDgOMMhDoIOEA6QjjGNi9A6cfYrsmPH0cKXns3y5Lmtv7pI0ieNv1avhoTteMEQ5ZBSOGuXmYbGyMmhCoC+MxiqpJW9Mti7CfMvGqqXeXMbP6dC/y6HwC0PPZ0MvG+Kvx4uwN+Sh3s7yNqFThXwXM1urtEmH5Ad5G8DwH5YFr95b955+23yhur340yoINchwKUBziOkI4Cjg0AI4KcCosmrkeEeQQ0xQUZqCm3H5F9gmtyuf6hdC83gPxHya+nJdB0sSSL6i2nCXKVKI8sAtPs6ooGyESLMdvCnAn716Z3ZiFs1plzwdgcEBe7Ja8Firfz1DVRh0td7K6Lekmu7OxPLWjTN1Ju3vGaz6hM/ZnrEhCtjUDdoP3xVs1xBVx5AzBugaIe9ONZ/biUpVJDjPQ6n4BhLtzqqQDjcVl3RI0gSyqOCcIBjklTPiq7B3izjKJzyRHf1j93BBm7fyphXS/qbaBPpI6mascKVS51ifysPICh6GOFXNhRChu1cGbYVMphUBOvna7/iP1UuANwq9/TnxlFXJqvXKM96vbnwQs58BprZzERsMK86V8L+cd+Cfc2xtbv5129sUSBOqIBZr1eAbBFluU6Jni77xTCFIhmDe0IV+Y06E8tjWwA+R/5DewaLC4Py6IFQBBmiUkGs6glwlIBvQRjpNxxfYDZwFJr7JoxVawilH5Y1H/QzL7srvTwLBOdN8z9in7kh3MkpjVgPBe3OB8Uv8D+uLc+95UaHq+lsHdIgvfOiLiXOscLAPzFyLHVFXnh9fFyTXK5vUSGNRrUsVi7TiLL9ZY+RxcbFp1qVb9sOMQM2kQoKyLO2gnPs5Yf54SHG0JuAAmUjq1m/v6CgABQMMgGmIZIk+sMYxhxhVgFxhn0GLeBxaWQI2A7Ll0NRwgjDDuBA8+Q5AaqrPKku0ZNa750Q8jU8qkXIz9d46YdLbqetp4Fg3/Pxs2tz+ce1L6Rkv8KdfHa/fq51btAUiWCRIztCA4pg3AKLiKAkJyNtyr4sSn/eB0sb4o9ksuzABN3dr1EvK1/4hRbhw4QV+gYk3bhXsgKbvsW+Tl2gu9oFo6FYe+6EzAGS6YAIYsd7GzutWuD5JLNDgR6DGS0fgTyNMjsGzYtEjw14ekroBfGxq+U+/5UyuEquGkh6r4uxssruHnFW/tekYq7rWk4s/vOhgp4rbutEiF2M5DwOuuodjZvdciq8uMtNZcyXBOEEjnWGiYmuB/L/TZg3ADynmii832lwImGSaEEHkA3NPdCFf40rQJgGfvRQHIsjJo2ChSUQwxFQbyojyOtkwt5O5o5HwX5wwqUuizLvdJE4e0I8tLg+MMv9RI3vYt8r7m96s/1uOYVcA2QrDXOcu/bMk25gV/Vd4wGTC51xwx5BceoOTqOqg0cV03LJ6l0wFVS8ZyPcB1Xm39bdr0B5LwzOLBmMwAQ8koJ7PjVTSh3gCGxCU8ggRqIVBV+hqb4Y8WPJlg0s1iunU5kn5hA8cGj80QBTCHPdn6nvra2oMmpzULqFBG1gjx6QBrrHpB8uD/EyyDOL6TYpzXCO6LHBeDeaMbEzY+MXilDiFGeiPxqB/ooV5lrxBHAAW1YHLEtRoLiAh2IyprBAfADPB9KpLkB4gaQ144xLVTsZ784gblZI6SZBYNZARyc5x2jITOL387zjbNj4Rny8TKN95Fh5j6i7A5A1oSbV+TOzM6HxtdA5M+wbBBuj0BeVde5p9N9y5EQWHSuLzFneB4RXkHBGyB5T8hfZhmhI6WD6vA3yhwkcADL8HcbDkdcJw4ga9c7AJM8wOwT1AHOg1zThowbQN4+Zo9+pmxTsILR3yMQBl02k51bRmkhhCJBFBT+muxTvarAZ12bmTBoFsa9O4q5lXp2L77ZxBKPmRt2jBpdYuA8gOSr7JtLwPhQLru2gV3aryvnlNPz1Bci9lvfw33FyUv1R5V5x0MBwwnEAWAZCMeR0FHAAeBnA8w6FK4aXepQR4BU0233I7IfQ/FnWxtA3lrela8SIYtJR5tITAC85pHNpIlN1eLU0zqGOsKooabS89xk6lR76vULGKjHQfJXapEXvLLnuchr4eMXClhflR27aMTFk4hSq0pIt/8Q74oeH4rsV0C0Rp/qJwn6OmTImB1r9Cfw2FEDD5COoo7I/Sxk/BS81h5z2+YFGKUM9ymix21tAHnHmp5tNtEsO6iMGKaWFs8WCbX2uFDgYQKtn28cFiZdYacwLoBxlkI7H3r80qjJuhdNSP2t1yhX5yEbuGAxF4k+ab/kRHiFw/046OHBjrG+9rn17+dGzZH8ol/3F3fLuaGiaKaoRoCaShMmQBMdtXBmzFQ+dtQdm6iFPkE/gnRcqoX+qUKhG0D+x0uxGxIYNBAaEmzK4O/HBC+qPNXHGp3mo5V65Oxa2AlVWCqPi+ZObdY0cV2kk+r+18HxztrX5XR6pTOs00YOznnZJy94bcxHXS0U96bY10SLeC+6PoDEQjfMfQFD/whwPPluVuuQsTHP7BgdJU2AH1rq3FJobw2bkl4fCnDOQhVz5/oQXG4/UDqSRR1yA8MNIG9m2P/yBCUL9xgLkLTfD8Z8nO0QwKrzWGTNMIamY4sYUxHQ7VkzKTyx63gPYjyIHGkc54mTC/WwK/XBy+BymiqfRJFroSR5/lwL1sytdvP8vIKfgKQW/7OPNM+e9nQuU3cOfK+NIC0fG091Wk/l8iRB/lpq/YVT8wUgnapkWSjx1NpidKhVa40hThE1ygqkrgPcPwF8tqaNynX3A7IfJc/96OO2NoC8DpAvI+gCJgc/DrBDRvr0iBrnwe5xjiKDNUOWuciwTRhZwK88prJoBiJuh3EE4iLQVjUW7vE86UGSF0DS9QdFl10auqAiXjrQuYDE9UHNa/7aK3OMp0ZXZySfJjF0Ho3dq6t5Lzj+Skp96TtYbnLUMZ1FswXdxQ9wfZbmzOcCBOvYT02tu2gSWdGcsQ20NoB85A38D/8OfE7g0YHsIMDENEppBH0IlkxLjWcGTFAKi/0C+tpkNzepoUu1E8LzOqlxr3/BEfCa9estwYc1ZF1THL9rtId3bzsFVi6iyRUAxBVAuUXJPgPHr0WIJP+4euMaSHIRaJdutA4xx1ilygIcBR0A1qixgWE3+jMB7H+v85OTTlkz29oA8q599t8/owZFADsLWbNPTyWtTmLpTLPYLKjVHYuTdtlmtZEDxM9WvCpajyQIqgqlrUUmq5HOSs3vhjXoldLXjed/JOK8ZC7FO4qHfv46pMv12EdOII/WKq/InvGesscXQXJm1rTPzkMBPOqMRei21h472bKm6Vhpg5U6WH7XVOwWqlnXBOUMuD801L+tDSABQE+AzOdR7p8Oz8aUShIb1AeDe5U2qxaILKDImW1HFo/rGVADNGtUWQaJuFJ7vDcauzD0rXPtxjMR3a8cCSuzj6dNFy3437r776h52dt5in32UxfqpZfqkXH/q6XMS4ybZkXxdxukVtAFC9AFIHq7XoEweNmOxqmO29Ru96roE11s6AgqhsWJfNd5jjGYts2QbwAZ+8fYMWlcUFbxufZwJwwxiWK0pdqdHgQNFBOoAeIQu5UGVK8a1e42xy7FTgLTZQ1WXQfFh87+OteluJU2L+p7p1zhy2wc/uLU90WhC30xijw7d+gKB/sXgHDNTuEyr3plu/qQulAJe6FbNb8ZoSmGH4DwlEFr4hQrhZqeS5+oPjSeP5w6inTzrnRSVZ9Wrm9R5AaQ8/rwaGqENgpxQKKQJCay2LqiORmGKZercK2VIFaLhSFAUXVGcqYbNuXxe3yveSMdPh2KPk2/1WWwhQ/Dk71+ofBz5WiQ7gYs3YVmOolBr8mN3UiDr4HdWtR5+r7Iy+aH1/72XUo/V0zTVssXytVgC+EvcwDwgeo1IxzCg8Y/IXwUIIzbomP9WWqTnw08VYCSJQW3IhRuOPc105ZebwB5aR1yJxYKs1DlMULWjLbAct2smGwt2DOFk113NyupuZFWZMlbQbI89pLU1o3h6F4cQpcOyEK36+mGF0HukqXCrwDjtZok78K3i0D9R5pprX3+Z6rjayDbvS/eqAPfx1/PDfDAg1TNuEqK3CJBHdq2efwnhCeqkddML2zNHicOcq/8rg0MN4B88PjYpWIZQ+h9osGMZgGG8bNAYbFTICqNkFCxU5hBswJlZd70kaQBNJWk8r6o6BQwa4SkyzVJab2DrTVbgxtH8AUK4sWIUWsAchkbr2pIfgkAeWWKp4++2U6Kp+BIu3Oy4FID55pa+Mn3QFKdKs8B0JHAUdAB1AFZnxA+BR3n7nR1KVRv2rWgHAa1sNYfuek9/oXrP/5U1VCGxAkYzSwlo6UARzPCaDQbWP1larOFtNJdKOztav2qjk0j621g1SQreG6itboHC1e72Fcz87mBXpvo9USwvD8Xdal7S6C3DbqW7pAzcF95Dt4Z6Z3dd4XqeGYbcAKOa899z+zjLTsCPiRZ52iug40Rc+y8rzu2jFehimmejSxdbyH418BRxdpVjOfiowXbbW0R5GJ/noeqabPBVqMNkhiaf3UFvgZ6TGHAhRkIK0ebSoD14hQ2d7BPIhDeAkDdTotuNGIemty50f2+Wm/kWjSJs7opT8PLR3yyeKUksSpSwfO/swJyXxPTvTUuheVY1vw3pBCQ6CPCT6mly58I+uAnpA84Ptp24UPuH4DeIb1DeoPwJukNQFyID6hEj18hCmxrA8ioALGzn0HiYkRH0XWOIydBMJhSeFyjDkMYYSGHZquqDXNnhAUNLx6kl6hzuA2ci6jt/HZdtH29kAKe3E/35GcPNdv78Z5H6oQrH8ZVcsyJ7uMjij28hwaq2/jZK4mH7miNHN8AvTdQA94hvEF8A/QzruMNqMCnN7h+SqiP+QnpHe5v3e8/RXwQyDorpWyR5AaQj9YISmWQgvBujECvHA0x1xguIE3PkUXh8VTNwcpQXwPC0sohTw4VnnVZT6lz4mMAtKo5oJUMfsUTu0/2TgFWt+qND65+hKgYpXE1Pb6vJPv1tOGOv8c7OfLkzVrjSUQvAJOkn5AC9GoECL0HYOoNKj/h76iA6HiD9EZ43Dc62u+IjvcH5B8wfbqUU+Xiw0+G0re11SAfeQOjKhmQ5iEkXgbCOxvMDjAZDtddPaoU+3oFBNVHVVXxohP5F64FOAqL5o5OwFEXwFG4Lr4rLS/9trPS6ok6kK6UXqWV7dc78NIDYIYV64SvAO09tcuQYQ4gdA9wE94h/4AUaTP8A23Mp4AfFD/JD8A+AH5A5feUPgB/B/wT7tOlevS2tgjy8eUejnNOIlUXhSJ+Ww2zSYJi8cCu7JhozvTjP8G/jtojS42y1SA5T6DxzrraJXaNVmh+K4igs872pchTqym67qp96jYo87bqeFNh77UddeGxp9niPaOKq5xqfp3SSN4HoEtBTi8jPB8N+CI6/ATxAcc7xAJ++oiIEnGRYpvwEdFliRxj+zukDxmOm074BpB/bGDlpY491Q61J8CMTAFqrOITTICZiBggD6HcuG5NC9KKFmTtdtuSt80rMv93AOMaUtyTOpEX0+cz6bPFoHlnvXBt8PkaWJ4qZuMEBNs7rf7cK7XFS1x1YkXYdqX2yAuAZleix2up9SXVJV07kckrmKkAGsh3ZH+H9CZXSaXL71FvfIN7pOLSm2qt0fM7XFFzdH9TAOYn2H1zveRdzWm2PHsDyC+VoyiCKr4zMbsowVjtEjiP+LAOhluNIrs5x4gqZ/fCGDInybToSNwyiLp48K0wYarp2ClbRmwaiE3af20o8XTOcUHW+QPSMq3YR3AJwOu89BsnkrvA8Zyb/VAK/QeehiH/gONN8gA+6CdcPyF/l1rNMYDP9Q55qUe2CPK9dK1r1PkO+bsT7xA+KeW6P9RznJ3tTBtAbjXIB1eMQBKQzeM6kpGaf2+K4epmHzmgDYNXhg0NZrUTXofF7aRpcxIlnhgeXioZ9ffXlRLTyuwfr3XNeULA7eqMKv/W6466UHO8o1Z5Mde/M429qWbUg7Ju1GN/5ex663cCgVWfMaaD2oSpqfFHuV4aMnqLWqMHILoq3fBdro8ATr3D/UM5vyvnGP2xEKKoPILZbk1BvpI2gNwiyK+tLECi8WhWhCZK5NdTCGuNsVi8miWYxb5IskWYNGNr5sQgOSsPe+m4ff3AWmRml0xl1hof511qnd7WR6OnNUi/0JTB/dTDPybgwhckzf6A+15K7R+pPfKstnssM43vgn8E6KmvKb61mqTrQ7W+qDL60yLKOvIzjwQ58GHHnH0/gtnL2y2ptGEx4hOd7K1Rs0WQD67jETge3NxlkKKK46TUUwRVj436e+FVlzaO5u0z5bAdTWnOJHkCPKdRzUno5Vh4dp8Blq7dXp9jJbo7BcdyEe7oFusLYHdl8FxnrXPdPzT+iHNhrz7eRfEXu9e3GDQ8id65EtGTxxIhvrX0GfgJcZ5vjJ8/44J3BjjW1PoNLPOR1BtYZiapN98PH++/PU88PfHxsn3atjaAfHj5JOggImdTdsKzQTlOtyqgCYQEmkpxL/LcLjJUE4xSO02HZqTQuSOdjbzocqqoS2i0NhZz/pyX/tQS8C50qa9R8dYuX4kQv3THP8or5gbS33p9vCsTmKK7vIz6ECM7AXQqg+JCzDRKb0LMOqJ2rt3fJY8aJfEO9w8of+YxrFv9SmQrbiC5AeSvLgrMgLwbfBQICXKVESBhYdAndpW5vpvKJh8ewCrd7d7HOw/CP6qetsJlJjqhonrAmS0jqEsK3PeMy/CLaHrJgkF64D12G8R1Tva15763AxzPmbtU+r3VGBstMK6rRYv1PmWER/goM5LvAD5IvoN8h/guw7uOPNokwQBPFlJ9Z4SDRRW6jfJudcgNIB88/gikKtJTJa5ttqhqyi+n6SB7qdEGtkvQYC/c3wHNnRHRvSC5Ej2uRn+4Ehl2f5S40e3lg+K2N0BmOSzOE2bQg3YJV+9zp9cOcbtBdPnG3KLEOs4DvSkaLrUL/dkaNXUAPABznnFUHSDHu0okiZzfAXwSzMxB2vKUYO49RyFeSWfcJt7xWW5rA8jVlRIwGpjI6MWUoXAyBnjO9qzS9tZZTlrDMHUeo7Ng7mkN8mIYdhKOXaoHXuxac0XI5o6pagIrhc3zlPwSM+ZLafalfP0atfHe/PfGbRfnOu8E49XoVCgqOx+l5hjgOA9zl3S6zkKiRZiS3gqn+h3yMgbkP+X5J6b8A+4/M/yD7i4jMAmUkAcDszdR5DrzSADe8c8JfVGMY1u/sv7jM2liONrU8WZa8wWsLJly16L1KAbdcEYiNiyZc1ScbLsgvnriQb0Y51lTAF/h+J5ZItTOJc5x/OIws84juq+C3yUguSD2wLvsBbsrtxTDcf4R34yebjVobj6FVMDxDfKYcQxw/AnXDyiEJgog/oTjB+Q/4rpmsQn3H5B+RNRZnsfw5gnHnM3TMUfGMzlMQh7SPMta369da9RsILkB5EMlSAKfYbsgiEwdvUJ9Os1uCLFFUiyD4pwLW7Bm3FVG0Ll2ILcDt5tR40oqiAuRyuUM+3Kt7rSxc0JF1L0K45dR6E5NxTVw1PVa5dnn9Wggecfj7vXCPt+US9r8E0K9/IDwBsdPAD8A/Kwd6xjlUWxz/JACTDE3c4qQhf+E4S27Dlac0VTyEjpgckxp2KqKW4r9J69cGjJQHRarTZYiXrEQngj71joCpBZ3WgNSluexahlLnnWJ761D3lX7uqPk14PnJaD8cubKXwxO+Pgb1Ree+uxl8/bzaeVktbzvVGqLP+D6HfAf8ADEAnw/5yjR30u6HR3sOv5TfWXcP8t85CfcP+D6nAY7tsriaTk7x0nFjcVlg2ejsmJfW8ZfwCLaAPI/9nIRZkXXkT0DhnX4u9QQa2ExBsIjJS/WC6hMmTmSZFP8Ifo5yLV5vYV4Lq+ne9eOet6BCuq0AQn0g3NdjaEDvI5tc0tNG7g843lhpEiLB1xRnXj0hHIt8taF8alrQeb6ZJBDOMCLaERT39FneMtoeUEMg9f7QPhQ3d5Ue0qNkniX/CDJK/CRpa5YXBobQCYD3We1+PJ2rXy6vDcD2dYGkGd7OEGYrMWJ5FxHjNpeiR/JYrOADi1mVKkPIM87D+R94HgWld0h338m6DC3vmdcK1YLaymqnUSAXMQb654r9wPIDaA/tV040zm7O0y+aE62EABeRozShWbQtRGfudMeNUfXrKgTUV+hA84NmK6TXSJHfy/36+qO+Sfcf8L9DdJPAB8yxSC4ca5AWBSWZQCn0skeEpDnTjZ7c7fynS8ph1sUuQHk/YkoNbkBTnXGmKzRYMz5GJeodaoBybBqqGk4ToHyesTXBZv95TrAnIg8cA3oeN6fuCcK/NrnONcReSMn/qXZzpPbSPyhmeNdTfLarcY74D+hqriD2ph5gwrQlYvq/GNjx+hNtYsNvEN8g6U30GIkSMikgYoZx9J7gYyooMkMJHl0st07e1+0gqVOPvStk70B5MOZl1zwRhdEh1JmcyiGTkT3RNeR61JlhZpd65ZLYOseuwqIJ4B5GVxuq49L1248j5CaSMUlAHwgQvylIuqvPt1qFPmF5z2NzoVjRIb+BqFEg0EPVFUEb8IUqOK25bp/tBlHKFTA5R/w/KHp+CHPn2JRdSSBMuMYjWrBYfE2LFJsSvCUzt/3RjncAPIPCRi8ZsblrIszQNIqKM2gSZBkY2dYBbfZWJnSzRrbH/aGdBkle842dBEcV8HzHjXxvt54bVbykijvpec7y77PueTShTRdv/h5n08fZMg/y4B3SZ/xIeld7nONcRageJd7Fad4g4f2o9zf4TlmH7MH2Hp+B3Xsx7dYRniEWa2nLyUyR7vQr4w9nVEOaRtybQB55zoqZnGiLzMPeVcz5T56YJuVLFhqs5xEISgWemEcsmHO5NCJ5tYciT6W8nDFovWe6PHUH+VujxldzzsvgeGlF3UPk0b3Fjh1JoQhXXpDDzB/TlXMe+R1TQUQ30rNMcRt5TWlDvWdSKd/yovTYMw//oDrp2YR3JmnTfz0Ib37uD9erEU06ueMjgRgFSBtTscXZpHqObLEZgO7AeRjAYLDzcyN5hbAJRBeZLSLZVf5GfZdBfSUS5XfEfSy+rNen+I6w+kGd47CXKgR8pf4zLhguX0D+BaR4wX9x1vRrHTX61k3BtPV6HMtlZb6AFPr0W0HyFf/7nJNQR8s9UYvIBhD30X8Vm8BhB6R4SyO+wHXZ6k3vjUnwsawwYfIg8xcZ8xUgvIGfIYY60FNs6cASh+sdLVPKIf9x0M8wEja1gaQAGwwYKCnZBlpyDTzADVmMMCOPQCKGWAG6304hRETc4AnM4CJLPcBpgKSCwAkVyKER42jLo2+XFLjuWigdVp35P3SZmusRN1ZAtAdkeQCqE/BeaHu2+4jrQhc6EJN9aa1LsKmNUZ15igRKhzpTunb9Q7XAdLHnG4rdB7dSwpeZh2hz6g96gOuA13zFFlPvyKbGIU6gKQEGYGswqgZViiHRXD+jHJoWxS5AeSd6297IZkwJGcyhzHDLCMxIzEAk8yxnZlEhtEL+DkIESXqLL93qbaXUXL1ALgAxzWdwQs867Mo8gwEsNB8bJjgK3OIHYjoatPmMqhejeZugvraTXdYqN4TnV56mHTfizk/OR0h/4TrE9BB0kGuzxIV1p8fkH9I+lDW7EQo/4gaZJmBLGk5XG/K/ib4Z4SI8YGq1AfFckomy4xjd64ojcXWqIHDh6KQe8vwbFt/1/W/AS42wNEUUz5ymEUdklSJ/HxpS1CPtHafAohAScnLVMbZYOEVSfH7cmStCs9qBdhW7kssGzVrUdtdwPRrn/Wa7sfNeutdKHuDSviQCrnmGnQogr/VrrMcVVSiKn6/V0ZMqIN7UA0jlf4Jb9TB+RJqPT8BfgDKoGBCqetwmRe3Rk2dcdQ8EF4ph1mYjI99NZuJ1xZB3rNSNFBcYW9Y8jNUoEMDQqOzryfOCFLqi5yTPLFr2sDBUJs8K0Je4hzfm9reAi1dF4XVNfHdS4/lvUCIx/Uj7xXhvZKmX/wsHrFomM8yUwPAqDf+CBEKdHXIMvvYQLCK4OoNjiqAW71oYvzH/d2NH27IrcVcxniunRh63Y2+M9062daBad/qWaMcbin2BpD3LC+QBlekyiUKXKTFkT4rmNmmqD+W5s0MhHMtnK2gpy5M+3NP19Klwt7y570isdcGynkB1G4BH3gvOAF/5kem0/Jkb/LVPoupsF7eivNgY8QA6IVw3+dZyMaqeYtUus44+kfrXHuRQSNOOtY+T4OdfMAsr61RDjHbuC4phwn0UptcHKEb5XADyC+urAxPLOGiz23OVtlWG+VhPZpUDFxqtBldAV+0SFndFq60Lh5KcXgBRHCZecIVpZxuO/GgB/Q9UeDVx+m6OPA9jJ+rTKDzcoO0UpPjIoxee4oc3OgARnnpOlePai/daXmdaZy3ZY/aosclHuM/4flDefp5HPWWTYca6WklRFQnX0edpNknAFkph4bQhkTOS8oh+vnJmXJIbpTDrQZ5T4oNAAPhR4c0t0mLRtnpkLg6l/v+4ic/T7ZHj/LhmvkagNbi/cV60ppm5Eq0wAtg+0cHFhcrCnw8/b33j63RyGsN1ri8w+ksqtS8ZKRSa5QqMP4EUMRt53lHSD/Ue10DP+G58Kz1A/I3UD8s4f34mvLwE7JjV0tsFey5UWPwWeezNGrcEpQjKslkixaZBZPDhwS+H+DsReRYGDinX/wGjhtA3pVtCTA45C4t0uwKbn0K3YMgVmW6aspeAbaELl9qKJ4U0tuvbe/v0Ixcj4guRUq/8DrujhoX4Mj1TH9VUJfXhTmuojAuK6iTp9W808/pGPxo/9HADwpNR+n39rtQ5Mv0E9CPEJmYwbKJUKjOTeIHdukdUh6Ojjwadp8hfHsuoza/NnURZE85NJSmzKR4jslBL/40p+c8u3VC2dLsLcW+cUwHQzBpRV6i1BKrZkWvAhG5SnBkej2wQFj0nMVL9beHDLB0FxCtR6C8opDWh1u8et+HI17Nf6UfTSSuKRf9QnDDe7af/4FSNTkUlsu/F7HbuGT8gPRDRd9RGbVR81YEcd+lYtG6cC3UR2HKvOeRnx8vYyaANDl8mP3cVKVHGefUlj6fjHv1lEOcUA5j3qJSDnlOOVzOjne75BZFbhHkrXUsvVySCmEIsXEAixN2LXLPdgitey1SpArDhg6DszZyULZJ3gpB/AP0DB8LkW9H0Lce8NVxkL7Wx5XuKW+96Fuf1ZpP9cmsaf/zNLKcf53g/lFA7iM8YYpxFqraTp1txCeAz9Kk+ZzdCKvJlj4BfhQ/mg+RH0opO0KJxyYsmyirpQ6767Ot3jONcjgCnggrg+W9cVeVOjtRWdkQbAPIG/vZVMtTcpbmi6KWXUFPEMpgeO1el6FwwIN2TZURtgqGHo+J+iNmCqL9KfulLgeOa4IUd9c7vxKOr26+y7bggc/lcqjIi+wirpQdyoSCilBtdRrU7C6oar7V7uPFbMs/VOuQdS7SS0oNvMv1k8QHyANLnqGi/B0dZ658Fyp86qU6eFXVozzAVcVviJ30WaUcpoQ0Zagq/Ih1unI29+D8vUhbPXJLsa8daglggpDkytmVsxDlSBWKWeVe1+tFhEIVJINmWOmIXABijkHgBbiup5aXMGAtnb7Kb75jRrDLd4kVAP2Kx/aFtJ9r9cCzzwCXZdxuybudamFeCrp1Qv+J1+WzbFkRlYhB8PeuW915WfsbXD/k/lOOyr3+aPcN+bM3SD+ZWCxaJRZfdU9Fe9mBnEqE11sfLb4zw8LUrVEOraMcYh7rqZTDMTjZ6j++Zskw5+ebeO4WQd4XfNlchnLPbp6DbghOgDKkCoAV+KYOEOMS95nm3wtQCoWfXbncF1q6p+oxrY50ClacIwC/rHq93lPR12vyPZf7nojuDBx5G/i/ElryQRBffl4TgEM0Vprg7ZsiAnxrArgqzZg6BB4iE8WZsEaOsU3AG4U3GN58sAOP7vQYnTWPzvNAwrLDR4CTlzN0y4O7TnZUdyqfukWQyQoYxvNJDli4HFKOnIrRQk9H3TBwiyC/DJDeJhjdhawpT8hyZA+Ac8Ul1HscLofcIWa4XFXRRyWylDug3M9PwiXJPQbScdua4BSI7klRydvD2LqVm19Jvy8yay7wyNeC0UfB8cuzerfkzZQhHcps4zty2CGERqPeI5Jsw95vcP8os40/y0zkT7iX2qT/lMKilZ5/wvATAz4Bzco8EswVKjwk0hSdbPjcqFmQVde8W9lHnJztF8pRSAfMHTI713+89iltjZotgrwOkG3P9AxkTtmJKVNDFrKYTHAINJcj0+QQwycWdIgudy+iFg7BFQpABSgX6fac2N47GHlv1Cfdi4o3tv9CzVHL6FEP4dhXm1eX3tvFJ4oh8JpGR3f6DTVyjFnHn5VFI/Bns0qIFPpH+92L1Bnwg8BPGd5IHQVTSJTNSt/MQB4JJSJlx+feFm9dYi8n2kQr1r7/3m2it5+xDGCHuUHDpbd6S7P1lR1sW/+UANkFehLl2U3MdDM6RZeQSTocGSYXlANLmcGUIU0gs6RM9wxahinLPRfJs5BNE7KgieTw8LH+0H11G5BOjpJWrP/VY4W38e/+iIX333TmS3OpfIEM4KOkxAUcy5xim3FU52GNLv1W8bfWLEQBvcHwRuGHkr1DfigsK5CKkZsughQYnexjRH26MM5F1dmCK5RDF5jmRg1JYBKwDxOvwb0Nkfe1axXjpHaS3gbHN4C8ttwzOv0v1zFnuKZkyInIQIp0OiHTzUG5DJnQrA3pNsGKQC5V65BRl3SV26KmKSgTSHcNX+vO0HIBbCVpaxYSOhe2YH+AXHD3uxqVXgetGj3yEZC7J3q84Fixqux1/lxTmU382YRuZ6Otny0iFH4KnSBFb7bVvKzxBvINxDtyflPiu5NHy9D6CUmojRqRSCWV9mEeyVHv7KEKoHOmUdXCm5qP65xymGfK4fBxBNLQTogxdB73g9Rqm3Fy3MBxA8iLmWme6dXumZMmZWTCMpyTgRNTngBkGSfCj4DtRE6ET6BNMGUIk8gj3ScwTQAmSZnABPEIqDRxlEHaXEj6hWjtCpNGrXZ4AqjX1Hr0x4EjHq09nukYLihDJ2k4V84fa42gdj1D+Kwd5qKwMxtnodgfFOMtAFXpe770s5BVscc9ZM6YjrXmSHX+2pxBLchVQLYASHNHHgg76Ezfk00kykBM867SUw5RTLzKiE9POczJQFejHDbxXGCjHG4A+diajgd0jn0OQ/YjciYzwcmNE8mJ5BFAAKLziIQBwgRognyCpwxqAnmMtBtHiEcQA6QxHssD5AOEATBC/EKbawXg1uwTqu5GL6rr54+V9Dg4XnBgXELZjZriqngElhxEXg4Hr0aMy+cN/2pVCbKmwlNVed6KKviboDamM/Os8R4ca48UO1LwN8rfNNibMg6QO8y6z25W766ZQhvvsfAotwnw0cCPE8ohZ1M19ba9RTy3Ug5dQBIw1fJIMuDoMfaThlURjF8vdG/rnw4gzRZ0PGmfJ590yBNHJhtt4tGSHUCONBwhDBCPkI0AjqCOAI+AHyAbQB4AjIAGyA8SR9KOAA4QBpAHAWODxms776P7bXMrvGBw9WhkeAscb9EX7wTXu/Jr3ik8fFpzlA6RVntnoOU/OyCMlBuqArc/CpMm6o3Bjvkp9+BdQz9p/Jl3fPdkx+E9O0rNUJ2orcqsoTMhwVua7QmAEcPk+HxKJ5TDYol0Sjk8E8/FarQcICwgoQ2UgyelmGX1eZGmb2sDyAuRDBoL0J45Zddxes8H5mnAYMndBjM7SjywGDRAGgsYDpAGkAnAIGAg9AlxgHEAeICQQAzl80rxWE8xwMbLc5CLTOi0qP4nrgcPGOICz/rasPvddUlewNabfyfog9K7QmXnR5ldLDVIvEUUqR9t3rEOgwMlWvTCtVZT9SHxU4O9fb7sj8PxqDrAjVbuY9WVj2jQorACCZaFvLPSqPEis3fpZHiDcthVG3rKISeAY7gcRn2zcLlKOYaru9CWZv9pAdh/+DewE1K9jILtTPbEo2M65Hw8ep6O7joKOkA6AjoKfoR0UMjxHyOS5IT+d7BeP8TvmK8HsB5XkY68EWndXVy96Xx6H2hxeVnW9hav9Rwc7zEi++qs41XKTy7gWFXA30ok+Napfhf2TBG/rRYKYAXDD4jvIN5IvtP4DvJDg30AOnoaJM6RGlek406rsfQiB2VETVyaQ+FJFtDEKZqHdbNgby6HKtQDL40XpEI5lEod0mef9laHnMVza+OG3FLsLYK8BJCpYEkGPAvKDj8o03T0KR91nBIGH5X9aGYHSiOFI4QjpAPIMdJnpRpFImQmR8RITzq59BGnQRgf4yD7eQTQF6pCzRJAl14tfscJ64ZzLZKo6hVepkHqK6u0SpaTIvu5RV1Jh2+D4/XokUtq4JXoEfPrlz6B2ljB+wyIeINY6o8VKFEB8Ue5/hPgG4gfIH7WrjeMPwG8H16fDvvf38TSfcZCvduiRrj2VqoCngIUU6lJaiAsX+hkd99ri0wLi0rGkDkDoxmTyzYPCQAfEniY4ENnhV6637WTvcxKtihyA8iVdfjXDGXN7T0SNML2Non8lMs854E+JAgGcCincisgsgBARofaQCWI6ew+PTiiXpddract0m2WQeJaY7JFYwAxagSSptlOrB9U7529Cs+8DLVLXuKc3LjmTWuVA8g9yD2APaChhSc4bcqcyqytRJb31ijXujGXGzK50QCln3L9LDTBt6bLCP8RIz6oVMEy0tPMtspjUPQfY0DczT7pONYBbHOHm0HV0be4DKq6EGq2Kop0NywVzDEzanJ0soejA4PNJz7TiXhu7mTOLGqcRfvRpGj8TA4kgx0AEzANtkpG2GBwA8gHMzWGN3ayIPUbIxJIzPjUp78refaU3JO7zKCBgsV7ZwI4BFjIACVAKSLHiCzZgBEJ1Bg1SSUJicYR8AGw3dVUmVgfAm9KE5ogHYv81iel4H6H104uKtkZkiTl0ryYWgtbqHYRtUyQy8FlAeTcw7gH+AzwFeALyCcQewDDdeuGK1Ei76k13tGQYetUf0D+U1Fv/H0xx+h6E/QDrh9w/xHRZXEYRBkUlxqLRmUwnEN6d/BTxEQA9OBD2+SYdgYZYHUWsSspFJ3Qs8idLuQhIs90dBzGVKLO2dyItVZYT3onI1DMGcAAR0SiTfCi/jl3KA3wByiH2jrZG0Cuptjf9pF6LJolpYa0t6zJP3VUgmsgMDD0ACvoDaIOhA0tfa7ptXAAkQQNEAZSR8A+y30MwqCsAw0DTLHttFmzLGkt/a4jXfPC3vgJ11sHDB+QH1EiGwUYTp2fDjplovnZGq9czqAWDTQ8AfYMyGFGgAYpomdjKscoF2lhjVz6aPLOmirvUe9ZRpEO4VDYMT/lTQn8Z2nKvKt0sQtjpjBlqiJ47WZjBkjgJ4kfMLzJcFBKGR5eB5wETwabMrDfwQ1IXVNr1k9WSSQc6shT5mU0x4poRerg6UR9aEE5vFCFRU0iFpRDL51smymHuEQ55Jcac9v6Z4kgB1sAUJy5rSqoCHtOBA5yHwAfIA2CDoRGQEeAB0BjRJI4SBjoOoA+QBzhPIJIcR0DoAMMQzRrcAA4wnEAtUcvaHi6w57vvI4A65n2xtaJrV3ZrAakcrhrBlZ1zyx0JmRepoIMxJPAEZBTRZ0I6iTdpBq+8bS5dNpx1u365FVw7G+z9n1lQMezUZ0yjlOYMe9AU+uZARKa02vgJ4g3gIVVo59I9gboE9PkTLtSqiPoGT6OSJ8HCPsyilNqf2ym6K3eSHZ+MKWTfUo5dLsAfxdcDufMogfXQjms2pB7BKMmd5TD2lnvKIdq8nnb4PgGkGsRi1tzf8NaFjvQkXDIP6fRjuloKR1gNpZ0NhoujkNJsweYjoKOhB0hHICIsiR8Ej6AVuYkIxKNmUgNBWCHs3BKOrtetFRj+Jkh66+Z8fEB4gPSm6KbPgNffX/qxsNVwdFP7Wn34cwIsdjeloPSu6ZNGSDpEO4kCsc1Pch7ZiIv39cBHIoXTAXEt9aAKWM9wZrBO+roDvGjCEzUBs0PkOUEwzfQfmiwt2k3fI5vH4Ln9kLUWCvBhAGii131GC9mqDZ/f32jZihA6olItenTzaxSpXBDCwZr525I96h5rlIOUTrZCePxABXKYYXTnnJYB9pZ/G62tQHkCUAuR1eYYoSbsye2IOT8Nh3S5KOmHLONZCIYg+J1OFyqTZjobMfnM0I6lo72saTfE9i0I48gpjjgpbMuBMtZ3xcQfmwK1+UnAySrVcA7xA9An6hOjcX7W65KqSmhTGgVBTi2sGSAcQToJIv/d/sZYVGUJcLkjFgR/+UFtYpbNcdbne2aVhd6YIkANfOq39rMY40U222In8TP0s0uQFnGfKSfID60Hw4AhcHiG+v/fKfAba6QFzOfy8EkziiHmC0Q5OXrLN1vy8GdTodZPJeLv1XnIXPX2C5D6ClB2ZuJV6UcIntQDocl5bBXUfPVD3aLHjeAPN0tdqUx05lWRZBVSPwl1dZOx3z0Q8p5sJSOlEZAJRpkoRKiCueWmh+DfghGk4Q2FXAs98FEFn62MJXmzrr4I5u69CR5HVWpcv9lmLnS6BCG9q4PSBnRVS3FS69SMdXb+6SqxRhqJ6NSujh+OrfHCq88rYrdYsTgJEU8bbZqmZYT551qFF510P/CnnUxyhOGWZFye40UP0paHXxqcjbZCguFNyS+6+ifcDmSNWYMWh2v/J4DGC1neLJS/zuRsOsGBqwCZG3ANMqhIU3RtOGHN8qhRNA6Xn1/7llQDlvTO1L7QjnksbB5Unqw7bI1ajaAPEt/xjib+orlaOXFZgmkO3zyacpMadKQJqoAG1QUyDFVdXEBmVGnm4qyT1XyqeCYQWQFMB5Zt0F2rrPYdtpJ0EfxPnmr3imK0ZYPyD/g+pD0AffPApClm918vxEeOt6n2HMySFlMIDW8U/vXW+vx3CTgOjhqCXr3oOip8Va8+ENT1AHepeoRow4gUeuRc+RYa47Ez8Ke+YFasyR/YkhvMBx4cEd2YEgxYkOGBnJKc+/JVTrZGXkYI62t84lpSTmsqkmt2VLFcwvlMGXH8ckWlMP60bI1as6jb0qXe1maTbxmyiHOND82yuEGkDeXuoo/JMC9zEWWSwWKRAeR8zRNtJQ5DBMteYyX20RoghjRYWhEltEbjiFcoQmOCYYMx7HIo0XKHduPEAdQyyhyBjCH/Aj3zwAJHOI6jnAcIP8soy7zBfgEkeGiFh1s1zzis5CwHnFufUsYCGOxsS0lx4U/1q+6D14Ax6VKei7g+BOuH6pzi637rJ9FiOJHAcffw6O6Ct2q8KvrAHi5zfAG4kNDOgRGZKA0OVSEJeABmDV6s5zhYwCk2DdqOhGQEjGq6Yp1e1wG8o5RyzwI+jLlcAY+Wkc5ZEifcQfkZEhZpY7pG+VwA8gHAfJjmsGwP6MaYh6y7vxGgD5pOh5Rx2ZQABA6llriLrZzQti6TwxFn7HcfpRwJNsYUKTmWGyfAI1L5BAgHBWNoUMwRQIAJX0A/gHwE/JP1RSy1iIhL2XIiALdl+5VLK0AcQfaGKM8wMyjYU2t48JWo43Kvp0i3cnrfuj44xJAa70xhtirXNnvcP8x0wabX8xPQFGLDL717xB+LzXKSiX8CeB3CD9g/ImU3ny0I4UJU1HVMQDZ54jKDJxyeTcsTRBH3o8Y8zHuZ5hZLJojyNZUOzFSYxHPdSt0pVKTpE4LFbPLYSCgt1vYpM/KEHpJgpL3LodRpxwOEzSkGX85C2pYBXP55nK4AeTKymVEpR4cNVA6H1sRyMxRUUfMPinrSOoIV+hDUtGYCWm0yr3eYeZi95exu89A4oiafsfn2u+lh9AtxGLGr4i+Ric7+MY/Cbwp0swfxcY0NxLbPPtYjr5m1r2DcZg1/1mSLgOMmgGSABm+3/H4akaW1hHwktzPnQrgdXB9LikEt1repchebA/0ozVq4vI7gN9Lal3qjfoB8HcQP0F+YLCJoGTBSHEi6tFTLko8hTSg6SS99VIWDgBzsxhwXH8PbVMbxVE03dyIVBsuAzEUyuEseTajpWNp4qUTERMDka1SDg3M8R7yYOBneW8tID2hHK4IaG5rA8gIlHbDuRDDSgBED7NM7McJH9MROY+Y8hGDHeE8MJWONVrqXDrWOrYmTnVFjJbk1KJOICwboqFTHRRTY8nUCGhWtn6H8NbAEDPfWHNkVTyclVXVc+WnHRmV1zy07nR0q3P3OryAoXfujj43bOgPCWFcGxi3xWs71uaJvNNndMwzjkABxTLb6K1J86PMQv5YcK6JMNUCPpDdgx6IODlWsLESqVWhh3RBtrw0biog1fT2EuWw8amLTmdQDuMNh4kXMR6LFlTLm7UQzwVzVxuO59eYutGdSjlEa9R42iiHG0D+ykp2BoS1P8PTZoERGpn96Ee6T0l5gg8ZVtTD59pjdKZh4UnjPsGsNHSaN01YNsiatazMQ8k8ut+pdLc/AH9XE3rFB1zvUjG5b+rX+igp+EfUH3UohvdBG3QthsPLAVMc6QvQRZLnnD28Z7/vGRgdzdq2ejTyel62EAe/aVZWxSaqNFk1yXqfU+ei0hP1xbkO2TNoajodohPxeOOHxnTgMftcuuCi9qdSYaAXsKqpfp07VKnzlREfmzKmfWqUQxWAPKMcVt58bb64kAtBNWUVyuFUSsGCnKX6cVKH7CJHypdVyp5y6EByx1Q72Xf0XjbK4QaQ50FL7vt4Xe2rCH7Hzt6lhYmuwbI+pknZM7JPNGVQM0gCAXJh3jXBLFPdOI8x6pOzp3ZElsIkKJNe/G5wAPSpaL58QvqE+6GrRZbtOAj6BPDZcbIPAA6Kn3O9Mfo0zpD82UXdlLk5MJJFqIIdOCqHg6NUPL8FFnYO6Lfw8TprZsGn9tnKAL8rao0/Oz71T0F1249gyhTmzMJjBm+AfofxB8AfSPah/XBQknOSN+pdEZeNHcFQI0oC0OTBISqdbBR+c2tnucOHGPUBh0hXq/oQTymHkR7n7sSQPGorbVzoaR2e5k725Q+1dZ87yiERjRokwJv02brLITfK4QaQF49dCwHTFimw7uhrgU6Zud7R/ZOZk6Y0eFbyicaSNndAozrmozmKpAplD1O5Tx0Uz+Wxk4BjKZfPHWvUDjU+55/4LKM+8wXNV6WaS310w+KuSPEowwhYIpBnsAt/bzFUfCgKJhUQDNAUlja31bwsuu+PpdTz6E6uYhOaVXZ+j1qjfkgFNGv6XKLIOWLELFVGVJCs4PgOw6RkChHG3Im4FWfAEjkyR9SIMmyNrlGD0ghplMPs8GFAOh6j4dJRDtFFczEwXoyra6m2mnjBADPYMV7TLcqhmnJT9yF3lMO54VKAfsJMOZxCZGONctgAeKMcbgB5tvvt0gUFLp1V2VvzZs+MT59wKPau7i63ifQsWKZhAkszh8yQjiJHBqOmzDsiSzoyxnxi7CduOzanGLX6Y+vUqgLBzDn+0Qm+/ixMkd9jkBo/QHyUlBjK2RESgns4ExjIyVpjnIfAvTRswtHRTrbV6DLKZd7Cpjlpn+UGaxf3koxZiAp/FKGJ9yYiESD4e0mr3zuLhBjVAWJ+EfwJlt/lbyCjeUP8REqf8d69dXx7Be7WZVbt/Hp8LAUgiVLXMwOmYwMmGcFjSbFr57qnHPqVWsMFyqF5NGpS73K4VLmbO+Id5dDkcFoTz50ph1ZMvKKTzUOGRps79AvKYc2hNsrhBpBn3cWVUZQKhqdSU01CUcIuTZ6niXk6YmIAHYYcpl08wD0sF5SGYtwVHWvHAEMRy2W1Ykhh5KVqYwdUybKQH/sA8KNZlM4Uux+dkX0Flx+ztmGZDXSflCfAS1ods5klnGqgV2uKGVBudUir21BMySxHw6bVJ+N1XhAP77FzRtCYHyifyRukH/LOWjXkx36H63dVemDxse7UeCqVcAZM4A3UTyR+Kg1HTkVBApESR/eim0usxmaOiK5qt9oIHLzR9Joobi803I9ZqzZqfNEpPqUckieUQy9RI1kA0pA+Qhl80divDl2wEuTPlEPUIfaMVcohFaUASk3xeKMcbgD5QIrNfuZuPhBUpmLWbVLlO8uY0oGTUsqeYNmC2yVKSkQTzo04qyFumzCMU7Xq3krCdSyUippuF1TGISJJ/WTzbW6c4zcFYLzP+ocxHK1Cs5PxSNIElY51bbjAyRK5ogAhkUurqgNA5jbqE6XZHC3WmadNzpI+yz7MWdpddSc/K+BJ/vv/2t7V9cax5cYiT/eMfDfJBkHy/39dkJcAC3sszUf3YeWBPB89GvlugnvzsixA8FiS7RlrupqHxSoGoU9rEXgZ/cZpZ4yP7rz3XTKNJBUfUL1S+BDSq96m/hrGnOvsG+///08/fx2WQizq5Bk/iIPlMAQZ3Q22SI899g7F85bDIFLRbjlUA+oSBBmWwxNdPe9LvCbLoak6TwLDclgNWF5ZDj1nSo1DqPmFhvZKrkkkQaKPBxq+3hkt4ndpUUDj11Iql+2G6wZsFsPmpqDGEmThRIQa/R7x012vKoxN4TR7+GUaPcpYfTDNDm9xzLyOAAbeYjD6NoQMu4K80uwGq1cAV57XTXZZoVKc5NQAWAx7N8NwRVs3JTEjOX+dJPr8Y1MT/HXKU8P2FytZW0TbdeyLsZhZ7MnfXlG2FastqWfYBb1iVLkA+BDgnaVcAdxRZIeFVfATC0xZHLOzZc4vKuLVZMt3rwasxas+CcIs2v8az3Ms0Lqjrs1y2KyJOinZrfrjYYhcjdjFe+DLbth+myyHc4RjE2qeHTXyYn/kcyfD3HJobfaxizKvCsW0HCZBPl83ez0SoQioJVw0BZzdNNPFRhJyWkxE7/W6sWzWqMT85h9bjdkrEvd5kQS15+cEBT4AKiXcLl5hHYePSAuXzS1UaxdlYnNfe0yzCKkIoixyExoJlilwAuI9xzbw7aM6GiM77NXiUAlcufavuSjQxoIYqvgUCnm4+jgJUN4q8JCJUKLtfQgyuLIn8OAC8scQXPARARN+/FZXp+23012u24baQziexItJkCEH2fW5HnbxhdpixIIhnx01Zu5IibOqVvtsOexHW/RVsEP2OFoO2xIvqleQVHmhVj/VeS+Ku5nUDpZDhPC0ArUULO21Vet/UbcKpOUwCfLl225Z/UijGsO4+qnv+Kqq7BfVIrWe17vKJrRKmAxnTjteGemOFJVICFKhRWQLbiB9tUGM4ThB0qZ8xpb0TQA76eM/MPuA8RKpPje2QWnwHcL3el5udtLtdDMxKEEbA96zfRBzlYgh3LSESM+FRA+s8IO2QKWZjeWT88gvvBrq+w3Ala5EX7oThu33/MlWKbog03qNP4AgSeEVIu/xcbWl3Ki6q6o3NHaO2Ju+2AqHRO3WK8Qs1Ng0ky8K2A6WEGr2I0Fir2OHdRChnRec6uNoOayfhKjPwjBjDKeF58aXrUgfu+F0j2qWQ0YfclgO4zXE0bptOSzmHm/Z/a3HpUDuD1hZnDw5LIe+uoHdcpijPkmQk4r99kSA/GX7hc9dGnomOJflbtedhUZYrVAYqfTVWVJBMRh9pKZWUmSL0KuWzK2hKVaANxg2F0u8XoWItbWzMGwC3tiO24Ir4Z5sAW5U3MWw72fd67nwdDcV9ZyJXoeQU1+UfuXFDhoRicfxIVLiPFdi1YL0ZWQq/v3H814kfbvy3N0ubXwn5htjedYlfNM/ew/Sj9Q/AX73X+VdRK4+siMPQva6ngiaB9c+Dft3IWR2kUQMJosc2ojHcFrpfTyoeGgFJ6FmJo0DmYzB8e40AL+wHHJYDqOK9C2HEtmQ7qhheTr+t2AgUShsshzGjKYWYJ8sh5t1JbtZGeX6dAOLYzf06bzyOccu8Q/bg/zFnZJPup6EAaU/ji/6amOpOJW7VewKbKA9hHaVqu9c8AbRM0ROEC7i1sNCgRn4gKAKpIrRKKgg7lTuVLGISNtgMAEqBcYTSBEDsSuxoaJSQVsLuVU73WEQwXo3qBd7AmGBShEnQlfRPWjCfy+d6BQaBDk+BCoqUAmCDEIUFVXt1xRaxWi3WHz1AzWGvSPxuy/OQh/2bip080239O8LIBcUuXBd7lyXB24P27XgZEatFbUUoO5dRBlhYd7K9dZGWAaDxA5K+izUEE60XagJD3azHKq+Prq3SqwarCnXk4BztBxOS7xCQW/ZkKu45dBWgdyj1/nKctie+7TCQo2oImN0pz0/lUmo0S/lmEQS5K858unN0lVGweFeKl+pfu34pGImYjBUtfrx+Ouy1DeV8w+LQCtTCtRUhQUGwSaGXSopoNgqShGiyGZCEwK607VlFewnH1zU4tPc2OkFSVwoPBV3FN5DXTVC72yySqvyIomik2OrFqNtJfPnYqshopJEGStrpUh77K2BD4A3GtwSSbuA/N5aAGOZFhpBjrEl4OLH6e6Z/gmRDyzLhwgeti7GtxXl+hjzgI0IdgKrfp5vfnXfo40fpE7HAE6WQ5Wj5bDGUgyVrkuN+HlfvcBSUMywLQqW2HLYwiAOlsMnJZuecWGL/7taif1cAO5dqHm2HPZcyTajo3EzkC8shxzP0eaAi5eNzPlhUmcSJHx2bEQPEvKLa4y/w7JT0opJBfZvpW7/suB8uaOqop78QrKpiJmb7BYXZ7t4ugVMSDH67pwWEdFOzO1ardPOZSVsWfvFqY9NYaZh5ShRUpW2Lwf49DF2eRMFisXX14qvtKX4LKeKq9KMpCGzdxg+YHyH2QXghd5vfA8xZqxCYFuLwAtELhBcAPmA4Iql3LmWh/37P9vyX9/pA9xy3H562CLYKj4OkjN87vtZOwoH6cgQasYbQnr1JxKWw1PshVF30HBZRkFYrYfn4rxENJm0UKRPlkNBHNnj2at5cjJVvILU1yM2Q8l+rvtGn/Ol5TDeG1jgA+M2hWZgCDTWyBXyxShC4h+SIFfhJ/L7P7enZYQSUIH1suP2b+sYreDrcpWRUi3H5MBR6XzlzJBXcfxAXRcnWLe9KSoH8am2x4uvbVUF4NWg+lEbbX2tf659X/HSSAjVHYKrLweLY7XZO5vNUXiF4gcMPwD8iNTuadCbF0gE2raUndPyjmp3nIuhokZuJbAUSBvbKXGEfCJIXy/g7pZP7ZMuOERKz3xE/sJyqHv07GbLoWpXgH3PY/Qhd4O9LVgeDxBvo1+5W6/WPlsOx/NTa1sOFcqwHJZZ5JmbkOwC07PlUF5ZDs3XDckOyJuH5667jVbCZDls/09Hy2EiRZo/thzt7zuKYLmbX5fFL7rf5dev9CF5+vqwUhxegZi5lxiGcucQwQmgLCJFWzJ4FLzhq9CwGWqp0wykQWQXwQbRe5TYG0R/Ts/Jwn5yR5EPMdypvIPyAcN3KP8mJt+hbcOgfGDRd8B+Anpl0TvWcofIXv/jX/fyn/9NOStwoxNM9Tgv2asfWZcC2W2IHOY3I4ldLNhqDzzvQk3zWE+OGivlF5ZDBWzzJZMHyyE+Ww7Fd1tX1ch5xPD1/96baxKODpZDErUIFmMfJejH85jR9JavHSyHQLh5wmreXjeLTEJNgT521LX45kMMy6HJk0STFWQS5J8KAXQjJOL1deexx8OD+vMkVeJpNUFcwMaRTwgee00x2lKqoLxXsEjkGRZj0U0hdxRViBYAqhJVZJ+BkeqhGSKxfOzDY6tbD5LFa1R7RJL61lPVgQcgV4CbgBvBW/ijf2DVd+pyheABq5vsVqnrg0UqBGQp3j7YK3BagccDKAWyAdirE+SHzxxy8WAHU0GJ3poVhVY77jfvQkbbRTCtJujOmaiedAgm3ntUHFZJWFgO8cJy+LzE0ax7sjvxfmU5bCERfLIc7m45xM1dPAfLYQ+tkGPLtVWLbW9OO8Yz5h73seXwuGsd3XKIlG+SIP8/SLG3hMSDC8rdUM+C9d2DA+bj0fNBRuaRPBkdJxeMpy13h0GMoYwKFpSq4D+th0xCCDZ5e3vH9e6rIlQegNwiJ/HUeosCFgrWMQYpTvEiuwA7jBU0Tz5XqVQxz7zEQ8gHRYzW9kxpRdG7lWXzz1TI3cTKAn77jVIfwOMeJ/wgw/MJ8uMGfIs9zlsFz6u/4r3C1oLCR8SGEQrDJotXmqclqJ5jsL/aMB+Hkv3Zcng8wf7SctjCLvhiy2FUk7YoqNUPExyTjJhWkwvaCE6zHPp4jy/xIrZVIB8Vgs+WQ4G5UDO3VVQh+94th4XA3m6ecap3JVv+l5bDRBLkH6/6RNq0Xz/lWrF/8/FGCcVSnm7iLUdwVIife0DsjXrBPPHB3oeU+HFwJHPP1slS9kjeeUDlHYIikMWrRHfVmKgRpkrxIXbFAyoGwmBEPa9ENUqt7DtppqdoywKaQR97PAeOPSo+s+clU/WAhd4BEIFsO/i2An+zsfpiq+Bfzi6YVAPfTsOhMis0babv7zkWPlsOD5+fxmPMWyMC+HF/Le6FboPZZTlYDlkKyl7dctiFmhgRmpRsQkevr/chg9BCqHmc9XjT5bGC/Luqu2fLYcuGjNxLfrUZsSf7JJIg/4SGpr/xgrgUWD4qHn9dQd1iWZN6ehifK85hESZfVKXyC7HmUAJ98bzMIKoGFdJtP9N2Kb9eawxc624vpXxfAuVN//CAHKJ6JBTduTqW6SYAVU90a1sCp2Oo7BX2l2/HP7jXQx7jc0jnEGqmER3j1JrAi7nFZ8thzOabQYovAmeJf09jT1FkQTpxayjZ6NKvVoOd/PhPOY9tiC8sh17sz8/JCbJbDreIO/tqkSEm0n1auCvTCaVbDsMB6q4dwBbFEq0A1OEzbJkYmlfxH3uoZFqSEolE4ssDZSKRSCSSIBOJRCIJMpFIJJIgE4lEIgkykUgkkiATiUQiCTKRSCSSIBOJRCIJMpFIJJIgE4lEIgkykUgkkiATiUQikQSZSCQSSZCJRCKRBJlIJBJJkIlEIpEEmUgkEkmQiUQikQSZSCQSSZCJRCKRBJlIJBJJkIlEIpEEmUgkEokkyEQikUiCTCQSiSTIRCKRSIJMJBKJJMhEIpFIgkwkEokkyEQikUiCTCQSiSTIRCKRSIJMJBKJJMhEIpFIJEEmEolEEmQikUgkQSYSiUQSZCKRSPzZ+B+GrlwhibMxxQAAAABJRU5ErkJggg=="; function Sakura(x, y, s, r, fn) { this.x = x; this.y = y; this.s = s; this.r = r; this.fn = fn; } Sakura.prototype.draw = function(cxt) { cxt.save(); var xc = 40 * this.s / 4; cxt.translate(this.x, this.y); cxt.rotate(this.r); cxt.drawImage(img, 0, 0, 40 * this.s, 40 * this.s) cxt.restore(); } Sakura.prototype.update = function() { this.x = this.fn.x(this.x, this.

Vite打包后的dist不能直接在浏览器打开吗

不能 原因 Vite 本身依赖于原生ES模块来做模块加载,而原生ES模块是不支持 file:// 本地访问的。 解决办法 方案一:使用http-server插件启动 1.安装node.js;(已安装跳过) 2.安装http-server。 npm install http-server -g 或 yarn global add http-server 3、进入dist根目录执行启动项目 http-server 方案二:使用nginx启动 1、把dist拷贝至nginx的html目录下(其他目录也行,需在nginx里配置root); 2、配置nginx.conf 3、保存并启动nginx,访问http://127.0.0.1:3000即可。 (完)

哈工大软件构造实验Lab2

目录 1 实验目标概述··· 1 2 实验环境配置··· 1 3 实验过程··· 1 3.1 Poetic Walks· 1 3.1.1 Get the code and prepare Git repository· 1 3.1.2 Problem 1: Test Graph <String>· 1 3.1.3 Problem 2: Implement Graph <String>· 1 3.1.3.1 Implement ConcreteEdgesGraph· 2 3.1.3.2 Implement ConcreteVerticesGraph· 2 3.1.4 Problem 3: Implement generic Graph<L>· 2 3.1.4.1 Make the implementations generic· 2 3.1.4.2 Implement Graph.empty()· 2 3.1.5 Problem 4: Poetic walks· 2 3.1.5.1 Test GraphPoet· 2

GNN(图神经网络)基本概念

功能:节点分类和图分类 空域 :空间上考虑图结构的模型,即考虑目标节点和其他节点的几何关系(有无连接)。 模型代表:GAT(Graph Attention Networks)图注意力模型 用注意力机制对邻近节点特征加权求和。邻近节点特征的权重完全取决于节点特征,独立于图结构。 (将卷积神经网络中的池化看成一种特殊的平均加权的注意力机制,或者说注意力机制是一种具有对输入分配偏好的通用池化方法(含参数的池化方法) 图 1:图注意力网络示意图和更新公式 对于上述公式的一些解释: 公式(1)对 l 层节点嵌入 做了线性变换,W^((l)) 是该变换可训练的参数 公式(2)计算了成对节点间的原始注意力分数。它首先拼接了两个节点的 z 嵌入,注意 || 在这里表示拼接;随后对拼接好的嵌入以及一个可学习的权重向量 做点积;最后应用了一个 LeakyReLU 激活函数。这一形式的注意力机制通常被称为加性注意力,区别于 Transformer 里的点积注意力。 公式(3)对于一个节点所有入边得到的原始注意力分数应用了一个 softmax 操作,得到了注意力权重。 公式(4)形似 GCN 的节点特征更新规则,对所有邻节点的特征做了基于注意力的加权求和。 频域: 模型代表:GCN(Graph Convolutional Network )图卷积网络 优点:省参数 缺点:不易作用于动态图 (对于同阶的邻域上分配给不同的邻居的权重是完全相同的(无法允许为邻居中的不同节点指定不同的权重) 一次图卷积操作包含对邻节点特征的标准化求和: 其中 N(i) 是对节点 i 距离为 1 邻节点的集合。我们通常会加一条连接节点 i 和它自身的边使得 i 本身也被包括在 N(i) 里。 是一个基于图结构的标准化常数; σ是一个激活函数(GCN 使用了 ReLU); W^((l)) 是节点特征转换的权重矩阵,被所有节点共享。 由于 c_ij 和图的机构相关,使得在一张图上学习到的 GCN 模型比较难直接应用到另一张图上。 共同步骤: 加工图邻接矩阵对图邻接矩阵特征分解,得到特征值,核心区别(如何收集并累和距离为 1 的邻居节点的特征表示 ) 将特征向量看作常数,而卷积核作用在特征值上 GAT 用注意力机制替代了图卷积中固定的标准化操作,将原本的标准化常数替换为使用注意力权重的邻居节点特征聚合函数。

学会正确地二次封装组件,让同事抱着你的大腿喊大神!

highlight: a11y-dark 一、二次封装的需求场景 二次封装,是指因为业务上的需要,对element-ui、antd、e-chart等其他组件库,做二次封装。以下是常见的二次封装场景: 1.封装UI样式 说个我做项目遇到的情况,项目里用到组件库的是antd,antd的搜索框长这样 但是ui图长这样: 如果要实现和ui图一样的效果,你就需要利用前缀和后缀的插槽,加上搜索图标和清空图标: <a-input :placeholder="placeholder" :style="inputStyle" @keydown.enter=handleEnter v-model="searchValue" @change="searchValueChange"> <a-icon slot="prefix" type="search"/> <a-icon slot="suffix" v-show="searchValue!='' || manualHide" type="close" style="cursor: pointer" @click="clearSearchValue"/> </a-input> 有时还需要改改样式: <style lang="less" scoped> /deep/ .ant-input:hover { border-color: #f5222d; } /deep/ .ant-input:focus { border-color: #ff4d4f; box-shadow: 0 0 0 2px rgba(245, 34, 45, 0.2); } </style> 那么这样就带来一个问题,要知道搜索框可是复用频率很高的,如果每次都需要粘贴同样的插槽和样式代码,那不是很憨憨吗? 而且后期维护,如果要改搜索框的样式,那就得改好几处地方,所以这一段组件是一定要封装的。 2.封装业务逻辑 在真实的项目中,我们需要封装一些与业务数据绑定的选择器。 比如下面这个表格选择器,在文件夹里面选择用户上传的表。基本项目所有业务都是需要选表的,所以这个组件复用频率很高。 这种业务组件的特点是,组件会带有很多业务数据请求的方法,比如下面这种请求后台数据,然后把数据绑定在表格组件上。 loadData(arg) { let params = this.getQueryParams()//查询条件 this.loading = true queryFolderList(params).then((res) => { if (!

品牌定位个性六种形态及结论的重大意义

一、品牌定位个性六种形态 1、仪式型 品牌与特殊场合连结,使品牌成为一种经验; 2、标志型 透过标志增加附加价值; 3、优良传承型 第一个以某种特性为诉求的品牌,通常可将自己定位成该品类的先驱; 4、傲气逼人型 设计师的品牌通常为此类,显示其与众不同; 5、归属感型 让消费者觉得可融入其所向往的族群; 6、传奇型 品牌有其真正的历史渊源而且几乎成为神话(Levi’s 501-于19世纪推出的第一条牛仔裤;Timberland-印第安土著平底靴手法制造) 二、品牌定位结论重大意义 1、品牌定位是品牌识别体系的最前沿。 2、品牌定位是品牌与消费者沟通的策略性指导原则。 3、没有正确清楚的品牌定位, 任何沟通活动就像没有目标的飞矢。 4、制定品牌定位是产品/品牌负责人的天职。 5、品牌定位是需经由对消费者和竞争品牌的了解,不断思考揣摩及修正。 6、成功的品牌定位是品牌成功之母。 haowel.com

从零学Java(31)之构造方法

作者简介 作者名:编程界明世隐 简介:CSDN博客专家,从事软件开发多年,精通Java、JavaScript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注,期待与您一起学习、成长、起飞! 导航 ✪ 从零学Java系列目录索引 ◄上一篇【30】递归 ►下一篇【32】参数传递 引言 ♀ 小AD:明哥明哥,几天不见你都王者10几星了,这是要冲荣耀的节奏吗? ♂ 明世隐:那必须的,我最近贼猛了。 ♀ 小AD:还得是我明哥呀! ♂ 明世隐:😄😄 ♀ 小AD:我星耀都还没上。。。,你不觉得脸上没光吗? ♂ 明世隐:跟我有什么关系,你在砖石多挣扎几次,指不定剑指荣耀呢! ♀ 小AD:荣耀个鬼哦,我上来星耀再说。 ♂ 明世隐:我说的是荣耀黄金😂😂😂 ♀ 小AD:你这个人,太坏了,我用脚趾打,也不至于吧🙈🙈 ♂ 明世隐:你知道你为啥上不去吗? ♀ 小AD:不就是操作不够、意识不行?我知道的。 ♂ 明世隐:对,这是一方面,还有一方面你出装也不是很对。 ♀ 小AD:怎么就不对了,我都是按推荐出装选的,选完英雄后就有个推荐出装,比如这个 ♂ 明世隐:这个装备没毛病,但是要看人的要,意识不行,操作不行就不能光出这个装备,输出是很高,但没有容错率,分分钟暴毙。 ♀ 小AD:我知道我操作不行,那大家都这样出呀! ♂ 明世隐:所以你换个思路,多出些肉装,打野一套秒不了你,接下来你就可以反打了。 ♀ 小AD:那作为一个射手,出肉装有什么用,我是要打输出的呢。 ♂ 明世隐:话是没错,可你一秒就蒸发了,还怎么打输出呢,生存下来了,才有机会输出。 ♀ 小AD:好像有那么一丢丢道理。 ♂ 明世隐:不是一丢丢,是很有道理,我最近就用肉凯上了一波大分,你以为我的星星是天上掉下来的。 ♀ 小AD:肉凯?我没听错吧,这英雄不是一刀一个小鲁班吗?峡谷凯爹谁不知道。 ♂ 明世隐:出肉也就3、5刀一个小鲁班,贼能抗,经常一打3,如果发育好的话甚至1打5。 ♀ 小AD:出肉你有伤害吗? ♂ 明世隐:你去看了就知道了,看我战绩去,伤害也是非常爆表(靠大招和装备的被动打伤害),容错率比暴击凯高的多,正好符合我的性格冲锋陷阵! ♀ 小AD:哦,出装我看看,虽然我不玩。 ♂ 明世隐:好 ♀ 小AD:那我鲁班怎么出呢? ♂ 明世隐:看这个,就靠末世打输出 ♀ 小AD:我试试,那你什么时候带我上分 ♂ 明世隐:就今天啊,择日不如撞日!

MATLAB画小猪佩琪

程序分析 绘制小猪佩琪图像主要就是用许多椭圆、线条拼接而成的;为了方便绘制椭圆我自定义一个椭圆函数具体使用方法可以参考之前推文链接EllipseAndCircle函数 椭圆函数 function XY=EllipseAndCircle(varargin) % author:2377389590@qq.com % EllipseAndCircle(a,b,x,y,Angle,Rotate,LineColor,LineWidth,PlotType,FillColor,Alpha) % a、b :为长短半径 % x,y :圆心坐标 % Angle :开始/结束角度 % Rotate:旋转角度 % LineColor:线条颜色 % LineWidth:线宽 % FillColor :填充的颜色 % Alpha:透明度 a=varargin{1};b=varargin{2}; x=varargin{3};y=varargin{4}; Angle=varargin{5};Rotate=varargin{6}; LineColor=varargin{7}; LineWidth=varargin{8}; theta=Angle(1):pi/100:Angle(2); X=x+a*cos(theta); Y=y+b*sin(theta); XY=[X;Y]'*[cos(Rotate),-sin(Rotate);sin(Rotate),cos(Rotate)]; if length(varargin)==8||strcmp(varargin{9},'plot' ) plot(XY(:,1),XY(:,2),'-','color',LineColor,'linewidth',LineWidth); hold on; axis equal elseif length(varargin)==11||strcmp(varargin{9},'fill' ) try FillColor=varargin{10}; Alpha=varargin{11}; fill(XY(:,1),XY(:,2),FillColor,'LineWidth',LineWidth,'FaceAlpha',Alpha,'edgecolor',LineColor) % hold on; axis equal catch disp('参数输入错误1') end else disp('参数输入错误2') end end “猪尾巴”曲线 为了找到合适的符合“猪尾巴”卷曲的曲线方程,小编把落灰的高数书翻了一遍,最后发现使用阿基米德螺旋线变形方式可以达到类似的效果 clc;clear;close all theta = -5*pi:0.

Gitlab 基础配置

Gitlab 基础配置 文章目录 Gitlab 基础配置1. 邮箱发送短信2. 注册账号3. 创建项目3.1 创建空白项目3.2 创建模板项目3.3 导入项目 4. 删除项目5. gitlab项目上传github 1. 邮箱发送短信 $ docker exec -ti gitlab bash $ vi /etc/gitlab/gitlab.rb gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp-mail.outlook.com" gitlab_rails['smtp_port'] = 25 gitlab_rails['smtp_user_name'] = "<xxxx>@outlook.com" gitlab_rails['smtp_password'] = "<xxxxx>" gitlab_rails['smtp_domain'] = "outlook.com" gitlab_rails['smtp_authentication'] = "login" gitlab_rails['smtp_enable_starttls_auto'] = true gitlab_rails['smtp_tls'] = false gitlab_rails['gitlab_email_enabled'] = true gitlab_rails['gitlab_email_from'] = '<xxxx>@outlook.com' gitlab_rails['gitlab_email_display_name'] = 'Gitlab' 保存退出修改,执行命令gitlab-ctl reconfigure重新配置gitlab $ gitlab-ctl reconfigure 执行命令gitlab-ctl console测试发邮件,进入控制台之后执行命令 Notify.test_email('<xxxxxx>@139.com', '邮件标题', '邮件正文').

mysql Blob和Text类型

一、基本概念 1.Text类型(大文本系列)===>>VARCHAR的增强 TINYTEXT: 255个字节 TEXT: 65535字节 MEDIUMTEXT: 16M LONGTEXT: 4G 2.Blob类型(大二进制系列)===>>BINARY的增强 TINYBLOB: 255个字节 BLOB: 65535字节 MEDIUMBLOB: 16M LONGBLOB: 4G 3.分别对应的java类型及其应用 ① 存储一部小说或者text类型的文档,此时考虑使用TEXT系列. TEXT系列对应Java中的String类型. 仅仅只需要把VARCHAR改成TEXT系 列 即可,Java代码不需要改动. ②二进制类型,主要用来存储图像,音频,视频等二级制数据. 一般的,在开发中我们都不会把二进制数据保存到数据库中,而是把二进制文件的保存路径存储在数据库中,再通过路径去找到文件即可. 二、主要的差别 1、主要差别 TEXT与BLOB的主要差别就是BLOB保存二进制数据,TEXT保存字符数据。目前几乎所有博客内容里的图片都不是以二进制存储在数据库的,而是把图片上传到服务器然后正文里使用<img>标签引用,这样的博客就可以使用TEXT类型。而BLOB就可以把图片换算成二进制保存到数据库中。 2、类型区别 BLOB有4种类型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它们只是可容纳值的最大长度不同。 TEXT也有4种类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这些类型同BLOB类型一样,有相同的最大长度和存储需求。 3、字符集 BLOB列没有字符集,并且排序和比较基于列值字节的数值值。TEXT列有一个字符集,并且根据字符集的校对规则对值进行排序和比较 4、大小写 在TEXT或BLOB列的存储或检索过程中,不存在大小写转换,都一样! 5、严格模式 运行在非严格模式时,如果你为BLOB或TEXT列分配一个超过该列类型的最大长度的值值,值被截取以保证适合。如果截掉的字符不是空格,将会产生一条警告。使用严格SQL模式,会产生错误,并且值将被拒绝而不是截取并给出警告。 6、其它 当保存或检索BLOB和TEXT列的值时不删除尾部空格。 对于BLOB和TEXT列的索引,必须指定索引前缀的长度。 BLOB和TEXT列不能有默认值。 当排序时只使用该列的前max_sort_length个字节。max_sort_length的 默认值是1024。 当你想要使超过max_sort_length的字节有意义,对含长值的BLOB或TEXT列使用GROUP BY或ORDER BY的另一种方式是将列值转换为固定长度的对象。标准方法是使用SUBSTRING函数。 BLOB或TEXT对象的最大大小由其类型确定,但在客户端和服务器之间实际可以传递的最大值由可用内存数量和通信缓存区大小确定。你可以通过更改max_allowed_packet变量的值更改消息缓存区的大小,但必须同时修改服务器和客户端程序。 三、慎用 BLOB与TEXT是为了存储极大的字符串而设计的数据类型,采用二进制与字符串方式存储。mysql对待这两个类型可谓煞费苦心,mysql会把这两种类型的值当做一个独立的对象处理,存储引擎在存储时通常会做特殊处理, 当BLOB与TEXT的值太大时,InnoDB会使用专门的“外部”存储区域来进行存储,此时每个值在行内会采用1~4个自己存储指针,在外部存储区域存储实际值。 Mysql对BLOB与TEXT类型进行排序的处理上与其他类型不同,只针对最前面的max_sort_length自己进行排序,如果只需要对前面的更少的字节进行排序,那么可以通过设置max_sort_length参数或者substring(value,length)来截取部分字符串。 在实际使用中应该慎用这两个类型,尤其是会创建临时表的情况下,因为如果临时表大小超过max_heap_table_size或者tmp_table_size,就会将临时表存储在磁盘上,进而导致整体速度下降!

笛卡尔空间轨迹规划(直线、圆弧)

目录 毕设(5)—笛卡尔空间轨迹规划(直线、圆弧) 直线轨迹规划圆弧轨迹规划Matlab代码验证 毕设中用到了很多代码,其中一部分我通过看书和看论文学习并实现的代码,会通过Gitee仓库分享出来,这些代码仅用于学习使用,祝各位毕业生顺利完成毕设! 毕设系列内容:毕业设计——四自由度机械臂轨迹规划 毕设(5)—笛卡尔空间轨迹规划(直线、圆弧) 机械臂在笛卡尔空间中常用的规划算法有直线和圆弧两种,他们的具体实现都是通过运动学逆解将运动轨迹转化为关节角度变化序列的方式。 直线轨迹规划 设机械臂任务是从空间中两点\(P_1\)、\(P_2\)间运动,如下图所示 则两点长度\(L\)可得 \[L=\sqrt{(x_1-x_0)^2+(y_1-y_0)^2+(z_1-z_0)^2} \] 在本文中采用的速度规划是匀速,如果有S型之类的速度规划算法也可以采用 \[d=v\cdot t \] d为一个插补周期内移动的距离,t为插补的时间间隔 圆弧轨迹规划 空间中两两不在同一条直线的三点可确定一个平面,也可以确定一个圆弧。设空间中有三点\(P_1\)、\(P_2\)、\(P_3\),机械臂需要通过三点沿圆弧轨迹运动,如下图所示 矢量图我用的是AxGlyph软件画的,有需要可以自行到官网购买 公式太多,不再赘述,大致流程如下 求出\(P_{123}\)、\(P_{12}\)和\(P_{23}\)的方程,通过三个平面方程获得圆心\(O_1\)坐标和圆弧半径在\(P_{123}\)平面建立新坐标系,计算两个坐标系之间的齐次变换矩阵在\(P_{123}\)平面计算平面圆弧的轨迹,通过变换矩阵转换为空间圆弧轨迹圆弧轨迹通过运动学逆解转换为各关节角度变化序列 Matlab代码验证 代码有点长,具体函数代码可以到仓库中自行查找 test4.m clear, clc, close all; L(1) = Link([0 0 0 0 0 0], 'modified'); L(2) = Link([0 0 0 -pi / 2 0 0], 'modified'); L(3) = Link([0 0 135 0 0 0], 'modified'); L(4) = Link([0 0 147 0 0 0], 'modified'); L(5) = Link([0 131 61 -pi / 2 0 0], 'modified'); robot = SerialLink(L, 'name', 'Dobot'); angle1 = [-pi / 3, -pi / 9, pi / 3, -2 * pi / 9, 0]; angle2 = [-pi / 9, -pi / 3, pi / 2, -pi / 6, pi / 9]; angle3 = [7 * pi / 36, -pi / 4, 5 * pi / 12, -pi / 6, 2 * pi / 9]; angle4 = [4 * pi / 9, -pi / 9, 7 * pi / 18, -5 * pi / 18, pi / 3]; angleT = [angle1; angle2; angle3]; for i = 1:size(angleT, 1) fk = myfkine(angleT(i, :)); points(i, :) = [fk(1, 4), fk(2, 4), fk(3, 4)]; theta5(i) = angleT(i, 5); end [q, t] = line_traj(points, theta5, [0, 5], 100); %[q, t] = arc_traj(points, theta5, [0, 5, 10], 40); qdeg = rad2deg(q); figure(1); T = zeros(4, 4, size(q, 1)); for i = 1:size(q, 1) T(:, :, i) = myfkine(q(i, :)); end plot3(squeeze(T(1, 4, :)), squeeze(T(2, 4, :)), squeeze(T(3, 4, :)), 'r-', 'LineWidth', 2); title('轨迹图'); hold on; plot3(points(:, 1), points(:, 2), points(:, 3), 'bo', 'MarkerSize', 7, 'LineWidth', 2); hold on; robot.

RSA加解密算法的简单实现

就前不久完成的RSA加解密实现这一实验来水一篇文章 算法原理: 一.米勒拉宾素性检测算法 米勒-拉宾(MillerRabbin)素性测试算法是一个高效判断素数的方法。 其涉及到的原理如下: 1、费马小定理: 如果p为质数 (在mod p 的情况下) 2、对于任意一个小于p的正整数x,发现1(模p)的非平凡平方根存在,则说明p是合数。 其中定理第二部分可以理解为: 如果p是一个素数,0 < x< p, 则方程 ≡ 1(mod p) 的解为 x=1 ,x= p-1 反之 如果 x^ 2 ≡ 1(mod p) 的解不是 x=1 ,x= p-1 那 p 就不是素数 二.拓展欧几里得算法 如果a、b是整数,那么一定存在整数x、y使得ax+by=gcd(a,b) 1、首先,对于要求最大公约数的两个数 a, b 一定存在满足上式关系; 2、对上式往下层层递推: (1)…ax + by = gcd (a, b); (2)…bx1 + a % by1 = gcd (b, a%b); (运用欧几里算法) (3)…gcd (a, b) = gcd(b,a%b); (欧几里得算法) (4)…ax + by = b x1 + a % b*y1; (在计算机里 a % b = (a - a / b * b))

软考高级,信息系统项目管理师(高项)经验分享

软考高级,信息系统项目管理师(高项)经验分享 信息系统项目管理师(俗称高项)成绩出来了,终于成为高级工程师了。 本文以编写整体管理论文的格式进行,将分为项目启动、项目计划、项目执行、项目检查、项目收尾5个过程回顾高项的考试历程,希望对其他同学有借鉴意义。个人觉得可能对于一次考不过的人参考价值比较大。 第一阶段、项目启动阶段Start——决定考哪个科目。 如图,高级资格的类型有:信息系统项目管理师、系统分析师、系统架构设计师、网络规划设计师、系统规划与管理师。 通过百度得知,信息系统项目管理师网上评价是这么多科目里头资料最多,通过率最高,考起来最容易的。 第二阶段、项目规划阶段Plan——制定学习计划。 明确考试方向之后,我制定了的学习计划, 1月1日-1月15日 收集相关学习资料和考试信息。 1月16日-4月40日 学习相关教程 5月份参加考试。 第三阶段、项目执行阶段Do——开始学习。 3.1怎么还有分第一版,第二版,第三版? 刚刚开始,我上百度去找《信息系项目管理师教程》,发现居然有第二版,第三版等。后来才知道原来2012年下半年开始用第二版,17年下半年开始用第三版也就是目前的版本。 然后PDF居然百度上也找不到!我放弃了,打开万能的淘宝,买了一本PDF。卖家还贴心的送了我马老师、胡老师、江山老师等等的教程。 3.2单纯看书真的很难。 开始觉得看一下书一般就可以了。我一般白天有空看会书,晚上陪孩子睡觉,然后拿出手机一天看一些。前面一些基础知识,还算看的懂,但是看到后面慢慢开始一脸懵逼,感觉好像大学的时候看离散数学。当初看离散数学这种比较难懂的书的时候我大不了就是这个章节看个2~3次大概就能懂了,但是高项的这本《信息系项目管理师教程-第3版》看不懂的章节我硬生生的看了5次,还是一头雾水,感觉无法入门,抓不到灵魂。好吧计算机的书有时候也是这样的,前面的章节的知识在后面几个章节才会讲。于是我决定囫囵吞枣的把整本书看完。可是我硬着头皮看了两遍,还是看不懂。 最后我决定还算看视频吧,应该能看的懂。 3.3看视频。 由于卖家给我的视频有很多。什么马老师、胡老师、江山老师一堆老师的视频。 看到现在,总结一下,初期入门,建议看马老师、江山老师。看完两位老师的视频,基本上科目一,科目二的内容就算能入门了。 然后如果还是不太懂,可以看看阿诺老师的视频,她说的内容会比考试多一些,但是更全面,能够更好的理解整个10大领域。 然后再看胡老师的论文课程。 基本上这几个老师的视频看完,再做一些历年真题,10大管理的论文准备一下,就可以上考场了。 第四阶段、项目检验阶段Cheak——考试才是最好的检验标准。 4.1第一轮考试 我看完了马老师,胡老师的视频,做了点真题,自己组织了范围进度两篇论文。自我感觉还不错。就去考试了。 结果,46、45、37.论文挂了。 不过确实那些视频看完科目1科目2问题不大。 4.2第二轮考试 第二轮我的复习重点改变,重点复习论文。 我掏钱买了胡老师的论文,因为胡老师有论文批改的服务。 然后直接以之前做过的一个项目作为背景准备了7篇论文。 同时科目一科目二,分数也比较危险,所以我就买了马老师的最新视频。 但是因为太注重论文了,科目一科目二没有好好复习。 结果,41、36、47只有论文过了。 4.3第三轮考试 这次,我本着要最新的资料的思路。我又买了江山老师和阿诺老师的视频,好好巩固基础知识,加上马老师视频的更新。 这次我是论文和基础知识两手抓,两手都要硬。 原先打算准备一下安全的论文,结果发现安全的框架很难确定,范文也很少。所以最后决定放弃安全。 因为这几年流行写双拼,所以我直接准备了10篇论文,要写双拼论文的时候,就是抽出其中两篇,删减一点,然后拼接起来。每个过程里头的例子其实是可以相互穿插着用的。当然,必须是同一个项目,如果论文是不同项目的互相穿插使用,总有点不流畅的样子。最简单的,项目预算和项目工期这种东西,如果不是同一个项目,写进度管理和成本管理双拼的时候就特别假。比如7个月的工期,人力资源方面的预算不可能才给10万,这些都是要用实际项目或者经过推敲和整理才能写的符合逻辑。 最终,这次我以54、55、51的成绩通过了 第五阶段、项目收尾阶段Act——整体回顾。 整个考试。最终整理出来的资料。88G 5.1输入: 1. 《信息系项目管理师教程-第3版》--68M 2. 视频教程--74G 3. 历年真题—78M 4. 复习过程中收集的别人考过的论文—143M 5. 中级教程,拿来参考的—500M 6. 各种杂项资料--43M 7. 其他一些七七八八的 5.2工具技术(经验教训): 1. 可以背诵ITTO。 很多老师说不用背诵,但是我感觉背诵了ITTO对论文有帮助,所以我去背诵了,还整理了一下。因为我的论文是以ITTO为大纲,以工具技术为例子来写的。过程中确实不好背诵,之前请教过一个网友,他是一名博士生,他说很好背啊,背不下来抄写10次,肯定会背了。所以我抄了10次,确实背下来了。 2. 背诵一些常见知识点。 这些知识点就是科目二里头那些问答题的知识点,其实科目三的时候也会作为子题目出题的,所以还是要背诵的。最简单的,比如项目管理计划编制的过程有哪些?我特意整理了一个口诀:母队受处(分),总管审计。我把这些常见知识点都整理在笔记和ITTO里头,便于回顾复习。 3. 看视频。

多个事务并发执行(交叉并发方式、同时并发方式)、并发操作带来数据不一致性主要包括(丢失修改,不可重复读,读“脏”数据)、封锁(概念、类型)、活锁和死锁(概念、预防/解决方法)

并发(同时)控制学习内容主线 引言 1、多个事务串行执行。 执行方式:第一个事务做完——》第二个事务... 优点:调度简单(按一定次序执行),事务之间不会互相干扰,不会破坏事务的ACID特性。 缺点:不能充分利用资源 2、多个事务并发执行。 →交叉并发方式(单CPU) →同时并发方式(多CPU) 本章讨论的数据库系统并发控制技术是以单处理机系统为基础的交叉并发方式。 事务并发执行可能带来的数据不一致问题 并发操作带来数据不一致性主要包括: →丢失修改: T1事务获取数据为16,T2事务获取数据为16,T1将数据-1为15,而T2的值仍为16,所以T2将获取的数据-1后仍为15 →不可重复读: T1事务没有处理完,T2事务将数据修改后,T1数据查询并使用了修改后的事务 →读“脏”数据: T1事务修改了数据的值:200,T2获取T1的值:200,此时T1出现故障,数据恢复为100,而此时,T2获取数据的值为200,与此时数据的值不符。 1、丢失修改。以飞机订票为例 T甲 售票点 T乙售票点时刻1:R(A)=16(即:有16张票)时刻2R(A)=16 时刻3: A=A-1 W(A)=15 卖出一张票(将剩下的票写回去) 时刻4 A=A-1 W(A)=15 卖出一张票(将剩下的票写回去) 数据覆盖导致丢失修改甲事务的执行被乙事务干扰,破坏了事务的隔离性 2、不可重复读(不可重复获取数据) T1 事务(R为读) T2事务 时刻1: R(A)=50 R(B)=100 求和=150 时刻2: R(B)=100 B=B*2 W(B)=200 时刻3: R(A)=50 R(B)=200(重复了) 求和=250 (验算不对) 破坏了事务的隔离性 3、读“脏”数据 T1 事务(R为读) T2事务 时刻1: R(C)=100 C=C*2 W(C)=200 时刻2:R(C)=200 时刻3: 出现故障,回滚数据 ROLLBACK C恢复为100 破坏了事务的隔离性 产生上述三类数据不一致性的主要原因是并发操作破坏了事务的隔离性。并发控制就是要用正确的方式调度并发操作,使一个用户事务的执行不受其他事务的干扰,从而避免造成数据的不一致性。 解决办法:封锁 封锁 1、封锁概念 封锁就是事务T在对某个数据对象(例如表、记录等)操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其它的事务不能更新此数据对象。 2、基本的封锁类型有两种 排他锁(简称x锁): 排他锁又称为写锁,若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它事务都不能再对A加任何类型的锁,直到T释放A上的锁。这就保证了其他事务在T释放A上的锁之前不能再读取和修改A。 (加锁事务可读可改,其它事务不可读不可改)

CSS之BFC

一、什么是BFC? 官方解释:Formatting context 是 W3C CSS2.1规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。最常见的Formatting context 有 Block fomatting context (简称BFC)和 Inline formatting context (简称IFC)。Block formatting context直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与,它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。通俗地讲,BFC是一个容器,用于管理块级元素。通俗理解:BFC是一个独立的布局环境,可以理解为一个容器,在这个容器中按照一定规则进行物品摆放,并且不会影响其它环境中的物品。如果一个元素符合触发BFC的条件,则BFC中的元素布局不受外部影响。 二、如何创建BFC(条件) 给元素添加浮动float为 left、right;给元素添加overflow为 hidden、auto、scroll;给元素添加display为 table-cell、table-caption、inline-block、inline-flex、flex;给元素添加定位position为 absolute、fixed;根元素body; 三、BFC布局规则(特点) 内部的Box会在垂直方向,自上而下排列,一个接一个地放置(即块级元素独占一行)。BFC的区域不会与float box(浮动容器)重叠(利用这点可以实现自适应两栏布局)。内部的Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠(margin重叠三个条件:同属于一个BFC;相邻;块级元素)。计算BFC的高度时,浮动元素也参与计算。BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。每个元素的左margin值和容器的左border相接触。 四、BFC的作用 解决margin的重叠问题: 由于BFC是一个独立的区域,内部的元素和外部的元素互不影响,将两个元素变为两个BFC,就解决了margin重叠的问题。 解决垂直布局的块级盒子上下外边距折叠: 如果有垂直布局的盒子,上盒子设置下外边距10px,下盒子设置上外边距20px,那么最后的布局只会让较大的外边距生效,不会一起生效。 <style> .box{ background-color: blueviolet; } .box .son{ width: 50px; height: 50px; } .son1{ background-color: red; margin-bottom: 10px; } .son2{ background-color: orange; margin-top: 20px; } </style> <body> <div class="box"> <div class="son son1"></div> <div class="son son2"></div> </div> </body> 这时让其中一个盒子创建BFC,就能解决外边距折叠问题。如套上div大盒子,设置overflow:hidden

一条命令运行rancher

1、rancher安装 控制台中rke用户下执行docker命令: docker run --name=rancher -d --privileged --restart=unless-stopped -p 30040:80 -p 30050:443 rancher/rancher:latest 2、检查是否正常启动 可通过下面两个命令查看: docker ps | grep rancher ## 查看正在运行中的docker容器 3、浏览器访问 输入https://IP:PORT 点击高级,然后点击继续前往 4、密码 根据提示,输入并修改密码 浏览器输入密码后,选择红框的,并在下方输入自己想要设置的密码 进入后里面有一个默认的k3s 5、加入其他存在的集群 点击Import Existing 选择Generic 集群名字随意输入,只要你能记住 根据红框的操作执行命令注册进来 执行命令 kubectl apply -f https://172.17.8.51:30050/v3/import/2llq4b95zbspwqlcjrb898dtwqmqgtcxtfxjdlkgp8c79jpzf8tfn6_c-m-5ffgdfz6.yaml 报了认证的问题,执行第二个命令 curl --insecure -sfL https://172.17.8.51:30050/v3/import/2llq4b95zbspwqlcjrb898dtwqmqgtcxtfxjdlkgp8c79jpzf8tfn6_c-m-5ffgdfz6.yaml | kubectl apply -f - 我这边是运行成功了

启动参数详解(System.getProperty,ApplicationArguments)

一.前言 在我们的项目中,如果想在启动参数中定义一些自定义的参数,然后在程序中使用,应该怎么处理呢?下面介绍两种最常用的方法. 二.普通Java项目 我们可以在VM options中定义一些启动参数,然后使用System.getProperty()在项目中获取并使用. 举例: 我们定义的参数是selfArgs,对应的值是bling,-D是固定写法. 在项目中直接获取: 注意:在使用jar包方式启动时,系统参数一定要放在jar名称前,否则会不起作用 例: java -jar -DselfArgs=bling xxx.jar 除了一些自定义参数,System.getProperty还可以获取以下这些系统参数. sun.desktop awt.toolkit java.specification.version sun.cpu.isalist sun.jnu.encoding java.class.path java.vm.vendor sun.arch.data.model user.variant java.vendor.url user.timezone os.name java.vm.specification.version sun.java.launcher user.country sun.boot.library.path sun.java.command jdk.debug sun.cpu.endian user.home user.language java.specification.vendor java.version.date java.home file.separator java.vm.compressedOopsMode line.separator java.specification.name java.vm.specification.vendor java.awt.graphicsenv user.script sun.management.compiler java.runtime.version user.name path.separator os.version java.runtime.name file.encoding java.vm.name java.vendor.version java.vendor.url.bug java.io.tmpdir java.version user.dir os.arch java.vm.specification.name java.awt.printerjob sun.os.patch.level java.library.path java.vendor java.vm.info java.vm.version sun.io.unicode.encoding java.class.version 三.

Abaqus CPU并行计算 加速计算信息汇总

Abaqus CPU并行计算 加速计算信息汇总 下面是网络上https://www.eng-tips.com/viewthread.cfm?qid=445089的答疑: In Abaqus CAE, what does it mean Use multiple processors? Does that mean number of processors or number of cores? Meaning if I have a computer with 8 processors and each of them several cores; should I put the number of processors or total number of cores to use? 在Abaqus CAE中,使用多处理器是什么意思?这是指处理器的数量还是核心的数量?这意味着如果我有一台有8个处理器的计算机,每个处理器有多个内核;我应该输入要使用的处理器数量还是内核总数? 答复:Multiple processors in the context of Abaqus usually mean cpu threads. Lets say you have two physical CPUs with 8 cores each (Intel) with hyperthreading (2 threads per CPU core).

C语言大作业 俄罗斯方块(一)主界面和排行榜界面

目录 主界面 排行榜界面 主界面 1.创建绘图窗口,大小为640x360像素 initgraph(640, 360, SHOWCONSOLE); setbkmode(TRANSPARENT); SHOWCONSOLE 显示控制台窗口; TRANSPARENT 背景是透明的; 2.打开音乐,循环播放音乐 mciSendString("open BGM.mp3", NULL, 0, NULL); mciSendString("play BGM.mp3 repeat", NULL, 0, NULL); open 打开音乐; play 播放音乐,repeat 重复播放; stop 关闭音乐; 3.设置背景图片,文字,声音图标 //背景图片 IMAGE background; loadimage(&background, "background.jpg", 640, 360); putimage(0, 0, &background); //字体 settextstyle(70, 0, FONT); settextcolor(RGB(65, 105, 225)); outtextxy(160, 50, "俄罗斯方块"); //声音图片 IMAGE sound; loadimage(&sound, "sound.png", 40, 40); putimage(600, 0, &sound); 4.设置按钮(圆角矩形+文字) void button(int x, int y, int w, int h, const char* text) { setfillcolor(RGB(240, 248, 255)); fillroundrect(x, y, x + w, y + h, 10, 10); settextstyle(20, 0, FONT); settextcolor(RGB(105, 147, 211)); int tx = x + (w - textwidth(text)) / 2; int ty = y + (h - textheight(text)) / 2; outtextxy(tx, ty, text); } 5.

juc之CurrentHashMap (二)

我们熟知的缓存技术(比如redis、memcached)的核心其实就是在内存中维护一张巨大的哈希表,还有大家熟知的HashMap、CurrentHashMap等的应用。 文章目录 1.ConcurrentHashMap与HashMap等的区别1.1 HashMap1.2 HashTable 2.ConcurrentHashMap2.1 JDK1.7版本的CurrentHashMap的实现原理2.2 JDK1.8版本的CurrentHashMap的实现原理 3.总结 1.ConcurrentHashMap与HashMap等的区别 1.1 HashMap 我们知道HashMap是线程不安全的,在多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap。 1.2 HashTable HashTable和HashMap的实现原理几乎一样,差别无非是 HashTable不允许key和value为null HashTable是线程安全的 但是HashTable线程安全的策略实现代价却太大了,简单粗暴,get/put所有相关操作都是synchronized的,这相当于给整个哈希表加了一把大锁。 多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞,相当于将所有的操作串行化,在竞争激烈的并发场景中性能就会非常差。 2.ConcurrentHashMap 主要就是为了应对hashmap在并发环境下不安全而诞生的,ConcurrentHashMap的设计与实现非常精巧,大量的利用了volatile,final,CAS等lock-free技术来减少锁竞争对于性能的影响。 我们都知道Map一般都是数组+链表结构(JDK1.8该为数组+红黑树)。 ConcurrentHashMap避免了对全局加锁改成了局部加锁操作,这样就极大地提高了并发环境下的操作速度,由于ConcurrentHashMap在JDK1.7和1.8中的实现非常不同,接下来我们谈谈JDK在1.7和1.8中的区别。 2.1 JDK1.7版本的CurrentHashMap的实现原理 在JDK1.7中ConcurrentHashMap采用了数组+Segment+分段锁的方式实现。 ConcurrentHashMap中的分段锁称为Segment,它即类似于HashMap的结构,即内部拥有一个Entry数组,数组中的每个元素又是一个链表,同时又是一个ReentrantLock(Segment继承了ReentrantLock)。 内部结构图 从上面的结构我们可以了解到,ConcurrentHashMap定位一个元素的过程需要进行两次Hash操作。 第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部。 该结构的优劣势 坏处是这一种结构的带来的副作用是Hash的过程要比普通的HashMap要长。 好处是写操作的时候可以只对元素所在的Segment进行加锁即可,不会影响到其他的Segment,这样,在最理想的情况下,ConcurrentHashMap可以最高同时支持Segment数量大小的写操作(刚好这些写操作都非常平均地分布在所有的Segment上)。 所以,通过这一种结构,ConcurrentHashMap的并发能力可以大大的提高。 2.2 JDK1.8版本的CurrentHashMap的实现原理 synchronized+cas+node+红黑树的实现方式来设计,内部大量采用CAS操作,Node中的val和next都有volatle修饰。保证了原子性。 JDK8中彻底放弃了Segment转而采用的是Node,其设计思想也不再是JDK1.7中的分段锁思想。 查找,替换,赋值的操作都有CAS class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; volatile V val; volatile Node<K,V> next; //... 省略部分代码 } Java8 ConcurrentHashMap结构基本上和Java8的HashMap一样,不过保证线程安全性。 在JDK8中ConcurrentHashMap的结构,由于引入了红黑树,使得ConcurrentHashMap的实现非常复杂,我们都知道,红黑树是一种性能非常好的二叉查找树,其查找性能为O(logN),但是其实现过程也非常复杂,而且可读性也非常差,Doug Lea的思维能力确实不是一般人能比的,早期完全采用链表结构时Map的查找时间复杂度为O(N),JDK8中ConcurrentHashMap在链表的长度大于某个阈值的时候会将链表转换成红黑树进一步提高其查找性能。 3.总结 其实可以看出JDK1.8版本的ConcurrentHashMap的数据结构已经接近HashMap,相对而言,ConcurrentHashMap只是增加了同步的操作来控制并发,从JDK1.7版本的ReentrantLock+Segment+HashEntry,到JDK1.8版本中synchronized+CAS+HashEntry+红黑树。 1.数据结构:取消了Segment分段锁的数据结构,取而代之的是数组+链表+红黑树的结构。 2.保证线程安全机制:JDK1.7采用segment的分段锁机制实现线程安全,其中segment继承自ReentrantLock。JDK1.8采用CAS+Synchronized保证线程安全。 3.锁的粒度:原来是对需要进行数据操作的Segment加锁,现调整为对每个数组元素加锁(Node)。

Flyway简介及使用

Flyway简介及使用 1、简介 1.1 Flyway是什么? Flyway是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式。 Flyway可以独立于应用实现管理并跟踪数据库变更,支持数据库版本自动升级,并且有一套默认的规约,不需要复杂的配置。 Migrations可以写成SQL脚本,也可以写在Java代码中,不仅支持Command Line和Java API,还支持Build构建工具和Spring Boot等。 同时在分布式环境下能够安全可靠地升级数据库,同时也支持失败恢复等。 关于FlywayHomepage - Flyway 1.2为什么要使用Flyway 在真实的项目开发中,我们每个人都会有一个应用软件和与其相联系的数据库。对于个人开发来说,这样就够了。但是,项目开发一般都不止一个人,因此一定会出现我在我的本地有一套软件和相应的数据库系统,我的另一个同事会在他的本地有一套他自己的软件和相应的数据库系统。我们需要面临的第一个问题就是我们两个人如何集成我们的数据库系统,之后还要处理如何将数据库系统迁移到测试环境和生产环境当中去。 1.3 flyway工作原理 一言以蔽之:flyway通过历史记录表(flyway_schema_history)来记录版本历史。每次随项目启动时将会自动扫描在resources/db/migration下的文件并查询flyway_schema_history判断是否为新增文件。如果是新增的文件,则执行该迁移文件。如果不是,则忽略。 当flyway在一个空数据库执行时,它将直接创建一张默认名为flyway_schema_history的数据记录为空的历史记录表,这张表将被用来跟踪或记录数据库的状态。尔后flyway将会开始扫描文档系统或项目classpath路径下的迁移文件。 flyway按版本号顺序排列迁移文件,并按序执行,并更新历史记录表中的内容: 当项目再次发版时,flyway会再次扫描迁移文件,然后将迁移文的版本号与历史记录表中的版本号进行对比。flyway会忽略版本号小于等于表中当前最大版本的迁移文件,剩余待执行迁移文件会按版本号升序执行。(译者注:并非真正忽略,而是会校验checksum值是否一致,以此来保证历史版本文件未被篡改。) 历史记录表变动如下: 所以每次当你打算升级数据库时(包含DDL、DML语句),只需要在指定路径下创建一个版本号大于历史记录表中当前最大的版本号的迁移文件即可。在下次flyway启动时(随项目启动或其他形式),数据库将会自动完成升级,你无须再手动执行脚本。 2、使用 2.1 集成Spring Boot 2.1.1 创建Migration目录 在工程的 src/main/resources 目录下创建db/migration目录(Flyway加载Migrations时的默认Locations) 2.1.2 Maven配置:pom文件添加依赖 <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>${flyway.version}</version> </dependency> 2.1.3 项目配置文件(yml) spring: # 数据库连接配置 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/flyway-demo?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: root flyway: # 是否启用flyway enabled: true # 编码格式,默认UTF-8 encoding: UTF-8 # 迁移sql脚本文件存放路径,默认db/migration locations: classpath:db/migration # 迁移sql脚本文件名称的前缀,默认V sql-migration-prefix: V # 迁移sql脚本文件名称的分隔符,默认2个下划线__ sql-migration-separator: __ # 迁移sql脚本文件名称的后缀 sql-migration-suffixes: .

C#实现C++的SYSTEMTIME类型

做上位机开发免不了要调.dll库,最近有个要实现的库给过来,但是没有任何说明文档,只要下来一份C++的调用示例。按部就班,用到哪里写哪里,按照类型字长等,转成C#的类型。 碰到SYSTEMTIME,C#没有对应类型,这种情况下需要去到C++类型的定义里面。 typedef struct _SYSTEMTIME { WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds; } SYSTEMTIME; 参考格式,在C#中封装好对应的结构体,C++中WORD对应C#中UInt16。 [StructLayout(LayoutKind.Sequential)] public struct SYSTEMTIME { public UInt16 wYear; public UInt16 wMonth; public UInt16 wDayOfWeek; public UInt16 wDay; public UInt16 wHour; public UInt16 wMinute; public UInt16 wSecond; public UInt16 wMilliseconds; } 使用的时候再赋值就好了。 SYSTEMTIME sYSTEMTIME = new SYSTEMTIME(); DateTime dateTime = DateTime.Now; sYSTEMTIME.wYear = (ushort)dateTime.Year; sYSTEMTIME.wMonth = (ushort)dateTime.