前言:從交易記錄到顧客價值
善用商業數據分析的工具和技巧,光靠一份最簡單的交易紀錄(只有顧客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)
package 'ROCR' was built under R version 3.5.1Loading required package: gplots
package 'gplots' was built under R version 3.5.1
Attaching package: 'gplots'
The following object is masked from 'package:stats':
lowess
library(googleVis)
package 'googleVis' was built under R version 3.5.1Creating a generic function for 'toJSON' from package 'jsonlite' in package 'googleVis'
Welcome to googleVis version 0.6.2
Please read Google's Terms of Use
before you start using the package:
https://developers.google.com/terms/
Note, the plot method of googleVis will by default use
the standard browser to display its output.
See the googleVis package vignettes for more details,
or visit http://github.com/mages/googleVis.
To suppress this message use:
suppressPackageStartupMessages(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) # 交易次數 51243
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
par(cex=0.8)
hist(X$date, "years", las=2, freq=T, xlab="", main="No. Transaction by Year")

有多少不一樣的cid
n_distinct(X$cid) # 顧客數 18417
[1] 18417
1.2 顧客資料 (A)
- mutate(): 長一個新欄位
- days: recency: 整筆資料的最後一天-date
money = mean(amount), # 平均購買金額
senior = max(days), # 第一次購買距今天數"
0, since = min(date) # 第一次購買日期"
) %>% data.frame
1.4 顧客資料摘要
summary(A)
cid recent freq money senior since
Min. : 10 Min. : 1 Min. : 1.00 Min. : 5 Min. : 1 Min. :2005-01-02
1st Qu.: 81990 1st Qu.: 244 1st Qu.: 1.00 1st Qu.: 22 1st Qu.: 988 1st Qu.:2007-10-23
Median :136430 Median :1070 Median : 2.00 Median : 30 Median :2087 Median :2010-04-15
Mean :137574 Mean :1253 Mean : 2.78 Mean : 58 Mean :1984 Mean :2010-07-26
3rd Qu.:195100 3rd Qu.:2130 3rd Qu.: 3.00 3rd Qu.: 50 3rd Qu.:2992 3rd Qu.:2013-04-18
Max. :264200 Max. :4014 Max. :45.00 Max. :4500 Max. :4016 Max. :2015-12-31
1.5 變數的分布狀況
frequency : decrete variable pmin() : 設一個上限,超過上限的都算在最後一個區間
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="")

2. 層級式集群分析
2.1 RFM顧客分群
12345678910NA107322661296223732071942178123922096127NA
2.2 顧客群組屬性
看看每一群裡面平均的RFM為多少
每個泡泡為一個群
- x y 軸放最重要的變數: frequency,
- 大小: 這個族群的營收貢獻
- 顏色: 多久沒來買
- text: 族群大小
127那群: 是最重要的顧客,較常來買,每次買的金額也高。對他們要想盡辦法保留 2266那群: 常買但買的東西不多。可以看他喜好,盡量刺激他買多一點
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)")

3. 規則分群
用kmeans分群算是一種“統計”的分群 用階層式的“規則”分群,可以每年都用同樣的規則做分群,就可以比較每年的變化狀況 藉此可以比較顧客在行銷滑水道裡面滑去哪裡了 ##### 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、R、F、M都很重要
計算freq>1,找買超過一次的顧客(有回購的人) \[ 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 \] \[ \frac{\sum_{t=1}^N (\frac{S_i}{F_i})}{N} \] \[ \frac{ \sum_{t=1}^N }{} \]
K = as.integer(sum(A$senior[A$freq>1]) / sum(A$freq[A$freq>1])); K
sum(A$senior[A$freq>1] / A$freq[A$freq>1]) / nrow(A)
回購顧客的平均購買週期 K = 521 days
3.3 滑動資料窗格
每個年底都會彙整資料 用一個大Y變數把每個年份的資料框都存起來 status: 他屬於哪一群顧客(沉睡? 主力?….)
Y = list() # 建立一個空的LIST
for(y in 2010:2015) { # 每年年底將顧客資料彙整成一個資料框
D = as.Date(paste0(c(y, y-1),"-12-31")) # 當期、前期的期末日期
Y[[paste0("Y",y)]] = X %>% # 從交易資料做起,命名list的elements為Y+年份
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)
3.4 每年年底的累計顧客人數
sapply(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)
chrome的設定 > 進階 > 隱私權及安全性 > 內容設定 > Flash > [新增] > 127.0.0.1
plot( gvisMotionChart(
CustSegments, "status", "year",
options=list(width=900, height=600) ) )
R2頻率增加 N2購買金額應加
3.7 族群屬性動態分析
看看水缸中的顧客如何流動
- 381個顧客本來2014年在N1,2015年變成了N2
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 # 流量矩陣
tx %>% prop.table(1) %>% round(3) # 流量矩陣(%)
3.8 互動式流量分析
柱子: 粗的流動到細的地方 小山丘: 留在原水缸
S1的人一部分繼續睡,一部份跑到S2(睡更深)
chorddiag(tx, groupColors=cols)
4. 建立模型
在這個案例裡面,我們的資料是收到Y2015年底,所以我們可以假設現在的時間是Y2015年底,我們想要用現有的資料建立模型,來預測每一位顧客:
- 在Y2016年是否會來購買 (保留率:Retain)
- 她來購買的話,會買多少錢 (購買金額:Revenue)
但是,我們並沒有Y2016的資料,為了要建立模型,我們需要先把時間回推一期,也就是說:
- 用Y2014年底以前的資料整理出預測變數(X)
- 用Y2015年的資料整理出目標變數(Y)
假如Y2016的情況(跟Y2015比)沒有太大的變化的話,接下來我們就可以
- 使用該模型,以Y2015年底的資料,預測Y2016的狀況
4.1 準備資料
我們用Y2014年底的資料做自變數,Y2015年的資料做應變數 當期購買次數&金額為第8,9欄 第1欄為cId,拿來當join時的key
left_join: 如果兩邊沒有match的資料,保留左邊的資料右邊填na或null merge: 如果兩邊沒有match的資料,就直接砍了不會保留
欄位名稱中的.x和.y是R自動加進去的
CX = left_join(Y$Y2014, Y$Y2015[,c(1,8,9)], by="cid")
head(CX)
- y_freq.y欄位: 2015年會不會來買(Retain)
- y_revenue.y欄位: 2015年會來買多少錢
names(CX)[8:11] = c("freq0","revenue0","Retain", "Revenue")
CX$Retain = CX$Retain > 0
head(CX)
table(CX$Retain) %>% prop.table() # 平均保留機率 = 22.54%
4.2 建立類別模型
mRet = glm(Retain ~ ., CX[,c(2:3,6,8:10)], family=binomial())
summary(mRet)
4.3 估計類別模型的準確性
pred = predict(mRet,type="response")
table(pred>0.5,CX$Retain)
# 混淆矩陣 (Confusion Matrix)
table(pred>0.5,CX$Retain) %>%
{sum(diag(.))/sum(.)} # 正確率(ACC): 85.19%
colAUC(pred,CX$Retain) # 辯識率(AUC): 87.92%
prediction(pred, CX$Retain) %>% # ROC CURVE
performance("tpr", "fpr") %>%
plot(print.cutoffs.at=seq(0,1,0.1))
4.4 建立數量模型
subset : 對會來買的人做回歸模型 log : 應變數取log後再看R-squared
dx = subset(CX, Revenue > 0) # 只對有來購買的人做模型
mRev = lm(log(Revenue) ~ recent + freq + log(1+money) + senior +
status + freq0 + log(1+revenue0), dx)
summary(mRev) # 判定係 數: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="")
5.2 估計顧客終生價值(CLV)
顧客\(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)
所有人的CLV
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)
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="")
S3族群
par(mfrow=c(1,2), mar=c(4,3,3,2), cex=0.8)
hist(CX$ProbRetain[CX$status=="S3"],main="ProbRetain",xlab="")
hist(log(CX$PredRevenue[CX$status=="S3"],10),main="PredRevenue",xlab="")
7.2 估計預期報酬
可以依據之前使用行銷工具的經驗來推出effect和cost, 這裡假設行銷工具的成本和預期效益為
cost = 10 # 成本
effect = 0.75 # 效益:下一期的購買機率
估計這項行銷工具對每一位R2顧客的預期報酬
Target = subset(CX, status=="R2")
Target$ExpReturn = (effect - Target$ProbRetain) * Target$PredRevenue - cost
summary(Target$ExpReturn)
這一項工具對R2顧客的預期報酬是負的
這項工具對於Retain大於0.75的人其實沒甚麼用 他們算出來的ExpReturn會是負的
7.3 選擇行銷對象
但是,我們還是可以挑出許多預期報酬很大的行銷對象
Target %>% arrange(desc(ExpReturn)) %>% select(cid, ExpReturn) %>% head(15)
找出預期報償為正的顧客 可以對他們實施這項行銷工具
sum(Target$ExpReturn > 0) # 可實施對象:258
在R2之中,有258人的預期報酬大於零,如果對這258人使用這項工具,我們的期望報酬是:
sum(Target$ExpReturn[Target$ExpReturn > 0]) # 預期報酬: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
這個結果是合理的嗎? 你想要怎麼修正這項分析的程序呢?
- 因為每個群算出來的probRetain不一樣,而且同一套行銷工具應用到不同族群的顧客產生出來的cost和effect也不一樣,所以無法直接用相同的算法套運到所有族群。
LS0tDQp0aXRsZTogIkNWTe+8mumhp+WuouWDueWAvOeuoeeQhiAiDQphdXRob3I6ICLorJ3pm6jpnZwgTTA3NDAyMDAwNiwgMjAxOC8wNy8yOSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCjxicj4NCg0KIyMjIOWJjeiogO+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+DQoNCiMjIyDln7rmnKzmlbTnkIblh73mlbgNCg0KKiBhcnJhbmdlOiDmoLnmk5rkvaDpgbjlrprnmoTorormlbjlgZrmjpLliJcgKOWPr+S7peaYr+WkmuWAi+iuiuaVuCkNCg0KKiBmaWx0ZXI6IOagueaTmuS9oOioreWumueahOaineS7tuWBmnJvdyDnr6npgbgob3Igc2VsZWN0aW9uKQ0KDQoqIG11dGF0ZTog5qC55pOa5L2g57Wm5a6a55qE5YC86LOm5LqI5paw6K6K5pW477yM5oiW5piv6K6K5pu06IiK6K6K5pW4DQoNCiogc2VsZWN0OiDmoLnmk5rntablrprnmoTorormlbjlkI3nqLHlgZrpgbjmk4fvvIzkuZ/lj6/ku6XlgZrliKrpmaTorormlbgNCg0KKiBncm91cF9ieTog5qC55pOa57Wm5a6a6K6K5pW45YGaZ3JvdXDvvIzku6XpipzmjqVzdW1tYXJpc2UNCg0KKiBzdW1tYXJpc2U6IOizh+aWmeaVtOS9tQ0KDQoNCg0KIyMjIDEgMS4g6LOH5paZ5pW055CGDQoNCiMjIyMjIDEuMSDkuqTmmJPos4fmlpkgKFgpDQpgYGB7cn0NClggPSByZWFkLnRhYmxlKA0KICAncHVyY2hhc2VzLnR4dCcsIGhlYWRlcj1GQUxTRSwgc2VwPSdcdCcsIHN0cmluZ3NBc0ZhY3RvcnM9RikNCm5hbWVzKFgpID0gYygnY2lkJywnYW1vdW50JywnZGF0ZScpDQpYJGRhdGUgPSBhcy5EYXRlKFgkZGF0ZSkNCnN1bW1hcnkoWCkgICAgICAgICAgICAgICAgICAjIOS6pOaYk+asoeaVuCA1MTI0Mw0KYGBgDQoNCg0KYGBge3IgZmlnLmhlaWdodD0zLCBmaWcud2lkdGg9Ny4yfQ0KcGFyKGNleD0wLjgpDQpoaXN0KFgkZGF0ZSwgInllYXJzIiwgbGFzPTIsIGZyZXE9VCwgeGxhYj0iIiwgbWFpbj0iTm8uIFRyYW5zYWN0aW9uIGJ5IFllYXIiKQ0KIyB5ZWFyc+WPr+S7peaPm+aIkHdlZWtz5LmL6aGe55qEDQpgYGANCg0K5pyJ5aSa5bCR5LiN5LiA5qij55qEY2lkDQpgYGB7cn0NCm5fZGlzdGluY3QoWCRjaWQpICAgICAgICAgICAjIOmhp+WuouaVuCAxODQxNw0KYGBgDQoNCiMjIyMjIDEuMiDpoaflrqLos4fmlpkgKEEpDQoNCiogbXV0YXRlKCk6IOmVt+S4gOWAi+aWsOashOS9jQ0KKiBkYXlzOiByZWNlbmN5OiDmlbTnrYbos4fmlpnnmoTmnIDlvozkuIDlpKktZGF0ZQ0KYGBge3J9DQpBID0gWCAlPiUgDQogIG11dGF0ZShkYXlzID0gYXMuaW50ZWdlcihhcy5EYXRlKCIyMDE2LTAxLTAxIikgLSBkYXRlKSkgJT4lIA0KICBncm91cF9ieShjaWQpICU+JSBzdW1tYXJpc2UoDQogICAgcmVjZW50ID0gbWluKGRheXMpLCAgICAgIyDmnIDov5Hos7zosrfot53ku4rlpKnmlbgNCiAgICBmcmVxID0gbigpLCAgICAgICAgICAgICAjIOizvOiyt+asoeaVuA0KICAgIG1vbmV5ID0gbWVhbihhbW91bnQpLCAgICMg5bmz5Z2H6LO86LK36YeR6aGNDQogICAgc2VuaW9yID0gbWF4KGRheXMpLCAgICAgIyDnrKzkuIDmrKHos7zosrfot53ku4rlpKnmlbgNCiAgICBzaW5jZSA9IG1pbihkYXRlKSAgICAgICAjIOesrOS4gOasoeizvOiyt+aXpeacnw0KICApICU+JSBkYXRhLmZyYW1lDQpgYGANCg0KIyMjIyMgMS40IOmhp+Wuouizh+aWmeaRmOimgQ0KYGBge3J9DQpzdW1tYXJ5KEEpDQpgYGANCg0KIyMjIyMgMS41IOiuiuaVuOeahOWIhuW4g+eLgOazgQ0KDQpmcmVxdWVuY3kgOiBkZWNyZXRlIHZhcmlhYmxlIA0KcG1pbigpIDog6Kit5LiA5YCL5LiK6ZmQ77yM6LaF6YGO5LiK6ZmQ55qE6YO9566X5Zyo5pyA5b6M5LiA5YCL5Y2A6ZaTDQpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04fQ0KcDAgPSBwYXIoY2V4PTAuOCwgbWZyb3c9YygyLDIpLCBtYXI9YygzLDMsNCwyKSkNCmhpc3QoQSRyZWNlbnQsMjAsbWFpbj0icmVjZW5jeSIseWxhYj0iIix4bGFiPSIiKQ0KaGlzdChwbWluKEEkZnJlcSwgMTApLDA6MTAsbWFpbj0iZnJlcXVlbmN5Iix5bGFiPSIiLHhsYWI9IiIpDQpoaXN0KEEkc2VuaW9yLDIwLG1haW49InNlbmlvcml0eSIseWxhYj0iIix4bGFiPSIiKQ0KaGlzdChsb2coQSRtb25leSwxMCksLG1haW49ImxvZyhtb25leSkiLHlsYWI9IiIseGxhYj0iIikNCmBgYA0KPGJyPjxocj4NCg0KIyMjIDIuIOWxpOe0muW8j+mbhue+pOWIhuaekA0KDQojIyMjIyAyLjEgUkZN6aGn5a6i5YiG576kDQpgYGB7cn0NCnNldC5zZWVkKDExMSkNCkEkZ3JwID0ga21lYW5zKHNjYWxlKEFbLDI6NF0pLDEwKSRjbHVzdGVyICPlj6rnlKhSLCBGLCBN5LiJ5YCL5qyE5L2NDQp0YWJsZShBJGdycCkgICMg5peP576k5aSn5bCPDQpgYGANCg0KIyMjIyMgMi4yIOmhp+Wuoue+pOe1hOWxrOaApw0KDQrnnIvnnIvmr4/kuIDnvqToo6HpnaLlubPlnYfnmoRSRk3ngrrlpJrlsJENCg0K5q+P5YCL5rOh5rOh54K65LiA5YCL576kDQoNCiogeCB5IOi7uOaUvuacgOmHjeimgeeahOiuiuaVuDogZnJlcXVlbmN5LA0KKiDlpKflsI86IOmAmeWAi+aXj+e+pOeahOeHn+aUtuiyoueNuw0KKiDpoY/oibI6IOWkmuS5heaykuS+huiytw0KKiB0ZXh0OiDml4/nvqTlpKflsI8NCg0KDQoxMjfpgqPnvqQ6IOaYr+acgOmHjeimgeeahOmhp+Wuou+8jOi8g+W4uOS+huiyt++8jOavj+asoeiyt+eahOmHkemhjeS5n+mrmOOAguWwjeS7luWAkeimgeaDs+eboei+puazleS/neeVmQ0KMjI2NumCo+e+pDog5bi46LK35L2G6LK355qE5p2x6KW/5LiN5aSa44CC5Y+v5Lul55yL5LuW5Zac5aW977yM55uh6YeP5Yi65r+A5LuW6LK35aSa5LiA6bueDQoNCmBgYHtyIGZpZy5oZWlnaHQ9NC41LCBmaWcud2lkdGg9OH0NCmdyb3VwX2J5KEEsIGdycCkgJT4lIHN1bW1hcmlzZSgNCiAgcmVjZW50PW1lYW4ocmVjZW50KSwgDQogIGZyZXE9bWVhbihmcmVxKSwgDQogIG1vbmV5PW1lYW4obW9uZXkpLCANCiAgc2l6ZT1uKCkgKSAlPiUgDQogIG11dGF0ZSggcmV2ZW51ZSA9IHNpemUqbW9uZXkvMTAwMCApICAlPiUgDQogIGZpbHRlcihzaXplID4gMSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHg9ZnJlcSwgeT1tb25leSkpICsNCiAgZ2VvbV9wb2ludChhZXMoc2l6ZT1yZXZlbnVlLCBjb2w9cmVjZW50KSxhbHBoYT0wLjUpICsNCiAgc2NhbGVfc2l6ZShyYW5nZT1jKDQsMzApKSArDQogIHNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdz0iZ3JlZW4iLGhpZ2g9InJlZCIpICsNCiAgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMChsaW1pdHM9YygzMCwzMDAwKSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNpemUgKSxzaXplPTMpICsNCiAgdGhlbWVfYncoKSArIGd1aWRlcyhzaXplPUYpICsNCiAgbGFicyh0aXRsZT0iQ3VzdG9tZXIgU2VnZW1lbnRzIiwNCiAgICAgICBzdWJ0aXRsZT0iKGJ1YmJsZV9zaXplOnJldmVudWVfY29udHJpYnV0aW9uOyB0ZXh0Omdyb3VwX3NpemUpIiwNCiAgICAgICBjb2xvcj0iUmVjZW5jeSIpICsNCiAgeGxhYigiRnJlcXVlbmN5IChsb2cpIikgKyB5bGFiKCJBdmVyYWdlIFRyYW5zYWN0aW9uIEFtb3VudCAobG9nKSIpDQpgYGANCjxicj48aHI+DQoNCiMjIyAzLiDopo/liYfliIbnvqQNCueUqGttZWFuc+WIhue+pOeul+aYr+S4gOeoriLntbHoqIgi55qE5YiG576kDQrnlKjpmo7lsaTlvI/nmoQi6KaP5YmHIuWIhue+pO+8jOWPr+S7peavj+W5tOmDveeUqOWQjOaoo+eahOimj+WJh+WBmuWIhue+pO+8jOWwseWPr+S7peavlOi8g+avj+W5tOeahOiuiuWMlueLgOazgQ0K6JeJ5q2k5Y+v5Lul5q+U6LyD6aGn5a6i5Zyo6KGM6Yq35ruR5rC06YGT6KOh6Z2i5ruR5Y675ZOq6KOh5LqGDQojIyMjIyAzLjEg6aGn5a6i5YiG576k6KaP5YmHDQpgYGB7cn0NClNUUyA9IGMoIk4xIiwiTjIiLCJSMSIsIlIyIiwiUzEiLCJTMiIsIlMzIikNClN0YXR1cyA9IGZ1bmN0aW9uKHJ4LGZ4LG14LHN4LEspIHtmYWN0b3IoDQogIGlmZWxzZShzeCA8IDIqSywNCiAgICAgICAgIGlmZWxzZShmeCpteCA+IDUwLCAiTjIiLCAiTjEiKSwNCiAgICAgICAgIGlmZWxzZShyeCA8IDIqSywNCiAgICAgICAgICAgICAgICBpZmVsc2Uoc3gvZnggPCAwLjc1KkssIlIyIiwiUjEiKSwNCiAgICAgICAgICAgICAgICBpZmVsc2UocnggPCAzKkssIlMxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHJ4IDwgNCpLLCJTMiIsIlMzIikpKSksIFNUUyl9DQpgYGANCg0KPGNlbnRlcj4NCg0KIVvlnJbkuInjgIHpoaflrqLliIbnvqTopo/liYddKGZpZy9maWczLmpmaWYpDQoNCjwvY2VudGVyPg0KDQojIyMjIyAzLjIg5bmz5Z2H6LO86LK36YCx5pyfDQoNCkvjgIFS44CBRuOAgU3pg73lvojph43opoENCg0K6KiI566XZnJlcT4x77yM5om+6LK36LaF6YGO5LiA5qyh55qE6aGn5a6iKOacieWbnuizvOeahOS6uikNCiQkIFZfaSA9IFxzdW1fe3Q9MH1eTiBnIFx0aW1lcyBtX2kgXGZyYWN7cl9pXnR9eygxK2QpXnR9ID0gZyBcdGltZXMgbV9pIFxzdW1fe3Q9MH1eTiAoXGZyYWN7cl9pfXsxK2R9KV50ICAkJA0KJCQgXGZyYWN7XHN1bV97dD0xfV5OIChcZnJhY3tTX2l9e0ZfaX0pfXtOfSAkJA0KJCQgXGZyYWN7IFxzdW1fe3Q9MX1eTiAgIH17fSAkJA0KYGBge3J9DQpLID0gYXMuaW50ZWdlcihzdW0oQSRzZW5pb3JbQSRmcmVxPjFdKSAvIHN1bShBJGZyZXFbQSRmcmVxPjFdKSk7IEsNCg0Kc3VtKEEkc2VuaW9yW0EkZnJlcT4xXSAvIEEkZnJlcVtBJGZyZXE+MV0pIC8gbnJvdyhBKQ0KYGBgDQrlm57os7zpoaflrqLnmoTlubPlnYfos7zosrfpgLHmnJ8gYEsgPSA1MjEgZGF5c2ANCg0KIyMjIyMgMy4zIOa7keWLleizh+aWmeeql+agvA0KDQrmr4/lgIvlubTlupXpg73mnIPlvZnmlbTos4fmlpkNCueUqOS4gOWAi+Wkp1norormlbjmiormr4/lgIvlubTku73nmoTos4fmlpnmoYbpg73lrZjotbfkvoYNCnN0YXR1czog5LuW5bGs5pa85ZOq5LiA576k6aGn5a6iKOayieedoT8g5Li75YqbPy4uLi4pDQpgYGB7cn0NClkgPSBsaXN0KCkgICAgICAgICAgICAgICMg5bu656uL5LiA5YCL56m655qETElTVA0KZm9yKHkgaW4gMjAxMDoyMDE1KSB7ICAgIyDmr4/lubTlubTlupXlsIfpoaflrqLos4fmlpnlvZnmlbTmiJDkuIDlgIvos4fmlpnmoYYNCiAgRCA9IGFzLkRhdGUocGFzdGUwKGMoeSwgeS0xKSwiLTEyLTMxIikpICMg55W25pyf44CB5YmN5pyf55qE5pyf5pyr5pel5pyfIA0KICBZW1twYXN0ZTAoIlkiLHkpXV0gPSBYICU+JSAgICAgICAgIyDlvp7kuqTmmJPos4fmlpnlgZrotbfvvIzlkb3lkI1saXN055qEZWxlbWVudHPngrpZK+W5tOS7vQ0KICAgICAgZmlsdGVyKGRhdGUgPD0gRFsxXSkgJT4lICAgICAgICAjIOWwh+izh+aWmeWIh+m9iuWIsOacn+acq+aXpeacnw0KICAgICAgbXV0YXRlKGRheXMgPSAxICsgYXMuaW50ZWdlcihEWzFdIC0gZGF0ZSkpICU+JSAgICMg5Lqk5piT6Led5pyf5pyr5aSp5pW4DQogICAgICBncm91cF9ieShjaWQpICU+JSBzdW1tYXJpc2UoICAgICMg5L6d6aGn5a6i5b2Z57i9IC4uLg0KICAgICAgICAgIHJlY2VudCA9IG1pbihkYXlzKSwgICAgICAgICAgICMgICDmnIDlvozkuIDmrKHos7zosrfot53mnJ/mnKvlpKnmlbggICANCiAgICAgICAgICBmcmVxID0gbigpLCAgICAgICAgICAgICAgICAgICAjICAg6LO86LK35qyh5pW4ICjoh7PmnJ/mnKvngrrmraIpICAgDQogICAgICAgICAgbW9uZXkgPSBtZWFuKGFtb3VudCksICAgICAgICAgIyAgIOW5s+Wdh+izvOiyt+mHkemhjSAo6Iez5pyf5pyr54K65q2iKQ0KICAgICAgICAgIHNlbmlvciA9IG1heChkYXlzKSwgICAgICAgICAgICMgICDnrKzkuIDmrKHos7zosrfot53mnJ/mnKvlpKnmlbgNCiAgICAgICAgICBzdGF0dXMgPSBTdGF0dXMocmVjZW50LGZyZXEsbW9uZXksc2VuaW9yLEspLCAgIyDmnJ/mnKvni4DmhYsNCiAgICAgICAgICBzaW5jZSA9IG1pbihkYXRlKSwgICAgICAgICAgICAgICAgICAgICAgIyDnrKzkuIDmrKHos7zosrfml6XmnJ8NCiAgICAgICAgICB5X2ZyZXEgPSBzdW0oZGF0ZSA+IERbMl0pLCAgICAgICAgICAgICAgIyDnlbbmnJ/os7zosrfmrKHmlbgNCiAgICAgICAgICB5X3JldmVudWUgPSBzdW0oYW1vdW50W2RhdGUgPiBEWzJdXSkgICAgIyDnlbbmnJ/os7zosrfph5HpoY0NCiAgICAgICkgJT4lIGRhdGEuZnJhbWUgfQ0KYGBgDQoNCmBgYHtyfQ0KaGVhZChZJFkyMDE1KQ0KYGBgDQoNCiMjIyMjIDMuNCDmr4/lubTlubTlupXnmoTntK/oqIjpoaflrqLkurrmlbgNCmBgYHtyfQ0Kc2FwcGx5KFksIG5yb3cpDQpgYGANCg0KIyMjIyMgMy41IOaXj+e+pOWkp+Wwj+iuiuWMlui2qOWLog0KDQrnnaHokZfnmoTkurrmnIPotorkvobotorlpJrvvIzmiYDku6XkurrotorkvobotorlpJoNCuacieS6m+a8lOeul+azleacg+aKiuayieedoeWkquS5heeahOmhp+WuouWIquaOiQ0K55So6YCZ5YCL5ZyW5Y+v5Lul55yL5LiA5LiL5q+P5LiA5YCL5peP576k55qE6aGn5a6i6K6K5YyW54uA5rOBDQpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04fQ0KY29scyA9IGMoImdvbGQiLCJvcmFuZ2UiLCJibHVlIiwiZ3JlZW4iLCJwaW5rIiwibWFnZW50YSIsImRhcmtyZWQiKSAjIOioreWumumhj+iJsg0Kc2FwcGx5KFksIGZ1bmN0aW9uKGRmKSB0YWJsZShkZiRzdGF0dXMpKSAlPiUgYmFycGxvdChjb2w9Y29scykNCmxlZ2VuZCgidG9wbGVmdCIscmV2KFNUUyksZmlsbD1yZXYoY29scykpDQpgYGANCg0KIyMjIyMgMy42IOaXj+e+pOWxrOaAp+WLleaFi+WIhuaekA0KYGBge3J9DQpDdXN0U2VnbWVudHMgPSBkby5jYWxsKHJiaW5kLCBsYXBwbHkoWSwgZnVuY3Rpb24oZCkgew0KICBncm91cF9ieShkLCBzdGF0dXMpICU+JSBzdW1tYXJpc2UoDQogICAgYXZlcmFnZV9mcmVxdWVuY3kgPSBtZWFuKGZyZXEpLA0KICAgIGF2ZXJhZ2VfYW1vdW50ID0gbWVhbihtb25leSksDQogICAgdG90YWxfcmV2ZW51ZSA9IHN1bSh5X3JldmVudWUpLA0KICAgIHRvdGFsX25vX29yZGVycyA9IHN1bSh5X2ZyZXEpLA0KICAgIGF2ZXJhZ2VfcmVjZW5jeSA9IG1lYW4ocmVjZW50KSwNCiAgICBhdmVyYWdlX3Nlbmlvcml0eSA9IG1lYW4oc2VuaW9yKSwNCiAgICBncm91cF9zaXplID0gbigpDQogICl9KSkgJT4lIHVuZ3JvdXAgJT4lIA0KICBtdXRhdGUoeWVhcj1yZXAoMjAxMDoyMDE1LCBlYWNoPTcpKSAlPiUgZGF0YS5mcmFtZQ0KaGVhZChDdXN0U2VnbWVudHMpDQpgYGANCg0KY2hyb21l55qE6Kit5a6aID4g6YCy6ZqOID4g6Zqx56eB5qyK5Y+K5a6J5YWo5oCnID4g5YWn5a656Kit5a6aID4gRmxhc2ggPiBb5paw5aKeXSA+IDEyNy4wLjAuMQ0KYGBge3IgZXZhbD1GfQ0KcGxvdCggZ3Zpc01vdGlvbkNoYXJ0KA0KICBDdXN0U2VnbWVudHMsICJzdGF0dXMiLCAieWVhciIsDQogIG9wdGlvbnM9bGlzdCh3aWR0aD05MDAsIGhlaWdodD02MDApICkgKQ0KYGBgDQoNCjxjZW50ZXI+DQoNCiFb5ZyW5Zub44CB6aGn5a6i5YiG576k6KaP5YmHXShmaWcvZmlnNC5qZmlmKQ0KDQo8L2NlbnRlcj4NCg0KUjLpoLvnjoflop7liqANCk4y6LO86LK36YeR6aGN5oeJ5YqgDQoNCg0KIyMjIyMgMy43IOaXj+e+pOWxrOaAp+WLleaFi+WIhuaekA0KDQrnnIvnnIvmsLTnvLjkuK3nmoTpoaflrqLlpoLkvZXmtYHli5UNCg0KKiAzODHlgIvpoaflrqLmnKzkvoYyMDE05bm05ZyoTjHvvIwyMDE15bm06K6K5oiQ5LqGTjINCg0KYGBge3J9DQpkZiA9IG1lcmdlKFkkWTIwMTRbLGMoMSw2KV0sIFkkWTIwMTVbLGMoMSw2KV0sDQogICAgICAgICAgIGJ5PSJjaWQiLCBhbGwueD1UKQ0KdHggPSB0YWJsZShkZiRzdGF0dXMueCwgZGYkc3RhdHVzLnkpICU+JSANCiAgYXMuZGF0YS5mcmFtZS5tYXRyaXgoKSAlPiUgYXMubWF0cml4KCkNCnR4ICAgICMg5rWB6YeP55+p6ZmjDQpgYGANCg0KYGBge3J9DQp0eCAlPiUgcHJvcC50YWJsZSgxKSAlPiUgcm91bmQoMykgICAjIOa1gemHj+efqemZoyglKQ0KYGBgDQoNCiMjIyMjIDMuOCDkupLli5XlvI/mtYHph4/liIbmnpANCg0K5p+x5a2QOiDnspfnmoTmtYHli5XliLDntLDnmoTlnLDmlrkNCuWwj+WxseS4mDog55WZ5Zyo5Y6f5rC057y4DQoNClMx55qE5Lq65LiA6YOo5YiG57m857qM552h77yM5LiA6YOo5Lu96LeR5YiwUzIo552h5pu05rexKQ0KYGBge3J9DQpjaG9yZGRpYWcodHgsIGdyb3VwQ29sb3JzPWNvbHMpDQpgYGANCg0KIVtdKGZpZy9jaG9yZC5qcGcpDQoNCjxicj48aHI+DQoNCiMjIyA0LiDlu7rnq4vmqKHlnosNCg0K5Zyo6YCZ5YCL5qGI5L6L6KOh6Z2i77yM5oiR5YCR55qE6LOH5paZ5piv5pS25YiwWTIwMTXlubTlupXvvIzmiYDku6XmiJHlgJHlj6/ku6XlgYfoqK3nj77lnKjnmoTmmYLplpPmmK9ZMjAxNeW5tOW6le+8jOaIkeWAkeaDs+imgeeUqOePvuacieeahOizh+aWmeW7uueri+aooeWei++8jOS+humgkOa4rOavj+S4gOS9jemhp+Wuou+8mg0KDQorIOWcqFkyMDE25bm05piv5ZCm5pyD5L6G6LO86LK3ICjkv53nlZnnjofvvJpSZXRhaW4pDQorIOWlueS+huizvOiyt+eahOipse+8jOacg+iyt+WkmuWwkemMoiAo6LO86LK36YeR6aGN77yaUmV2ZW51ZSkNCg0K5L2G5piv77yM5oiR5YCR5Lim5rKS5pyJWTIwMTbnmoTos4fmlpnvvIzngrrkuobopoHlu7rnq4vmqKHlnovvvIzmiJHlgJHpnIDopoHlhYjmiormmYLplpPlm57mjqjkuIDmnJ/vvIzkuZ/lsLHmmK/oqqrvvJoNCg0KKyDnlKhZMjAxNOW5tOW6leS7peWJjeeahOizh+aWmeaVtOeQhuWHuumgkOa4rOiuiuaVuChYKSANCisg55SoWTIwMTXlubTnmoTos4fmlpnmlbTnkIblh7rnm67mqJnorormlbgoWSkgDQoNCuWBh+WmglkyMDE255qE5oOF5rOBKOi3n1kyMDE15q+UKeaykuacieWkquWkp+eahOiuiuWMlueahOipse+8jOaOpeS4i+S+huaIkeWAkeWwseWPr+S7pQ0KDQorIOS9v+eUqOipsuaooeWei++8jOS7pVkyMDE15bm05bqV55qE6LOH5paZ77yM6aCQ5risWTIwMTbnmoTni4Dms4ENCg0KIyMjIyMgNC4xIOa6luWCmeizh+aWmQ0KDQrmiJHlgJHnlKhZMjAxNOW5tOW6leeahOizh+aWmeWBmuiHquiuiuaVuO+8jFkyMDE15bm055qE6LOH5paZ5YGa5oeJ6K6K5pW4DQrnlbbmnJ/os7zosrfmrKHmlbgm6YeR6aGN54K656ysOCw55qyEDQrnrKwx5qyE54K6Y0lk77yM5ou/5L6G55W2am9pbuaZgueahGtleQ0KDQpsZWZ0X2pvaW46IOWmguaenOWFqemCiuaykuaciW1hdGNo55qE6LOH5paZ77yM5L+d55WZ5bem6YKK55qE6LOH5paZ5Y+z6YKK5aGrbmHmiJZudWxsDQptZXJnZTog5aaC5p6c5YWp6YKK5rKS5pyJbWF0Y2jnmoTos4fmlpnvvIzlsLHnm7TmjqXnoI3kuobkuI3mnIPkv53nlZkNCg0K5qyE5L2N5ZCN56ix5Lit55qELnjlkowueeaYr1Loh6rli5XliqDpgLLljrvnmoQNCg0KDQoNCmBgYHtyfQ0KQ1ggPSBsZWZ0X2pvaW4oWSRZMjAxNCwgWSRZMjAxNVssYygxLDgsOSldLCBieT0iY2lkIikNCmhlYWQoQ1gpDQpgYGANCg0KKiB5X2ZyZXEueeashOS9jTogMjAxNeW5tOacg+S4jeacg+S+huiytyhSZXRhaW4pDQoqIHlfcmV2ZW51ZS555qyE5L2NOiAyMDE15bm05pyD5L6G6LK35aSa5bCR6YyiDQoNCmBgYHtyfQ0KbmFtZXMoQ1gpWzg6MTFdID0gYygiZnJlcTAiLCJyZXZlbnVlMCIsIlJldGFpbiIsICJSZXZlbnVlIikNCkNYJFJldGFpbiA9IENYJFJldGFpbiA+IDANCmhlYWQoQ1gpDQpgYGANCg0KYGBge3J9DQp0YWJsZShDWCRSZXRhaW4pICU+JSBwcm9wLnRhYmxlKCkgICMg5bmz5Z2H5L+d55WZ5qmf546HID0gMjIuNTQlDQpgYGANCg0KIyMjIyMgNC4yIOW7uueri+mhnuWIpeaooeWeiw0KYGBge3J9DQptUmV0ID0gZ2xtKFJldGFpbiB+IC4sIENYWyxjKDI6Myw2LDg6MTApXSwgZmFtaWx5PWJpbm9taWFsKCkpDQpzdW1tYXJ5KG1SZXQpDQpgYGANCg0KIyMjIyMgNC4zIOS8sOioiOmhnuWIpeaooeWei+eahOa6lueiuuaApw0KYGBge3J9DQpwcmVkID0gcHJlZGljdChtUmV0LHR5cGU9InJlc3BvbnNlIikNCnRhYmxlKHByZWQ+MC41LENYJFJldGFpbikgDQojIOa3t+a3huefqemZoyAoQ29uZnVzaW9uIE1hdHJpeCkgIA0KYGBgDQpgYGB7cn0NCnRhYmxlKHByZWQ+MC41LENYJFJldGFpbikgJT4lIA0KICB7c3VtKGRpYWcoLikpL3N1bSguKX0gICAgICAgICAgICAjIOato+eiuueOhyhBQ0MpOiA4NS4xOSUgDQpgYGANCmBgYHtyfQ0KY29sQVVDKHByZWQsQ1gkUmV0YWluKSAgICAgICAgICAgICAjIOi+r+itmOeOhyhBVUMpOiA4Ny45MiUNCmBgYA0KYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NH0NCnByZWRpY3Rpb24ocHJlZCwgQ1gkUmV0YWluKSAlPiUgICAgIyBST0MgQ1VSVkUgDQogIHBlcmZvcm1hbmNlKCJ0cHIiLCAiZnByIikgJT4lIA0KICBwbG90KHByaW50LmN1dG9mZnMuYXQ9c2VxKDAsMSwwLjEpKQ0KYGBgDQoNCiMjIyMjIDQuNCDlu7rnq4vmlbjph4/mqKHlnosNCg0Kc3Vic2V0IDog5bCN5pyD5L6G6LK355qE5Lq65YGa5Zue5q245qih5Z6LDQpsb2cgOiDmh4norormlbjlj5Zsb2flvozlho3nnItSLXNxdWFyZWQNCg0KYGBge3J9DQpkeCA9IHN1YnNldChDWCwgUmV2ZW51ZSA+IDApICAjIOWPquWwjeacieS+huizvOiyt+eahOS6uuWBmuaooeWeiw0KbVJldiA9IGxtKGxvZyhSZXZlbnVlKSB+IHJlY2VudCArIGZyZXEgKyBsb2coMSttb25leSkgKyBzZW5pb3IgKw0KICAgICAgICAgIHN0YXR1cyArIGZyZXEwICsgbG9nKDErcmV2ZW51ZTApLCBkeCkgIA0Kc3VtbWFyeShtUmV2KSAgICAgICAgICAgICAgICAgIyDliKTlrprkv4Ig5pW477yaUjIgPSAwLjcxMw0KYGBgDQoNCiog57SF57ea54K66aCQ5ris5YC8DQoq44CA57KJ57SF5ZyI54K65a+m6Zqb5YC8DQoNCmBgYHtyIGZpZy5oZWlnaHQ9NC41LCBmaWcud2lkdGg9NC41fQ0KcGxvdChsb2coZHgkUmV2ZW51ZSksIHByZWRpY3QobVJldiksIGNvbD0ncGluaycsIGNleD0wLjY1KQ0KYWJsaW5lKDAsMSxjb2w9J3JlZCcpIA0KYGBgDQo8YnI+PGhyPg0KDQojIyMgNS4g5Lyw6KiI6aGn5a6i57WC55Sf5YO55YC8DQoNCiMjIyMjIDUuMSBZMjAxNueahOmgkOa4rOWAvA0K5L2/55So5qih5Z6L5bCNWTIwMTXlubTlupXnmoTos4fmlpnlgZrpoJDmuKzvvIzlsI3os4fmlpnkuK3nmoTmr4/kuIDkvY3poaflrqLvvIzpoJDmuKzlpbnlgJHlnKhZMjAxNueahOS/neeVmeeOh+WSjOizvOiyt+mHkemhjeOAgg0KYGBge3J9DQpDWCA9IFkkWTIwMTUNCm5hbWVzKENYKVs4OjldID0gYygiZnJlcTAiLCJyZXZlbnVlMCIpDQoNCiMg6aCQ5risWTIwMTbkv53nlZnnjocNCkNYJFByb2JSZXRhaW4gPSBwcmVkaWN0KG1SZXQsQ1gsdHlwZT0ncmVzcG9uc2UnKQ0KDQojIOmgkOa4rFkyMDE26LO86LK36YeR6aGNDQpDWCRQcmVkUmV2ZW51ZSA9IGV4cChwcmVkaWN0KG1SZXYsQ1gpKQ0KYGBgDQoNCmBgYHtyIGZpZy5oZWlnaHQ9Mi41LCBmaWcud2lkdGg9OH0NCnBhcihtZnJvdz1jKDEsMiksIG1hcj1jKDQsMywzLDIpLCBjZXg9MC44KQ0KaGlzdChDWCRQcm9iUmV0YWluLG1haW49IlByb2JSZXRhaW4iLCB5bGFiPSIiKQ0KaGlzdChsb2coQ1gkUHJlZFJldmVudWUsMTApLG1haW49ImxvZyhQcmVkUmV2ZW51ZSkiLCB5bGFiPSIiKQ0KYGBgDQo8YnI+DQoNCiMjIyMjIDUuMiDkvLDoqIjpoaflrqLntYLnlJ/lg7nlgLwoQ0xWKQ0KDQo8Y2VudGVyPumhp+WuoiRpJOeahOe1gueUn+WDueWAvDwvY2VudGVyPg0KDQokJCBWX2kgPSBcc3VtX3t0PTB9Xk4gZyBcdGltZXMgbV9pIFxmcmFje3JfaV50fXsoMStkKV50fSA9IGcgXHRpbWVzIG1faSBcc3VtX3t0PTB9Xk4gKFxmcmFje3JfaX17MStkfSledCAgJCQNCg0KPGNlbnRlcj4kbV9pJOOAgSRyX2kk77ya6aGn5a6iJGkk55qE6aCQ5pyfKOavj+acnynnh5/mlLbosqLnjbvjgIHkv53nlZnmqZ/njoc8L2NlbnRlcj4NCg0KPGNlbnRlcj4kZyTjgIEkZCTvvJrlhazlj7jnmoQo56iF5YmNKeeHn+alreWIqea9pOWIqeeOh+OAgeizh+mHkeaIkOacrDwvY2VudGVyPg0KDQoNCg0KYGBge3J9DQpnID0gMC41ICAgIyAo56iF5YmNKeeNsuWIqeeOhw0KTiA9IDUgICAgICMg5pyf5pW4ID0gNQ0KZCA9IDAuMSAgICMg5Yip546HID0gMTAlDQpDWCRDTFYgPSBnICogQ1gkUHJlZFJldmVudWUgKiByb3dTdW1zKHNhcHBseSgNCiAgMDpOLCBmdW5jdGlvbihpKSAoQ1gkUHJvYlJldGFpbi8oMStkKSleaSApICkNCg0Kc3VtbWFyeShDWCRDTFYpDQpgYGANCg0K5omA5pyJ5Lq655qEQ0xWDQpgYGB7ciBmaWcuaGVpZ2h0PTIuNSwgZmlnLndpZHRoPTcuMn0NCnBhcihtYXI9YygyLDIsMywxKSwgY2V4PTAuOCkNCmhpc3QobG9nKENYJENMViwxMCksIHhsYWI9IiIsIHlsYWI9IiIpDQpgYGANCg0KIyMjIyMgNS4zIOavlOi8g+WQhOaXj+e+pOeahOWDueWAvA0KDQpgYGB7cn0NCiMg5ZCE5peP576k55qE5bmz5Z2H54ef5pS26LKi542744CB5L+d55WZ5qmf546H44CB57WC55Sf5YO55YC8DQpzYXBwbHkoQ1hbLDEwOjEyXSwgdGFwcGx5LCBDWCRzdGF0dXMsIG1lYW4pDQpgYGANCg0KDQoNCmBgYHtyfQ0KcGFyKG1hcj1jKDMsMyw0LDIpLCBjZXg9MC44KQ0KYm94cGxvdChsb2coQ0xWKX5zdGF0dXMsIENYLCBtYWluPSJDTFYgYnkgR3JvdXBzIikNCg0KYGBgDQo8YnI+PGhyPg0KDQojIyMgNi4g6Kit5a6a6KGM6Yq3562W55Wl44CB6KaP5YqD6KGM6Yq35bel5YW3DQoNCjxicj48aHI+DQoNCiMjIyA3LiDpgbjmk4fooYzpirflsI3osaENCg0K57Wm5a6a5p+Q5LiA6KGM6Yq35bel5YW355qE5oiQ5pys5ZKM6aCQ5pyf5pWI55uK77yM6YG45pOH5Y+v5Lul5pa96KGM6YCZ6aCF5bel5YW355qE5bCN6LGh44CCIA0KDQojIyMjIyA3LjEg5bCNUjLml4/nvqTpgLLooYzkv53nlZkNClIy5peP576k55qE6aCQ5ris5L+d55WZ546H5ZKM6LO86LK36YeR6aGNDQpgYGB7ciBmaWcuaGVpZ2h0PTIuNSwgZmlnLndpZHRoPTh9DQpwYXIobWZyb3c9YygxLDIpLCBtYXI9Yyg0LDMsMywyKSwgY2V4PTAuOCkNCmhpc3QoQ1gkUHJvYlJldGFpbltDWCRzdGF0dXM9PSJSMiJdLG1haW49IlByb2JSZXRhaW4iLHhsYWI9IiIpDQpoaXN0KGxvZyhDWCRQcmVkUmV2ZW51ZVtDWCRzdGF0dXM9PSJSMiJdLDEwKSxtYWluPSJQcmVkUmV2ZW51ZSIseGxhYj0iIikNCmBgYA0KDQpTM+aXj+e+pA0KYGBge3IgZmlnLmhlaWdodD0yLjUsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93PWMoMSwyKSwgbWFyPWMoNCwzLDMsMiksIGNleD0wLjgpDQpoaXN0KENYJFByb2JSZXRhaW5bQ1gkc3RhdHVzPT0iUzMiXSxtYWluPSJQcm9iUmV0YWluIix4bGFiPSIiKQ0KaGlzdChsb2coQ1gkUHJlZFJldmVudWVbQ1gkc3RhdHVzPT0iUzMiXSwxMCksbWFpbj0iUHJlZFJldmVudWUiLHhsYWI9IiIpDQpgYGANCg0KDQoNCiMjIyMjIDcuMiDkvLDoqIjpoJDmnJ/loLHphawNCg0K5Y+v5Lul5L6d5pOa5LmL5YmN5L2/55So6KGM6Yq35bel5YW355qE57aT6amX5L6G5o6o5Ye6ZWZmZWN05ZKMY29zdO+8jA0K6YCZ6KOh5YGH6Kit6KGM6Yq35bel5YW355qE5oiQ5pys5ZKM6aCQ5pyf5pWI55uK54K6DQpgYGB7cn0NCmNvc3QgPSAxMCAgICAgICAgIyDmiJDmnKwNCmVmZmVjdCA9IDAuNzUgICAgIyDmlYjnm4rvvJrkuIvkuIDmnJ/nmoTos7zosrfmqZ/njocNCmBgYA0KDQrkvLDoqIjpgJnpoIXooYzpirflt6XlhbflsI3mr4/kuIDkvY1SMumhp+WuoueahOmgkOacn+WgsemFrA0KYGBge3J9DQpUYXJnZXQgPSBzdWJzZXQoQ1gsIHN0YXR1cz09IlIyIikNClRhcmdldCRFeHBSZXR1cm4gPSAoZWZmZWN0IC0gVGFyZ2V0JFByb2JSZXRhaW4pICogVGFyZ2V0JFByZWRSZXZlbnVlIC0gY29zdA0Kc3VtbWFyeShUYXJnZXQkRXhwUmV0dXJuKQ0KYGBgDQrpgJnkuIDpoIXlt6XlhbflsI1SMumhp+WuoueahOmgkOacn+WgsemFrOaYr+iyoOeahA0KDQrpgJnpoIXlt6XlhbflsI3mlrxSZXRhaW7lpKfmlrwwLjc155qE5Lq65YW25a+m5rKS55Sa6bq855SoDQrku5blgJHnrpflh7rkvobnmoRFeHBSZXR1cm7mnIPmmK/osqDnmoQNCg0KIyMjIyMgNy4zIOmBuOaTh+ihjOmKt+WwjeixoQ0KDQrkvYbmmK/vvIzmiJHlgJHpgoTmmK/lj6/ku6XmjJHlh7roqLHlpJrpoJDmnJ/loLHphazlvojlpKfnmoTooYzpirflsI3osaENCmBgYHtyfQ0KVGFyZ2V0ICU+JSBhcnJhbmdlKGRlc2MoRXhwUmV0dXJuKSkgJT4lIHNlbGVjdChjaWQsIEV4cFJldHVybikgJT4lIGhlYWQoMTUpDQpgYGANCg0K5om+5Ye66aCQ5pyf5aCx5YSf54K65q2j55qE6aGn5a6iDQrlj6/ku6XlsI3ku5blgJHlr6bmlr3pgJnpoIXooYzpirflt6XlhbcNCg0KYGBge3J9DQpzdW0oVGFyZ2V0JEV4cFJldHVybiA+IDApICAgICAgICAgICAgICAgICAjIOWPr+WvpuaWveWwjeixoe+8mjI1OA0KYGBgDQrlnKhSMuS5i+S4re+8jOaciTI1OOS6uueahOmgkOacn+WgsemFrOWkp+aWvOmbtu+8jOWmguaenOWwjemAmTI1OOS6uuS9v+eUqOmAmemgheW3peWFt++8jOaIkeWAkeeahOacn+acm+WgsemFrOaYr++8mg0KYGBge3J9DQpzdW0oVGFyZ2V0JEV4cFJldHVybltUYXJnZXQkRXhwUmV0dXJuID4gMF0pICAgIyDpoJDmnJ/loLHphazvvJo2NDY0DQpgYGANCg0KIyMjIyMgUVVJWjoNCuaIkeWAkeWPr+S7peeul+WHuuWwjeaJgOacieeahOaXj+e+pOWvpuaWvemAmemgheW3peWFt+eahOacn+acm+WgsemFrCAuLi4NCmBgYHtyfQ0KVGFyZ2V0ID0gQ1gNClRhcmdldCRFeHBSZXR1cm4gPSAoZWZmZWN0IC0gVGFyZ2V0JFByb2JSZXRhaW4pICogVGFyZ2V0JFByZWRSZXZlbnVlIC0gY29zdA0KZmlsdGVyKFRhcmdldCwgVGFyZ2V0JEV4cFJldHVybiA+IDApICU+JQ0KICBncm91cF9ieShzdGF0dXMpICU+JSBzdW1tYXJpc2UoDQogICAgTm8uVGFyZ2V0ID0gbigpLA0KICAgIEF2Z1JPSSA9IG1lYW4oRXhwUmV0dXJuKSwNCiAgICBUb3RhbFJPSSA9IHN1bShFeHBSZXR1cm4pICkgJT4lIGRhdGEuZnJhbWUNCmBgYA0K6YCZ5YCL57WQ5p6c5piv5ZCI55CG55qE5ZeO77yfIOS9oOaDs+imgeaAjum6vOS/ruato+mAmemgheWIhuaekOeahOeoi+W6j+WRou+8nw0KDQorIOWboOeCuuavj+WAi+e+pOeul+WHuuS+hueahHByb2JSZXRhaW7kuI3kuIDmqKPvvIzogIzkuJTlkIzkuIDlpZfooYzpirflt6Xlhbfmh4nnlKjliLDkuI3lkIzml4/nvqTnmoTpoaflrqLnlKLnlJ/lh7rkvobnmoRjb3N05ZKMZWZmZWN05Lmf5LiN5LiA5qij77yM5omA5Lul54Sh5rOV55u05o6l55So55u45ZCM55qE566X5rOV5aWX6YGL5Yiw5omA5pyJ5peP576k44CCDQorDQoNCjxicj48YnI+PGhyPg0KDQojIyMgOC4g57WQ6KuWDQoNCuWmguaenOS9oOWPquaciemhp+WuoklE44CB5Lqk5piT5pel5pyf44CB5Lqk5piT6YeR6aGN5LiJ5YCL5qyE5L2N55qE6Kmx77yM5L2g5Y+v5Lul5YGa55qE5YiG5p6Q5YyF5ous77yaDQoNCisg5YWo6auU6aGn5a6i5ZKM5q+P5LiA5YCL6aGn5a6i5YiG576k55qE77yaDQogICAgKyDml4/nvqTlpKflsI/oiIfmiJDplbfotqjli6INCiAgICArIOaXj+e+pOWxrOaAp+WIhuaekO+8muWmguW5s+Wdh0NMVuOAgeW5s+Wdh+eHn+aUtuiyoueNu+OAgeaIkOmVt+eOh+OAgeavm+WIqeeOhyjpnIDopoHmnInmiJDmnKzos4fmlpkp562J562JDQogICAgKyDntYTplpPmtYHph4/lkozlubPlnYfmtYHli5XmqZ/njocNCg0KKyDmr4/kuIDlgIvpoaflrqLnmoTvvJoNCiAgICArIOS/neeVmeeOh+OAgemgkOacn+izvOiyt+mHkemhjeOAgee1gui6q+WDueWAvA0KICAgICsg55uu5YmN5omA5Zyo576k57WE77yM5Lul5Y+K5LiL5LiA5pyf5pyD6L2J5Yiw5YCL576k57WE55qE5qmf546HDQogICAgKyDlpoLmnpzmnInooYzpirflt6XlhbfnmoTkvb/nlKjntIDpjITnmoToqbHvvIzmiJHlgJHkuZ/lj6/ku6XkvLDoqIjmr4/kuIDmqKPooYzpirflt6XlhbfjgIHlsI3mr4/kuIDkvY3poaflrqLnmoTmiJDlip/mqZ/njocNCg0K5LiA6Iis6ICM6KiA77yM6YCZ5LiA5Lqb5YiG5p6Q55qE57WQ5p6c77yM6Laz5aSg6K6T5oiR5YCR5Yi25a6a6aGn5a6i55m85bGV5ZKM6aGn5a6i5L+d55WZ562W55Wl77yb6Iez5pa86aGn5a6i5ZC45pS2562W55Wl77yM5oiR5YCR6YCa5bi46YKE6ZyA6KaB5b6eQ1JN5pKI5Ye66aGn5a6i5YCL5Lq65bGs5oCn6LOH5paZ5omN6IO95YGa5Yiw44CCIA0KDQoNCjxicj48YnI+PGhyPjxicj48YnI+PGJyPg0KDQo8c3R5bGU+DQouY2FwdGlvbiB7DQogIGNvbG9yOiAjNzc3Ow0KICBtYXJnaW4tdG9wOiAxMHB4Ow0KfQ0KcCBjb2RlIHsNCiAgd2hpdGUtc3BhY2U6IGluaGVyaXQ7DQp9DQpwcmUgew0KICB3b3JkLWJyZWFrOiBub3JtYWw7DQogIHdvcmQtd3JhcDogbm9ybWFsOw0KICBsaW5lLWhlaWdodDogMTsNCn0NCnByZSBjb2RlIHsNCiAgd2hpdGUtc3BhY2U6IGluaGVyaXQ7DQp9DQpwLGxpIHsNCiAgZm9udC1mYW1pbHk6ICJUcmVidWNoZXQgTVMiLCAi5b6u6Luf5q2j6buR6auUIiwgIk1pY3Jvc29mdCBKaGVuZ0hlaSI7DQp9DQoNCi5yew0KICBsaW5lLWhlaWdodDogMS4yOw0KfQ0KDQp0aXRsZXsNCiAgY29sb3I6ICNjYzAwMDA7DQogIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgIuW+rui7n+ato+m7kemrlCIsICJNaWNyb3NvZnQgSmhlbmdIZWkiOw0KfQ0KDQpib2R5ew0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KaDEsaDIsaDMsaDQsaDV7DQogIGNvbG9yOiAjMDA4ODAwOw0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KaDN7DQogIGNvbG9yOiAjMDA4ODAwOw0KICBiYWNrZ3JvdW5kOiAjZTZmZmU2Ow0KICBsaW5lLWhlaWdodDogMjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQoNCmg1ew0KICBjb2xvcjogIzAwNjAwMDsNCiAgYmFja2dyb3VuZDogI2Y4ZjhmODsNCiAgbGluZS1oZWlnaHQ6IDEuNTsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQoNCmVtew0KICBjb2xvcjogIzAwMDBjMDsNCiAgYmFja2dyb3VuZDogI2YwZjBmMDsNCiAgfQ0KPC9zdHlsZT4NCg0K