前言:從交易記錄到顧客價值
善用商業數據分析的工具和技巧,光靠一份最簡單的交易紀錄(只有顧客ID、交易日期和交易金額三個欄位),我們就可以做一系列很深入、很有價值的顧客價值分析和行銷策略規劃,包括:
- 交易記錄分析:
- 顧客群組與標籤:
- 集群分析
- 群組屬性分析
- 組間流動機率
- 顧客(個人)流動機率
從這一些分析我們可以看到公司主要的營收和獲利的重要來源,我們也可以看到這一些產生獲利的群組是不是有成長或者衰退的趨勢;據此我們可以設定行銷的重點,決定行銷的策略,和規劃行銷的工具。除了上述的敘述統計、集群分析、和資料視覺化之外,我們還可以利用這些簡單的交易紀錄:
- 建立預測性模型,預測每一位顧客的:
- 保留機率
- 預期營收
- 組間變換機率
- 下次可能購買時間
利用這一些預測我們就可以進行全面客製化的:
- 顧客價值管理:
- 顧客終生價值
- 顧客吸收策略
- 顧客發展策略
- 顧客保留策略
- 針對性行銷:
Setup
Sys.setlocale("LC_ALL","C")
[1] "C"
packages = c(
"dplyr","ggplot2","googleVis","devtools","magrittr","caTools","ROCR","caTools")
existing = as.character(installed.packages()[,1])
for(pkg in packages[!(packages %in% existing)]) install.packages(pkg)
if(!is.element("chorddiag", existing))
devtools::install_github("mattflor/chorddiag")
Library
rm(list=ls(all=T))
options(digits=4, scipen=12)
library(dplyr)
library(ggplot2)
library(caTools)
library(ROCR)
library(googleVis)
library(chorddiag)
1 1. 資料整理
1.1 交易資料 (X)
X = read.table(
'purchases.txt', header=FALSE, sep='\t', stringsAsFactors=F)
names(X) = c('cid','amount','date')
X$date = as.Date(X$date)
summary(X)
cid amount date
Min. : 10 Min. : 5 Min. :2005-01-02
1st Qu.: 57720 1st Qu.: 25 1st Qu.:2009-01-17
Median :102440 Median : 30 Median :2011-11-23
Mean :108935 Mean : 62 Mean :2011-07-14
3rd Qu.:160525 3rd Qu.: 60 3rd Qu.:2013-12-29
Max. :264200 Max. :4500 Max. :2015-12-31
# 交易次數 51243
par(cex=0.8)
hist(X$date, "years", las=2, freq=T, xlab="", main="No. Transaction by Year")

# 從圖中可看出交易逐年成長,但有放緩的趨勢
n_distinct(X$cid)
[1] 18417
# 顧客數 18417
1.2 顧客資料 (A)
A = X %>%
mutate(days = as.integer(as.Date("2016-01-01") - date)) %>%
group_by(cid) %>% summarise(
recent = min(days),
freq = n(),
money = mean(amount),
senior = max(days),
since = min(date)
) %>% data.frame
# recent : 最近購買距今天數(整筆資料最後一天加一)
# freq : 購買次數
# money : 平均購買金額
# senior : 第一次購買距今天數
# since : 第一次購買日期
1.4 顧客資料摘要
summary(A)
cid recent freq money senior
Min. : 10 Min. : 1 Min. : 1.00 Min. : 5 Min. : 1
1st Qu.: 81990 1st Qu.: 244 1st Qu.: 1.00 1st Qu.: 22 1st Qu.: 988
Median :136430 Median :1070 Median : 2.00 Median : 30 Median :2087
Mean :137574 Mean :1253 Mean : 2.78 Mean : 58 Mean :1984
3rd Qu.:195100 3rd Qu.:2130 3rd Qu.: 3.00 3rd Qu.: 50 3rd Qu.:2992
Max. :264200 Max. :4014 Max. :45.00 Max. :4500 Max. :4016
since
Min. :2005-01-02
1st Qu.:2007-10-23
Median :2010-04-15
Mean :2010-07-26
3rd Qu.:2013-04-18
Max. :2015-12-31
1.5 變數的分布狀況
p0 = par(cex=0.8, mfrow=c(2,2), mar=c(3,3,4,2))
hist(A$recent,20,main="recency",ylab="",xlab="")
hist(pmin(A$freq, 10),0:10,main="frequency",ylab="",xlab="")
hist(A$senior,20,main="seniority",ylab="",xlab="")
hist(log(A$money,10),,main="log(money)",ylab="",xlab="")

# pmin() 設一個上限
# recency : 最近購買距今天數最左側看似許多顧客才剛來,但卻有一條長尾,表示更多的多顧客很久未光顧了
# frequency : 購買次數在十年的時間內亦表現不佳
# money : 平均購買金額小額居多
# seniority : 第一次購買距今天數可看出依然有許多新顧客持續加入
2. 層級式集群分析
2.1 RFM顧客分群
set.seed(111)
A$grp = kmeans(scale(A[,2:4]),10)$cluster
table(A$grp)
1 2 3 4 5 6 7 8 9 10
1073 2266 1296 2237 3207 1942 1781 2392 2096 127
# 分成十群,先看族群大小
2.2 顧客群組屬性
group_by(A, grp) %>% summarise(
recent=mean(recent),
freq=mean(freq),
money=mean(money),
size=n() ) %>%
mutate( revenue = size*money/1000 ) %>%
filter(size > 1) %>%
ggplot(aes(x=freq, y=money)) +
geom_point(aes(size=revenue, col=recent),alpha=0.5) +
scale_size(range=c(4,30)) +
scale_color_gradient(low="green",high="red") +
scale_x_log10() + scale_y_log10(limits=c(30,3000)) +
geom_text(aes(label = size ),size=3) +
theme_bw() + guides(size=F) +
labs(title="Customer Segements",
subtitle="(bubble_size:revenue_contribution; text:group_size)",
color="Recency") +
xlab("Frequency (log)") + ylab("Average Transaction Amount (log)")

# 泡泡大小是營收貢獻
# 不光要知道靜態屬性,要知道泡泡怎麼變化,很重要
# 若用每年年底做一次,泡泡會動,但統計規則可能每年都不一樣(Kmean)
3. 規則分群
3.1 顧客分群規則
STS = c("N1","N2","R1","R2","S1","S2","S3")
Status = function(rx,fx,mx,sx,K) {factor(
ifelse(sx < 2*K,
ifelse(fx*mx > 50, "N2", "N1"),
ifelse(rx < 2*K,
ifelse(sx/fx < 0.75*K,"R2","R1"),
ifelse(rx < 3*K,"S1",
ifelse(rx < 4*K,"S2","S3")))), STS)}
3.2 平均購買週期
K = as.integer(sum(A$senior[A$freq>1]) / sum(A$freq[A$freq>1])); K
[1] 521
回購顧客的平均購買週期 K = 521 days
3.3 滑動資料窗格
Y = list() # 建立一個空的LIST
for(y in 2010:2015) { # 每年年底將顧客資料彙整成一個資料框
D = as.Date(paste0(c(y, y-1),"-12-31")) # 當期、前期的期末日期
Y[[paste0("Y",y)]] = X %>% # 從交易資料做起
filter(date <= D[1]) %>% # 將資料切齊到期末日期
mutate(days = 1 + as.integer(D[1] - date)) %>% # 交易距期末天數
group_by(cid) %>% summarise( # 依顧客彙總 ...
recent = min(days), # 最後一次購買距期末天數
freq = n(), # 購買次數 (至期末為止)
money = mean(amount), # 平均購買金額 (至期末為止)
senior = max(days), # 第一次購買距期末天數
status = Status(recent,freq,money,senior,K), # 期末狀態
since = min(date), # 第一次購買日期
y_freq = sum(date > D[2]), # 當期購買次數
y_revenue = sum(amount[date > D[2]]) # 當期購買金額
) %>% data.frame }
head(Y$Y2015)
# list每個元件都可以有名字
3.4 每年年底的累計顧客人數
sapply(Y, nrow)
Y2010 Y2011 Y2012 Y2013 Y2014 Y2015
10407 11674 13562 15468 16905 18417
# 資料框的資料筆數,對Y裡的每個元素做nrow
3.5 族群大小變化趨勢
cols = c("gold","orange","blue","green","pink","magenta","darkred")
sapply(Y, function(df) table(df$status)) %>% barplot(col=cols)
legend("topleft",rev(STS),fill=rev(cols))

#活躍顧客,看粉色以下
3.6 族群屬性動態分析
CustSegments = do.call(rbind, lapply(Y, function(d) {
group_by(d, status) %>% summarise(
average_frequency = mean(freq),
average_amount = mean(money),
total_revenue = sum(y_revenue),
total_no_orders = sum(y_freq),
average_recency = mean(recent),
average_seniority = mean(senior),
group_size = n()
)})) %>% ungroup %>%
mutate(year=rep(2010:2015, each=7)) %>% data.frame
head(CustSegments)
# R2族群最大、頻率最高,雖然創造的利潤不是最高但平均購買金額最高
plot( gvisMotionChart(
CustSegments, "status", "year",
options=list(width=900, height=600) ) )
# N1 相當停滯,族群有些微減少
# N2 頻率未增加反下降,平均購買金額顯著提升,族群大小持平
# R1 頻率和平均購買金額皆有提升,族群成長較明顯
# R2 頻率成長幅度最大,平均購買金額小幅提升,族群些微成長
3.7 族群屬性動態分析
df = merge(Y$Y2014[,c(1,6)], Y$Y2015[,c(1,6)],
by="cid", all.x=T)
tx = table(df$status.x, df$status.y) %>%
as.data.frame.matrix() %>% as.matrix()
tx
N1 N2 R1 R2 S1 S2 S3
N1 1705 381 144 45 831 0 0
N2 0 1131 267 430 263 0 0
R1 0 0 1240 43 819 0 0
R2 0 0 199 1742 75 0 0
S1 0 0 115 3 819 1026 0
S2 0 0 78 1 0 692 1339
S3 0 0 97 0 0 0 3420
# 流量矩陣
tx %>% prop.table(1) %>% round(3) # 流量矩陣(%)
N1 N2 R1 R2 S1 S2 S3
N1 0.549 0.123 0.046 0.014 0.268 0.000 0.000
N2 0.000 0.541 0.128 0.206 0.126 0.000 0.000
R1 0.000 0.000 0.590 0.020 0.390 0.000 0.000
R2 0.000 0.000 0.099 0.864 0.037 0.000 0.000
S1 0.000 0.000 0.059 0.002 0.417 0.523 0.000
S2 0.000 0.000 0.037 0.000 0.000 0.328 0.635
S3 0.000 0.000 0.028 0.000 0.000 0.000 0.972
3.8 互動式流量分析
chorddiag(tx, groupColors=cols)
4. 建立模型
在這個案例裡面,我們的資料是收到Y2015年底,所以我們可以假設現在的時間是Y2015年底,我們想要用現有的資料建立模型,來預測每一位顧客:
- 在Y2016年是否會來購買 (保留率:Retain)
- 她來購買的話,會買多少錢 (購買金額:Revenue)
但是,我們並沒有Y2016的資料,為了要建立模型,我們需要先把時間回推一期,也就是說:
- 用Y2014年底以前的資料整理出預測變數(X)
- 用Y2015年的資料整理出目標變數(Y)
假如Y2016的情況(跟Y2015比)沒有太大的變化的話,接下來我們就可以
- 使用該模型,以Y2015年底的資料,預測Y2016的狀況
4.1 準備資料
我們用Y2014年底的資料做自變數,Y2015年的資料做應變數
CX = left_join(Y$Y2014, Y$Y2015[,c(1,8,9)], by="cid")
head(CX)
# 1是cid這個欄位做建置,要把次序對起來
# left_join假設後面沒有,不會直接刪掉,而是保留然後填NA
names(CX)[8:11] = c("freq0","revenue0","Retain", "Revenue")
CX$Retain = CX$Retain > 0 #CX$Retain > 0有無保留住
head(CX)
table(CX$Retain) %>% prop.table()
FALSE TRUE
0.7701 0.2299
# 平均保留機率 = 22.54%
4.2 建立類別模型
mRet = glm(Retain ~ ., CX[,c(2:3,6,8:10)], family=binomial())
summary(mRet)
Call:
glm(formula = Retain ~ ., family = binomial(), data = CX[, c(2:3,
6, 8:10)])
Deviance Residuals:
Min 1Q Median 3Q Max
-3.689 -0.473 -0.298 -0.142 3.386
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.074007 0.089431 -12.01 < 2e-16 ***
recent -0.002067 0.000131 -15.73 < 2e-16 ***
freq 0.095217 0.013882 6.86 0.0000000000069 ***
statusN2 0.669429 0.070234 9.53 < 2e-16 ***
statusR1 0.488321 0.084389 5.79 0.0000000071864 ***
statusR2 1.290002 0.110841 11.64 < 2e-16 ***
statusS1 0.670604 0.146532 4.58 0.0000047279944 ***
statusS2 1.353554 0.208210 6.50 0.0000000000798 ***
statusS3 2.573689 0.275786 9.33 < 2e-16 ***
freq0 0.566557 0.065532 8.65 < 2e-16 ***
revenue0 -0.000132 0.000135 -0.98 0.33
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 18228 on 16904 degrees of freedom
Residual deviance: 11766 on 16894 degrees of freedom
AIC: 11788
Number of Fisher Scoring iterations: 6
4.3 估計類別模型的準確性
pred = predict(mRet,type="response")
table(pred>0.5,CX$Retain)
FALSE TRUE
FALSE 12045 1530
TRUE 974 2356
# 混淆矩陣 (Confusion Matrix)
table(pred>0.5,CX$Retain) %>%
{sum(diag(.))/sum(.)} # 正確率(ACC): 85.19%
[1] 0.8519
colAUC(pred,CX$Retain) # 辯識率(AUC): 87.92%
[,1]
FALSE vs. TRUE 0.8792
prediction(pred, CX$Retain) %>% # ROC CURVE
performance("tpr", "fpr") %>%
plot(print.cutoffs.at=seq(0,1,0.1))

4.4 建立數量模型
dx = subset(CX, Revenue > 0)
mRev = lm(log(Revenue) ~ recent + freq + log(1+money) + senior +
status + freq0 + log(1+revenue0), dx)
summary(mRev)
Call:
lm(formula = log(Revenue) ~ recent + freq + log(1 + money) +
senior + status + freq0 + log(1 + revenue0), data = dx)
Residuals:
Min 1Q Median 3Q Max
-3.245 -0.209 -0.067 0.205 3.435
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.0587930 0.0458344 1.28 0.1997
recent 0.0003541 0.0000507 6.98 0.00000000000337 ***
freq 0.0526850 0.0046504 11.33 < 2e-16 ***
log(1 + money) 0.9320818 0.0135203 68.94 < 2e-16 ***
senior -0.0001369 0.0000182 -7.52 0.00000000000007 ***
statusN2 0.0127716 0.0262656 0.49 0.6268
statusR1 0.1927532 0.0407579 4.73 0.00000233405019 ***
statusR2 0.0297685 0.0352479 0.84 0.3984
statusS1 0.0082406 0.0630355 0.13 0.8960
statusS2 -0.2406398 0.0865731 -2.78 0.0055 **
statusS3 -0.3667341 0.1181061 -3.11 0.0019 **
freq0 0.0103133 0.0172551 0.60 0.5501
log(1 + revenue0) 0.0632756 0.0094003 6.73 0.00000000001930 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.463 on 3873 degrees of freedom
Multiple R-squared: 0.713, Adjusted R-squared: 0.712
F-statistic: 802 on 12 and 3873 DF, p-value: <2e-16
# 只對有來購買的人做模型,沒來買的就不管
# 判定係數:R2 = 0.713
plot(log(dx$Revenue), predict(mRev), col='pink', cex=0.65)
abline(0,1,col='red')

5. 估計顧客終生價值
5.1 Y2016的預測值
使用模型對Y2015年底的資料做預測,對資料中的每一位顧客,預測她們在Y2016的保留率和購買金額。
CX = Y$Y2015
names(CX)[8:9] = c("freq0","revenue0")
# 預測Y2016保留率
CX$ProbRetain = predict(mRet,CX,type='response')
# 預測Y2016購買金額
CX$PredRevenue = exp(predict(mRev,CX))
par(mfrow=c(1,2), mar=c(4,3,3,2), cex=0.8)
hist(CX$ProbRetain,main="ProbRetain", ylab="")
hist(log(CX$PredRevenue,10),main="log(PredRevenue)", ylab="")

# 保留率超過0.5的占比不高
# 購買金額依舊偏低
5.2 估計顧客終生價值(CLV)
顧客終生價值(Customer LifetimeValue)指的是每個購買者在未來可能為企業帶來的收益總和。研究表明,如同某種產品一樣,顧客對於企業利潤的貢獻也可以分為導入期、快速增長期、成熟期和衰退期。
每個客戶的價值都由三部分構成:
- 歷史價值(到目前為止已經實現了的顧客價值)
- 當前價值(如果顧客當前行為模式不發生改變的話,將來會給公司帶來的顧客價值)
- 潛在價值(如果公司通過有效的交叉銷售可以調動顧客購買積極性,或促使顧客向別人推薦產品和服務等,從而可能增加的顧客價值)
顧客\(i\)的終生價值
\[ V_i = \sum_{t=0}^N g \times m_i \frac{r_i^t}{(1+d)^t} = g \times m_i \sum_{t=0}^N (\frac{r_i}{1+d})^t \]
\(m_i\)、\(r_i\):顧客\(i\)的預期(每期)營收貢獻、保留機率
\(g\)、\(d\):公司的(稅前)營業利潤利率、資金成本
g = 0.5 # (稅前)獲利率
N = 5 # 期數 = 5
d = 0.1 # 利率 = 10%
CX$CLV = g * CX$PredRevenue * rowSums(sapply(
0:N, function(i) (CX$ProbRetain/(1+d))^i ) )
summary(CX$CLV)
Min. 1st Qu. Median Mean 3rd Qu. Max.
3 16 24 51 45 5094
par(mar=c(2,2,3,1), cex=0.8)
hist(log(CX$CLV,10), xlab="", ylab="")

5.3 比較各族群的價值
# 各族群的平均營收貢獻、保留機率、終生價值
sapply(CX[,10:12], tapply, CX$status, mean)
ProbRetain PredRevenue CLV
N1 0.20269 31.98 20.17
N2 0.44075 131.23 110.89
R1 0.34150 69.85 54.60
R2 0.74925 91.27 136.31
S1 0.05724 56.10 29.66
S2 0.03475 49.48 25.58
S3 0.02326 49.36 25.17
# 可看出R2最佳,一如上述的分析
# 但是N2能創造的revenue最大,亦是重點族群
par(mar=c(3,3,4,2), cex=0.8)
boxplot(log(CLV)~status, CX, main="CLV by Groups")

7. 選擇行銷對象
給定某一行銷工具的成本和預期效益,選擇可以施行這項工具的對象。
7.1 對R2族群進行保留
R2族群的預測保留率和購買金額
par(mfrow=c(1,2), mar=c(4,3,3,2), cex=0.8)
hist(CX$ProbRetain[CX$status=="R2"],main="ProbRetain",xlab="")
hist(log(CX$PredRevenue[CX$status=="R2"],10),main="PredRevenue",xlab="")

# 細看R2的預測保留率和購買金額
7.2 估計預期報酬
假設行銷工具的成本和預期效益為
cost = 10 # 成本
effect = 0.75 # 效益:下一期的購買機率
估計這項行銷工具對每一位R2顧客的預期報酬
Target = subset(CX, status=="R2")
Target$ExpReturn = (effect - Target$ProbRetain) * Target$PredRevenue - cost
summary(Target$ExpReturn)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-515.8 -15.4 -11.5 -10.3 -8.1 646.9
# ExpReturn是對所有人做的,還是可以挑出很多正的,所以不能用平均值
這一項工具對R2顧客的預期報酬是負的
7.3 選擇行銷對象
但是,我們還是可以挑出許多預期報酬很大的行銷對象
Target %>% arrange(desc(ExpReturn)) %>% select(cid, ExpReturn) %>% head(15)
sum(Target$ExpReturn > 0) # 可實施對象:258
[1] 258
在R2之中,有258人的預期報酬大於零,如果對這258人使用這項工具,我們的期望報酬是:
sum(Target$ExpReturn[Target$ExpReturn > 0]) # 預期報酬:6464
[1] 6464
#不再只是對族群,而是每個人
QUIZ:
我們可以算出對所有的族群實施這項工具的期望報酬 …
Target = CX
Target$ExpReturn = (effect - Target$ProbRetain) * Target$PredRevenue - cost
filter(Target, Target$ExpReturn > 0) %>%
group_by(status) %>% summarise(
No.Target = n(),
AvgROI = mean(ExpReturn),
TotalROI = sum(ExpReturn) ) %>% data.frame
這個結果是合理的嗎? 你想要怎麼修正這項分析的程序呢?
- 也許合理,因為我們並不知道確切的分群標準,只能從分群後的結果進行判讀。
- 給你最多生意的顧客(也就是終身價值最高的顧客),往往不是為你行銷的最佳人員。想知道一位顧客的完整價值,必須估算這個人引進可獲利新顧客的能力。但是,大多數公司對「顧客引介力」(referral power)的估計,頂多是衡量某個人有無引介別人的意願而已,這點須注意。
LS0tDQp0aXRsZTogIkNWTe+8mumhp+WuouWDueWAvOeuoeeQhiAiDQphdXRob3I6ICJHcm91cCAzICwgMjAxOC8wOC8xNCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCjxicj4NCg0KIyMjIOWJjeiogO+8muW+nuS6pOaYk+iomOmMhOWIsOmhp+WuouWDueWAvA0KDQrlloTnlKjllYbmpa3mlbjmk5rliIbmnpDnmoTlt6XlhbflkozmioDlt6fvvIzlhYnpnaDkuIDku73mnIDnsKHllq7nmoTkuqTmmJPntIDpjIQo5Y+q5pyJ6aGn5a6iSUTjgIHkuqTmmJPml6XmnJ/lkozkuqTmmJPph5HpoY3kuInlgIvmrITkvY0p77yM5oiR5YCR5bCx5Y+v5Lul5YGa5LiA57O75YiX5b6I5rex5YWl44CB5b6I5pyJ5YO55YC855qE6aGn5a6i5YO55YC85YiG5p6Q5ZKM6KGM6Yq3562W55Wl6KaP5YqD77yM5YyF5ous77yaDQoNCisgKirkuqTmmJPoqJjpjITliIbmnpAqKu+8mg0KICAgICsg5pWY6L+w57Wx6KiIDQogICAgKyDotqjli6LjgIHkuqTlj4nliIbmnpANCiAgICArIOizh+aWmeimluimuuWMlg0KDQorICoq6aGn5a6i576k57WE6IiH5qiZ57GkKirvvJoNCiAgICArIOmbhue+pOWIhuaekA0KICAgICsg576k57WE5bGs5oCn5YiG5p6QDQogICAgKyDntYTplpPmtYHli5XmqZ/njocNCiAgICArIOmhp+WuoijlgIvkurop5rWB5YuV5qmf546HDQoNCg0KPGNlbnRlcj4NCg0KIVvlnJbkuIDjgIHpoaflrqLlg7nlgLznrqHnkIbnmoTlsaTmrKFdKGZpZy9maWcxLnBuZykNCg0KPC9jZW50ZXI+DQoNCjxicj7lvp7pgJnkuIDkupvliIbmnpDmiJHlgJHlj6/ku6XnnIvliLDlhazlj7jkuLvopoHnmoTnh5/mlLblkoznjbLliKnnmoTph43opoHkvobmupDvvIzmiJHlgJHkuZ/lj6/ku6XnnIvliLDpgJnkuIDkupvnlKLnlJ/njbLliKnnmoTnvqTntYTmmK/kuI3mmK/mnInmiJDplbfmiJbogIXoobDpgIDnmoTotqjli6LvvJvmk5rmraTmiJHlgJHlj6/ku6XoqK3lrprooYzpirfnmoTph43pu57vvIzmsbrlrprooYzpirfnmoTnrZbnlaXvvIzlkozopo/lioPooYzpirfnmoTlt6XlhbfjgILpmaTkuobkuIrov7DnmoTmlZjov7DntbHoqIjjgIHpm4bnvqTliIbmnpDjgIHlkozos4fmlpnoppboprrljJbkuYvlpJbvvIzmiJHlgJHpgoTlj6/ku6XliKnnlKjpgJnkupvnsKHllq7nmoTkuqTmmJPntIDpjITvvJoNCg0KKyAqKuW7uueri+mgkOa4rOaAp+aooeWeiyoq77yM6aCQ5ris5q+P5LiA5L2N6aGn5a6i55qE77yaDQogICAgKyDkv53nlZnmqZ/njocNCiAgICArIOmgkOacn+eHn+aUtg0KICAgICsg57WE6ZaT6K6K5o+b5qmf546HDQogICAgKyDkuIvmrKHlj6/og73os7zosrfmmYLplpMNCg0KPGJyPuWIqeeUqOmAmeS4gOS6m+mgkOa4rOaIkeWAkeWwseWPr+S7pemAsuihjOWFqOmdouWuouijveWMlueahO+8miANCg0KKyAqKumhp+WuouWDueWAvOeuoeeQhioq77yaDQogICAgKyDpoaflrqLntYLnlJ/lg7nlgLwNCiAgICArIOmhp+WuouWQuOaUtuetlueVpQ0KICAgICsg6aGn5a6i55m85bGV562W55WlDQogICAgKyDpoaflrqLkv53nlZnnrZbnlaUNCg0KKyAqKumHneWwjeaAp+ihjOmKtyoq77yaDQogICAgKyDoqK3oqIjooYzpirfmlrnmoYgNCiAgICArIOmBuOaTh+ihjOmKt+aWueahiA0KICAgICsg6YG45pOH6KGM6Yq35bCN6LGhDQoNCg0KPGNlbnRlcj4NCg0KIVvlnJbkuozjgIHpoaflrqLlg7nlgLznrqHnkIbmtYHnqItdKGZpZy9maWcyLnBuZykNCg0KPC9jZW50ZXI+DQoNCg0KDQo8YnI+PGhyPg0KDQojIyMjIyBTZXR1cCANCmBgYHtyfQ0KU3lzLnNldGxvY2FsZSgiTENfQUxMIiwiQyIpDQpwYWNrYWdlcyA9IGMoDQogICJkcGx5ciIsImdncGxvdDIiLCJnb29nbGVWaXMiLCJkZXZ0b29scyIsIm1hZ3JpdHRyIiwiY2FUb29scyIsIlJPQ1IiLCJjYVRvb2xzIikNCmV4aXN0aW5nID0gYXMuY2hhcmFjdGVyKGluc3RhbGxlZC5wYWNrYWdlcygpWywxXSkNCmZvcihwa2cgaW4gcGFja2FnZXNbIShwYWNrYWdlcyAlaW4lIGV4aXN0aW5nKV0pIGluc3RhbGwucGFja2FnZXMocGtnKQ0KDQppZighaXMuZWxlbWVudCgiY2hvcmRkaWFnIiwgZXhpc3RpbmcpKQ0KICBkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoIm1hdHRmbG9yL2Nob3JkZGlhZyIpDQpgYGANCg0KIyMjIyMgTGlicmFyeQ0KYGBge3IgZWNobz1ULCBtZXNzYWdlPUYsIGNhY2hlPUYsIHdhcm5pbmc9Rn0NCnJtKGxpc3Q9bHMoYWxsPVQpKQ0Kb3B0aW9ucyhkaWdpdHM9NCwgc2NpcGVuPTEyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoY2FUb29scykNCmxpYnJhcnkoUk9DUikNCmxpYnJhcnkoZ29vZ2xlVmlzKQ0KbGlicmFyeShjaG9yZGRpYWcpDQpgYGANCjxicj48aHI+DQoNCiMjIyAxIDEuIOizh+aWmeaVtOeQhg0KDQojIyMjIyAxLjEg5Lqk5piT6LOH5paZIChYKQ0KYGBge3J9DQpYID0gcmVhZC50YWJsZSgNCiAgJ3B1cmNoYXNlcy50eHQnLCBoZWFkZXI9RkFMU0UsIHNlcD0nXHQnLCBzdHJpbmdzQXNGYWN0b3JzPUYpDQpuYW1lcyhYKSA9IGMoJ2NpZCcsJ2Ftb3VudCcsJ2RhdGUnKQ0KWCRkYXRlID0gYXMuRGF0ZShYJGRhdGUpDQpzdW1tYXJ5KFgpICAgICAgICAgICAgICAgICAgDQojIOS6pOaYk+asoeaVuCA1MTI0Mw0KYGBgDQoNCmBgYHtyIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTcuMn0NCnBhcihjZXg9MC44KQ0KaGlzdChYJGRhdGUsICJ5ZWFycyIsIGxhcz0yLCBmcmVxPVQsIHhsYWI9IiIsIG1haW49Ik5vLiBUcmFuc2FjdGlvbiBieSBZZWFyIikNCiMg5b6e5ZyW5Lit5Y+v55yL5Ye65Lqk5piT6YCQ5bm05oiQ6ZW377yM5L2G5pyJ5pS+57ep55qE6Lao5YuiDQpgYGANCg0KDQpgYGB7cn0NCm5fZGlzdGluY3QoWCRjaWQpICAgICAgICAgICANCiMg6aGn5a6i5pW4IDE4NDE3DQpgYGANCg0KIyMjIyMgMS4yIOmhp+Wuouizh+aWmSAoQSkNCmBgYHtyfQ0KQSA9IFggJT4lIA0KICBtdXRhdGUoZGF5cyA9IGFzLmludGVnZXIoYXMuRGF0ZSgiMjAxNi0wMS0wMSIpIC0gZGF0ZSkpICU+JSANCiAgZ3JvdXBfYnkoY2lkKSAlPiUgc3VtbWFyaXNlKA0KICAgIHJlY2VudCA9IG1pbihkYXlzKSwgICAgDQogICAgZnJlcSA9IG4oKSwgICAgICAgICAgICAgDQogICAgbW9uZXkgPSBtZWFuKGFtb3VudCksICAgDQogICAgc2VuaW9yID0gbWF4KGRheXMpLCAgICAgDQogICAgc2luY2UgPSBtaW4oZGF0ZSkgICAgICAgDQogICkgJT4lIGRhdGEuZnJhbWUNCiMgcmVjZW50IDog5pyA6L+R6LO86LK36Led5LuK5aSp5pW4KOaVtOethuizh+aWmeacgOW+jOS4gOWkqeWKoOS4gCkgDQojIGZyZXEgOiDos7zosrfmrKHmlbgNCiMgbW9uZXkgOiDlubPlnYfos7zosrfph5HpoY0NCiMgc2VuaW9yIDog56ys5LiA5qyh6LO86LK36Led5LuK5aSp5pW4DQojIHNpbmNlIDog56ys5LiA5qyh6LO86LK35pel5pyfDQoNCmBgYA0KDQojIyMjIyAxLjQg6aGn5a6i6LOH5paZ5pGY6KaBDQpgYGB7cn0NCnN1bW1hcnkoQSkNCmBgYA0KDQojIyMjIyAxLjUg6K6K5pW455qE5YiG5biD54uA5rOBDQpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04fQ0KcDAgPSBwYXIoY2V4PTAuOCwgbWZyb3c9YygyLDIpLCBtYXI9YygzLDMsNCwyKSkNCmhpc3QoQSRyZWNlbnQsMjAsbWFpbj0icmVjZW5jeSIseWxhYj0iIix4bGFiPSIiKQ0KaGlzdChwbWluKEEkZnJlcSwgMTApLDA6MTAsbWFpbj0iZnJlcXVlbmN5Iix5bGFiPSIiLHhsYWI9IiIpICANCmhpc3QoQSRzZW5pb3IsMjAsbWFpbj0ic2VuaW9yaXR5Iix5bGFiPSIiLHhsYWI9IiIpDQpoaXN0KGxvZyhBJG1vbmV5LDEwKSwsbWFpbj0ibG9nKG1vbmV5KSIseWxhYj0iIix4bGFiPSIiKQ0KIyBwbWluKCkg6Kit5LiA5YCL5LiK6ZmQDQojIHJlY2VuY3kgOiDmnIDov5Hos7zosrfot53ku4rlpKnmlbjmnIDlt6blgbTnnIvkvLzoqLHlpJrpoaflrqLmiY3liZvkvobvvIzkvYbljbvmnInkuIDmop3plbflsL7vvIzooajnpLrmm7TlpJrnmoTlpJrpoaflrqLlvojkuYXmnKrlhYnpoafkuoYNCiMgZnJlcXVlbmN5IDog6LO86LK35qyh5pW45Zyo5Y2B5bm055qE5pmC6ZaT5YWn5Lqm6KGo54++5LiN5L2zDQojIG1vbmV5IDog5bmz5Z2H6LO86LK36YeR6aGN5bCP6aGN5bGF5aSaDQojIHNlbmlvcml0eSA6IOesrOS4gOasoeizvOiyt+i3neS7iuWkqeaVuOWPr+eci+WHuuS+neeEtuacieioseWkmuaWsOmhp+WuouaMgee6jOWKoOWFpQ0KDQpgYGANCjxicj48aHI+DQoNCiMjIyAyLiDlsaTntJrlvI/pm4bnvqTliIbmnpANCg0KIyMjIyMgMi4xIFJGTemhp+WuouWIhue+pA0KYGBge3J9DQpzZXQuc2VlZCgxMTEpDQpBJGdycCA9IGttZWFucyhzY2FsZShBWywyOjRdKSwxMCkkY2x1c3RlciAgDQp0YWJsZShBJGdycCkgIA0KIyDliIbmiJDljYHnvqTvvIzlhYjnnIvml4/nvqTlpKflsI8NCmBgYA0KDQojIyMjIyAyLjIg6aGn5a6i576k57WE5bGs5oCnDQpgYGB7ciBmaWcuaGVpZ2h0PTQuNSwgZmlnLndpZHRoPTh9DQpncm91cF9ieShBLCBncnApICU+JSBzdW1tYXJpc2UoDQogIHJlY2VudD1tZWFuKHJlY2VudCksIA0KICBmcmVxPW1lYW4oZnJlcSksIA0KICBtb25leT1tZWFuKG1vbmV5KSwgDQogIHNpemU9bigpICkgJT4lIA0KICBtdXRhdGUoIHJldmVudWUgPSBzaXplKm1vbmV5LzEwMDAgKSAgJT4lIA0KICBmaWx0ZXIoc2l6ZSA+IDEpICU+JSANCiAgZ2dwbG90KGFlcyh4PWZyZXEsIHk9bW9uZXkpKSArDQogIGdlb21fcG9pbnQoYWVzKHNpemU9cmV2ZW51ZSwgY29sPXJlY2VudCksYWxwaGE9MC41KSArDQogIHNjYWxlX3NpemUocmFuZ2U9Yyg0LDMwKSkgKw0KICBzY2FsZV9jb2xvcl9ncmFkaWVudChsb3c9ImdyZWVuIixoaWdoPSJyZWQiKSArDQogIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAobGltaXRzPWMoMzAsMzAwMCkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzaXplICksc2l6ZT0zKSArICAgICAgICAgIA0KICB0aGVtZV9idygpICsgZ3VpZGVzKHNpemU9RikgKyAgICAgICAgICAgICAgICAgICANCiAgbGFicyh0aXRsZT0iQ3VzdG9tZXIgU2VnZW1lbnRzIiwgICAgICAgICAgICAgICAgDQogICAgICAgc3VidGl0bGU9IihidWJibGVfc2l6ZTpyZXZlbnVlX2NvbnRyaWJ1dGlvbjsgdGV4dDpncm91cF9zaXplKSIsDQogICAgICAgY29sb3I9IlJlY2VuY3kiKSArDQogIHhsYWIoIkZyZXF1ZW5jeSAobG9nKSIpICsgeWxhYigiQXZlcmFnZSBUcmFuc2FjdGlvbiBBbW91bnQgKGxvZykiKQ0KIyDms6Hms6HlpKflsI/mmK/nh5/mlLbosqLnjbsNCiMg5LiN5YWJ6KaB55+l6YGT6Z2c5oWL5bGs5oCn77yM6KaB55+l6YGT5rOh5rOh5oCO6bq86K6K5YyW77yM5b6I6YeN6KaBDQojIOiLpeeUqOavj+W5tOW5tOW6leWBmuS4gOasoe+8jOazoeazoeacg+WLle+8jOS9hue1seioiOimj+WJh+WPr+iDveavj+W5tOmDveS4jeS4gOaooyhLbWVhbikNCg0KYGBgDQo8YnI+PGhyPg0KDQojIyMgMy4g6KaP5YmH5YiG576kDQoNCiMjIyMjIDMuMSDpoaflrqLliIbnvqTopo/liYcNCmBgYHtyfQ0KU1RTID0gYygiTjEiLCJOMiIsIlIxIiwiUjIiLCJTMSIsIlMyIiwiUzMiKQ0KU3RhdHVzID0gZnVuY3Rpb24ocngsZngsbXgsc3gsSykge2ZhY3RvcigNCiAgaWZlbHNlKHN4IDwgMipLLA0KICAgICAgICAgaWZlbHNlKGZ4Km14ID4gNTAsICJOMiIsICJOMSIpLA0KICAgICAgICAgaWZlbHNlKHJ4IDwgMipLLA0KICAgICAgICAgICAgICAgIGlmZWxzZShzeC9meCA8IDAuNzUqSywiUjIiLCJSMSIpLA0KICAgICAgICAgICAgICAgIGlmZWxzZShyeCA8IDMqSywiUzEiLA0KICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocnggPCA0KkssIlMyIiwiUzMiKSkpKSwgU1RTKX0NCmBgYA0KDQo8Y2VudGVyPg0KDQohW+WcluS4ieOAgemhp+WuouWIhue+pOimj+WJh10oZmlnL2ZpZzMuamZpZikNCg0KPC9jZW50ZXI+DQoNCiMjIyMjIDMuMiDlubPlnYfos7zosrfpgLHmnJ8NCmBgYHtyfQ0KSyA9IGFzLmludGVnZXIoc3VtKEEkc2VuaW9yW0EkZnJlcT4xXSkgLyBzdW0oQSRmcmVxW0EkZnJlcT4xXSkpOyBLDQpgYGANCuWbnuizvOmhp+WuoueahOW5s+Wdh+izvOiyt+mAseacnyBgSyA9IDUyMSBkYXlzYA0KDQojIyMjIyAzLjMg5ruR5YuV6LOH5paZ56qX5qC8DQpgYGB7cn0NClkgPSBsaXN0KCkgICAgICAgICAgICAgICMg5bu656uL5LiA5YCL56m655qETElTVA0KZm9yKHkgaW4gMjAxMDoyMDE1KSB7ICAgIyDmr4/lubTlubTlupXlsIfpoaflrqLos4fmlpnlvZnmlbTmiJDkuIDlgIvos4fmlpnmoYYNCiAgRCA9IGFzLkRhdGUocGFzdGUwKGMoeSwgeS0xKSwiLTEyLTMxIikpICMg55W25pyf44CB5YmN5pyf55qE5pyf5pyr5pel5pyfIA0KICBZW1twYXN0ZTAoIlkiLHkpXV0gPSBYICU+JSAgICAgICAgIyDlvp7kuqTmmJPos4fmlpnlgZrotbcNCiAgICBmaWx0ZXIoZGF0ZSA8PSBEWzFdKSAlPiUgICAgICAgICMg5bCH6LOH5paZ5YiH6b2K5Yiw5pyf5pyr5pel5pyfDQogICAgbXV0YXRlKGRheXMgPSAxICsgYXMuaW50ZWdlcihEWzFdIC0gZGF0ZSkpICU+JSAgICMg5Lqk5piT6Led5pyf5pyr5aSp5pW4DQogICAgZ3JvdXBfYnkoY2lkKSAlPiUgc3VtbWFyaXNlKCAgICAjIOS+nemhp+WuouW9mee4vSAuLi4NCiAgICAgIHJlY2VudCA9IG1pbihkYXlzKSwgICAgICAgICAgICMgICDmnIDlvozkuIDmrKHos7zosrfot53mnJ/mnKvlpKnmlbggICANCiAgICAgIGZyZXEgPSBuKCksICAgICAgICAgICAgICAgICAgICMgICDos7zosrfmrKHmlbggKOiHs+acn+acq+eCuuatoikgICANCiAgICAgIG1vbmV5ID0gbWVhbihhbW91bnQpLCAgICAgICAgICMgICDlubPlnYfos7zosrfph5HpoY0gKOiHs+acn+acq+eCuuatoikNCiAgICAgIHNlbmlvciA9IG1heChkYXlzKSwgICAgICAgICAgICMgICDnrKzkuIDmrKHos7zosrfot53mnJ/mnKvlpKnmlbgNCiAgICAgIHN0YXR1cyA9IFN0YXR1cyhyZWNlbnQsZnJlcSxtb25leSxzZW5pb3IsSyksICAjIOacn+acq+eLgOaFiw0KICAgICAgc2luY2UgPSBtaW4oZGF0ZSksICAgICAgICAgICAgICAgICAgICAgICMg56ys5LiA5qyh6LO86LK35pel5pyfDQogICAgICB5X2ZyZXEgPSBzdW0oZGF0ZSA+IERbMl0pLCAgICAgICAgICAgICAgIyDnlbbmnJ/os7zosrfmrKHmlbgNCiAgICAgIHlfcmV2ZW51ZSA9IHN1bShhbW91bnRbZGF0ZSA+IERbMl1dKSAgICAjIOeVtuacn+izvOiyt+mHkemhjQ0KICAgICkgJT4lIGRhdGEuZnJhbWUgfQ0KYGBgDQoNCmBgYHtyfQ0KaGVhZChZJFkyMDE1KSAgDQojIGxpc3Tmr4/lgIvlhYPku7bpg73lj6/ku6XmnInlkI3lrZcNCmBgYA0KDQojIyMjIyAzLjQg5q+P5bm05bm05bqV55qE57Sv6KiI6aGn5a6i5Lq65pW4DQpgYGB7cn0NCnNhcHBseShZLCBucm93KSAgDQojIOizh+aWmeahhueahOizh+aWmeethuaVuO+8jOWwjVnoo6HnmoTmr4/lgIvlhYPntKDlgZpucm93DQpgYGANCg0KIyMjIyMgMy41IOaXj+e+pOWkp+Wwj+iuiuWMlui2qOWLog0KYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OH0NCmNvbHMgPSBjKCJnb2xkIiwib3JhbmdlIiwiYmx1ZSIsImdyZWVuIiwicGluayIsIm1hZ2VudGEiLCJkYXJrcmVkIikNCnNhcHBseShZLCBmdW5jdGlvbihkZikgdGFibGUoZGYkc3RhdHVzKSkgJT4lIGJhcnBsb3QoY29sPWNvbHMpDQpsZWdlbmQoInRvcGxlZnQiLHJldihTVFMpLGZpbGw9cmV2KGNvbHMpKSAgDQoj5rS76LqN6aGn5a6i77yM55yL57KJ6Imy5Lul5LiLDQpgYGANCg0KIyMjIyMgMy42IOaXj+e+pOWxrOaAp+WLleaFi+WIhuaekA0KYGBge3J9DQpDdXN0U2VnbWVudHMgPSBkby5jYWxsKHJiaW5kLCBsYXBwbHkoWSwgZnVuY3Rpb24oZCkgew0KICBncm91cF9ieShkLCBzdGF0dXMpICU+JSBzdW1tYXJpc2UoDQogICAgYXZlcmFnZV9mcmVxdWVuY3kgPSBtZWFuKGZyZXEpLA0KICAgIGF2ZXJhZ2VfYW1vdW50ID0gbWVhbihtb25leSksDQogICAgdG90YWxfcmV2ZW51ZSA9IHN1bSh5X3JldmVudWUpLA0KICAgIHRvdGFsX25vX29yZGVycyA9IHN1bSh5X2ZyZXEpLA0KICAgIGF2ZXJhZ2VfcmVjZW5jeSA9IG1lYW4ocmVjZW50KSwNCiAgICBhdmVyYWdlX3Nlbmlvcml0eSA9IG1lYW4oc2VuaW9yKSwNCiAgICBncm91cF9zaXplID0gbigpDQogICl9KSkgJT4lIHVuZ3JvdXAgJT4lIA0KICBtdXRhdGUoeWVhcj1yZXAoMjAxMDoyMDE1LCBlYWNoPTcpKSAlPiUgZGF0YS5mcmFtZQ0KaGVhZChDdXN0U2VnbWVudHMpDQojIFIy5peP576k5pyA5aSn44CB6aC7546H5pyA6auY77yM6ZuW54S25Ym16YCg55qE5Yip5r2k5LiN5piv5pyA6auY5L2G5bmz5Z2H6LO86LK36YeR6aGN5pyA6auYDQpgYGANCg0KYGBge3IgZXZhbD1GfQ0KcGxvdCggZ3Zpc01vdGlvbkNoYXJ0KA0KICBDdXN0U2VnbWVudHMsICJzdGF0dXMiLCAieWVhciIsDQogIG9wdGlvbnM9bGlzdCh3aWR0aD05MDAsIGhlaWdodD02MDApICkgKQ0KIyBOMSDnm7jnlbblgZzmu6/vvIzml4/nvqTmnInkupvlvq7muJvlsJENCiMgTjIg6aC7546H5pyq5aKe5Yqg5Y+N5LiL6ZmN77yM5bmz5Z2H6LO86LK36YeR6aGN6aGv6JGX5o+Q5Y2H77yM5peP576k5aSn5bCP5oyB5bmzDQojIFIxIOmgu+eOh+WSjOW5s+Wdh+izvOiyt+mHkemhjeeahuacieaPkOWNh++8jOaXj+e+pOaIkOmVt+i8g+aYjumhrw0KIyBSMiDpoLvnjofmiJDplbfluYXluqbmnIDlpKfvvIzlubPlnYfos7zosrfph5HpoY3lsI/luYXmj5DljYfvvIzml4/nvqTkupvlvq7miJDplbcNCg0KYGBgDQoNCjxjZW50ZXI+DQoNCiFb5ZyW5Zub44CB6aGn5a6i5YiG576k6KaP5YmHXShmaWcvZmlnNC5qZmlmKQ0KDQo8L2NlbnRlcj4NCg0KDQojIyMjIyAzLjcg5peP576k5bGs5oCn5YuV5oWL5YiG5p6QDQpgYGB7cn0NCmRmID0gbWVyZ2UoWSRZMjAxNFssYygxLDYpXSwgWSRZMjAxNVssYygxLDYpXSwNCiAgICAgICAgICAgYnk9ImNpZCIsIGFsbC54PVQpDQp0eCA9IHRhYmxlKGRmJHN0YXR1cy54LCBkZiRzdGF0dXMueSkgJT4lIA0KICBhcy5kYXRhLmZyYW1lLm1hdHJpeCgpICU+JSBhcy5tYXRyaXgoKQ0KdHggICAgDQojIOa1gemHj+efqemZow0KYGBgDQoNCmBgYHtyfQ0KdHggJT4lIHByb3AudGFibGUoMSkgJT4lIHJvdW5kKDMpICAgIyDmtYHph4/nn6npmaMoJSkNCmBgYA0KDQojIyMjIyAzLjgg5LqS5YuV5byP5rWB6YeP5YiG5p6QDQpgYGB7cn0NCmNob3JkZGlhZyh0eCwgZ3JvdXBDb2xvcnM9Y29scykNCmBgYA0KDQohW10oZmlnL2Nob3JkLmpwZykNCg0KPGJyPjxocj4NCg0KIyMjIDQuIOW7uueri+aooeWeiw0KDQrlnKjpgJnlgIvmoYjkvovoo6HpnaLvvIzmiJHlgJHnmoTos4fmlpnmmK/mlLbliLBZMjAxNeW5tOW6le+8jOaJgOS7peaIkeWAkeWPr+S7peWBh+ioreePvuWcqOeahOaZgumWk+aYr1kyMDE15bm05bqV77yM5oiR5YCR5oOz6KaB55So54++5pyJ55qE6LOH5paZ5bu656uL5qih5Z6L77yM5L6G6aCQ5ris5q+P5LiA5L2N6aGn5a6i77yaDQoNCisg5ZyoWTIwMTblubTmmK/lkKbmnIPkvobos7zosrcgKOS/neeVmeeOh++8mlJldGFpbikNCisg5aW55L6G6LO86LK355qE6Kmx77yM5pyD6LK35aSa5bCR6YyiICjos7zosrfph5HpoY3vvJpSZXZlbnVlKQ0KDQrkvYbmmK/vvIzmiJHlgJHkuKbmspLmnIlZMjAxNueahOizh+aWme+8jOeCuuS6huimgeW7uueri+aooeWei++8jOaIkeWAkemcgOimgeWFiOaKiuaZgumWk+WbnuaOqOS4gOacn++8jOS5n+WwseaYr+iqqu+8mg0KDQorIOeUqFkyMDE05bm05bqV5Lul5YmN55qE6LOH5paZ5pW055CG5Ye66aCQ5ris6K6K5pW4KFgpIA0KKyDnlKhZMjAxNeW5tOeahOizh+aWmeaVtOeQhuWHuuebruaomeiuiuaVuChZKSANCg0K5YGH5aaCWTIwMTbnmoTmg4Xms4Eo6LefWTIwMTXmr5Qp5rKS5pyJ5aSq5aSn55qE6K6K5YyW55qE6Kmx77yM5o6l5LiL5L6G5oiR5YCR5bCx5Y+v5LulDQoNCisg5L2/55So6Kmy5qih5Z6L77yM5LulWTIwMTXlubTlupXnmoTos4fmlpnvvIzpoJDmuKxZMjAxNueahOeLgOazgQ0KDQojIyMjIyA0LjEg5rqW5YKZ6LOH5paZDQrmiJHlgJHnlKhZMjAxNOW5tOW6leeahOizh+aWmeWBmuiHquiuiuaVuO+8jFkyMDE15bm055qE6LOH5paZ5YGa5oeJ6K6K5pW4DQoNCmBgYHtyfQ0KQ1ggPSBsZWZ0X2pvaW4oWSRZMjAxNCwgWSRZMjAxNVssYygxLDgsOSldLCBieT0iY2lkIikgDQpoZWFkKENYKQ0KIyAx5pivY2lk6YCZ5YCL5qyE5L2N5YGa5bu6572u77yM6KaB5oqK5qyh5bqP5bCN6LW35L6GDQojIGxlZnRfam9pbuWBh+ioreW+jOmdouaykuacie+8jOS4jeacg+ebtOaOpeWIquaOie+8jOiAjOaYr+S/neeVmeeEtuW+jOWhq05BDQpgYGANCg0KYGBge3J9DQpuYW1lcyhDWClbODoxMV0gPSBjKCJmcmVxMCIsInJldmVudWUwIiwiUmV0YWluIiwgIlJldmVudWUiKQ0KQ1gkUmV0YWluID0gQ1gkUmV0YWluID4gMCAgI0NYJFJldGFpbiA+IDDmnInnhKHkv53nlZnkvY8NCmhlYWQoQ1gpDQpgYGANCg0KYGBge3J9DQp0YWJsZShDWCRSZXRhaW4pICU+JSBwcm9wLnRhYmxlKCkgIA0KIyDlubPlnYfkv53nlZnmqZ/njocgPSAyMi41NCUNCmBgYA0KDQojIyMjIyA0LjIg5bu656uL6aGe5Yil5qih5Z6LDQpgYGB7cn0NCm1SZXQgPSBnbG0oUmV0YWluIH4gLiwgQ1hbLGMoMjozLDYsODoxMCldLCBmYW1pbHk9Ymlub21pYWwoKSkNCnN1bW1hcnkobVJldCkNCmBgYA0KDQojIyMjIyA0LjMg5Lyw6KiI6aGe5Yil5qih5Z6L55qE5rqW56K65oCnDQpgYGB7cn0NCnByZWQgPSBwcmVkaWN0KG1SZXQsdHlwZT0icmVzcG9uc2UiKQ0KdGFibGUocHJlZD4wLjUsQ1gkUmV0YWluKSANCiMg5re35reG55+p6ZmjIChDb25mdXNpb24gTWF0cml4KSAgDQpgYGANCmBgYHtyfQ0KdGFibGUocHJlZD4wLjUsQ1gkUmV0YWluKSAlPiUgDQogIHtzdW0oZGlhZyguKSkvc3VtKC4pfSAgICAgICAgICAgICMg5q2j56K6546HKEFDQyk6IDg1LjE5JSANCmBgYA0KYGBge3J9DQpjb2xBVUMocHJlZCxDWCRSZXRhaW4pICAgICAgICAgICAgICMg6L6v6K2Y546HKEFVQyk6IDg3LjkyJQ0KYGBgDQpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD00fQ0KcHJlZGljdGlvbihwcmVkLCBDWCRSZXRhaW4pICU+JSAgICAjIFJPQyBDVVJWRSANCiAgcGVyZm9ybWFuY2UoInRwciIsICJmcHIiKSAlPiUgDQogIHBsb3QocHJpbnQuY3V0b2Zmcy5hdD1zZXEoMCwxLDAuMSkpDQpgYGANCg0KIyMjIyMgNC40IOW7uueri+aVuOmHj+aooeWeiw0KYGBge3J9DQpkeCA9IHN1YnNldChDWCwgUmV2ZW51ZSA+IDApICANCm1SZXYgPSBsbShsb2coUmV2ZW51ZSkgfiByZWNlbnQgKyBmcmVxICsgbG9nKDErbW9uZXkpICsgc2VuaW9yICsNCiAgICAgICAgICBzdGF0dXMgKyBmcmVxMCArIGxvZygxK3JldmVudWUwKSwgZHgpICAgDQpzdW1tYXJ5KG1SZXYpICANCiMg5Y+q5bCN5pyJ5L6G6LO86LK355qE5Lq65YGa5qih5Z6L77yM5rKS5L6G6LK355qE5bCx5LiN566hDQojIOWIpOWumuS/guaVuO+8mlIyID0gMC43MTMNCmBgYA0KYGBge3IgZmlnLmhlaWdodD00LjUsIGZpZy53aWR0aD00LjV9DQpwbG90KGxvZyhkeCRSZXZlbnVlKSwgcHJlZGljdChtUmV2KSwgY29sPSdwaW5rJywgY2V4PTAuNjUpDQphYmxpbmUoMCwxLGNvbD0ncmVkJykgDQpgYGANCjxicj48aHI+DQoNCiMjIyA1LiDkvLDoqIjpoaflrqLntYLnlJ/lg7nlgLwNCg0KIyMjIyMgNS4xIFkyMDE255qE6aCQ5ris5YC8DQrkvb/nlKjmqKHlnovlsI1ZMjAxNeW5tOW6leeahOizh+aWmeWBmumgkOa4rO+8jOWwjeizh+aWmeS4reeahOavj+S4gOS9jemhp+Wuou+8jOmgkOa4rOWlueWAkeWcqFkyMDE255qE5L+d55WZ546H5ZKM6LO86LK36YeR6aGN44CCDQpgYGB7cn0NCkNYID0gWSRZMjAxNQ0KbmFtZXMoQ1gpWzg6OV0gPSBjKCJmcmVxMCIsInJldmVudWUwIikNCg0KIyDpoJDmuKxZMjAxNuS/neeVmeeOhw0KQ1gkUHJvYlJldGFpbiA9IHByZWRpY3QobVJldCxDWCx0eXBlPSdyZXNwb25zZScpDQoNCiMg6aCQ5risWTIwMTbos7zosrfph5HpoY0NCkNYJFByZWRSZXZlbnVlID0gZXhwKHByZWRpY3QobVJldixDWCkpDQpgYGANCg0KYGBge3IgZmlnLmhlaWdodD0yLjUsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93PWMoMSwyKSwgbWFyPWMoNCwzLDMsMiksIGNleD0wLjgpDQpoaXN0KENYJFByb2JSZXRhaW4sbWFpbj0iUHJvYlJldGFpbiIsIHlsYWI9IiIpDQpoaXN0KGxvZyhDWCRQcmVkUmV2ZW51ZSwxMCksbWFpbj0ibG9nKFByZWRSZXZlbnVlKSIsIHlsYWI9IiIpDQojIOS/neeVmeeOh+i2hemBjjAuNeeahOWNoOavlOS4jemrmA0KIyDos7zosrfph5HpoY3kvp3oiIrlgY/kvY4NCmBgYA0KPGJyPg0KDQojIyMjIyA1LjIg5Lyw6KiI6aGn5a6i57WC55Sf5YO55YC8KENMVikNCg0K6aGn5a6i57WC55Sf5YO55YC8KEN1c3RvbWVyIExpZmV0aW1lVmFsdWUp5oyH55qE5piv5q+P5YCL6LO86LK36ICF5Zyo5pyq5L6G5Y+v6IO954K65LyB5qWt5bi25L6G55qE5pS255uK57i95ZKM44CC56CU56m26KGo5piO77yM5aaC5ZCM5p+Q56iu55Si5ZOB5LiA5qij77yM6aGn5a6i5bCN5pa85LyB5qWt5Yip5r2k55qE6LKi54275Lmf5Y+v5Lul5YiG54K65bCO5YWl5pyf44CB5b+r6YCf5aKe6ZW35pyf44CB5oiQ54af5pyf5ZKM6KGw6YCA5pyf44CCDQoNCuavj+WAi+WuouaItueahOWDueWAvOmDveeUseS4iemDqOWIhuani+aIkO+8mg0KDQorIOatt+WPsuWDueWAvCjliLDnm67liY3ngrrmraLlt7LntpPlr6bnj77kuobnmoTpoaflrqLlg7nlgLwpDQorIOeVtuWJjeWDueWAvCjlpoLmnpzpoaflrqLnlbbliY3ooYzngrrmqKHlvI/kuI3nmbznlJ/mlLnorornmoToqbHvvIzlsIfkvobmnIPntablhazlj7jluLbkvobnmoTpoaflrqLlg7nlgLwpDQorIOa9m+WcqOWDueWAvCjlpoLmnpzlhazlj7jpgJrpgY7mnInmlYjnmoTkuqTlj4npirfllK7lj6/ku6Xoqr/li5XpoaflrqLos7zosrfnqY3mpbXmgKfvvIzmiJbkv4Pkvb/poaflrqLlkJHliKXkurrmjqjolqbnlKLlk4HlkozmnI3li5nnrYnvvIzlvp7ogIzlj6/og73lop7liqDnmoTpoaflrqLlg7nlgLwpDQoNCjxjZW50ZXI+6aGn5a6iJGkk55qE57WC55Sf5YO55YC8PC9jZW50ZXI+DQoNCiQkIFZfaSA9IFxzdW1fe3Q9MH1eTiBnIFx0aW1lcyBtX2kgXGZyYWN7cl9pXnR9eygxK2QpXnR9ID0gZyBcdGltZXMgbV9pIFxzdW1fe3Q9MH1eTiAoXGZyYWN7cl9pfXsxK2R9KV50ICAkJA0KDQo8Y2VudGVyPiRtX2kk44CBJHJfaSTvvJrpoaflrqIkaSTnmoTpoJDmnJ8o5q+P5pyfKeeHn+aUtuiyoueNu+OAgeS/neeVmeapn+eOhzwvY2VudGVyPg0KDQo8Y2VudGVyPiRnJOOAgSRkJO+8muWFrOWPuOeahCjnqIXliY0p54ef5qWt5Yip5r2k5Yip546H44CB6LOH6YeR5oiQ5pysPC9jZW50ZXI+DQoNCmBgYHtyfQ0KZyA9IDAuNSAgICMgKOeoheWJjSnnjbLliKnnjocNCk4gPSA1ICAgICAjIOacn+aVuCA9IDUNCmQgPSAwLjEgICAjIOWIqeeOhyA9IDEwJQ0KQ1gkQ0xWID0gZyAqIENYJFByZWRSZXZlbnVlICogcm93U3VtcyhzYXBwbHkoDQogIDA6TiwgZnVuY3Rpb24oaSkgKENYJFByb2JSZXRhaW4vKDErZCkpXmkgKSApDQoNCnN1bW1hcnkoQ1gkQ0xWKQ0KYGBgDQoNCmBgYHtyIGZpZy5oZWlnaHQ9Mi41LCBmaWcud2lkdGg9Ny4yfQ0KcGFyKG1hcj1jKDIsMiwzLDEpLCBjZXg9MC44KQ0KaGlzdChsb2coQ1gkQ0xWLDEwKSwgeGxhYj0iIiwgeWxhYj0iIikNCmBgYA0KDQojIyMjIyA1LjMg5q+U6LyD5ZCE5peP576k55qE5YO55YC8DQoNCmBgYHtyfQ0KIyDlkITml4/nvqTnmoTlubPlnYfnh5/mlLbosqLnjbvjgIHkv53nlZnmqZ/njofjgIHntYLnlJ/lg7nlgLwNCnNhcHBseShDWFssMTA6MTJdLCB0YXBwbHksIENYJHN0YXR1cywgbWVhbikNCiMg5Y+v55yL5Ye6UjLmnIDkvbPvvIzkuIDlpoLkuIrov7DnmoTliIbmnpANCiMg5L2G5pivTjLog73libXpgKDnmoRyZXZlbnVl5pyA5aSn77yM5Lqm5piv6YeN6bue5peP576kDQpgYGANCg0KDQpgYGB7cn0NCnBhcihtYXI9YygzLDMsNCwyKSwgY2V4PTAuOCkNCmJveHBsb3QobG9nKENMVil+c3RhdHVzLCBDWCwgbWFpbj0iQ0xWIGJ5IEdyb3VwcyIpDQoNCmBgYA0KPGJyPjxocj4NCg0KIyMjIDYuIOioreWumuihjOmKt+etlueVpeOAgeimj+WKg+ihjOmKt+W3peWFtw0KDQohW10oZmlnLy0yNS02MzguanBnKQ0KDQo8YnI+PGhyPg0KDQojIyMgNy4g6YG45pOH6KGM6Yq35bCN6LGhDQoNCue1puWumuafkOS4gOihjOmKt+W3peWFt+eahOaIkOacrOWSjOmgkOacn+aViOebiu+8jOmBuOaTh+WPr+S7peaWveihjOmAmemgheW3peWFt+eahOWwjeixoeOAgiANCg0KIyMjIyMgNy4xIOWwjVIy5peP576k6YCy6KGM5L+d55WZDQpSMuaXj+e+pOeahOmgkOa4rOS/neeVmeeOh+WSjOizvOiyt+mHkemhjQ0KYGBge3IgZmlnLmhlaWdodD0yLjUsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93PWMoMSwyKSwgbWFyPWMoNCwzLDMsMiksIGNleD0wLjgpDQpoaXN0KENYJFByb2JSZXRhaW5bQ1gkc3RhdHVzPT0iUjIiXSxtYWluPSJQcm9iUmV0YWluIix4bGFiPSIiKQ0KaGlzdChsb2coQ1gkUHJlZFJldmVudWVbQ1gkc3RhdHVzPT0iUjIiXSwxMCksbWFpbj0iUHJlZFJldmVudWUiLHhsYWI9IiIpDQojIOe0sOeci1Iy55qE6aCQ5ris5L+d55WZ546H5ZKM6LO86LK36YeR6aGNDQpgYGANCg0KIyMjIyMgNy4yIOS8sOioiOmgkOacn+WgsemFrA0K5YGH6Kit6KGM6Yq35bel5YW355qE5oiQ5pys5ZKM6aCQ5pyf5pWI55uK54K6DQpgYGB7cn0NCmNvc3QgPSAxMCAgICAgICAgIyDmiJDmnKwNCmVmZmVjdCA9IDAuNzUgICAgIyDmlYjnm4rvvJrkuIvkuIDmnJ/nmoTos7zosrfmqZ/njocNCmBgYA0KDQrkvLDoqIjpgJnpoIXooYzpirflt6XlhbflsI3mr4/kuIDkvY1SMumhp+WuoueahOmgkOacn+WgsemFrA0KYGBge3J9DQpUYXJnZXQgPSBzdWJzZXQoQ1gsIHN0YXR1cz09IlIyIikNClRhcmdldCRFeHBSZXR1cm4gPSAoZWZmZWN0IC0gVGFyZ2V0JFByb2JSZXRhaW4pICogVGFyZ2V0JFByZWRSZXZlbnVlIC0gY29zdA0Kc3VtbWFyeShUYXJnZXQkRXhwUmV0dXJuKSAgDQojIEV4cFJldHVybuaYr+WwjeaJgOacieS6uuWBmueahO+8jOmChOaYr+WPr+S7peaMkeWHuuW+iOWkmuato+eahO+8jOaJgOS7peS4jeiDveeUqOW5s+Wdh+WAvA0KYGBgDQrpgJnkuIDpoIXlt6XlhbflsI1SMumhp+WuoueahOmgkOacn+WgsemFrOaYr+iyoOeahA0KDQojIyMjIyA3LjMg6YG45pOH6KGM6Yq35bCN6LGhDQrkvYbmmK/vvIzmiJHlgJHpgoTmmK/lj6/ku6XmjJHlh7roqLHlpJrpoJDmnJ/loLHphazlvojlpKfnmoTooYzpirflsI3osaENCmBgYHtyfQ0KVGFyZ2V0ICU+JSBhcnJhbmdlKGRlc2MoRXhwUmV0dXJuKSkgJT4lIHNlbGVjdChjaWQsIEV4cFJldHVybikgJT4lIGhlYWQoMTUpDQpgYGANCg0KYGBge3J9DQpzdW0oVGFyZ2V0JEV4cFJldHVybiA+IDApICAgICAgICAgICAgICAgICAjIOWPr+WvpuaWveWwjeixoe+8mjI1OA0KYGBgDQrlnKhSMuS5i+S4re+8jOaciTI1OOS6uueahOmgkOacn+WgsemFrOWkp+aWvOmbtu+8jOWmguaenOWwjemAmTI1OOS6uuS9v+eUqOmAmemgheW3peWFt++8jOaIkeWAkeeahOacn+acm+WgsemFrOaYr++8mg0KYGBge3J9DQpzdW0oVGFyZ2V0JEV4cFJldHVybltUYXJnZXQkRXhwUmV0dXJuID4gMF0pICAgIyDpoJDmnJ/loLHphazvvJo2NDY0DQojIOS4jeWGjeWPquaYr+WwjeaXj+e+pO+8jOiAjOaYr+avj+WAi+S6ug0KYGBgDQoNCiMjIyMjIFFVSVo6DQrmiJHlgJHlj6/ku6Xnrpflh7rlsI3miYDmnInnmoTml4/nvqTlr6bmlr3pgJnpoIXlt6XlhbfnmoTmnJ/mnJvloLHphawgLi4uDQpgYGB7cn0NClRhcmdldCA9IENYDQpUYXJnZXQkRXhwUmV0dXJuID0gKGVmZmVjdCAtIFRhcmdldCRQcm9iUmV0YWluKSAqIFRhcmdldCRQcmVkUmV2ZW51ZSAtIGNvc3QNCmZpbHRlcihUYXJnZXQsIFRhcmdldCRFeHBSZXR1cm4gPiAwKSAlPiUNCiAgZ3JvdXBfYnkoc3RhdHVzKSAlPiUgc3VtbWFyaXNlKA0KICAgIE5vLlRhcmdldCA9IG4oKSwNCiAgICBBdmdST0kgPSBtZWFuKEV4cFJldHVybiksDQogICAgVG90YWxST0kgPSBzdW0oRXhwUmV0dXJuKSApICU+JSBkYXRhLmZyYW1lDQpgYGANCumAmeWAi+e1kOaenOaYr+WQiOeQhueahOWXju+8nyDkvaDmg7PopoHmgI7purzkv67mraPpgJnpoIXliIbmnpDnmoTnqIvluo/lkaLvvJ8NCg0KKyDkuZ/oqLHlkIjnkIbvvIzlm6DngrrmiJHlgJHkuKbkuI3nn6XpgZPnorrliIfnmoTliIbnvqTmqJnmupbvvIzlj6rog73lvp7liIbnvqTlvoznmoTntZDmnpzpgLLooYzliKToroDjgIINCisg57Wm5L2g5pyA5aSa55Sf5oSP55qE6aGn5a6i77yI5Lmf5bCx5piv57WC6Lqr5YO55YC85pyA6auY55qE6aGn5a6i77yJ77yM5b6A5b6A5LiN5piv54K65L2g6KGM6Yq355qE5pyA5L2z5Lq65ZOh44CC5oOz55+l6YGT5LiA5L2N6aGn5a6i55qE5a6M5pW05YO55YC877yM5b+F6aCI5Lyw566X6YCZ5YCL5Lq65byV6YCy5Y+v542y5Yip5paw6aGn5a6i55qE6IO95Yqb44CC5L2G5piv77yM5aSn5aSa5pW45YWs5Y+45bCN44CM6aGn5a6i5byV5LuL5Yqb44CN77yIcmVmZXJyYWwgcG93ZXLvvInnmoTkvLDoqIjvvIzpoILlpJrmmK/ooaHph4/mn5DlgIvkurrmnInnhKHlvJXku4vliKXkurrnmoTmhI/poZjogIzlt7LvvIzpgJnpu57poIjms6jmhI/jgIINCg0KPGJyPjxicj48aHI+DQoNCiMjIyA4LiDntZDoq5YNCg0K5aaC5p6c5L2g5Y+q5pyJ6aGn5a6iSUTjgIHkuqTmmJPml6XmnJ/jgIHkuqTmmJPph5HpoY3kuInlgIvmrITkvY3nmoToqbHvvIzkvaDlj6/ku6XlgZrnmoTliIbmnpDljIXmi6zvvJoNCg0KKyDlhajpq5TpoaflrqLlkozmr4/kuIDlgIvpoaflrqLliIbnvqTnmoTvvJoNCiAgICArIOaXj+e+pOWkp+Wwj+iIh+aIkOmVt+i2qOWLog0KICAgICsg5peP576k5bGs5oCn5YiG5p6Q77ya5aaC5bmz5Z2HQ0xW44CB5bmz5Z2H54ef5pS26LKi542744CB5oiQ6ZW3546H44CB5q+b5Yip546HKOmcgOimgeacieaIkOacrOizh+aWmSnnrYnnrYkNCiAgICArIOe1hOmWk+a1gemHj+WSjOW5s+Wdh+a1geWLleapn+eOhw0KDQorIOavj+S4gOWAi+mhp+WuoueahO+8mg0KICAgICsg5L+d55WZ546H44CB6aCQ5pyf6LO86LK36YeR6aGN44CB57WC6Lqr5YO55YC8DQogICAgKyDnm67liY3miYDlnKjnvqTntYTvvIzku6Xlj4rkuIvkuIDmnJ/mnIPovYnliLDlgIvnvqTntYTnmoTmqZ/njocNCiAgICArIOWmguaenOacieihjOmKt+W3peWFt+eahOS9v+eUqOe0gOmMhOeahOipse+8jOaIkeWAkeS5n+WPr+S7peS8sOioiOavj+S4gOaoo+ihjOmKt+W3peWFt+OAgeWwjeavj+S4gOS9jemhp+WuoueahOaIkOWKn+apn+eOhw0KDQrkuIDoiKzogIzoqIDvvIzpgJnkuIDkupvliIbmnpDnmoTntZDmnpzvvIzotrPlpKDorpPmiJHlgJHliLblrprpoaflrqLnmbzlsZXlkozpoaflrqLkv53nlZnnrZbnlaXvvJvoh7PmlrzpoaflrqLlkLjmlLbnrZbnlaXvvIzmiJHlgJHpgJrluLjpgoTpnIDopoHlvp5DUk3mkojlh7rpoaflrqLlgIvkurrlsazmgKfos4fmlpnmiY3og73lgZrliLDjgIIgDQoNCg0KPGJyPjxicj48aHI+PGJyPjxicj48YnI+DQoNCjxzdHlsZT4NCi5jYXB0aW9uIHsNCiAgY29sb3I6ICM3Nzc7DQogIG1hcmdpbi10b3A6IDEwcHg7DQp9DQpwIGNvZGUgew0KICB3aGl0ZS1zcGFjZTogaW5oZXJpdDsNCn0NCnByZSB7DQogIHdvcmQtYnJlYWs6IG5vcm1hbDsNCiAgd29yZC13cmFwOiBub3JtYWw7DQogIGxpbmUtaGVpZ2h0OiAxOw0KfQ0KcHJlIGNvZGUgew0KICB3aGl0ZS1zcGFjZTogaW5oZXJpdDsNCn0NCnAsbGkgew0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KLnJ7DQogIGxpbmUtaGVpZ2h0OiAxLjI7DQp9DQoNCnRpdGxlew0KICBjb2xvcjogI2NjMDAwMDsNCiAgZm9udC1mYW1pbHk6ICJUcmVidWNoZXQgTVMiLCAi5b6u6Luf5q2j6buR6auUIiwgIk1pY3Jvc29mdCBKaGVuZ0hlaSI7DQp9DQoNCmJvZHl7DQogIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgIuW+rui7n+ato+m7kemrlCIsICJNaWNyb3NvZnQgSmhlbmdIZWkiOw0KfQ0KDQpoMSxoMixoMyxoNCxoNXsNCiAgY29sb3I6ICMwMDg4MDA7DQogIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgIuW+rui7n+ato+m7kemrlCIsICJNaWNyb3NvZnQgSmhlbmdIZWkiOw0KfQ0KDQpoM3sNCiAgY29sb3I6ICMwMDg4MDA7DQogIGJhY2tncm91bmQ6ICNlNmZmZTY7DQogIGxpbmUtaGVpZ2h0OiAyOw0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KaDV7DQogIGNvbG9yOiAjMDA2MDAwOw0KICBiYWNrZ3JvdW5kOiAjZjhmOGY4Ow0KICBsaW5lLWhlaWdodDogMS41Ow0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KZW17DQogIGNvbG9yOiAjMDAwMGMwOw0KICBiYWNrZ3JvdW5kOiAjZjBmMGYwOw0KICB9DQo8L3N0eWxlPg0KDQo=