版权声明:本套课程材料开源,使用和分享必须遵守「创作共用许可协议 CC BY-NC-SA」(来源引用-非商业用途使用-以相同方式共享)。
Chap02:函数对象
本章要点目录
## 本章所需R包
library(bruceR)
bruceR (v2026.1)
Broadly Useful Convenient and Efficient R functions
Packages also loaded:
✔ dplyr ✔ data.table
✔ tidyr ✔ emmeans
✔ stringr ✔ lmerTest
✔ forcats ✔ effectsize
✔ ggplot2 ✔ performance
✔ cowplot ✔ interactions
Main functions of `bruceR`:
cc() Describe() TTEST()
add() Freq() MANOVA()
.mean() Corr() EMMEANS()
set.wd() Alpha() PROCESS()
import() EFA() model_summary()
print_table() CFA() lavaan_summary()
For full functionality, please install all dependencies:
install.packages("bruceR", dep=TRUE)
Online documentation:
https://psychbruce.github.io/bruceR
To use this package in publications, please cite:
Bao, H. W. S. (2021). bruceR: Broadly useful convenient and efficient R functions (Version 2026.1) [Computer software]. https://doi.org/10.32614/CRAN.package.bruceR
R对象类型与相互转换

【知识点】R对象与函数
“万物皆对象,万事皆函数。” —— John Chambers(R语言创始人之一)
- “Everything that exists in R is an object.”
(所用的一切都是对象)
- 向量(vector)⭐️
- 数值向量(numeric vector)
- 字符向量(character vector)
- 逻辑向量(logical vector)
- 矩阵(matrix)
- 数组(array)
- 列表(list)⭐️
- 数据框(data frame)⭐️
- R里90%的分析都是围绕
data.frame(包括data.table)展开的
- 相当于Excel表格在R里的样子(每一列是一个变量,每一行是一个观测值)
- “Everything that happens in R is the result of a function
call.”
(所做的一切都是函数)

向量(vector)
(1)数值向量
【实践1】数值向量
c():生成任何类型向量(合并一组同类型的数据)⭐️
[1] 1
[1] 1 2 3 4 5
[1] 1 2 3 4 5
[1] 1 2 3 4 5 10 15
seq():生成数值序列
[1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
seq(from=1, to=5, by=0.5)
[1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
rep():重复向量元素
[1] 1 2 1 2 1 2
[1] 1 1 1 2 2 2
(2)字符向量
【实践2】字符向量
c(1:5, 10.5, "next") # 如果混着放,统统变成字符型!
[1] "1" "2" "3" "4" "5" "10.5" "next"
"Psychology" # 一个字符串,本质上是一个长度为1的字符向量
[1] "Psychology"
"Psychology"[1] # 向量的第1个元素
[1] "Psychology"
"Psychology"[0] # 向量的第0个元素(没有)
character(0)
"Psychology"[2] # 向量的第2个元素(缺失)
[1] NA
length():计算对象内的元素个数
nchar("Psychology") # 字符个数为10
[1] 10
a = c("Psychology", "ECNU", "Shanghai", "China")
a
[1] "Psychology" "ECNU" "Shanghai" "China"
[1] 4
[1] 10 4 8 5
class():获取R对象类型(可能是单个类型或多种类型的叠加)
str():显示R对象内部结构(常用于探索数据结构)⭐️
[1] "character"
str(a) # structure:显示R对象的结构
chr [1:4] "Psychology" "ECNU" "Shanghai" "China"
cc()(来自bruceR包):比c()更方便的字符向量设定
- 自动根据分隔符号(英文逗号、换行符等)拆解字符串
- 为什么要设计这个函数?
## cc() 用法:必须是英文逗号或换行符
cc("心理学, 社会学, 教育学, 管理学, 计算机, 人工智能")
[1] "心理学" "社会学" "教育学" "管理学" "计算机" "人工智能"
cc("
心理学
社会学
教育学
管理学
计算机
人工智能
")
[1] "心理学" "社会学" "教育学" "管理学" "计算机" "人工智能"
【知识点】因子型向量
因子型(factor)变量是社会科学研究中的常用变量类型,本质是对分类变量(categorical
variable)的虚拟编码(dummy
coding),以方便统计模型的处理。R语言中,原始的分类变量一般都需要转换为因子型变量!
as.factor():将任意类型向量转换为因子型向量⭐️
- 因子(factor)本质上是带有“类别/分组信息”的向量(将向量中的不重复元素排序后作为类别选项)
- 因子水平(levels)是所有可能的类别(当涉及类别间的对比时,默认以第一类为参照组)
factor():比as.factor()更完整的因子型向量设定⭐️
levels:定义因子水平顺序
labels:定义因子水平标签
## 数值向量 ==> 因子向量
a = c(2, 0, 0, 0, 6, 2)
a
[1] 2 0 0 0 6 2
[1] 2 0 6
[1] 2 0 0 0 6 2
Levels: 0 2 6
[1] "0" "2" "6"
## 字符向量 ==> 因子向量
a = c("Psychology", "ECNU", "Shanghai", "China")
as.factor(a)
[1] Psychology ECNU Shanghai China
Levels: China ECNU Psychology Shanghai
factor(a, levels=c("China", "Shanghai", "ECNU", "Psychology"))
[1] Psychology ECNU Shanghai China
Levels: China Shanghai ECNU Psychology
factor(
a,
levels = c("China", "Shanghai", "ECNU", "Psychology"),
labels = c("CN", "SH", "ECNU", "Psy")
)
[1] Psy ECNU SH CN
Levels: CN SH ECNU Psy
(3)逻辑向量
【实践3】逻辑向量
c(TRUE, TRUE, FALSE, TRUE, FALSE, FALSE)
[1] TRUE TRUE FALSE TRUE FALSE FALSE
[1] FALSE FALSE TRUE TRUE TRUE
%in%:向量化判断前一个对象的每个元素是否在后一个对象中
c(0, 5, 10, 15) %in% 1:10
[1] FALSE TRUE TRUE FALSE
ifelse():根据条件语句,向量化逻辑判断
ifelse(1:10 >= 5, "Yes", "No") # ifelse(test, yes, no)
[1] "No" "No" "No" "No" "Yes" "Yes" "Yes" "Yes" "Yes" "Yes"
【知识点】条件判断运算符与对象类型判断函数
## 条件判断运算符
a == b
a != b
a > b
a < b
a >= b
a <= b
a %in% b
## 对象类型判断函数
is.na(x)
is.null(x)
is.numeric(x)
is.character(x)
is.factor(x)
# 还有非常多其他 is.xxx() 系列函数!
向量相互转换
【实践4】逻辑向量—数值向量—字符向量的相互转换
as.logical():0转换为FALSE,非0转换为TRUE
as.character():转换为字符向量
as.numeric():转换为数值向量(无法转换的记为NA缺失值)
[1] FALSE TRUE TRUE TRUE TRUE TRUE
[1] "0" "1" "2" "3" "4" "5"
as.numeric(c("-1.5", "0", "1.5"))
[1] -1.5 0.0 1.5
as.numeric(c("1.2", "-.12", "1.2.3")) # NA表示缺失值
Warning: 强制改变过程中产生了NA
[1] 1.20 -0.12 NA
【知识点】管道操作符
%>%:管道操作符⭐️(tidyverse系列包的通用函数)
- 默认将【左侧结果】传给【右侧函数】的【第1个参数】!
- 快捷键:Ctrl + Shift + M(注意检查其他软件的快捷键冲突)
- 如果提示
没有"%>%"这个函数,请library(tidyverse)或library(bruceR)
a = c("Psychology", "ECNU", "Shanghai", "China")
as.factor(a) # 不使用管道操作符
[1] Psychology ECNU Shanghai China
Levels: China ECNU Psychology Shanghai
a %>% as.factor() # 使用管道操作符,默认传给as.factor()第1个参数
[1] Psychology ECNU Shanghai China
Levels: China ECNU Psychology Shanghai
a %>% as.factor() %>% as.numeric() # 默认传给这些函数的第1个参数
[1] 3 2 4 1
a %>% as.factor() %>% as.numeric() %>% c(666) # 默认传给c()第1个参数
[1] 3 2 4 1 666
a %>% as.factor() %>% as.numeric() %>% c(., 666) # .占位第1个参数
[1] 3 2 4 1 666
a %>% as.factor() %>% as.numeric() %>% c(666, .) # .占位第2个参数
[1] 666 3 2 4 1
a %>% as.factor() %>% as.numeric() %>% c(666, 888, .) # .占位第3个参数
[1] 666 888 3 2 4 1
a %>% as.factor() %>% as.numeric() %>% c(666, ., 888) # .占位第2个参数
[1] 666 3 2 4 1 888
知识点小结:LHS %>% RHS这种写法,可以将LHS(Left-Hand
Side)的输出结果作为RHS(Right-Hand
Side)第1个参数的输入值,从而实现流程化的管道操作效果,避免繁琐、可读性差的“函数套娃”!
## 可读性差的“函数套娃”
c(666, as.numeric(as.factor(as.character(c("Psychology", "ECNU")))))
[1] 666 2 1
向量元素操作
【实践5】向量元素命名与提取
names():对象元素名称或命名
- 直接使用:返回对象元素名称
- 赋值使用:赋予对象元素名称(将会改变当前对象)
[1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
[20] "T" "U" "V" "W" "X" "Y" "Z"
a = 1:5
names(a) # 直接用法(刚刚出生,还没名字)
NULL
names(a) = LETTERS[1:5] # 赋值用法,a已改变
a
A B C D E
1 2 3 4 5
[1] "A" "B" "C" "D" "E"
x[...]:[]操作符取对象元素内容
x[逻辑/数值向量]:取对应位置元素(若为负数,则删除对应元素)
x[字符向量]:取对应名称元素
E
5
A C E
1 3 5
B C D E
2 3 4 5
A E
1 5
unique():取向量中的所有独特元素(去重复值)
table():向量元素频次统计
x = c(2, 0, 0, 0, 6, 2)
rev(x)
[1] 2 6 0 0 0 2
[1] 0 0 0 2 2 6
[1] 2 0 6
x %>% unique() %>% sort() %>% rev()
[1] 6 2 0
x
0 2 6
3 2 1
[1] TRUE FALSE FALSE FALSE FALSE TRUE
[1] 2 2
[1] NA 0 0 0 6 NA
【实践6】向量代数运算
a = 1:5
a + 1 # 1:5 + 1 【思考:a + 1:2 的结果?】
[1] 2 3 4 5 6
[1] 2 4 6 8 10
[1] 1 4 9 16 25
[1] 5 8 9 8 5
[1] 1 0 1 0 1
sum()、mean()、min()、max():向量求和、平均值、最小值、最大值
[1] 5050
[1] 50.5
[1] 1
[1] 100
x = c(1, NA, 3, NA, 5)
sum(x)
[1] NA
[1] 9
[1] NA
[1] 3
[1] NA
[1] 1
[1] NA
[1] 5
abs()、log()、sqrt()等:各种常用的数学运算
[1] 1
log(2.718281828) # ln 自然对数转换
[1] 1
[1] 9
[1] 3
[1] 3
[1] 0.5724
pi %>% sqrt() %>% log() %>% abs() # 管道操作符
[1] 0.5724
【实践7】向量元素拼接
paste()、paste0():把向量元素拼接在一起
sep参数:多个输入之间的黏合字符
collaspe参数:向量不同元素之间的黏合字符
paste(1, 2, 3, 4, 5) # paste() 拼接带空格
[1] "1 2 3 4 5"
paste0(1, 2, 3, 4, 5) # paste0() 拼接不带空格
[1] "12345"
paste(1, 2, 3, 4, 5, sep="-") # 多个参数输入之间拼接
[1] "1-2-3-4-5"
paste(1:5, collapse="-") # 单个向量的不同元素之间拼接
[1] "1-2-3-4-5"
paste(1:10, collapse="+") # 打印计算公式
[1] "1+2+3+4+5+6+7+8+9+10"
cat(paste(1:10, collapse="+"), "=", sum(1:10))
1+2+3+4+5+6+7+8+9+10 = 55

列表(list)
【实践8】列表构建与操作
list():建立一个列表对象,可存储任意类型、任意结构的对象
$:根据元素名称,取列表中的元素内容(Tab键弹出所有元素名称)
[[...]]:取列表中对应位置的元素内容(不同于[...])
输入后按Tab键弹出所有元素名称
l = list(Year=2000:2015, Month=1:12, Day=1:31, Letter=LETTERS)
l
$Year
[1] 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
[16] 2015
$Month
[1] 1 2 3 4 5 6 7 8 9 10 11 12
$Day
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
[26] 26 27 28 29 30 31
$Letter
[1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
[20] "T" "U" "V" "W" "X" "Y" "Z"
[1] "Year" "Month" "Day" "Letter"
[1] 4
[1] 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014
[16] 2015
$Month
[1] 1 2 3 4 5 6 7 8 9 10 11 12
l[[2]] # 取第2个元素,返回元素本身,相当于 l$Month
[1] 1 2 3 4 5 6 7 8 9 10 11 12
unlist():解除列表结构,还原为向量
unlist(l) # 解除列表结构,强行统一对象类型(数值 -> 字符)
Year1 Year2 Year3 Year4 Year5 Year6 Year7 Year8
"2000" "2001" "2002" "2003" "2004" "2005" "2006" "2007"
Year9 Year10 Year11 Year12 Year13 Year14 Year15 Year16
"2008" "2009" "2010" "2011" "2012" "2013" "2014" "2015"
Month1 Month2 Month3 Month4 Month5 Month6 Month7 Month8
"1" "2" "3" "4" "5" "6" "7" "8"
Month9 Month10 Month11 Month12 Day1 Day2 Day3 Day4
"9" "10" "11" "12" "1" "2" "3" "4"
Day5 Day6 Day7 Day8 Day9 Day10 Day11 Day12
"5" "6" "7" "8" "9" "10" "11" "12"
Day13 Day14 Day15 Day16 Day17 Day18 Day19 Day20
"13" "14" "15" "16" "17" "18" "19" "20"
Day21 Day22 Day23 Day24 Day25 Day26 Day27 Day28
"21" "22" "23" "24" "25" "26" "27" "28"
Day29 Day30 Day31 Letter1 Letter2 Letter3 Letter4 Letter5
"29" "30" "31" "A" "B" "C" "D" "E"
Letter6 Letter7 Letter8 Letter9 Letter10 Letter11 Letter12 Letter13
"F" "G" "H" "I" "J" "K" "L" "M"
Letter14 Letter15 Letter16 Letter17 Letter18 Letter19 Letter20 Letter21
"N" "O" "P" "Q" "R" "S" "T" "U"
Letter22 Letter23 Letter24 Letter25 Letter26
"V" "W" "X" "Y" "Z"
lapply():批量应用函数,返回为列表
## lapply(向量或列表, 函数)
lapply(l, length) # 每个元素批量应用length()函数
$Year
[1] 16
$Month
[1] 12
$Day
[1] 31
$Letter
[1] 26
lapply(l, mean) # 每个元素批量应用mean()函数
Warning in mean.default(X[[i]], ...): 参数不是数值也不是逻辑值:返回NA
$Year
[1] 2008
$Month
[1] 6.5
$Day
[1] 16
$Letter
[1] NA
[1] 1 4 9 16 25
lapply(a, function(x) x^2) # x是形参(形式参数)
[[1]]
[1] 1
[[2]]
[1] 4
[[3]]
[1] 9
[[4]]
[1] 16
[[5]]
[1] 25
lapply(a, function(x) x^2) %>% unlist()
[1] 1 4 9 16 25
R函数使用与参数设置
【知识点】R函数体的结构
function(...):函数接收输入参数,内部操作后,返回输出结果
{ }:大括号内定义所有形式参数(形参)的操作过程
- 返回结果可用两种方式
return(...):显式返回
invisible(...):隐式返回
func = function(param1, param2, ...) {
## 函数内部操作
results = param1 + param2
cat(param1, "+", param2, "=", results, "\n")
## 函数返回结果
return(results)
# 也可以隐式返回:
# invisible(results)
}
func(16, 9)
16 + 9 = 25
[1] 25
常用R函数使用
【实践9】文件夹里有什么?
## 请自己运行
library(bruceR)
set.wd() # 设置工作路径为当前打开文件的路径
list.files() # 列出当前路径的所有文件/文件夹
list.files("../") # 列出上一级路径的所有文件/文件夹
list.files("../../") # 列出上两级路径的所有文件/文件夹
【实践10】今天晚上吃什么?
## 请自己运行
choice = c("河西食堂", "河东食堂", "环球港", "点外卖")
sample(choice, size=1) # 随机抽样
# 设置随机种子,使结果可重复
set.seed(123) # 随机种子可以是任意整数,没有特定含义
sample(choice, size=1)
【实践11】正态分布随机数的平均值和标准差?
set.seed(123) # 设置随机种子,使结果可重复
x = rnorm(30) # 生成30个随机数(正态分布)
mean(x) # 求平均值
[1] -0.0471
[1] 0.981

x > mean(x) + sd(x) # 返回TRUE/FALSE向量
[1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE
[13] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE TRUE
x[x > mean(x) + sd(x)] # 返回(取出)符合条件的数值
[1] 1.559 1.715 1.224 1.787 1.254
which(x > mean(x) + sd(x)) # 返回符合条件数值所在位置
[1] 3 6 11 16 30
set.seed(123) # 设置随机种子,使结果可重复
x = rnorm(1000) # 生成1000个随机数(正态分布)
mean(x) # 求平均值
[1] 0.01613
[1] 0.9917

【实践12】“Hello World”的几种打印方法?
cli是命令行交互的专业R包,系统性提供了各种输出文本设定函数
[1] "Hello World!"
Hello World!
Hello World!
cli::cli_text("Hello World!")
cli::cli_h1("Hello World!")
cli::cli_h2("Hello World!")
cli::cli_h3("Hello World!")
cli::cli_alert("Hello World!")
cli::cli_alert_success("Hello World!")
cli::cli_alert_info("Hello World!")
cli::cli_alert_warning("Hello World!")
cli::cli_alert_danger("Hello World!")

R逻辑控制语句
if判断语句
if (condition) {
# Do something
} else if {
# Do something
} else {
# Do sth. else
}
x = 3
if (x %in% 1:5) {
cat("Yes")
} else {
cat("No")
}
Yes
while循环语句
while (condition) {
# Do something
}
x = 1
while (x < 5) {
cat(x, "is smaller than 5\n")
x = x + 1
}
1 is smaller than 5
2 is smaller than 5
3 is smaller than 5
4 is smaller than 5
for循环语句
for (var in seq) {
# Do something
}
for (x in 1:5) {
y = x * 2
print(y)
}
[1] 2
[1] 4
[1] 6
[1] 8
[1] 10
【作业3】编程解决抛硬币问题
问题情境:一枚硬币,连续抛了N次都是正面朝上,再抛一次反面朝上的概率是多少?
- 比如,一枚硬币,连续抛了3次都是正面朝上,再抛一次反面朝上的概率是多少?
- 连续10次呢?连续1000次呢?连续1亿次呢?……
- 思路提示:利用假设检验的思想,判断这枚硬币是不是普通硬币(H0:硬币是普通的)
作业要求:
- 编写一段R程序,计算并判断至少连续多少次正面朝上,可以认定硬币不再是普通硬币(拒绝零假设)
- 尽可能用R Markdown完成
平台提交:
返回课程主页
© 包寒吴霜
LS0tDQp0aXRsZTogIuOAilLor63oqIDjgIvnrKwy56ug77ya5Ye95pWw5a+56LGhIg0Kc3VidGl0bGU6IDxhIGhyZWY9Imh0dHBzOi8vcHN5Y2hicnVjZS5naXRodWIuaW8vUkNvdXJzZS8iPui/lOWbnuivvueoi+S4u+mhtTwvYT4NCmF1dGhvcjogIuaOiOivvuaVmeW4iO+8muWMheWvkuWQtOmcnCINCiMgZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogZmFsc2UNCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGFuY2hvcl9zZWN0aW9uczogdHJ1ZQ0KICAgIGhpZ2hsaWdodDogcHlnbWVudHMNCiAgICBjc3M6IFJtZENTUy5jc3MNCi0tLQ0KDQpgYGB7PWh0bWx9DQo8cCBzdHlsZT0iZm9udC1zaXplOiAxMnB4Ij7niYjmnYPlo7DmmI7vvJrmnKzlpZfor77nqIvmnZDmlpnlvIDmupDvvIzkvb/nlKjlkozliIbkuqvlv4XpobvpgbXlrojjgIzliJvkvZzlhbHnlKjorrjlj6/ljY/orq4gQ0MgQlktTkMtU0HjgI3vvIjmnaXmupDlvJXnlKgt6Z2e5ZWG5Lia55So6YCU5L2/55SoLeS7peebuOWQjOaWueW8j+WFseS6q++8ieOAgjxpbWcgc3JjPSJpbWcvQ0MtQlktTkMtU0EuanBnIiB3aWR0aD0iMTIwcHgiIGhlaWdodD0iNDJweCIgc3R5bGU9ImZsb2F0OiByaWdodCIgLz48L3A+DQpgYGANCg0KYGBge3IgQ29uZmlnLCBpbmNsdWRlPUZBTFNFfQ0Kb3B0aW9ucygNCiAga25pdHIua2FibGUuTkEgPSAiIiwNCiAgZGlnaXRzID0gNA0KKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBjb21tZW50ID0gIiIsDQogIGZpZy53aWR0aCA9IDYsDQogIGZpZy5oZWlnaHQgPSA0LA0KICBkcGkgPSAzMDANCikNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyBDaGFwMDLvvJrlh73mlbDlr7nosaENCg0KIyMjIyDlvoDmnJ/opoHngrnlm57pob4NCg0KLSAgIFtDaGFwMDEgXCMgUuWMheWuieijheS4jueuoeeQhl0oaHR0cHM6Ly9wc3ljaGJydWNlLmdpdGh1Yi5pby9SQ291cnNlL0NoYXAwMSNyJUU1JThDJTg1JUU1JUFFJTg5JUU4JUEzJTg1JUU0JUI4JThFJUU3JUFFJUExJUU3JTkwJTg2KXsudXJpfQ0KDQojIyMjIOacrOeroOimgeeCueebruW9lQ0KDQotICAgW+OAkOefpeivhueCueOAkVLlr7nosaHkuI7lh73mlbBdKCPnn6Xor4bngrly5a+56LGh5LiO5Ye95pWwKQ0KLSAgIFvjgJDlrp7ot7Ux44CR5pWw5YC85ZCR6YePXSgj5a6e6Le1MeaVsOWAvOWQkemHjykNCi0gICBb44CQ5a6e6Le1MuOAkeWtl+espuWQkemHj10oI+Wunui3tTLlrZfnrKblkJHph48pDQotICAgW+OAkOefpeivhueCueOAkeWboOWtkOWei+WQkemHj10oI+efpeivhueCueWboOWtkOWei+WQkemHjynvvIjph43ngrnvvIkNCi0gICBb44CQ5a6e6Le1M+OAkemAu+i+keWQkemHj10oI+Wunui3tTPpgLvovpHlkJHph48pDQotICAgW+OAkOefpeivhueCueOAkeadoeS7tuWIpOaWrei/kOeul+espuS4juWvueixoeexu+Wei+WIpOaWreWHveaVsF0oI+efpeivhueCueadoeS7tuWIpOaWrei/kOeul+espuS4juWvueixoeexu+Wei+WIpOaWreWHveaVsCkNCi0gICBb44CQ5a6e6Le1NOOAkemAu+i+keWQkemHj+KAlOaVsOWAvOWQkemHj+KAlOWtl+espuWQkemHj+eahOebuOS6kui9rOaNol0oI+Wunui3tTTpgLvovpHlkJHph4/mlbDlgLzlkJHph4/lrZfnrKblkJHph4/nmoTnm7jkupLovazmjaIpDQotICAgW+OAkOefpeivhueCueOAkeeuoemBk+aTjeS9nOespl0oI+efpeivhueCueeuoemBk+aTjeS9nOespinvvIjph43ngrnvvIkNCi0gICBb44CQ5a6e6Le1NeOAkeWQkemHj+WFg+e0oOWRveWQjeS4juaPkOWPll0oI+Wunui3tTXlkJHph4/lhYPntKDlkb3lkI3kuI7mj5Dlj5YpDQotICAgW+OAkOWunui3tTbjgJHlkJHph4/ku6PmlbDov5DnrpddKCPlrp7ot7U25ZCR6YeP5Luj5pWw6L+Q566XKQ0KLSAgIFvjgJDlrp7ot7U344CR5ZCR6YeP5YWD57Sg5ou85o6lXSgj5a6e6Le1N+WQkemHj+WFg+e0oOaLvOaOpSnvvIjph43ngrnvvIkNCi0gICBb44CQ5a6e6Le1OOOAkeWIl+ihqOaehOW7uuS4juaTjeS9nF0oI+Wunui3tTjliJfooajmnoTlu7rkuI7mk43kvZwp77yI6YeN54K577yJDQotICAgW+OAkOefpeivhueCueOAkVLlh73mlbDkvZPnmoTnu5PmnoRdKCPnn6Xor4bngrly5Ye95pWw5L2T55qE57uT5p6EKe+8iOmHjeeCue+8iQ0KLSAgIFvjgJDlrp7ot7U544CR5paH5Lu25aS56YeM5pyJ5LuA5LmI77yfXSgj5a6e6Le1OeaWh+S7tuWkuemHjOacieS7gOS5iCkNCi0gICBb44CQ5a6e6Le1MTDjgJHku4rlpKnmmZrkuIrlkIPku4DkuYjvvJ9dKCPlrp7ot7UxMOS7iuWkqeaZmuS4iuWQg+S7gOS5iCkNCi0gICBb44CQ5a6e6Le1MTHjgJHmraPmgIHliIbluIPpmo/mnLrmlbDnmoTlubPlnYflgLzlkozmoIflh4blt67vvJ9dKCPlrp7ot7UxMeato+aAgeWIhuW4g+maj+acuuaVsOeahOW5s+Wdh+WAvOWSjOagh+WHhuW3rikNCi0gICBb44CQ5a6e6Le1MTLjgJHigJxIZWxsbyBXb3JsZOKAneeahOWHoOenjeaJk+WNsOaWueazle+8n10oI+Wunui3tTEyaGVsbG8td29ybGTnmoTlh6Dnp43miZPljbDmlrnms5UpDQoNCmBgYHtyfQ0KIyMg5pys56ug5omA6ZyAUuWMhQ0KbGlicmFyeShicnVjZVIpDQpgYGANCg0KIyBS5a+56LGh57G75Z6L5LiO55u45LqS6L2s5o2iDQoNCiFbXShpbWFnZXMvY2xpcGJvYXJkLTQyMjcxODkxODcucG5nKQ0KDQojIyMjIOOAkOefpeivhueCueOAkVLlr7nosaHkuI7lh73mlbAgeyPnn6Xor4bngrly5a+56LGh5LiO5Ye95pWwfQ0KDQo+IOKAnOS4h+eJqeeahuWvueixoe+8jOS4h+S6i+eahuWHveaVsOOAguKAnSDigJTigJQgSm9obiBDaGFtYmVyc++8iFLor63oqIDliJvlp4vkurrkuYvkuIDvvIkNCg0KLSAgIOKAnEV2ZXJ5dGhpbmcgdGhhdCBleGlzdHMgaW4gUiBpcyBhbiBvYmplY3Qu4oCdXA0KICAgIO+8iOaJgOeUqOeahOS4gOWIh+mDveaYr+Wvueixoe+8iQ0KICAgIC0gICDlkJHph4/vvIh2ZWN0b3LvvInirZDvuI8NCiAgICAgICAgLSAgIOaVsOWAvOWQkemHj++8iG51bWVyaWMgdmVjdG9y77yJDQogICAgICAgIC0gICDlrZfnrKblkJHph4/vvIhjaGFyYWN0ZXIgdmVjdG9y77yJDQogICAgICAgIC0gICDpgLvovpHlkJHph4/vvIhsb2dpY2FsIHZlY3Rvcu+8iQ0KICAgIC0gICDnn6npmLXvvIhtYXRyaXjvvIkNCiAgICAtICAg5pWw57uE77yIYXJyYXnvvIkNCiAgICAtICAg5YiX6KGo77yIbGlzdO+8ieKtkO+4jw0KICAgICAgICAtICAg5re35ZCI5a2Y5YKo5aSa56eN57G75Z6L55qE5a+56LGh5ZKM5pWw5o2uDQogICAgLSAgIOaVsOaNruahhu+8iGRhdGEgZnJhbWXvvInirZDvuI8NCiAgICAgICAgLSAgIFLph4w5MCXnmoTliIbmnpDpg73mmK/lm7Tnu5VgZGF0YS5mcmFtZWDvvIjljIXmi6xgZGF0YS50YWJsZWDvvInlsZXlvIDnmoQNCiAgICAgICAgLSAgIOebuOW9k+S6jkV4Y2Vs6KGo5qC85ZyoUumHjOeahOagt+WtkO+8iOavj+S4gOWIl+aYr+S4gOS4quWPmOmHj++8jOavj+S4gOihjOaYr+S4gOS4quingua1i+WAvO+8iQ0KLSAgIOKAnEV2ZXJ5dGhpbmcgdGhhdCBoYXBwZW5zIGluIFIgaXMgdGhlIHJlc3VsdCBvZiBhIGZ1bmN0aW9uIGNhbGwu4oCdXA0KICAgIO+8iOaJgOWBmueahOS4gOWIh+mDveaYr+WHveaVsO+8iQ0KDQohW10oaW1hZ2VzL2NsaXBib2FyZC0yNDgyNTQzOTY2LnBuZykNCg0KIyMg5ZCR6YeP77yIdmVjdG9y77yJDQoNCi0gICDljZXnu7TjgIHljZXnsbvlnovmlbDmja4NCg0KIyMjIO+8iDHvvInmlbDlgLzlkJHph48NCg0KIyMjIyDjgJDlrp7ot7Ux44CR5pWw5YC85ZCR6YePIHsj5a6e6Le1MeaVsOWAvOWQkemHj30NCg0KIyMjIyMgYGMoKWDvvJrnlJ/miJDku7vkvZXnsbvlnovlkJHph4/vvIjlkIjlubbkuIDnu4TlkIznsbvlnovnmoTmlbDmja7vvInirZDvuI8NCg0KLSAgIOKAnGPigJ3ooajnpLrigJxjb21iaW5l4oCdDQoNCmBgYHtyfQ0KMQ0KMTo1DQpjKDEsIDIsIDMsIDQsIDUpDQpjKDE6NSwgMTAsIDE1KQ0KYGBgDQoNCiMjIyMjIGBzZXEoKWDvvJrnlJ/miJDmlbDlgLzluo/liJcNCg0KYGBge3J9DQpzZXEoMSwgNSwgMC41KQ0Kc2VxKGZyb209MSwgdG89NSwgYnk9MC41KQ0KYGBgDQoNCiMjIyMjIGByZXAoKWDvvJrph43lpI3lkJHph4/lhYPntKANCg0KYGBge3J9DQpyZXAoMToyLCAzKQ0KcmVwKDE6MiwgZWFjaD0zKQ0KYGBgDQoNCiMjIyDvvIgy77yJ5a2X56ym5ZCR6YePDQoNCiMjIyMg44CQ5a6e6Le1MuOAkeWtl+espuWQkemHjyB7I+Wunui3tTLlrZfnrKblkJHph499DQoNCmBgYHtyfQ0KYygxOjUsIDEwLjUsICJuZXh0IikgICMg5aaC5p6c5re3552A5pS+77yM57uf57uf5Y+Y5oiQ5a2X56ym5Z6L77yBDQoNCiJQc3ljaG9sb2d5IiAgIyDkuIDkuKrlrZfnrKbkuLLvvIzmnKzotKjkuIrmmK/kuIDkuKrplb/luqbkuLox55qE5a2X56ym5ZCR6YePDQoiUHN5Y2hvbG9neSJbMV0gICMg5ZCR6YeP55qE56ysMeS4quWFg+e0oA0KIlBzeWNob2xvZ3kiWzBdICAjIOWQkemHj+eahOesrDDkuKrlhYPntKDvvIjmsqHmnInvvIkNCiJQc3ljaG9sb2d5IlsyXSAgIyDlkJHph4/nmoTnrKwy5Liq5YWD57Sg77yI57y65aSx77yJDQpgYGANCg0KIyMjIyMgYG5jaGFyKClg77ya6K6h566X5a2X56ym5Liy55qE5a2X56ym5Liq5pWwDQoNCiMjIyMjIGBsZW5ndGgoKWDvvJrorqHnrpflr7nosaHlhoXnmoTlhYPntKDkuKrmlbANCg0KYGBge3J9DQpuY2hhcigiUHN5Y2hvbG9neSIpICAjIOWtl+espuS4quaVsOS4ujEwDQphID0gYygiUHN5Y2hvbG9neSIsICJFQ05VIiwgIlNoYW5naGFpIiwgIkNoaW5hIikNCmENCmxlbmd0aChhKQ0KbmNoYXIoYSkgICMg5ZCR6YeP5YyW6K6h566XDQpgYGANCg0KIyMjIyMgYGNsYXNzKClg77ya6I635Y+WUuWvueixoeexu+Wei++8iOWPr+iDveaYr+WNleS4quexu+Wei+aIluWkmuenjeexu+Wei+eahOWPoOWKoO+8iQ0KDQojIyMjIyBgc3RyKClg77ya5pi+56S6UuWvueixoeWGhemDqOe7k+aehO+8iOW4uOeUqOS6juaOoue0ouaVsOaNrue7k+aehO+8ieKtkO+4jw0KDQpgYGB7cn0NCmNsYXNzKGEpDQpzdHIoYSkgICMgc3RydWN0dXJl77ya5pi+56S6UuWvueixoeeahOe7k+aehA0KYGBgDQoNCiMjIyMjIGBjYygpYO+8iOadpeiHqmBicnVjZVJg5YyF77yJ77ya5q+UYGMoKWDmm7Tmlrnkvr/nmoTlrZfnrKblkJHph4/orr7lrpoNCg0KLSAgIOiHquWKqOagueaNruWIhumalOespuWPt++8iOiLseaWh+mAl+WPt+OAgeaNouihjOespuetie+8ieaLhuino+Wtl+espuS4sg0KLSAgIOS4uuS7gOS5iOimgeiuvuiuoei/meS4quWHveaVsO+8nw0KICAgIC0gICDlj6rlm6DmiJHop4nlvpfljp/nlJ/mgIHnmoRgYygpYOS4jeWkquaWueS+v+W/q+aNtw0KDQpgYGB7cn0NCiMjIGNjKCkg55So5rOV77ya5b+F6aG75piv6Iux5paH6YCX5Y+35oiW5o2i6KGM56ymDQpjYygi5b+D55CG5a2mLCDnpL7kvJrlraYsIOaVmeiCsuWtpiwg566h55CG5a2mLCDorqHnrpfmnLosIOS6uuW3peaZuuiDvSIpDQpjYygiDQrlv4PnkIblraYNCuekvuS8muWtpg0K5pWZ6IKy5a2mDQrnrqHnkIblraYNCuiuoeeul+acug0K5Lq65bel5pm66IO9DQoiKQ0KYGBgDQoNCiMjIyMg44CQ55+l6K+G54K544CR5Zug5a2Q5Z6L5ZCR6YePIHsj55+l6K+G54K55Zug5a2Q5Z6L5ZCR6YePfQ0KDQrlm6DlrZDlnovvvIhmYWN0b3LvvInlj5jph4/mmK/npL7kvJrnp5HlrabnoJTnqbbkuK3nmoTluLjnlKjlj5jph4/nsbvlnovvvIzmnKzotKjmmK/lr7nliIbnsbvlj5jph4/vvIhjYXRlZ29yaWNhbCB2YXJpYWJsZe+8ieeahOiZmuaLn+e8luegge+8iGR1bW15IGNvZGluZ++8ie+8jOS7peaWueS+v+e7n+iuoeaooeWei+eahOWkhOeQhuOAglLor63oqIDkuK3vvIzljp/lp4vnmoTliIbnsbvlj5jph4/kuIDoiKzpg73pnIDopoHovazmjaLkuLrlm6DlrZDlnovlj5jph4/vvIENCg0KIyMjIyMgYGFzLmZhY3RvcigpYO+8muWwhuS7u+aEj+exu+Wei+WQkemHj+i9rOaNouS4uuWboOWtkOWei+WQkemHj+KtkO+4jw0KDQotICAg5Zug5a2Q77yIZmFjdG9y77yJ5pys6LSo5LiK5piv5bim5pyJ4oCc57G75YirL+WIhue7hOS/oeaBr+KAneeahOWQkemHj++8iOWwhuWQkemHj+S4reeahOS4jemHjeWkjeWFg+e0oOaOkuW6j+WQjuS9nOS4uuexu+WIq+mAiemhue+8iQ0KLSAgIOWboOWtkOawtOW5s++8iGxldmVsc++8ieaYr+aJgOacieWPr+iDveeahOexu+WIq++8iOW9k+a2ieWPiuexu+WIq+mXtOeahOWvueavlOaXtu+8jOm7mOiupOS7peesrOS4gOexu+S4uuWPgueFp+e7hO+8iQ0KDQojIyMjIyBgZmFjdG9yKClg77ya5q+UYGFzLmZhY3RvcigpYOabtOWujOaVtOeahOWboOWtkOWei+WQkemHj+iuvuWumuKtkO+4jw0KDQotICAgYGxldmVsc2DvvJrlrprkuYnlm6DlrZDmsLTlubPpobrluo8NCi0gICBgbGFiZWxzYO+8muWumuS5ieWboOWtkOawtOW5s+agh+etvg0KDQpgYGB7cn0NCiMjIOaVsOWAvOWQkemHjyA9PT4g5Zug5a2Q5ZCR6YePDQphID0gYygyLCAwLCAwLCAwLCA2LCAyKQ0KYQ0KdW5pcXVlKGEpDQoNCmEgPSBhcy5mYWN0b3IoYSkNCmENCmxldmVscyhhKSAgIyDlm6DlrZDmsLTlubPvvJrmiYDmnInlj6/og73nmoTnsbvliKsNCg0KIyMg5a2X56ym5ZCR6YePID09PiDlm6DlrZDlkJHph48NCmEgPSBjKCJQc3ljaG9sb2d5IiwgIkVDTlUiLCAiU2hhbmdoYWkiLCAiQ2hpbmEiKQ0KYXMuZmFjdG9yKGEpDQpmYWN0b3IoYSwgbGV2ZWxzPWMoIkNoaW5hIiwgIlNoYW5naGFpIiwgIkVDTlUiLCAiUHN5Y2hvbG9neSIpKQ0KZmFjdG9yKA0KICBhLA0KICBsZXZlbHMgPSBjKCJDaGluYSIsICJTaGFuZ2hhaSIsICJFQ05VIiwgIlBzeWNob2xvZ3kiKSwNCiAgbGFiZWxzID0gYygiQ04iLCAiU0giLCAiRUNOVSIsICJQc3kiKQ0KKQ0KYGBgDQoNCiMjIyDvvIgz77yJ6YC76L6R5ZCR6YePDQoNCiMjIyMg44CQ5a6e6Le1M+OAkemAu+i+keWQkemHjyB7I+Wunui3tTPpgLvovpHlkJHph499DQoNCmBgYHtyfQ0KYyhUUlVFLCBUUlVFLCBGQUxTRSwgVFJVRSwgRkFMU0UsIEZBTFNFKQ0KMTo1ID4gMg0KYGBgDQoNCiMjIyMjIGAlaW4lYO+8muWQkemHj+WMluWIpOaWreWJjeS4gOS4quWvueixoeeahOavj+S4quWFg+e0oOaYr+WQpuWcqOWQjuS4gOS4quWvueixoeS4rQ0KDQpgYGB7cn0NCmMoMCwgNSwgMTAsIDE1KSAlaW4lIDE6MTANCmBgYA0KDQojIyMjIyBgaWZlbHNlKClg77ya5qC55o2u5p2h5Lu26K+t5Y+l77yM5ZCR6YeP5YyW6YC76L6R5Yik5patDQoNCmBgYHtyfQ0KaWZlbHNlKDE6MTAgPj0gNSwgIlllcyIsICJObyIpICAjIGlmZWxzZSh0ZXN0LCB5ZXMsIG5vKQ0KYGBgDQoNCiMjIyMg44CQ55+l6K+G54K544CR5p2h5Lu25Yik5pat6L+Q566X56ym5LiO5a+56LGh57G75Z6L5Yik5pat5Ye95pWwIHsj55+l6K+G54K55p2h5Lu25Yik5pat6L+Q566X56ym5LiO5a+56LGh57G75Z6L5Yik5pat5Ye95pWwfQ0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiMjIOadoeS7tuWIpOaWrei/kOeul+espg0KYSA9PSBiDQphICE9IGINCmEgPiBiDQphIDwgYg0KYSA+PSBiDQphIDw9IGINCmEgJWluJSBiDQoNCiMjIOWvueixoeexu+Wei+WIpOaWreWHveaVsA0KaXMubmEoeCkNCmlzLm51bGwoeCkNCmlzLm51bWVyaWMoeCkNCmlzLmNoYXJhY3Rlcih4KQ0KaXMuZmFjdG9yKHgpDQojIOi/mOaciemdnuW4uOWkmuWFtuS7liBpcy54eHgoKSDns7vliJflh73mlbDvvIENCmBgYA0KDQojIyMg5ZCR6YeP55u45LqS6L2s5o2iDQoNCiMjIyMg44CQ5a6e6Le1NOOAkemAu+i+keWQkemHj+KAlOaVsOWAvOWQkemHj+KAlOWtl+espuWQkemHj+eahOebuOS6kui9rOaNoiB7I+Wunui3tTTpgLvovpHlkJHph4/mlbDlgLzlkJHph4/lrZfnrKblkJHph4/nmoTnm7jkupLovazmjaJ9DQoNCi0gICBgYXMubG9naWNhbCgpYO+8mmAwYOi9rOaNouS4umBGQUxTRWDvvIzpnZ5gMGDovazmjaLkuLpgVFJVRWANCi0gICBgYXMuY2hhcmFjdGVyKClg77ya6L2s5o2i5Li65a2X56ym5ZCR6YePDQotICAgYGFzLm51bWVyaWMoKWDvvJrovazmjaLkuLrmlbDlgLzlkJHph4/vvIjml6Dms5XovazmjaLnmoTorrDkuLpgTkFg57y65aSx5YC877yJDQoNCmBgYHtyfQ0KYXMubG9naWNhbCgwOjUpDQphcy5jaGFyYWN0ZXIoMDo1KQ0KYXMubnVtZXJpYyhjKCItMS41IiwgIjAiLCAiMS41IikpDQphcy5udW1lcmljKGMoIjEuMiIsICItLjEyIiwgIjEuMi4zIikpICAjIE5B6KGo56S657y65aSx5YC8DQpgYGANCg0KIyMjIyDjgJDnn6Xor4bngrnjgJHnrqHpgZPmk43kvZznrKYgeyPnn6Xor4bngrnnrqHpgZPmk43kvZznrKZ9DQoNCiMjIyMjIGAlPiVg77ya566h6YGT5pON5L2c56ym4q2Q77iP77yIdGlkeXZlcnNl57O75YiX5YyF55qE6YCa55So5Ye95pWw77yJDQoNCi0gICAqKum7mOiupOWwhuOAkOW3puS+p+e7k+aenOOAkeS8oOe7meOAkOWPs+S+p+WHveaVsOOAkeeahOOAkOesrDHkuKrlj4LmlbDjgJHvvIEqKg0KICAgIC0gICAqKuWmguaenOaDs+S8oOe7meWPs+S+p+WHveaVsOeahOWFtuS7luWPguaVsO+8jOmcgOimgeeUqOeCuWAuYOWNoOS9je+8gSoqDQotICAg5b+r5o236ZSu77yaQ3RybCArIFNoaWZ0ICsgTe+8iOazqOaEj+ajgOafpeWFtuS7lui9r+S7tueahOW/q+aNt+mUruWGsueqge+8iQ0KLSAgIOWmguaenOaPkOekumDmsqHmnIkiJT4lIui/meS4quWHveaVsGDvvIzor7dgbGlicmFyeSh0aWR5dmVyc2UpYOaIlmBsaWJyYXJ5KGJydWNlUilgDQoNCmBgYHtyfQ0KYSA9IGMoIlBzeWNob2xvZ3kiLCAiRUNOVSIsICJTaGFuZ2hhaSIsICJDaGluYSIpDQphcy5mYWN0b3IoYSkgICMg5LiN5L2/55So566h6YGT5pON5L2c56ymDQphICU+JSBhcy5mYWN0b3IoKSAgIyDkvb/nlKjnrqHpgZPmk43kvZznrKbvvIzpu5jorqTkvKDnu5lhcy5mYWN0b3IoKeesrDHkuKrlj4LmlbANCmEgJT4lIGFzLmZhY3RvcigpICU+JSBhcy5udW1lcmljKCkgICMg6buY6K6k5Lyg57uZ6L+Z5Lqb5Ye95pWw55qE56ysMeS4quWPguaVsA0KYSAlPiUgYXMuZmFjdG9yKCkgJT4lIGFzLm51bWVyaWMoKSAlPiUgYyg2NjYpICAjIOm7mOiupOS8oOe7mWMoKeesrDHkuKrlj4LmlbANCmEgJT4lIGFzLmZhY3RvcigpICU+JSBhcy5udW1lcmljKCkgJT4lIGMoLiwgNjY2KSAgIyAu5Y2g5L2N56ysMeS4quWPguaVsA0KYSAlPiUgYXMuZmFjdG9yKCkgJT4lIGFzLm51bWVyaWMoKSAlPiUgYyg2NjYsIC4pICAjIC7ljaDkvY3nrKwy5Liq5Y+C5pWwDQphICU+JSBhcy5mYWN0b3IoKSAlPiUgYXMubnVtZXJpYygpICU+JSBjKDY2NiwgODg4LCAuKSAgIyAu5Y2g5L2N56ysM+S4quWPguaVsA0KYSAlPiUgYXMuZmFjdG9yKCkgJT4lIGFzLm51bWVyaWMoKSAlPiUgYyg2NjYsIC4sIDg4OCkgICMgLuWNoOS9jeesrDLkuKrlj4LmlbANCmBgYA0KDQrnn6Xor4bngrnlsI/nu5PvvJpgTEhTICU+JSBSSFNg6L+Z56eN5YaZ5rOV77yM5Y+v5Lul5bCGYExIU2DvvIhMZWZ0LUhhbmQgU2lkZe+8ieeahOi+k+WHuue7k+aenOS9nOS4umBSSFNg77yIUmlnaHQtSGFuZCBTaWRl77yJ56ysMeS4quWPguaVsOeahOi+k+WFpeWAvO+8jOS7juiAjOWunueOsOa1geeoi+WMlueahOeuoemBk+aTjeS9nOaViOaenO+8jOmBv+WFjee5geeQkOOAgeWPr+ivu+aAp+W3rueahOKAnOWHveaVsOWll+Wog+KAne+8gQ0KDQpgYGB7cn0NCiMjIOWPr+ivu+aAp+W3rueahOKAnOWHveaVsOWll+Wog+KAnQ0KYyg2NjYsIGFzLm51bWVyaWMoYXMuZmFjdG9yKGFzLmNoYXJhY3RlcihjKCJQc3ljaG9sb2d5IiwgIkVDTlUiKSkpKSkNCmBgYA0KDQojIyMg5ZCR6YeP5YWD57Sg5pON5L2cDQoNCiMjIyMg44CQ5a6e6Le1NeOAkeWQkemHj+WFg+e0oOWRveWQjeS4juaPkOWPliB7I+Wunui3tTXlkJHph4/lhYPntKDlkb3lkI3kuI7mj5Dlj5Z9DQoNCiMjIyMjIGBuYW1lcygpYO+8muWvueixoeWFg+e0oOWQjeensOaIluWRveWQjQ0KDQotICAg55u05o6l5L2/55So77ya6L+U5Zue5a+56LGh5YWD57Sg5ZCN56ewDQotICAg6LWL5YC85L2/55So77ya6LWL5LqI5a+56LGh5YWD57Sg5ZCN56ew77yI5bCG5Lya5pS55Y+Y5b2T5YmN5a+56LGh77yJDQoNCmBgYHtyfQ0KTEVUVEVSUyAgIyAyNuS4quiLseaWh+Wtl+avjQ0KYSA9IDE6NQ0KbmFtZXMoYSkgICMg55u05o6l55So5rOV77yI5Yia5Yia5Ye655Sf77yM6L+Y5rKh5ZCN5a2X77yJDQoNCm5hbWVzKGEpID0gTEVUVEVSU1sxOjVdICAjIOi1i+WAvOeUqOazle+8jGHlt7LmlLnlj5gNCmENCm5hbWVzKGEpICAjIOeOsOWcqOS4iuWlveaIt+WPo++8jOacieWQjeWtl+S6hu+8gQ0KYGBgDQoNCiMjIyMjIGB4Wy4uLl1g77yaYFtdYOaTjeS9nOespuWPluWvueixoeWFg+e0oOWGheWuuQ0KDQotICAgYHhb6YC76L6RL+aVsOWAvOWQkemHj11g77ya5Y+W5a+55bqU5L2N572u5YWD57Sg77yI6Iul5Li66LSf5pWw77yM5YiZ5Yig6Zmk5a+55bqU5YWD57Sg77yJDQotICAgYHhb5a2X56ym5ZCR6YePXWDvvJrlj5blr7nlupTlkI3np7DlhYPntKANCg0KYGBge3J9DQphWyJFIl0NCmFbYygiQSIsICJDIiwgIkUiKV0NCg0KYVstMV0gICMg5Yig6Zmk5YWD57Sg77yM5L2G5LiN5pS55Y+YYQ0KYVstKDI6NCldICAjIOWIoOmZpOWFg+e0oO+8jOS9huS4jeaUueWPmGENCmBgYA0KDQojIyMjIyBgcmV2KClg77ya5ZCR6YeP5Y+N5ZCR5o6S5YiXDQoNCiMjIyMjIGBzb3J0KClg77ya5oyJ54Wn5pWw5YC85aSn5bCP5oiW5a2X5q+N5bqP6YeN5paw5o6S5YiXDQoNCiMjIyMjIGB1bmlxdWUoKWDvvJrlj5blkJHph4/kuK3nmoTmiYDmnInni6znibnlhYPntKDvvIjljrvph43lpI3lgLzvvIkNCg0KIyMjIyMgYHRhYmxlKClg77ya5ZCR6YeP5YWD57Sg6aKR5qyh57uf6K6hDQoNCmBgYHtyfQ0KeCA9IGMoMiwgMCwgMCwgMCwgNiwgMikNCnJldih4KQ0Kc29ydCh4KQ0KdW5pcXVlKHgpDQp4ICU+JSB1bmlxdWUoKSAlPiUgc29ydCgpICU+JSByZXYoKQ0KdGFibGUoeCkNCg0KeCAlaW4lIDE6NQ0KeFt4ICVpbiUgMTo1XQ0KeFt4ICVpbiUgMTo1XSA9IE5BDQp4DQpgYGANCg0KIyMjIyDjgJDlrp7ot7U244CR5ZCR6YeP5Luj5pWw6L+Q566XIHsj5a6e6Le1NuWQkemHj+S7o+aVsOi/kOeul30NCg0KYGBge3J9DQphID0gMTo1DQphICsgMSAgICAjIDE6NSArIDEg44CQ5oCd6ICD77yaYSArIDE6MiDnmoTnu5PmnpzvvJ/jgJENCmEgKiAyICAgICMgMTo1ICogMg0KYV4yICAgICAgIyAoMTo1KV4yDQphICogNToxICAjIOWvueW6lOS9jee9ruebuOS5mO+8jOmVv+W6puW/hemhu+ebuOetiQ0KYSAlJSAyICAgIyDlj5bkvZnmlbANCmBgYA0KDQojIyMjIyBgc3VtKClg44CBYG1lYW4oKWDjgIFgbWluKClg44CBYG1heCgpYO+8muWQkemHj+axguWSjOOAgeW5s+Wdh+WAvOOAgeacgOWwj+WAvOOAgeacgOWkp+WAvA0KDQotICAgYG5hLnJtYOWPguaVsO+8muW/veinhue8uuWkseWAvGBOQWANCg0KYGBge3J9DQpzdW0oMToxMDApICAjIOaxguWSjA0KbWVhbigxOjEwMCkgICMg5rGC5bmz5Z2H5YC8DQptaW4oMToxMDApICAjIOacgOWwj+WAvA0KbWF4KDE6MTAwKSAgIyDmnIDlpKflgLwNCg0KeCA9IGMoMSwgTkEsIDMsIE5BLCA1KQ0Kc3VtKHgpDQpzdW0oeCwgbmEucm09VFJVRSkNCm1lYW4oeCkNCm1lYW4oeCwgbmEucm09VFJVRSkNCm1pbih4KQ0KbWluKHgsIG5hLnJtPVRSVUUpDQptYXgoeCkNCm1heCh4LCBuYS5ybT1UUlVFKQ0KYGBgDQoNCiMjIyMjIGBhYnMoKWDjgIFgbG9nKClg44CBYHNxcnQoKWDnrYnvvJrlkITnp43luLjnlKjnmoTmlbDlrabov5DnrpcNCg0KYGBge3J9DQphYnMoLTEpDQpsb2coMi43MTgyODE4MjgpICAjIGxuIOiHqueEtuWvueaVsOi9rOaNog0Kc3FydCg4MSkNCnNxcnQoc3FydCg4MSkpDQo4MSAlPiUgc3FydCgpICU+JSBzcXJ0KCkNCg0KYWJzKGxvZyhzcXJ0KHBpKSkpDQpwaSAlPiUgc3FydCgpICU+JSBsb2coKSAlPiUgYWJzKCkgICMg566h6YGT5pON5L2c56ymDQpgYGANCg0KIyMjIyDjgJDlrp7ot7U344CR5ZCR6YeP5YWD57Sg5ou85o6lIHsj5a6e6Le1N+WQkemHj+WFg+e0oOaLvOaOpX0NCg0KIyMjIyMgYHBhc3RlKClg44CBYHBhc3RlMCgpYO+8muaKiuWQkemHj+WFg+e0oOaLvOaOpeWcqOS4gOi1tw0KDQotICAgYHNlcGDlj4LmlbDvvJrlpJrkuKrovpPlhaXkuYvpl7TnmoTpu4/lkIjlrZfnrKYNCi0gICBgY29sbGFzcGVg5Y+C5pWw77ya5ZCR6YeP5LiN5ZCM5YWD57Sg5LmL6Ze055qE6buP5ZCI5a2X56ymDQoNCmBgYHtyfQ0KcGFzdGUoMSwgMiwgMywgNCwgNSkgICMgcGFzdGUoKSDmi7zmjqXluKbnqbrmoLwNCnBhc3RlMCgxLCAyLCAzLCA0LCA1KSAgIyBwYXN0ZTAoKSDmi7zmjqXkuI3luKbnqbrmoLwNCg0KcGFzdGUoMSwgMiwgMywgNCwgNSwgc2VwPSItIikgICMg5aSa5Liq5Y+C5pWw6L6T5YWl5LmL6Ze05ou85o6lDQpwYXN0ZSgxOjUsIGNvbGxhcHNlPSItIikgICMg5Y2V5Liq5ZCR6YeP55qE5LiN5ZCM5YWD57Sg5LmL6Ze05ou85o6lDQpwYXN0ZSgxOjEwLCBjb2xsYXBzZT0iKyIpICAjIOaJk+WNsOiuoeeul+WFrOW8jw0KY2F0KHBhc3RlKDE6MTAsIGNvbGxhcHNlPSIrIiksICI9Iiwgc3VtKDE6MTApKQ0KYGBgDQoNCiFbXShpbWFnZXMvY2xpcGJvYXJkLTM2MjU1ODk1MDcucG5nKQ0KDQojIyDliJfooajvvIhsaXN077yJDQoNCi0gICDljZXnu7TjgIHlpJrnsbvlnovmlbDmja4NCg0KIyMjIyDjgJDlrp7ot7U444CR5YiX6KGo5p6E5bu65LiO5pON5L2cIHsj5a6e6Le1OOWIl+ihqOaehOW7uuS4juaTjeS9nH0NCg0KIyMjIyMgYGxpc3QoKWDvvJrlu7rnq4vkuIDkuKrliJfooajlr7nosaHvvIzlj6/lrZjlgqjku7vmhI/nsbvlnovjgIHku7vmhI/nu5PmnoTnmoTlr7nosaENCg0KLSAgIGAkYO+8muagueaNruWFg+e0oOWQjeensO+8jOWPluWIl+ihqOS4reeahOWFg+e0oOWGheWuue+8iFRhYumUruW8ueWHuuaJgOacieWFg+e0oOWQjeensO+8iQ0KLSAgIGBbWy4uLl1dYO+8muWPluWIl+ihqOS4reWvueW6lOS9jee9rueahOWFg+e0oOWGheWuue+8iOS4jeWQjOS6jmBbLi4uXWDvvIkNCg0KIVvovpPlhaXlkI7mjIlUYWLplK7lvLnlh7rmiYDmnInlhYPntKDlkI3np7BdKGltYWdlcy9jbGlwYm9hcmQtMzEzMTQ4MTMwOC5wbmcpDQoNCmBgYHtyfQ0KbCA9IGxpc3QoWWVhcj0yMDAwOjIwMTUsIE1vbnRoPTE6MTIsIERheT0xOjMxLCBMZXR0ZXI9TEVUVEVSUykNCmwNCm5hbWVzKGwpDQpsZW5ndGgobCkNCmwkWWVhcg0KbFsyXSAgICAjIOWPluesrDLkuKrlrZDpm4bvvIzov5Tlm55saXN05a2Q6ZuGDQpsW1syXV0gICMg5Y+W56ysMuS4quWFg+e0oO+8jOi/lOWbnuWFg+e0oOacrOi6q++8jOebuOW9k+S6jiBsJE1vbnRoDQpgYGANCg0KIyMjIyMgYHVubGlzdCgpYO+8muino+mZpOWIl+ihqOe7k+aehO+8jOi/mOWOn+S4uuWQkemHjw0KDQpgYGB7cn0NCnVubGlzdChsKSAgIyDop6PpmaTliJfooajnu5PmnoTvvIzlvLrooYznu5/kuIDlr7nosaHnsbvlnovvvIjmlbDlgLwgLT4g5a2X56ym77yJDQpgYGANCg0KIyMjIyMgYGxhcHBseSgpYO+8muaJuemHj+W6lOeUqOWHveaVsO+8jOi/lOWbnuS4uuWIl+ihqA0KDQpgYGB7cn0NCiMjIGxhcHBseSjlkJHph4/miJbliJfooagsIOWHveaVsCkNCmxhcHBseShsLCBsZW5ndGgpICAjIOavj+S4quWFg+e0oOaJuemHj+W6lOeUqGxlbmd0aCgp5Ye95pWwDQpsYXBwbHkobCwgbWVhbikgICAgIyDmr4/kuKrlhYPntKDmibnph4/lupTnlKhtZWFuKCnlh73mlbANCg0KYSA9IDE6NQ0KYV4yDQpsYXBwbHkoYSwgZnVuY3Rpb24oeCkgeF4yKSAgIyB45piv5b2i5Y+C77yI5b2i5byP5Y+C5pWw77yJDQpsYXBwbHkoYSwgZnVuY3Rpb24oeCkgeF4yKSAlPiUgdW5saXN0KCkNCmBgYA0KDQojIFLlh73mlbDkvb/nlKjkuI7lj4LmlbDorr7nva4NCg0KIyMjIyDjgJDnn6Xor4bngrnjgJFS5Ye95pWw5L2T55qE57uT5p6EIHsj55+l6K+G54K5cuWHveaVsOS9k+eahOe7k+aehH0NCg0KIyMjIyMgYGZ1bmN0aW9uKC4uLilg77ya5Ye95pWw5o6l5pS26L6T5YWl5Y+C5pWw77yM5YaF6YOo5pON5L2c5ZCO77yM6L+U5Zue6L6T5Ye657uT5p6cDQoNCi0gICBgeyB9YO+8muWkp+aLrOWPt+WGheWumuS5ieaJgOacieW9ouW8j+WPguaVsO+8iOW9ouWPgu+8ieeahOaTjeS9nOi/h+eoiw0KLSAgIOi/lOWbnue7k+aenOWPr+eUqOS4pOenjeaWueW8jw0KICAgIC0gICBgcmV0dXJuKC4uLilg77ya5pi+5byP6L+U5ZueDQogICAgLSAgIGBpbnZpc2libGUoLi4uKWDvvJrpmpDlvI/ov5Tlm54NCg0KYGBge3J9DQpmdW5jID0gZnVuY3Rpb24ocGFyYW0xLCBwYXJhbTIsIC4uLikgew0KICAjIyDlh73mlbDlhoXpg6jmk43kvZwNCiAgcmVzdWx0cyA9IHBhcmFtMSArIHBhcmFtMg0KICBjYXQocGFyYW0xLCAiKyIsIHBhcmFtMiwgIj0iLCByZXN1bHRzLCAiXG4iKQ0KICANCiAgIyMg5Ye95pWw6L+U5Zue57uT5p6cDQogIHJldHVybihyZXN1bHRzKQ0KICAjIOS5n+WPr+S7pemakOW8j+i/lOWbnu+8mg0KICAjIGludmlzaWJsZShyZXN1bHRzKQ0KfQ0KZnVuYygxNiwgOSkNCmBgYA0KDQojIyDluLjnlKhS5Ye95pWw5L2/55SoDQoNCiMjIyMg44CQ5a6e6Le1OeOAkeaWh+S7tuWkuemHjOacieS7gOS5iO+8nyB7I+Wunui3tTnmlofku7blpLnph4zmnInku4DkuYh9DQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KIyMg6K+36Ieq5bex6L+Q6KGMDQpsaWJyYXJ5KGJydWNlUikNCnNldC53ZCgpICAjIOiuvue9ruW3peS9nOi3r+W+hOS4uuW9k+WJjeaJk+W8gOaWh+S7tueahOi3r+W+hA0KDQpsaXN0LmZpbGVzKCkgICAgICAgICAgIyDliJflh7rlvZPliY3ot6/lvoTnmoTmiYDmnInmlofku7Yv5paH5Lu25aS5DQpsaXN0LmZpbGVzKCIuLi8iKSAgICAgIyDliJflh7rkuIrkuIDnuqfot6/lvoTnmoTmiYDmnInmlofku7Yv5paH5Lu25aS5DQpsaXN0LmZpbGVzKCIuLi8uLi8iKSAgIyDliJflh7rkuIrkuKTnuqfot6/lvoTnmoTmiYDmnInmlofku7Yv5paH5Lu25aS5DQpgYGANCg0KIyMjIyDjgJDlrp7ot7UxMOOAkeS7iuWkqeaZmuS4iuWQg+S7gOS5iO+8nyB7I+Wunui3tTEw5LuK5aSp5pma5LiK5ZCD5LuA5LmIfQ0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiMjIOivt+iHquW3sei/kOihjA0KY2hvaWNlID0gYygi5rKz6KW/6aOf5aCCIiwgIuays+S4nOmjn+WggiIsICLnjq/nkIPmuK8iLCAi54K55aSW5Y2WIikNCnNhbXBsZShjaG9pY2UsIHNpemU9MSkgICMg6ZqP5py65oq95qC3DQoNCiMg6K6+572u6ZqP5py656eN5a2Q77yM5L2/57uT5p6c5Y+v6YeN5aSNDQpzZXQuc2VlZCgxMjMpICAjIOmaj+acuuenjeWtkOWPr+S7peaYr+S7u+aEj+aVtOaVsO+8jOayoeacieeJueWumuWQq+S5iQ0Kc2FtcGxlKGNob2ljZSwgc2l6ZT0xKQ0KYGBgDQoNCiMjIyMg44CQ5a6e6Le1MTHjgJHmraPmgIHliIbluIPpmo/mnLrmlbDnmoTlubPlnYflgLzlkozmoIflh4blt67vvJ8geyPlrp7ot7UxMeato+aAgeWIhuW4g+maj+acuuaVsOeahOW5s+Wdh+WAvOWSjOagh+WHhuW3rn0NCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpICAjIOiuvue9rumaj+acuuenjeWtkO+8jOS9v+e7k+aenOWPr+mHjeWkjQ0KeCA9IHJub3JtKDMwKSAgIyDnlJ/miJAzMOS4qumaj+acuuaVsO+8iOato+aAgeWIhuW4g++8iQ0KDQptZWFuKHgpICAjIOaxguW5s+Wdh+WAvA0Kc2QoeCkgICAgIyDmsYLmoIflh4blt64NCmhpc3QoeCkgICMg55S755u05pa55Zu+DQoNCnggPiBtZWFuKHgpICsgc2QoeCkgICAgICAgICAjIOi/lOWbnlRSVUUvRkFMU0XlkJHph48NCnhbeCA+IG1lYW4oeCkgKyBzZCh4KV0gICAgICAjIOi/lOWbnijlj5blh7op56ym5ZCI5p2h5Lu255qE5pWw5YC8DQp3aGljaCh4ID4gbWVhbih4KSArIHNkKHgpKSAgIyDov5Tlm57nrKblkIjmnaHku7bmlbDlgLzmiYDlnKjkvY3nva4NCg0Kc2V0LnNlZWQoMTIzKSAgIyDorr7nva7pmo/mnLrnp43lrZDvvIzkvb/nu5Pmnpzlj6/ph43lpI0NCnggPSBybm9ybSgxMDAwKSAgIyDnlJ/miJAxMDAw5Liq6ZqP5py65pWw77yI5q2j5oCB5YiG5biD77yJDQoNCm1lYW4oeCkgICMg5rGC5bmz5Z2H5YC8DQpzZCh4KSAgICAjIOaxguagh+WHhuW3rg0KaGlzdCh4KSAgIyDnlLvnm7Tmlrnlm74NCmBgYA0KDQojIyMjIOOAkOWunui3tTEy44CR4oCcSGVsbG8gV29ybGTigJ3nmoTlh6Dnp43miZPljbDmlrnms5XvvJ8geyPlrp7ot7UxMmhlbGxvLXdvcmxk55qE5Yeg56eN5omT5Y2w5pa55rOVfQ0KDQotICAgYGNsaWDmmK/lkb3ku6TooYzkuqTkupLnmoTkuJPkuJpS5YyF77yM57O757uf5oCn5o+Q5L6b5LqG5ZCE56eN6L6T5Ye65paH5pys6K6+5a6a5Ye95pWwDQogICAgLSAgIOivpuinge+8mjxodHRwczovL2NsaS5yLWxpYi5vcmcvPg0KDQpgYGB7cn0NCnByaW50KCJIZWxsbyBXb3JsZCEiKQ0KY2F0KCJIZWxsbyBXb3JsZCEiKQ0KY2F0KCJIZWxsbyIsICJXb3JsZCEiKQ0KYGBgDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KY2xpOjpjbGlfdGV4dCgiSGVsbG8gV29ybGQhIikNCmNsaTo6Y2xpX2gxKCJIZWxsbyBXb3JsZCEiKQ0KY2xpOjpjbGlfaDIoIkhlbGxvIFdvcmxkISIpDQpjbGk6OmNsaV9oMygiSGVsbG8gV29ybGQhIikNCmNsaTo6Y2xpX2FsZXJ0KCJIZWxsbyBXb3JsZCEiKQ0KY2xpOjpjbGlfYWxlcnRfc3VjY2VzcygiSGVsbG8gV29ybGQhIikNCmNsaTo6Y2xpX2FsZXJ0X2luZm8oIkhlbGxvIFdvcmxkISIpDQpjbGk6OmNsaV9hbGVydF93YXJuaW5nKCJIZWxsbyBXb3JsZCEiKQ0KY2xpOjpjbGlfYWxlcnRfZGFuZ2VyKCJIZWxsbyBXb3JsZCEiKQ0KYGBgDQoNCiFbXShpbWFnZXMvY2xpcGJvYXJkLTcxNDEyNDM5NS5wbmcpDQoNCiMgUumAu+i+keaOp+WItuivreWPpQ0KDQojIyBpZuWIpOaWreivreWPpQ0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmlmIChjb25kaXRpb24pIHsNCiAgIyBEbyBzb21ldGhpbmcNCn0gZWxzZSBpZiB7DQogICMgRG8gc29tZXRoaW5nDQp9IGVsc2Ugew0KICAjIERvIHN0aC4gZWxzZQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KeCA9IDMNCmlmICh4ICVpbiUgMTo1KSB7DQogIGNhdCgiWWVzIikNCn0gZWxzZSB7DQogIGNhdCgiTm8iKQ0KfQ0KYGBgDQoNCiMjIHdoaWxl5b6q546v6K+t5Y+lDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0Kd2hpbGUgKGNvbmRpdGlvbikgew0KICAjIERvIHNvbWV0aGluZw0KfQ0KYGBgDQoNCmBgYHtyfQ0KeCA9IDENCndoaWxlICh4IDwgNSkgew0KICBjYXQoeCwgImlzIHNtYWxsZXIgdGhhbiA1XG4iKQ0KICB4ID0geCArIDENCn0NCmBgYA0KDQojIyBmb3Llvqrnjq/or63lj6UNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpmb3IgKHZhciBpbiBzZXEpIHsNCiAgIyBEbyBzb21ldGhpbmcNCn0NCmBgYA0KDQpgYGB7cn0NCmZvciAoeCBpbiAxOjUpIHsNCiAgeSA9IHggKiAyDQogIHByaW50KHkpDQp9DQpgYGANCg0KIyDjgJDkvZzkuJoz44CR57yW56iL6Kej5Yaz5oqb56Gs5biB6Zeu6aKYDQoNCumXrumimOaDheWig++8muS4gOaemuehrOW4ge+8jOi/nue7reaKm+S6hk7mrKHpg73mmK/mraPpnaLmnJ3kuIrvvIzlho3mipvkuIDmrKHlj43pnaLmnJ3kuIrnmoTmpoLnjofmmK/lpJrlsJHvvJ8NCg0KLSAgIOavlOWmgu+8jOS4gOaemuehrOW4ge+8jOi/nue7reaKm+S6hjPmrKHpg73mmK/mraPpnaLmnJ3kuIrvvIzlho3mipvkuIDmrKHlj43pnaLmnJ3kuIrnmoTmpoLnjofmmK/lpJrlsJHvvJ8NCi0gICDov57nu60xMOasoeWRou+8n+i/nue7rTEwMDDmrKHlkaLvvJ/ov57nu60x5Lq/5qyh5ZGi77yf4oCm4oCmDQotICAg5oCd6Lev5o+Q56S677ya5Yip55So5YGH6K6+5qOA6aqM55qE5oCd5oOz77yM5Yik5pat6L+Z5p6a56Gs5biB5piv5LiN5piv5pmu6YCa56Gs5biB77yISDDvvJrnoazluIHmmK/mma7pgJrnmoTvvIkNCg0K5L2c5Lia6KaB5rGC77yaDQoNCi0gICDnvJblhpnkuIDmrrVS56iL5bqP77yM6K6h566X5bm25Yik5pat6Iez5bCR6L+e57ut5aSa5bCR5qyh5q2j6Z2i5pyd5LiK77yM5Y+v5Lul6K6k5a6a56Gs5biB5LiN5YaN5piv5pmu6YCa56Gs5biB77yI5ouS57ud6Zu25YGH6K6+77yJDQotICAg5bC95Y+v6IO955SoUiBNYXJrZG93buWujOaIkA0KDQrlubPlj7Dmj5DkuqTvvJoNCg0KLSAgIFLku6PnoIHlkozov5DooYznu5PmnpzmiKrlm74NCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNClvov5Tlm57or77nqIvkuLvpobVdKGh0dHBzOi8vcHN5Y2hicnVjZS5naXRodWIuaW8vUkNvdXJzZS8pDQoNCsKpIOWMheWvkuWQtOmcnA0K