W2 解析データ
W2.1 シミュレーションデータの作成
nA <- 3 # A群の反復数(サンプル数)
nB <- 3 # B群の反復数(サンプル数)
G <- 10000 # 遺伝子数
PDEG <- 0.5 # DEGの割合
PA <- 0.5 # A群で高発現DEGの割合
FC <- 4 # 発現変動の度合い(倍率変化)
# 必要なパッケージのロードや前処理
library(TCC) # パッケージのロード
PB <- (1 - PA) # B群で高発現DEGの割合はPAが決まれば自動的に定まる
set.seed(1050) # 乱数種の指定
# シミュレーションデータ生成本番
tcc <- simulateReadCounts(Ngene = G, # 遺伝子数指定部分
PDEG = PDEG, # DEGの割合指定部分
DEG.assign = c(PA, PB), # 群ごとの高発現DEGの割合
replicates = c(nA, nB), # 群ごとの反復数
DEG.foldchange = c(FC, FC)) # 群ごとのDEGの倍率変化
truth <- as.numeric(tcc$simulation$trueDEG != 0) # 真のDEGの位置を1、non-DEGの位置を0としたベクトルを作成
Truth <- truth # コピー
Truth[1:(G*PDEG*PA)] <- "DEG_A" # DEG_Aパターンの位置
Truth[(G*PDEG*PA+1):(G*PDEG)] <- "DEG_B" # DEG_Bパターンの位置
Truth[Truth == 0] <- "non-DEG" # non-DEGパターンの位置
data <- tcc$count # カウント情報
data.cl <- tcc$group$group # 群ラベル情報
plotFCPseudocolor(tcc) # シミュレーション条件のpseudo-colorイメージを描画

# 出力
colnames(data) <- c(paste("A", 1:nA, sep=""), paste("B", 1:nB, sep=""))
tmp <- cbind(rownames(data), data)
out_f <- paste("JSLAB28_data.csv", sep="")
write.csv(tmp, out_f, row.names=F)
W2.2 log比の計算
以下のdataオブジェクトに対応する元データファイルは、JSLAB28_data.csvです。出力ファイルは、JSLAB28_truth.csvです。
x <- data # コピー
cl <- data.cl # コピー
meanA <- apply(x[, cl == 1], 1, FUN = mean) # A群の平均の計算
meanB <- apply(x[, cl == 2], 1, FUN = mean) # B群の平均の計算
logratio <- log2(meanB/meanA) # log比の計算
# パターンごとのlog比の要約統計量
summary(logratio[Truth == "DEG_A"]) # DEG_Aのlog比の要約統計量
Min. 1st Qu. Median Mean 3rd Qu. Max.
-Inf -2.474 -2.015 -1.629 Inf
summary(logratio[Truth == "DEG_B"]) # DEG_Bのlog比の要約統計量
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
-Inf 1.602 2.009 NaN 2.444 Inf 3
summary(logratio[Truth == "non-DEG"]) # non-DEGのlog比の要約統計量
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
-Inf -0.415 0.000 NaN 0.466 Inf 43
# 出力
med_DEG_A <- median(logratio[Truth == "DEG_A"], na.rm = TRUE) # DEG_Aのlog比の中央値
med_DEG_B <- median(logratio[Truth == "DEG_B"], na.rm = TRUE) # DEG_Bのlog比の中央値
med_nonDEG <- median(logratio[Truth == "non-DEG"], na.rm = TRUE)# non-DEGのlog比の中央値
tmp <- NULL
tmp <- rbind(tmp, c("DEG_A", med_DEG_A))
tmp <- rbind(tmp, c("DEG_B", med_DEG_B))
tmp <- rbind(tmp, c("non-DEG", med_nonDEG))
colnames(tmp) <- c("cluster_name", "logratio")
write.csv(tmp, "JSLAB28_truth.csv", row.names=F)
W2.3 MBCluster.Seqの実行
出力ファイルは、図1の右上部分に相当するJSLAB28_res.csv、K =
3~5のクラスタ中心のlog比情報を格納したJSLAB28_K3centers.csv、JSLAB28_K4centers.csv、JSLAB28_K5centers.csvです。
library(MBCluster.Seq) # パッケージのロード
set.seed(1000)
# MBCluster.Seqの実行(K = 3)
K <- 3 # クラスタ数
mbc <- RNASeq.Data(data, Normalizer = NULL,
Treatment = data.cl, GeneID = rownames(data))
c0 <- KmeansPlus.RNASeq(data = mbc, nK = K,
model = "nbinom", print.steps = F)
cls <- Cluster.RNASeq(data = mbc, model = "nbinom",
centers = c0$centers, method = "EM")
cluster <- cls$cluster # オブジェクト名の変更(クラスタ番号情報)
centers <- cls$centers # オブジェクト名の変更(クラスタ中心情報)
# 後処理と結果の大まかな確認
centers # クラスタ中心の発現パターン(log(B群/A群))
table(cluster) # クラスタごとに含まれる遺伝子数
K3 <- str_c("cluster", cluster) # クラスタ番号の左側に文字列"cluster"を連結
K3_centers <- log2(exp(2 * centers[,2])) # クラスタ中心のlog2(B/A)情報
# MBCluster.Seqの実行(K = 4)
K <- 4 # クラスタ数
mbc <- RNASeq.Data(data, Normalizer = NULL,
Treatment = data.cl, GeneID = rownames(data))
c0 <- KmeansPlus.RNASeq(data = mbc, nK = K,
model = "nbinom", print.steps = F)
cls <- Cluster.RNASeq(data = mbc, model = "nbinom",
centers = c0$centers, method = "EM")
cluster <- cls$cluster # オブジェクト名の変更(クラスタ番号情報)
centers <- cls$centers # オブジェクト名の変更(クラスタ中心情報)
# 後処理と結果の大まかな確認
centers # クラスタ中心の発現パターン(log(B群/A群))
table(cluster) # クラスタごとに含まれる遺伝子数
K4 <- str_c("cluster", cluster) # クラスタ番号の左側に文字列"cluster"を連結
K4_centers <- log2(exp(2 * centers[,2])) # クラスタ中心のlog2(B/A)情報
# MBCluster.Seqの実行(K = 5)
K <- 5 # クラスタ数
mbc <- RNASeq.Data(data, Normalizer = NULL,
Treatment = data.cl, GeneID = rownames(data))
c0 <- KmeansPlus.RNASeq(data = mbc, nK = K,
model = "nbinom", print.steps = F)
cls <- Cluster.RNASeq(data = mbc, model = "nbinom",
centers = c0$centers, method = "EM")
cluster <- cls$cluster # オブジェクト名の変更(クラスタ番号情報)
centers <- cls$centers # オブジェクト名の変更(クラスタ中心情報)
# 後処理と結果の大まかな確認
centers # クラスタ中心の発現パターン(log(B群/A群))
table(cluster) # クラスタごとに含まれる遺伝子数
K5 <- str_c("cluster", cluster) # クラスタ番号の左側に文字列"cluster"を連結
K5_centers <- log2(exp(2 * centers[,2])) # クラスタ中心のlog2(B/A)情報
# 出力
Frequency <- rep(1, length(Truth))
tmp <- cbind(rownames(data), Truth, logratio, K3, K4, K5, Frequency)
out_f <- paste("JSLAB28_res.csv", sep="")
write.csv(tmp, out_f, row.names=F)
tmp <- cbind(str_c("cluster", 1:3), K3_centers)
colnames(tmp) <- c("cluster_name", "logratio")
write.csv(tmp, "JSLAB28_K3centers.csv", row.names=F)
tmp <- cbind(str_c("cluster", 1:4), K4_centers)
colnames(tmp) <- c("cluster_name", "logratio")
write.csv(tmp, "JSLAB28_K4centers.csv", row.names=F)
tmp <- cbind(str_c("cluster", 1:5), K5_centers)
colnames(tmp) <- c("cluster_name", "logratio")
write.csv(tmp, "JSLAB28_K5centers.csv", row.names=F)
W2.4 ヒストグラム(図1下部)
入力ファイルは、JSLAB28_res.csvとJSLAB28_truth.csvです。以下のスクリプトは、生成AIの1つであるGeminiに入力ファイルを与えたのち、「JSLAB28_res.csvのTruth列とlogratio列を読み込んで、logratio列のヒストグラムをTruth列のカテゴリごとに色分けしてggplot2で描画するRのスクリプトを教えて。また、JSLAB28_truth.csvを読み込んでヒストグラムの上部に、横軸上がlogratio列の数値の位置に下向き矢印を追加し、さらにそのすぐ上にcluster_name列の文字列とlogratio列の数値情報も小数点以下3桁で示して。」
のような指令(プロンプト)を出して得た結果を簡潔にしたものです。
# データの読み込み
df <- read.csv("JSLAB28_res.csv")
tmp <- read.csv("JSLAB28_truth.csv")
clust_name <- tmp$cluster_name
clust_lr <- tmp$logratio
max_y <- 700
# --- 色の設定 ---
# ヒストグラムで使う "Set1" パレットから、クラスター数(4つ)分の色を抽出
# Set1の順番は、通常 ggplot の fill と一致します
my_pal <- brewer.pal(nrow(tmp), "Set1")
# ヒストグラムの作成
ggplot(df, aes(x = logratio, fill = Truth)) +
geom_histogram(binwidth = 0.1, alpha = 0.6, position = "identity") +
# x軸の範囲を -4 から 4 に指定
coord_cartesian(xlim = c(-4, 4), ylim = c(0, max_y)) +
# クラスタ中心情報の追加
annotate("segment", x = clust_lr, xend = clust_lr, y = max_y * 0.78, yend = max_y * 0.72,
arrow = arrow(length = unit(0.3, "cm")), size = 1, color = my_pal) +
annotate("text", x = clust_lr - 0.10, y = max_y * 0.9, label = clust_name, fontface = "plain", angle = 90, color = my_pal) +
annotate("text", x = clust_lr + 0.12, y = max_y * 0.9, label = sprintf("%.3f", clust_lr), fontface = "plain", angle = 90, color = my_pal) +
theme_minimal() +
scale_fill_brewer(palette = "Set1") +
labs(title = NULL,
x = "log2(B/A)",
y = "頻度",
fill = "パターン") +
# 凡例の位置調整
theme(
legend.position = c(0.99, 0.99), # 右上(x=0.95, y=0.95)に配置
legend.justification = c("right", "top"), # 凡例の右上角を基準点にする
legend.background = element_rect(fill = "white", color = "black", linewidth = 0.3) # 凡例に枠線を付与
)

W4 クラスタごとのヒストグラム
W4.1 K = 3
W2.4のスクリプトをベースとして入力ファイルを変更しただけです。入力ファイルは、W2.3実行結果として得たJSLAB28_res.csvとJSLAB28_K3centers.csvです。
# データの読み込み
df <- read.csv("JSLAB28_res.csv")
tmp <- read.csv("JSLAB28_K3centers.csv")
clust_name <- tmp$cluster_name
clust_lr <- tmp$logratio
max_y <- 700
# --- 色の設定 ---
# ヒストグラムで使う "Set1" パレットから、クラスター数(4つ)分の色を抽出
# Set1の順番は、通常 ggplot の fill と一致します
my_pal <- brewer.pal(nrow(tmp), "Set1")
# ヒストグラムの作成
ggplot(df, aes(x = logratio, fill = K3)) +
geom_histogram(binwidth = 0.1, alpha = 0.6, position = "identity") +
# x軸の範囲を -4 から 4 に指定
coord_cartesian(xlim = c(-4, 4), ylim = c(0, max_y)) +
# クラスタ中心情報の追加
annotate("segment", x = clust_lr, xend = clust_lr, y = max_y * 0.82, yend = max_y * 0.77,
arrow = arrow(length = unit(0.3, "cm")), size = 1, color = my_pal) +
annotate("text", x = clust_lr - 0.10, y = max_y * 0.93, label = clust_name, fontface = "plain", angle = 90, color = my_pal) +
annotate("text", x = clust_lr + 0.10, y = max_y * 0.93, label = sprintf("%.3f", clust_lr), fontface = "plain", angle = 90, color = my_pal) +
theme_minimal() +
scale_fill_brewer(palette = "Set1") +
labs(title = NULL,
x = "log2(B/A)",
y = "頻度",
fill = "クラスタ") +
# 凡例の位置調整
theme(
legend.position = c(0.99, 0.99), # 右上(x=0.95, y=0.95)に配置
legend.justification = c("right", "top"), # 凡例の右上角を基準点にする
legend.background = element_rect(fill = "white", color = "black", linewidth = 0.3) # 凡例に枠線を付与
)

W4.2 K = 4
入力ファイルは、W2.3実行結果として得たJSLAB28_res.csvとJSLAB28_K4centers.csvです。
# データの読み込み
df <- read.csv("JSLAB28_res.csv")
tmp <- read.csv("JSLAB28_K4centers.csv")
clust_name <- tmp$cluster_name
clust_lr <- tmp$logratio
max_y <- 700
# --- 色の設定 ---
# ヒストグラムで使う "Set1" パレットから、クラスター数(4つ)分の色を抽出
# Set1の順番は、通常 ggplot の fill と一致します
my_pal <- brewer.pal(nrow(tmp), "Set1")
# ヒストグラムの作成
ggplot(df, aes(x = logratio, fill = K4)) +
geom_histogram(binwidth = 0.1, alpha = 0.6, position = "identity") +
# x軸の範囲を -4 から 4 に指定
coord_cartesian(xlim = c(-4, 4), ylim = c(0, max_y)) +
# クラスタ中心情報の追加
annotate("segment", x = clust_lr, xend = clust_lr, y = max_y * 0.82, yend = max_y * 0.77,
arrow = arrow(length = unit(0.3, "cm")), size = 1, color = my_pal) +
annotate("text", x = clust_lr - 0.10, y = max_y * 0.93, label = clust_name, fontface = "plain", angle = 90, color = my_pal) +
annotate("text", x = clust_lr + 0.10, y = max_y * 0.93, label = sprintf("%.3f", clust_lr), fontface = "plain", angle = 90, color = my_pal) +
theme_minimal() +
scale_fill_brewer(palette = "Set1") +
labs(title = NULL,
x = "log2(B/A)",
y = "頻度",
fill = "クラスタ") +
# 凡例の位置調整
theme(
legend.position = c(0.99, 0.99), # 右上(x=0.95, y=0.95)に配置
legend.justification = c("right", "top"), # 凡例の右上角を基準点にする
legend.background = element_rect(fill = "white", color = "black", linewidth = 0.3) # 凡例に枠線を付与
)

W4.3 K = 5
入力ファイルは、W2.3実行結果として得たJSLAB28_res.csvとJSLAB28_K5centers.csvです。
# データの読み込み
df <- read.csv("JSLAB28_res.csv")
tmp <- read.csv("JSLAB28_K5centers.csv")
clust_name <- tmp$cluster_name
clust_lr <- tmp$logratio
max_y <- 700
# --- 色の設定 ---
# ヒストグラムで使う "Set1" パレットから、クラスター数(4つ)分の色を抽出
# Set1の順番は、通常 ggplot の fill と一致します
my_pal <- brewer.pal(nrow(tmp), "Set1")
# ヒストグラムの作成
ggplot(df, aes(x = logratio, fill = K5)) +
geom_histogram(binwidth = 0.1, alpha = 0.6, position = "identity") +
# x軸の範囲を -4 から 4 に指定
coord_cartesian(xlim = c(-4, 4), ylim = c(0, max_y)) +
# クラスタ中心情報の追加
annotate("segment", x = clust_lr, xend = clust_lr, y = max_y * 0.82, yend = max_y * 0.77,
arrow = arrow(length = unit(0.3, "cm")), size = 1, color = my_pal) +
annotate("text", x = clust_lr - 0.10, y = max_y * 0.93, label = clust_name, fontface = "plain", angle = 90, color = my_pal) +
annotate("text", x = clust_lr + 0.10, y = max_y * 0.93, label = sprintf("%.3f", clust_lr), fontface = "plain", angle = 90, color = my_pal) +
theme_minimal() +
scale_fill_brewer(palette = "Set1") +
labs(title = NULL,
x = "log2(B/A)",
y = "頻度",
fill = "クラスタ") +
# 凡例の位置調整
theme(
legend.position = c(0.99, 0.99), # 右上(x=0.95, y=0.95)に配置
legend.justification = c("right", "top"), # 凡例の右上角を基準点にする
legend.background = element_rect(fill = "white", color = "black", linewidth = 0.3) # 凡例に枠線を付与
)

W4.4 log比が-1から1の範囲の状況
以下で定義する関数は、生成AIの1つであるGeminiにJSLAB28_res.csvを与えたのち、「このファイルを読み込んで、logratio列が-1から1の範囲にある行を抜き出し、K3,
K4,
K5列に対してRのtable関数を実行するスクリプトを教えて。」という指令(プロンプト)を出して得た結果を簡潔にしたものです。いずれの列においても、条件を満たす計4273遺伝子中4271個がcluster3に割り当てられていることが分かります。
# 1. ファイルの読み込み
# CSVの1列目が遺伝子名(行名)のようなので row.names = 1 を指定しています
data <- read.csv("JSLAB28_res.csv", row.names = 1)
# 2. logratioが -1 から 1 の範囲にある行を抽出
# ※ Inf や -Inf を除外するために有限値判定を入れるのが一般的です
filtered_data <- subset(data, logratio >= -1 & logratio <= 1)
# 3. K3, K4, K5列に対して table 関数を実行
lapply(filtered_data[, c("K3", "K4", "K5")], table)
$K3
cluster1 cluster2 cluster3
1 1 4271
$K4
cluster1 cluster2 cluster3
1 1 4271
$K5
cluster2 cluster3 cluster5
1 4271 1
W5 サンキー図
W5.1 昇順(図4a)
入力ファイルはJSLAB28_res.csvです。
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "ascending" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupはnode列、fillはstage列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W5.2 降順(図4b)
入力ファイルはJSLAB28_res.csvです。
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "descending" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W5.3 クロス集計表
サンキー図中のK3とK4、およびK4とK5間のクロス集計表を得るためのスクリプトです。
入力ファイルはJSLAB28_res.csv、出力ファイルはJSLAB28_K3_K4.csvとJSLAB28_K4_K5.csvです。
in_f <- "JSLAB28_res.csv" # 入力ファイル名
# K3とK4間のクロス集計表
hoge <- table(df$K3, df$K4) # K3列とK4列のクロス集計表
Total <- colSums(hoge) # 列ごとのトータル情報の取得
hoge <- rbind(hoge, Total) # トータル情報を最下行で連結
Total <- rowSums(hoge) # 行ごとのトータル情報の取得
hoge <- cbind(hoge, Total) # トータル情報を最右列で連結
tmp <- cbind(rownames(hoge), hoge) # 行名情報を追加
write.csv(tmp, "JSLAB28_K3_K4.csv", row.names=F) # ファイル出力
# K4とK5間のクロス集計表
hoge <- table(df$K4, df$K5) # K4列とK5列のクロス集計表
Total <- colSums(hoge) # 列ごとのトータル情報の取得
hoge <- rbind(hoge, Total) # トータル情報を最下行で連結
Total <- rowSums(hoge) # 行ごとのトータル情報の取得
hoge <- cbind(hoge, Total) # トータル情報を最右列で連結
tmp <- cbind(rownames(hoge), hoge) # 行名情報を追加
write.csv(tmp, "JSLAB28_K4_K5.csv", row.names=F) # ファイル出力
W5.4 出現順(図5a)
入力ファイルはJSLAB28_res.csvです。
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "as_is" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W5.5 ファイルの冒頭部分を表示
入力ファイル(JSLAB28_res.csv)を読み込んで、最初の15行分を表示させているだけです。
in_f <- "JSLAB28_res.csv" # 入力ファイル名
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 最初の15行分を表示
head(data, n = 15) # head関数の実行
# A tibble: 15 × 7
...1 Truth logratio K3 K4 K5 Frequency
<chr> <chr> <dbl> <chr> <chr> <chr> <dbl>
1 gene_1 DEG_A -2.03 cluster1 cluster2 cluster5 1
2 gene_2 DEG_A -2.27 cluster1 cluster4 cluster1 1
3 gene_3 DEG_A -1.68 cluster1 cluster2 cluster5 1
4 gene_4 DEG_A -3 cluster1 cluster3 cluster3 1
5 gene_5 DEG_A -2.89 cluster1 cluster4 cluster1 1
6 gene_6 DEG_A -2.50 cluster1 cluster2 cluster5 1
7 gene_7 DEG_A -2.18 cluster1 cluster2 cluster5 1
8 gene_8 DEG_A -4.94 cluster1 cluster4 cluster1 1
9 gene_9 DEG_A -2.58 cluster1 cluster4 cluster1 1
10 gene_10 DEG_A -1.90 cluster1 cluster2 cluster5 1
11 gene_11 DEG_A -0.499 cluster3 cluster3 cluster3 1
12 gene_12 DEG_A -2.37 cluster1 cluster2 cluster5 1
13 gene_13 DEG_A -0.542 cluster3 cluster3 cluster3 1
14 gene_14 DEG_A -3.21 cluster1 cluster4 cluster1 1
15 gene_15 DEG_A -3.17 cluster1 cluster2 cluster5 1
W5.6 出現順(図5b)
入力ファイルをはJSLAB28_res.csvから、JSLAB28_res2.csvに変えただけです。これは、Truth列が最初にDEG_Bとなるgene_2501の行をヘッダー行とgene_1の間に移動させただけです。
in_f <- "JSLAB28_res2.csv" # 入力ファイル名
param_order <- "as_is" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6 サンキー図の不具合例
W6.1 出現順(縦5×横5インチ;図6a)
入力ファイルはJSLAB28_res.csvです。基本的にW5.4と同じですが、最終の作図段階において、横幅と縦幅をともに5インチしています。htmlを見る限りでは、W5.4(図5a)のスクリプトと同一ですが、このhtml作成時に利用しているRmdファイルの中にRチャンクオプションとして「fig.width=5,
fig.height=5」が追加されています。
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "as_is" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.2 出現順(縦5×横5インチ;図6b)
入力ファイルは、JSLAB28_res2.csvです。基本的にW5.6と同じですが、最終の作図段階において、横幅と縦幅をともに5インチしています。htmlを見る限りでは、W5.6(図5b)のスクリプトと同一ですが、このhtml作成時に利用しているRmdファイルの中にRチャンクオプションとして「fig.width=5,
fig.height=5」が追加されています。
in_f <- "JSLAB28_res2.csv" # 入力ファイル名
param_order <- "as_is" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.3 出現順(縦8×横8インチ)
入力ファイルはJSLAB28_res.csvです。基本的にW6.1と同じですが、最終の作図段階において、横幅と縦幅をともに8インチしています。htmlを見る限りでは、W6.1(図6a)のスクリプトと同一ですが、このhtml作成時に利用しているRmdファイルの中にRチャンクオプションとして「fig.width=8,
fig.height=8」が追加されています。
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "as_is" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.4 出現順(縦8×横8インチ)
入力ファイルは、JSLAB28_res2.csvです。基本的にW6.2と同じですが、最終の作図段階において、横幅と縦幅をともに8インチしています。htmlを見る限りでは、W6.2(図6b)のスクリプトと同一ですが、このhtml作成時に利用しているRmdファイルの中にRチャンクオプションとして「fig.width=8,
fig.height=8」が追加されています。
in_f <- "JSLAB28_res2.csv" # 入力ファイル名
param_order <- "as_is" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.5 昇順(縦5×横5インチ)
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "ascending" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.6 昇順(縦8×横8インチ)
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "ascending" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.7 降順(縦5×横5インチ)
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "descending" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.8 降順(縦8×横8インチ)
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "descending" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.9 出現順(縦5×横7インチ)
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "as_is" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.10 昇順(縦7×横5インチ)
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "ascending" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

W6.11 昇順(縦9×横5インチ)
in_f <- "JSLAB28_res.csv" # 入力ファイル名
param_order <- "ascending" # ノードの並び(デフォルトは"ascending")
# 必要なパッケージをロード
library(tidyverse) # パッケージの読込
library(ggsankeyfier) # パッケージの読込
# 入力ファイルの読み込み
data <- read_csv(in_f) # in_fで指定したファイルの読込
# 前処理(描画させたい列情報の抽出とlong型への変換
matome <- pivot_stages_longer( # long型データへの変換
data = data, # 入力はdataオブジェクト
stages_from = c("Truth", "K3", "K4", "K5"), # 描画させたいカテゴリ名情報
values_from = "Frequency") # 頻度をカウントしたい列名情報
# 作図1(サンキー図の基本形まで作成した結果をgに格納)
pos <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order) # ノード名情報描画時の位置情報(ノードの並び)
g <- ggplot(data = matome, # ggplot関数実行結果をgに格納。入力はmatomeオブジェクト
mapping = aes(x = stage, y = Frequency, # matomeのstage列とFreqency列をx軸とy軸として利用
group = node, fill = node, # groupとfillは、matome内のnode列で行う(変更不要)
edge_id = edge_id, # edge_idはmatome内のedge_id列(変更不要)
connector = connector)) + # connectorはmatome内のconnector列(変更不要)
geom_sankeynode(position = pos) + # ノード情報を追加
geom_sankeyedge(position = pos) # エッジ情報を追加
# 作図2-1(ノードに付随する情報を描画する際に利用する微調整用のパラメータ作成)
# y軸の高さは入力ファイルの行数次第なので、nrow(data)の何%程度上下にずらすかという感じの計算をしている
# nudge_xとnudge_yは、x軸とy軸それぞれの方向に少しずらしたい値です(nudgeは小突くという意味)
nudge_val_y <- sum(data$Frequency)*0.020 # y軸上の描画位置をベースラインから上下にずらしたい高さの幅情報
pos1 <- position_sankey(v_space = "auto", # ノード名情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # ノード名情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = nudge_val_y) # ノード名情報描画時の位置情報(y軸情報の位置をnudge_val_y上にずらす)
pos2 <- position_sankey(v_space = "auto", # 頻度情報描画時の位置情報(ノード間の縦幅間隔は自動)
order = param_order, # ノード名情報描画時の位置情報(ノードの並び)
nudge_x = 0.06, # 頻度情報描画時の位置情報(x軸情報の位置を0.06右にずらす)
nudge_y = -nudge_val_y) # 頻度情報描画時の位置情報(y軸情報の位置をnudge_val_y下にずらす)
# 作図2-2(基本形gをベースとして、ノードに付随する情報を追加した結果をg2に格納)
# stat = "sankeynode"は、描画するのがノード情報だという指令
# label = nodeは、描画するのがノード名だという指令
# label = Freqは、描画するのがノードに付随する頻度値だという指令
# position = pos1は、微調整用情報としてpos1を利用せよという指令
# position = pos2は、微調整用情報としてpos2を利用せよという指令
# hjust = 0は、文字を左揃えで描画せよという指令(デフォルトは中央揃え)
# size = 4は、サイズ4にせよという指令(この値に応じてnudge_yも適宜調整する)
g2 <- g +
geom_text(aes(label = node), stat = "sankeynode", position = pos1, hjust = 0, size = 4) +
geom_text(aes(label = Frequency), stat = "sankeynode", position = pos2, hjust = 0, size = 4)
# 作図3(g2をベースとして、背景や凡例などを消すなどの調整を行った結果をg3に格納)
g3 <- g2 + theme_minimal() + # 背景を白に変更
theme(panel.grid = element_blank(), # グリッド線を消す
legend.position = 'none', # 凡例を消す
axis.title = element_blank(), # 軸のタイトルを消す
axis.text.y = element_blank(), # y軸のメモリ表示を消す
axis.text.x = element_text(size = 15)) # x軸(カテゴリ名)はサイズ15にせよ
g3

LS0tDQp0aXRsZTogIlvnrKwyOOWbnl0oaHR0cHM6Ly93d3cuaXUuYS51LXRva3lvLmFjLmpwL2thZG90YS9yX3NlcTIuaHRtbCNib29rX0pTTEFCXzI4KeOBruOCpuOCp+ODluizh+aWmSINCmRhdGU6ICfmnIDntYLmm7TmlrA6IGByIGZvcm1hdChTeXMuRGF0ZSgpLCAiJVkvJW0vJWQiKWAnDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCi0tLQ0KYGBge3Iga2xpcHB5LCBlY2hvPUZBTFNFLCBpbmNsdWRlPVRSVUV9DQprbGlwcHk6OmtsaXBweSgpDQpgYGANCg0KIyBXMSDjga/jgZjjgoHjgasNCiMjIFcxLjEg44OR44OD44Kx44O844K444Gu44Kk44Oz44K544OI44O844OrDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgZXZhbD1GQUxTRSwgY29tbWVudD0iIn0NCmlmICghcmVxdWlyZSgiQmlvY01hbmFnZXIiLCBxdWlldGx5ID0gVFJVRSkpICAgICAjIEJpb2NNYW5hZ2Vy44OR44OD44Kx44O844K444GM44Kk44Oz44K544OI44O844Or44GV44KM44Gm44Gq44GR44KM44GwLi4uDQogICAgaW5zdGFsbC5wYWNrYWdlcygiQmlvY01hbmFnZXIiKSAgICAgICAgICAgICAgIyBCaW9jTWFuYWdlcuOCkuOCpOODs+OCueODiOODvOODq+OBm+OCiA0KQmlvY01hbmFnZXI6Omluc3RhbGwoIlRDQyIsIHVwZGF0ZT1GKSAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu44Kk44Oz44K544OI44O844OrDQpCaW9jTWFuYWdlcjo6aW5zdGFsbCgidGlkeXZlcnNlIiwgdXBkYXRlPUYpICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7jgqTjg7Pjgrnjg4jjg7zjg6sNCkJpb2NNYW5hZ2VyOjppbnN0YWxsKCJnZ3NhbmtleWZpZXIiLCB1cGRhdGU9RikgICAjIOODkeODg+OCseODvOOCuOOBruOCpOODs+OCueODiOODvOODqw0KaW5zdGFsbC5wYWNrYWdlcygiaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvc3JjL2NvbnRyaWIvQXJjaGl2ZS9NQkNsdXN0ZXIuU2VxL01CQ2x1c3Rlci5TZXFfMS4wLnRhci5neiIsIHJlcG9zPU5VTEwsIHR5cGU9InNvdXJjZSIpICAjIOODkeODg+OCseODvOOCuOOBruOCpOODs+OCueODiOODvOODqw0KYGBgDQoNCiMjIFcxLjIg44OR44OD44Kx44O844K444Gu44Ot44O844OJDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgY29tbWVudD0iIn0NCg0KbGlicmFyeShUQ0MpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu44Ot44O844OJDQpsaWJyYXJ5KE1CQ2x1c3Rlci5TZXEpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7jg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruODreODvOODiQ0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu44Ot44O844OJDQpsaWJyYXJ5KHN0cmluZ3IpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7jg63jg7zjg4kNCmxpYnJhcnkoZHBseXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruODreODvOODiQ0KbGlicmFyeShnZ3Bsb3QyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu44Ot44O844OJDQpsaWJyYXJ5KHJlc2hhcGUyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7jg63jg7zjg4kNCmxpYnJhcnkoUkNvbG9yQnJld2VyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruODreODvOODiQ0KYGBgDQoNCiMgVzIg6Kej5p6Q44OH44O844K/DQoNCiMjIFcyLjEgIOOCt+ODn+ODpeODrOODvOOCt+ODp+ODs+ODh+ODvOOCv+OBruS9nOaIkA0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGNvbW1lbnQ9IiIsIGZpZy53aWR0aD01fQ0KbkEgPC0gMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQee+pOOBruWPjeW+qeaVsO+8iOOCteODs+ODl+ODq+aVsO+8iQ0KbkIgPC0gMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQue+pOOBruWPjeW+qeaVsO+8iOOCteODs+ODl+ODq+aVsO+8iQ0KRyA8LSAxMDAwMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg6YG65Lyd5a2Q5pWwDQpQREVHIDwtIDAuNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBERUfjga7libLlkIgNClBBIDwtIDAuNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEHnvqTjgafpq5jnmbrnj75ERUfjga7libLlkIgNCkZDIDwtIDQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOeZuuePvuWkieWLleOBruW6puWQiOOBhO+8iOWAjeeOh+WkieWMlu+8iQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOBruODreODvOODieOChOWJjeWHpueQhg0KbGlicmFyeShUQ0MpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu44Ot44O844OJDQpQQiA8LSAoMSAtIFBBKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBC576k44Gn6auY55m654++REVH44Gu5Ymy5ZCI44GvUEHjgYzmsbrjgb7jgozjgbDoh6rli5XnmoTjgavlrprjgb7jgosNCnNldC5zZWVkKDEwNTApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOS5seaVsOeoruOBruaMh+Wumg0KDQojIOOCt+ODn+ODpeODrOODvOOCt+ODp+ODs+ODh+ODvOOCv+eUn+aIkOacrOeVqg0KdGNjIDwtIHNpbXVsYXRlUmVhZENvdW50cyhOZ2VuZSA9IEcsICAgICAgICAgICAgICMg6YG65Lyd5a2Q5pWw5oyH5a6a6YOo5YiGDQogICAgICAgICAgICAgUERFRyA9IFBERUcsICAgICAgICAgICAgICAgICAgICAgICAgIyBERUfjga7libLlkIjmjIflrprpg6jliIYNCiAgICAgICAgICAgICBERUcuYXNzaWduID0gYyhQQSwgUEIpLCAgICAgICAgICAgICAjIOe+pOOBlOOBqOOBrumrmOeZuuePvkRFR+OBruWJsuWQiA0KICAgICAgICAgICAgIHJlcGxpY2F0ZXMgPSBjKG5BLCBuQiksICAgICAgICAgICAgICMg576k44GU44Go44Gu5Y+N5b6p5pWwDQogICAgICAgICAgICAgREVHLmZvbGRjaGFuZ2UgPSBjKEZDLCBGQykpICAgICAgICAgIyDnvqTjgZTjgajjga5ERUfjga7lgI3njoflpInljJYNCg0KdHJ1dGggPC0gYXMubnVtZXJpYyh0Y2Mkc2ltdWxhdGlvbiR0cnVlREVHICE9IDApICMg55yf44GuREVH44Gu5L2N572u44KSMeOAgW5vbi1ERUfjga7kvY3nva7jgpIw44Go44GX44Gf44OZ44Kv44OI44Or44KS5L2c5oiQDQpUcnV0aCA8LSB0cnV0aCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjgrPjg5Tjg7wNClRydXRoWzE6KEcqUERFRypQQSldIDwtICJERUdfQSIgICAgICAgICAgICAgICAgICAjIERFR19B44OR44K/44O844Oz44Gu5L2N572uDQpUcnV0aFsoRypQREVHKlBBKzEpOihHKlBERUcpXSA8LSAiREVHX0IiICAgICAgICAgIyBERUdfQuODkeOCv+ODvOODs+OBruS9jee9rg0KVHJ1dGhbVHJ1dGggPT0gMF0gPC0gIm5vbi1ERUciICAgICAgICAgICAgICAgICAgICMgbm9uLURFR+ODkeOCv+ODvOODs+OBruS9jee9rg0KZGF0YSA8LSB0Y2MkY291bnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44Kr44Km44Oz44OI5oOF5aCxDQpkYXRhLmNsIDwtIHRjYyRncm91cCRncm91cCAgICAgICAgICAgICAgICAgICAgICAgIyDnvqTjg6njg5njg6vmg4XloLENCnBsb3RGQ1BzZXVkb2NvbG9yKHRjYykgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCt+ODn+ODpeODrOODvOOCt+ODp+ODs+adoeS7tuOBrnBzZXVkby1jb2xvcuOCpOODoeODvOOCuOOCkuaPj+eUuw0KDQojIOWHuuWKmw0KY29sbmFtZXMoZGF0YSkgPC0gYyhwYXN0ZSgiQSIsIDE6bkEsIHNlcD0iIiksIHBhc3RlKCJCIiwgMTpuQiwgc2VwPSIiKSkNCnRtcCA8LSBjYmluZChyb3duYW1lcyhkYXRhKSwgZGF0YSkNCm91dF9mIDwtIHBhc3RlKCJKU0xBQjI4X2RhdGEuY3N2Iiwgc2VwPSIiKQ0Kd3JpdGUuY3N2KHRtcCwgb3V0X2YsIHJvdy5uYW1lcz1GKQ0KYGBgDQoNCiMjIFcyLjIgbG9n5q+U44Gu6KiI566XDQrku6XkuIvjga5gZGF0YWDjgqrjg5bjgrjjgqfjgq/jg4jjgavlr77lv5zjgZnjgovlhYPjg4fjg7zjgr/jg5XjgqHjgqTjg6vjga/jgIFbSlNMQUIyOF9kYXRhLmNzdl0oSlNMQUIyOF9kYXRhLmNzdinjgafjgZnjgILlh7rlipvjg5XjgqHjgqTjg6vjga/jgIFbSlNMQUIyOF90cnV0aC5jc3ZdKEpTTEFCMjhfdHJ1dGguY3N2KeOBp+OBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGNvbW1lbnQ9IiIsIGZpZy53aWR0aD01fQ0KeCA8LSBkYXRhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44Kz44OU44O8DQpjbCA8LSBkYXRhLmNsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjgrPjg5Tjg7wNCm1lYW5BIDwtIGFwcGx5KHhbLCBjbCA9PSAxXSwgMSwgRlVOID0gbWVhbikgICAgICAjIEHnvqTjga7lubPlnYfjga7oqIjnrpcNCm1lYW5CIDwtIGFwcGx5KHhbLCBjbCA9PSAyXSwgMSwgRlVOID0gbWVhbikgICAgICAjIELnvqTjga7lubPlnYfjga7oqIjnrpcNCmxvZ3JhdGlvIDwtIGxvZzIobWVhbkIvbWVhbkEpICAgICAgICAgICAgICAgICAgICAjIGxvZ+avlOOBruioiOeulw0KDQojIOODkeOCv+ODvOODs+OBlOOBqOOBrmxvZ+avlOOBruimgee0hOe1seioiOmHjw0Kc3VtbWFyeShsb2dyYXRpb1tUcnV0aCA9PSAiREVHX0EiXSkgICAgICAgICAgICAgICMgREVHX0Hjga5sb2fmr5Tjga7opoHntITntbHoqIjph48NCnN1bW1hcnkobG9ncmF0aW9bVHJ1dGggPT0gIkRFR19CIl0pICAgICAgICAgICAgICAjIERFR19C44GubG9n5q+U44Gu6KaB57SE57Wx6KiI6YePDQpzdW1tYXJ5KGxvZ3JhdGlvW1RydXRoID09ICJub24tREVHIl0pICAgICAgICAgICAgIyBub24tREVH44GubG9n5q+U44Gu6KaB57SE57Wx6KiI6YePDQoNCiMg5Ye65YqbDQptZWRfREVHX0EgPC0gbWVkaWFuKGxvZ3JhdGlvW1RydXRoID09ICJERUdfQSJdLCBuYS5ybSA9IFRSVUUpICMgREVHX0Hjga5sb2fmr5Tjga7kuK3lpK7lgKQNCm1lZF9ERUdfQiA8LSBtZWRpYW4obG9ncmF0aW9bVHJ1dGggPT0gIkRFR19CIl0sIG5hLnJtID0gVFJVRSkgIyBERUdfQuOBrmxvZ+avlOOBruS4reWkruWApA0KbWVkX25vbkRFRyA8LSBtZWRpYW4obG9ncmF0aW9bVHJ1dGggPT0gIm5vbi1ERUciXSwgbmEucm0gPSBUUlVFKSMgbm9uLURFR+OBrmxvZ+avlOOBruS4reWkruWApA0KDQp0bXAgPC0gTlVMTA0KdG1wIDwtIHJiaW5kKHRtcCwgYygiREVHX0EiLCBtZWRfREVHX0EpKQ0KdG1wIDwtIHJiaW5kKHRtcCwgYygiREVHX0IiLCBtZWRfREVHX0IpKQ0KdG1wIDwtIHJiaW5kKHRtcCwgYygibm9uLURFRyIsIG1lZF9ub25ERUcpKQ0KDQpjb2xuYW1lcyh0bXApIDwtIGMoImNsdXN0ZXJfbmFtZSIsICJsb2dyYXRpbyIpDQp3cml0ZS5jc3YodG1wLCAiSlNMQUIyOF90cnV0aC5jc3YiLCByb3cubmFtZXM9RikNCmBgYA0KDQojIyBXMi4zIE1CQ2x1c3Rlci5TZXHjga7lrp/ooYwNCuWHuuWKm+ODleOCoeOCpOODq+OBr+OAgeWbszHjga7lj7PkuIrpg6jliIbjgavnm7jlvZPjgZnjgotbSlNMQUIyOF9yZXMuY3N2XShKU0xBQjI4X3Jlcy5jc3Yp44CBSyA9IDPvvZ4144Gu44Kv44Op44K544K/5Lit5b+D44GubG9n5q+U5oOF5aCx44KS5qC857SN44GX44GfW0pTTEFCMjhfSzNjZW50ZXJzLmNzdl0oSlNMQUIyOF9LM2NlbnRlcnMuY3N2KeOAgVtKU0xBQjI4X0s0Y2VudGVycy5jc3ZdKEpTTEFCMjhfSzRjZW50ZXJzLmNzdinjgIFbSlNMQUIyOF9LNWNlbnRlcnMuY3N2XShKU0xBQjI4X0s1Y2VudGVycy5jc3Yp44Gn44GZ44CCDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgY29tbWVudD0iIiwgZXZhbD1GQUxTRX0NCmxpYnJhcnkoTUJDbHVzdGVyLlNlcSkgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruODreODvOODiQ0Kc2V0LnNlZWQoMTAwMCkNCg0KIyBNQkNsdXN0ZXIuU2Vx44Gu5a6f6KGM77yISyA9IDPvvIkNCksgPC0gMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCr+ODqeOCueOCv+aVsA0KbWJjIDwtIFJOQVNlcS5EYXRhKGRhdGEsIE5vcm1hbGl6ZXIgPSBOVUxMLA0KICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGRhdGEuY2wsIEdlbmVJRCA9IHJvd25hbWVzKGRhdGEpKQ0KYzAgPC0gS21lYW5zUGx1cy5STkFTZXEoZGF0YSA9IG1iYywgbksgPSBLLA0KICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSAibmJpbm9tIiwgcHJpbnQuc3RlcHMgPSBGKQ0KY2xzIDwtIENsdXN0ZXIuUk5BU2VxKGRhdGEgPSBtYmMsIG1vZGVsID0gIm5iaW5vbSIsDQogICAgICAgICAgICAgICAgICAgICAgY2VudGVycyA9IGMwJGNlbnRlcnMsIG1ldGhvZCA9ICJFTSIpDQpjbHVzdGVyIDwtIGNscyRjbHVzdGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjgqrjg5bjgrjjgqfjgq/jg4jlkI3jga7lpInmm7TvvIjjgq/jg6njgrnjgr/nlarlj7fmg4XloLHvvIkNCmNlbnRlcnMgPC0gY2xzJGNlbnRlcnMgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCquODluOCuOOCp+OCr+ODiOWQjeOBruWkieabtO+8iOOCr+ODqeOCueOCv+S4reW/g+aDheWgse+8iQ0KDQojIOW+jOWHpueQhuOBqOe1kOaenOOBruWkp+OBvuOBi+OBqueiuuiqjQ0KY2VudGVycyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44Kv44Op44K544K/5Lit5b+D44Gu55m654++44OR44K/44O844Oz77yIbG9nKELnvqQvQee+pCnvvIkNCnRhYmxlKGNsdXN0ZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCr+ODqeOCueOCv+OBlOOBqOOBq+WQq+OBvuOCjOOCi+mBuuS8neWtkOaVsA0KSzMgPC0gc3RyX2MoImNsdXN0ZXIiLCBjbHVzdGVyKSAgICAgICAgICAgICAgICAgICMg44Kv44Op44K544K/55Wq5Y+344Gu5bem5YG044Gr5paH5a2X5YiXImNsdXN0ZXIi44KS6YCj57WQDQpLM19jZW50ZXJzIDwtIGxvZzIoZXhwKDIgKiBjZW50ZXJzWywyXSkpICAgICAgICAgIyDjgq/jg6njgrnjgr/kuK3lv4Pjga5sb2cyKEIvQSnmg4XloLENCg0KIyBNQkNsdXN0ZXIuU2Vx44Gu5a6f6KGM77yISyA9IDTvvIkNCksgPC0gNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCr+ODqeOCueOCv+aVsA0KbWJjIDwtIFJOQVNlcS5EYXRhKGRhdGEsIE5vcm1hbGl6ZXIgPSBOVUxMLA0KICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGRhdGEuY2wsIEdlbmVJRCA9IHJvd25hbWVzKGRhdGEpKQ0KYzAgPC0gS21lYW5zUGx1cy5STkFTZXEoZGF0YSA9IG1iYywgbksgPSBLLA0KICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSAibmJpbm9tIiwgcHJpbnQuc3RlcHMgPSBGKQ0KY2xzIDwtIENsdXN0ZXIuUk5BU2VxKGRhdGEgPSBtYmMsIG1vZGVsID0gIm5iaW5vbSIsDQogICAgICAgICAgICAgICAgICAgICAgY2VudGVycyA9IGMwJGNlbnRlcnMsIG1ldGhvZCA9ICJFTSIpDQpjbHVzdGVyIDwtIGNscyRjbHVzdGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjgqrjg5bjgrjjgqfjgq/jg4jlkI3jga7lpInmm7TvvIjjgq/jg6njgrnjgr/nlarlj7fmg4XloLHvvIkNCmNlbnRlcnMgPC0gY2xzJGNlbnRlcnMgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCquODluOCuOOCp+OCr+ODiOWQjeOBruWkieabtO+8iOOCr+ODqeOCueOCv+S4reW/g+aDheWgse+8iQ0KDQojIOW+jOWHpueQhuOBqOe1kOaenOOBruWkp+OBvuOBi+OBqueiuuiqjQ0KY2VudGVycyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44Kv44Op44K544K/5Lit5b+D44Gu55m654++44OR44K/44O844Oz77yIbG9nKELnvqQvQee+pCnvvIkNCnRhYmxlKGNsdXN0ZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCr+ODqeOCueOCv+OBlOOBqOOBq+WQq+OBvuOCjOOCi+mBuuS8neWtkOaVsA0KSzQgPC0gc3RyX2MoImNsdXN0ZXIiLCBjbHVzdGVyKSAgICAgICAgICAgICAgICAgICMg44Kv44Op44K544K/55Wq5Y+344Gu5bem5YG044Gr5paH5a2X5YiXImNsdXN0ZXIi44KS6YCj57WQDQpLNF9jZW50ZXJzIDwtIGxvZzIoZXhwKDIgKiBjZW50ZXJzWywyXSkpICAgICAgICAgIyDjgq/jg6njgrnjgr/kuK3lv4Pjga5sb2cyKEIvQSnmg4XloLENCg0KIyBNQkNsdXN0ZXIuU2Vx44Gu5a6f6KGM77yISyA9IDXvvIkNCksgPC0gNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCr+ODqeOCueOCv+aVsA0KbWJjIDwtIFJOQVNlcS5EYXRhKGRhdGEsIE5vcm1hbGl6ZXIgPSBOVUxMLA0KICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGRhdGEuY2wsIEdlbmVJRCA9IHJvd25hbWVzKGRhdGEpKQ0KYzAgPC0gS21lYW5zUGx1cy5STkFTZXEoZGF0YSA9IG1iYywgbksgPSBLLA0KICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSAibmJpbm9tIiwgcHJpbnQuc3RlcHMgPSBGKQ0KY2xzIDwtIENsdXN0ZXIuUk5BU2VxKGRhdGEgPSBtYmMsIG1vZGVsID0gIm5iaW5vbSIsDQogICAgICAgICAgICAgICAgICAgICAgY2VudGVycyA9IGMwJGNlbnRlcnMsIG1ldGhvZCA9ICJFTSIpDQpjbHVzdGVyIDwtIGNscyRjbHVzdGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjgqrjg5bjgrjjgqfjgq/jg4jlkI3jga7lpInmm7TvvIjjgq/jg6njgrnjgr/nlarlj7fmg4XloLHvvIkNCmNlbnRlcnMgPC0gY2xzJGNlbnRlcnMgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCquODluOCuOOCp+OCr+ODiOWQjeOBruWkieabtO+8iOOCr+ODqeOCueOCv+S4reW/g+aDheWgse+8iQ0KDQojIOW+jOWHpueQhuOBqOe1kOaenOOBruWkp+OBvuOBi+OBqueiuuiqjQ0KY2VudGVycyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44Kv44Op44K544K/5Lit5b+D44Gu55m654++44OR44K/44O844Oz77yIbG9nKELnvqQvQee+pCnvvIkNCnRhYmxlKGNsdXN0ZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOOCr+ODqeOCueOCv+OBlOOBqOOBq+WQq+OBvuOCjOOCi+mBuuS8neWtkOaVsA0KSzUgPC0gc3RyX2MoImNsdXN0ZXIiLCBjbHVzdGVyKSAgICAgICAgICAgICAgICAgICMg44Kv44Op44K544K/55Wq5Y+344Gu5bem5YG044Gr5paH5a2X5YiXImNsdXN0ZXIi44KS6YCj57WQDQpLNV9jZW50ZXJzIDwtIGxvZzIoZXhwKDIgKiBjZW50ZXJzWywyXSkpICAgICAgICAgIyDjgq/jg6njgrnjgr/kuK3lv4Pjga5sb2cyKEIvQSnmg4XloLENCg0KIyDlh7rlipsNCkZyZXF1ZW5jeSA8LSByZXAoMSwgbGVuZ3RoKFRydXRoKSkNCnRtcCA8LSBjYmluZChyb3duYW1lcyhkYXRhKSwgVHJ1dGgsIGxvZ3JhdGlvLCBLMywgSzQsIEs1LCBGcmVxdWVuY3kpDQpvdXRfZiA8LSBwYXN0ZSgiSlNMQUIyOF9yZXMuY3N2Iiwgc2VwPSIiKQ0Kd3JpdGUuY3N2KHRtcCwgb3V0X2YsIHJvdy5uYW1lcz1GKQ0KDQp0bXAgPC0gY2JpbmQoc3RyX2MoImNsdXN0ZXIiLCAxOjMpLCBLM19jZW50ZXJzKQ0KY29sbmFtZXModG1wKSA8LSBjKCJjbHVzdGVyX25hbWUiLCAibG9ncmF0aW8iKQ0Kd3JpdGUuY3N2KHRtcCwgIkpTTEFCMjhfSzNjZW50ZXJzLmNzdiIsIHJvdy5uYW1lcz1GKQ0KDQp0bXAgPC0gY2JpbmQoc3RyX2MoImNsdXN0ZXIiLCAxOjQpLCBLNF9jZW50ZXJzKQ0KY29sbmFtZXModG1wKSA8LSBjKCJjbHVzdGVyX25hbWUiLCAibG9ncmF0aW8iKQ0Kd3JpdGUuY3N2KHRtcCwgIkpTTEFCMjhfSzRjZW50ZXJzLmNzdiIsIHJvdy5uYW1lcz1GKQ0KDQp0bXAgPC0gY2JpbmQoc3RyX2MoImNsdXN0ZXIiLCAxOjUpLCBLNV9jZW50ZXJzKQ0KY29sbmFtZXModG1wKSA8LSBjKCJjbHVzdGVyX25hbWUiLCAibG9ncmF0aW8iKQ0Kd3JpdGUuY3N2KHRtcCwgIkpTTEFCMjhfSzVjZW50ZXJzLmNzdiIsIHJvdy5uYW1lcz1GKQ0KYGBgDQoNCiMjIFcyLjQg44OS44K544OI44Kw44Op44Og77yI5ZuzMeS4i+mDqO+8iQ0K5YWl5Yqb44OV44Kh44Kk44Or44Gv44CBW0pTTEFCMjhfcmVzLmNzdl0oSlNMQUIyOF9yZXMuY3N2KeOBqFtKU0xBQjI4X3RydXRoLmNzdl0oSlNMQUIyOF90cnV0aC5jc3Yp44Gn44GZ44CC5Lul5LiL44Gu44K544Kv44Oq44OX44OI44Gv44CB55Sf5oiQQUnjga4x44Gk44Gn44GC44KLW0dlbWluaV0oaHR0cHM6Ly9nZW1pbmkuZ29vZ2xlLmNvbS9hcHAp44Gr5YWl5Yqb44OV44Kh44Kk44Or44KS5LiO44GI44Gf44Gu44Gh44CB44CMPGZvbnQgY29sb3I9Im1hZ2VudGEiPltKU0xBQjI4X3Jlcy5jc3ZdKEpTTEFCMjhfcmVzLmNzdinjga5UcnV0aOWIl+OBqGxvZ3JhdGlv5YiX44KS6Kqt44G/6L6844KT44Gn44CBbG9ncmF0aW/liJfjga7jg5Ljgrnjg4jjgrDjg6njg6DjgpJUcnV0aOWIl+OBruOCq+ODhuOCtOODquOBlOOBqOOBq+iJsuWIhuOBkeOBl+OBpmdncGxvdDLjgafmj4/nlLvjgZnjgotS44Gu44K544Kv44Oq44OX44OI44KS5pWZ44GI44Gm44CC44G+44Gf44CBW0pTTEFCMjhfdHJ1dGguY3N2XShKU0xBQjI4X3RydXRoLmNzdinjgpLoqq3jgb/ovrzjgpPjgafjg5Ljgrnjg4jjgrDjg6njg6Djga7kuIrpg6jjgavjgIHmqKrou7jkuIrjgYxsb2dyYXRpb+WIl+OBruaVsOWApOOBruS9jee9ruOBq+S4i+WQkeOBjeefouWNsOOCkui/veWKoOOBl+OAgeOBleOCieOBq+OBneOBruOBmeOBkOS4iuOBq2NsdXN0ZXJfbmFtZeWIl+OBruaWh+Wtl+WIl+OBqGxvZ3JhdGlv5YiX44Gu5pWw5YCk5oOF5aCx44KC5bCP5pWw54K55Lul5LiLM+ahgeOBp+ekuuOBl+OBpuOAgjwvZm9udD7jgI0NCuOBruOCiOOBhuOBquaMh+S7pO+8iOODl+ODreODs+ODl+ODiO+8ieOCkuWHuuOBl+OBpuW+l+OBn+e1kOaenOOCkuewoea9lOOBq+OBl+OBn+OCguOBruOBp+OBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGNvbW1lbnQ9IiIsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTR9DQojIOODh+ODvOOCv+OBruiqreOBv+i+vOOBvw0KZGYgPC0gcmVhZC5jc3YoIkpTTEFCMjhfcmVzLmNzdiIpDQp0bXAgPC0gcmVhZC5jc3YoIkpTTEFCMjhfdHJ1dGguY3N2IikNCmNsdXN0X25hbWUgPC0gdG1wJGNsdXN0ZXJfbmFtZQ0KY2x1c3RfbHIgPC0gdG1wJGxvZ3JhdGlvDQptYXhfeSA8LSA3MDANCg0KIyAtLS0g6Imy44Gu6Kit5a6aIC0tLQ0KIyDjg5Ljgrnjg4jjgrDjg6njg6Djgafkvb/jgYYgIlNldDEiIOODkeODrOODg+ODiOOBi+OCieOAgeOCr+ODqeOCueOCv+ODvOaVsO+8iDTjgaTvvInliIbjga7oibLjgpLmir3lh7oNCiMgU2V0MeOBrumghueVquOBr+OAgemAmuW4uCBnZ3Bsb3Qg44GuIGZpbGwg44Go5LiA6Ie044GX44G+44GZDQpteV9wYWwgPC0gYnJld2VyLnBhbChucm93KHRtcCksICJTZXQxIikNCg0KIyDjg5Ljgrnjg4jjgrDjg6njg6Djga7kvZzmiJANCmdncGxvdChkZiwgYWVzKHggPSBsb2dyYXRpbywgZmlsbCA9IFRydXRoKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMSwgYWxwaGEgPSAwLjYsIHBvc2l0aW9uID0gImlkZW50aXR5IikgKw0KICAjIHjou7jjga7nr4Tlm7LjgpIgLTQg44GL44KJIDQg44Gr5oyH5a6aDQogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtNCwgNCksIHlsaW0gPSBjKDAsIG1heF95KSkgKw0KICANCiAgIyDjgq/jg6njgrnjgr/kuK3lv4Pmg4XloLHjga7ov73liqANCiAgYW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gY2x1c3RfbHIsIHhlbmQgPSBjbHVzdF9sciwgeSA9IG1heF95ICogMC43OCwgeWVuZCA9IG1heF95ICogMC43MiwNCiAgICAgICAgICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMywgImNtIikpLCBzaXplID0gMSwgY29sb3IgPSBteV9wYWwpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gY2x1c3RfbHIgLSAwLjEwLCB5ID0gbWF4X3kgKiAwLjksIGxhYmVsID0gY2x1c3RfbmFtZSwgZm9udGZhY2UgPSAicGxhaW4iLCBhbmdsZSA9IDkwLCBjb2xvciA9IG15X3BhbCkgKw0KICBhbm5vdGF0ZSgidGV4dCIsIHggPSBjbHVzdF9sciArIDAuMTIsIHkgPSBtYXhfeSAqIDAuOSwgbGFiZWwgPSBzcHJpbnRmKCIlLjNmIiwgY2x1c3RfbHIpLCBmb250ZmFjZSA9ICJwbGFpbiIsIGFuZ2xlID0gOTAsIGNvbG9yID0gbXlfcGFsKSArDQogIA0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArDQogIGxhYnModGl0bGUgPSBOVUxMLA0KICAgICAgIHggPSAibG9nMihCL0EpIiwNCiAgICAgICB5ID0gIumgu+W6piIsDQogICAgICAgZmlsbCA9ICLjg5Hjgr/jg7zjg7MiKSArDQogICMg5Yeh5L6L44Gu5L2N572u6Kq/5pW0DQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45OSwgMC45OSksICAgICAgIyDlj7PkuIooeD0wLjk1LCB5PTAuOTUp44Gr6YWN572uDQogICAgbGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKCJyaWdodCIsICJ0b3AiKSwgIyDlh6Hkvovjga7lj7PkuIrop5LjgpLln7rmupbngrnjgavjgZnjgosNCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjMpICMg5Yeh5L6L44Gr5p6g57ea44KS5LuY5LiODQogICkNCmBgYA0KDQojIFczIOOCr+ODreOCuembhuioiOihqA0K5YWl5Yqb44OV44Kh44Kk44Or44GvW0pTTEFCMjhfcmVzLmNzdl0oSlNMQUIyOF9yZXMuY3N2KeOAgeWHuuWKm+ODleOCoeOCpOODq+OBr1tKU0xBQjI4X0ZpZzJhLmNzdl0oSlNMQUIyOF9GaWcyYS5jc3Yp44GoW0pTTEFCMjhfRmlnMmIuY3N2XShKU0xBQjI4X0ZpZzJiLmNzdinjgahbSlNMQUIyOF9GaWcyYy5jc3ZdKEpTTEFCMjhfRmlnMmMuY3N2KeOBp+OBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFfQ0KaW5fZiA8LSAiSlNMQUIyOF9yZXMuY3N2IiAgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQoNCiMg5ZuzMmHjga7kvZzmiJDvvIhLID0gM+OBp+OBruOCr+ODqeOCueOCv+ODquODs+OCsOe1kOaenOOBruOCr+ODreOCuembhuioiOihqO+8iQ0KaG9nZSA8LSB0YWJsZShkZiRUcnV0aCwgZGYkSzMpICAgICAgICAgICAgICAgICAgICMgVHJ1dGjliJfjgahLM+WIl+OBruOCr+ODreOCuembhuioiOihqA0KVG90YWwgPC0gY29sU3Vtcyhob2dlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICMg5YiX44GU44Go44Gu44OI44O844K/44Or5oOF5aCx44Gu5Y+W5b6XDQpob2dlIDwtIHJiaW5kKGhvZ2UsIFRvdGFsKSAgICAgICAgICAgICAgICAgICAgICAgIyDjg4jjg7zjgr/jg6vmg4XloLHjgpLmnIDkuIvooYzjgafpgKPntZANClRvdGFsIDwtIHJvd1N1bXMoaG9nZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOihjOOBlOOBqOOBruODiOODvOOCv+ODq+aDheWgseOBruWPluW+lw0KaG9nZSA8LSBjYmluZChob2dlLCBUb3RhbCkgICAgICAgICAgICAgICAgICAgICAgICMg44OI44O844K/44Or5oOF5aCx44KS5pyA5Y+z5YiX44Gn6YCj57WQDQp0bXAgPC0gY2JpbmQocm93bmFtZXMoaG9nZSksIGhvZ2UpICAgICAgICAgICAgICAgIyDooYzlkI3mg4XloLHjgpLov73liqANCndyaXRlLmNzdih0bXAsICJKU0xBQjI4X0ZpZzJhLmNzdiIsIHJvdy5uYW1lcz1GKSAjIOODleOCoeOCpOODq+WHuuWKmw0KDQojIOWbszJi44Gu5L2c5oiQ77yISyA9IDTjgafjga7jgq/jg6njgrnjgr/jg6rjg7PjgrDntZDmnpzjga7jgq/jg63jgrnpm4boqIjooajvvIkNCmhvZ2UgPC0gdGFibGUoZGYkVHJ1dGgsIGRmJEs0KSAgICAgICAgICAgICAgICAgICAjIFRydXRo5YiX44GoSzTliJfjga7jgq/jg63jgrnpm4boqIjooagNClRvdGFsIDwtIGNvbFN1bXMoaG9nZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOWIl+OBlOOBqOOBruODiOODvOOCv+ODq+aDheWgseOBruWPluW+lw0KaG9nZSA8LSByYmluZChob2dlLCBUb3RhbCkgICAgICAgICAgICAgICAgICAgICAgICMg44OI44O844K/44Or5oOF5aCx44KS5pyA5LiL6KGM44Gn6YCj57WQDQpUb3RhbCA8LSByb3dTdW1zKGhvZ2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDooYzjgZTjgajjga7jg4jjg7zjgr/jg6vmg4XloLHjga7lj5blvpcNCmhvZ2UgPC0gY2JpbmQoaG9nZSwgVG90YWwpICAgICAgICAgICAgICAgICAgICAgICAjIOODiOODvOOCv+ODq+aDheWgseOCkuacgOWPs+WIl+OBp+mAo+e1kA0KdG1wIDwtIGNiaW5kKHJvd25hbWVzKGhvZ2UpLCBob2dlKSAgICAgICAgICAgICAgICMg6KGM5ZCN5oOF5aCx44KS6L+95YqgDQp3cml0ZS5jc3YodG1wLCAiSlNMQUIyOF9GaWcyYi5jc3YiLCByb3cubmFtZXM9RikgIyDjg5XjgqHjgqTjg6vlh7rlipsNCg0KIyDlm7MyY+OBruS9nOaIkO+8iEsgPSA144Gn44Gu44Kv44Op44K544K/44Oq44Oz44Kw57WQ5p6c44Gu44Kv44Ot44K56ZuG6KiI6KGo77yJDQpob2dlIDwtIHRhYmxlKGRmJFRydXRoLCBkZiRLNSkgICAgICAgICAgICAgICAgICAgIyBUcnV0aOWIl+OBqEs15YiX44Gu44Kv44Ot44K56ZuG6KiI6KGoDQpUb3RhbCA8LSBjb2xTdW1zKGhvZ2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDliJfjgZTjgajjga7jg4jjg7zjgr/jg6vmg4XloLHjga7lj5blvpcNCmhvZ2UgPC0gcmJpbmQoaG9nZSwgVG90YWwpICAgICAgICAgICAgICAgICAgICAgICAjIOODiOODvOOCv+ODq+aDheWgseOCkuacgOS4i+ihjOOBp+mAo+e1kA0KVG90YWwgPC0gcm93U3Vtcyhob2dlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICMg6KGM44GU44Go44Gu44OI44O844K/44Or5oOF5aCx44Gu5Y+W5b6XDQpob2dlIDwtIGNiaW5kKGhvZ2UsIFRvdGFsKSAgICAgICAgICAgICAgICAgICAgICAgIyDjg4jjg7zjgr/jg6vmg4XloLHjgpLmnIDlj7PliJfjgafpgKPntZANCnRtcCA8LSBjYmluZChyb3duYW1lcyhob2dlKSwgaG9nZSkgICAgICAgICAgICAgICAjIOihjOWQjeaDheWgseOCkui/veWKoA0Kd3JpdGUuY3N2KHRtcCwgIkpTTEFCMjhfRmlnMmMuY3N2Iiwgcm93Lm5hbWVzPUYpICMg44OV44Kh44Kk44Or5Ye65YqbDQpgYGANCg0KIyBXNCDjgq/jg6njgrnjgr/jgZTjgajjga7jg5Ljgrnjg4jjgrDjg6njg6ANCg0KIyMgVzQuMSBLID0gMw0KVzIuNOOBruOCueOCr+ODquODl+ODiOOCkuODmeODvOOCueOBqOOBl+OBpuWFpeWKm+ODleOCoeOCpOODq+OCkuWkieabtOOBl+OBn+OBoOOBkeOBp+OBmeOAguWFpeWKm+ODleOCoeOCpOODq+OBr+OAgVcyLjPlrp/ooYzntZDmnpzjgajjgZfjgablvpfjgZ9bSlNMQUIyOF9yZXMuY3N2XShKU0xBQjI4X3Jlcy5jc3Yp44GoW0pTTEFCMjhfSzNjZW50ZXJzLmNzdl0oSlNMQUIyOF9LM2NlbnRlcnMuY3N2KeOBp+OBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGNvbW1lbnQ9IiIsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTMuNX0NCiMg44OH44O844K/44Gu6Kqt44G/6L6844G/DQpkZiA8LSByZWFkLmNzdigiSlNMQUIyOF9yZXMuY3N2IikNCnRtcCA8LSByZWFkLmNzdigiSlNMQUIyOF9LM2NlbnRlcnMuY3N2IikNCmNsdXN0X25hbWUgPC0gdG1wJGNsdXN0ZXJfbmFtZQ0KY2x1c3RfbHIgPC0gdG1wJGxvZ3JhdGlvDQptYXhfeSA8LSA3MDANCg0KIyAtLS0g6Imy44Gu6Kit5a6aIC0tLQ0KIyDjg5Ljgrnjg4jjgrDjg6njg6Djgafkvb/jgYYgIlNldDEiIOODkeODrOODg+ODiOOBi+OCieOAgeOCr+ODqeOCueOCv+ODvOaVsO+8iDTjgaTvvInliIbjga7oibLjgpLmir3lh7oNCiMgU2V0MeOBrumghueVquOBr+OAgemAmuW4uCBnZ3Bsb3Qg44GuIGZpbGwg44Go5LiA6Ie044GX44G+44GZDQpteV9wYWwgPC0gYnJld2VyLnBhbChucm93KHRtcCksICJTZXQxIikNCg0KIyDjg5Ljgrnjg4jjgrDjg6njg6Djga7kvZzmiJANCmdncGxvdChkZiwgYWVzKHggPSBsb2dyYXRpbywgZmlsbCA9IEszKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMSwgYWxwaGEgPSAwLjYsIHBvc2l0aW9uID0gImlkZW50aXR5IikgKw0KICAjIHjou7jjga7nr4Tlm7LjgpIgLTQg44GL44KJIDQg44Gr5oyH5a6aDQogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtNCwgNCksIHlsaW0gPSBjKDAsIG1heF95KSkgKw0KICANCiAgIyDjgq/jg6njgrnjgr/kuK3lv4Pmg4XloLHjga7ov73liqANCiAgYW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gY2x1c3RfbHIsIHhlbmQgPSBjbHVzdF9sciwgeSA9IG1heF95ICogMC44MiwgeWVuZCA9IG1heF95ICogMC43NywNCiAgICAgICAgICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMywgImNtIikpLCBzaXplID0gMSwgY29sb3IgPSBteV9wYWwpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gY2x1c3RfbHIgLSAwLjEwLCB5ID0gbWF4X3kgKiAwLjkzLCBsYWJlbCA9IGNsdXN0X25hbWUsIGZvbnRmYWNlID0gInBsYWluIiwgYW5nbGUgPSA5MCwgY29sb3IgPSBteV9wYWwpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gY2x1c3RfbHIgKyAwLjEwLCB5ID0gbWF4X3kgKiAwLjkzLCBsYWJlbCA9IHNwcmludGYoIiUuM2YiLCBjbHVzdF9sciksIGZvbnRmYWNlID0gInBsYWluIiwgYW5nbGUgPSA5MCwgY29sb3IgPSBteV9wYWwpICsNCiAgDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgbGFicyh0aXRsZSA9IE5VTEwsDQogICAgICAgeCA9ICJsb2cyKEIvQSkiLA0KICAgICAgIHkgPSAi6aC75bqmIiwNCiAgICAgICBmaWxsID0gIuOCr+ODqeOCueOCvyIpICsNCiAgIyDlh6Hkvovjga7kvY3nva7oqr/mlbQNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjk5LCAwLjk5KSwgICAgICAjIOWPs+S4iih4PTAuOTUsIHk9MC45NSnjgavphY3nva4NCiAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoInJpZ2h0IiwgInRvcCIpLCAjIOWHoeS+i+OBruWPs+S4iuinkuOCkuWfuua6lueCueOBq+OBmeOCiw0KICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuMykgIyDlh6HkvovjgavmnqDnt5rjgpLku5jkuI4NCiAgKQ0KYGBgDQoNCiMjIFc0LjIgSyA9IDQNCuWFpeWKm+ODleOCoeOCpOODq+OBr+OAgVcyLjPlrp/ooYzntZDmnpzjgajjgZfjgablvpfjgZ9bSlNMQUIyOF9yZXMuY3N2XShKU0xBQjI4X3Jlcy5jc3Yp44GoW0pTTEFCMjhfSzRjZW50ZXJzLmNzdl0oSlNMQUIyOF9LNGNlbnRlcnMuY3N2KeOBp+OBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGNvbW1lbnQ9IiIsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTMuNX0NCiMg44OH44O844K/44Gu6Kqt44G/6L6844G/DQpkZiA8LSByZWFkLmNzdigiSlNMQUIyOF9yZXMuY3N2IikNCnRtcCA8LSByZWFkLmNzdigiSlNMQUIyOF9LNGNlbnRlcnMuY3N2IikNCmNsdXN0X25hbWUgPC0gdG1wJGNsdXN0ZXJfbmFtZQ0KY2x1c3RfbHIgPC0gdG1wJGxvZ3JhdGlvDQptYXhfeSA8LSA3MDANCg0KIyAtLS0g6Imy44Gu6Kit5a6aIC0tLQ0KIyDjg5Ljgrnjg4jjgrDjg6njg6Djgafkvb/jgYYgIlNldDEiIOODkeODrOODg+ODiOOBi+OCieOAgeOCr+ODqeOCueOCv+ODvOaVsO+8iDTjgaTvvInliIbjga7oibLjgpLmir3lh7oNCiMgU2V0MeOBrumghueVquOBr+OAgemAmuW4uCBnZ3Bsb3Qg44GuIGZpbGwg44Go5LiA6Ie044GX44G+44GZDQpteV9wYWwgPC0gYnJld2VyLnBhbChucm93KHRtcCksICJTZXQxIikNCg0KIyDjg5Ljgrnjg4jjgrDjg6njg6Djga7kvZzmiJANCmdncGxvdChkZiwgYWVzKHggPSBsb2dyYXRpbywgZmlsbCA9IEs0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMSwgYWxwaGEgPSAwLjYsIHBvc2l0aW9uID0gImlkZW50aXR5IikgKw0KICAjIHjou7jjga7nr4Tlm7LjgpIgLTQg44GL44KJIDQg44Gr5oyH5a6aDQogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtNCwgNCksIHlsaW0gPSBjKDAsIG1heF95KSkgKw0KICANCiAgIyDjgq/jg6njgrnjgr/kuK3lv4Pmg4XloLHjga7ov73liqANCiAgYW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gY2x1c3RfbHIsIHhlbmQgPSBjbHVzdF9sciwgeSA9IG1heF95ICogMC44MiwgeWVuZCA9IG1heF95ICogMC43NywNCiAgICAgICAgICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMywgImNtIikpLCBzaXplID0gMSwgY29sb3IgPSBteV9wYWwpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gY2x1c3RfbHIgLSAwLjEwLCB5ID0gbWF4X3kgKiAwLjkzLCBsYWJlbCA9IGNsdXN0X25hbWUsIGZvbnRmYWNlID0gInBsYWluIiwgYW5nbGUgPSA5MCwgY29sb3IgPSBteV9wYWwpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gY2x1c3RfbHIgKyAwLjEwLCB5ID0gbWF4X3kgKiAwLjkzLCBsYWJlbCA9IHNwcmludGYoIiUuM2YiLCBjbHVzdF9sciksIGZvbnRmYWNlID0gInBsYWluIiwgYW5nbGUgPSA5MCwgY29sb3IgPSBteV9wYWwpICsNCiAgDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgbGFicyh0aXRsZSA9IE5VTEwsDQogICAgICAgeCA9ICJsb2cyKEIvQSkiLA0KICAgICAgIHkgPSAi6aC75bqmIiwNCiAgICAgICBmaWxsID0gIuOCr+ODqeOCueOCvyIpICsNCiAgIyDlh6Hkvovjga7kvY3nva7oqr/mlbQNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjk5LCAwLjk5KSwgICAgICAjIOWPs+S4iih4PTAuOTUsIHk9MC45NSnjgavphY3nva4NCiAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoInJpZ2h0IiwgInRvcCIpLCAjIOWHoeS+i+OBruWPs+S4iuinkuOCkuWfuua6lueCueOBq+OBmeOCiw0KICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuMykgIyDlh6HkvovjgavmnqDnt5rjgpLku5jkuI4NCiAgKQ0KYGBgDQoNCiMjIFc0LjMgSyA9IDUNCuWFpeWKm+ODleOCoeOCpOODq+OBr+OAgVcyLjPlrp/ooYzntZDmnpzjgajjgZfjgablvpfjgZ9bSlNMQUIyOF9yZXMuY3N2XShKU0xBQjI4X3Jlcy5jc3Yp44GoW0pTTEFCMjhfSzVjZW50ZXJzLmNzdl0oSlNMQUIyOF9LNWNlbnRlcnMuY3N2KeOBp+OBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGNvbW1lbnQ9IiIsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTMuNX0NCiMg44OH44O844K/44Gu6Kqt44G/6L6844G/DQpkZiA8LSByZWFkLmNzdigiSlNMQUIyOF9yZXMuY3N2IikNCnRtcCA8LSByZWFkLmNzdigiSlNMQUIyOF9LNWNlbnRlcnMuY3N2IikNCmNsdXN0X25hbWUgPC0gdG1wJGNsdXN0ZXJfbmFtZQ0KY2x1c3RfbHIgPC0gdG1wJGxvZ3JhdGlvDQptYXhfeSA8LSA3MDANCg0KIyAtLS0g6Imy44Gu6Kit5a6aIC0tLQ0KIyDjg5Ljgrnjg4jjgrDjg6njg6Djgafkvb/jgYYgIlNldDEiIOODkeODrOODg+ODiOOBi+OCieOAgeOCr+ODqeOCueOCv+ODvOaVsO+8iDTjgaTvvInliIbjga7oibLjgpLmir3lh7oNCiMgU2V0MeOBrumghueVquOBr+OAgemAmuW4uCBnZ3Bsb3Qg44GuIGZpbGwg44Go5LiA6Ie044GX44G+44GZDQpteV9wYWwgPC0gYnJld2VyLnBhbChucm93KHRtcCksICJTZXQxIikNCg0KIyDjg5Ljgrnjg4jjgrDjg6njg6Djga7kvZzmiJANCmdncGxvdChkZiwgYWVzKHggPSBsb2dyYXRpbywgZmlsbCA9IEs1KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMSwgYWxwaGEgPSAwLjYsIHBvc2l0aW9uID0gImlkZW50aXR5IikgKw0KICAjIHjou7jjga7nr4Tlm7LjgpIgLTQg44GL44KJIDQg44Gr5oyH5a6aDQogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygtNCwgNCksIHlsaW0gPSBjKDAsIG1heF95KSkgKw0KICANCiAgIyDjgq/jg6njgrnjgr/kuK3lv4Pmg4XloLHjga7ov73liqANCiAgYW5ub3RhdGUoInNlZ21lbnQiLCB4ID0gY2x1c3RfbHIsIHhlbmQgPSBjbHVzdF9sciwgeSA9IG1heF95ICogMC44MiwgeWVuZCA9IG1heF95ICogMC43NywNCiAgICAgICAgICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMywgImNtIikpLCBzaXplID0gMSwgY29sb3IgPSBteV9wYWwpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gY2x1c3RfbHIgLSAwLjEwLCB5ID0gbWF4X3kgKiAwLjkzLCBsYWJlbCA9IGNsdXN0X25hbWUsIGZvbnRmYWNlID0gInBsYWluIiwgYW5nbGUgPSA5MCwgY29sb3IgPSBteV9wYWwpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gY2x1c3RfbHIgKyAwLjEwLCB5ID0gbWF4X3kgKiAwLjkzLCBsYWJlbCA9IHNwcmludGYoIiUuM2YiLCBjbHVzdF9sciksIGZvbnRmYWNlID0gInBsYWluIiwgYW5nbGUgPSA5MCwgY29sb3IgPSBteV9wYWwpICsNCiAgDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgbGFicyh0aXRsZSA9IE5VTEwsDQogICAgICAgeCA9ICJsb2cyKEIvQSkiLA0KICAgICAgIHkgPSAi6aC75bqmIiwNCiAgICAgICBmaWxsID0gIuOCr+ODqeOCueOCvyIpICsNCiAgIyDlh6Hkvovjga7kvY3nva7oqr/mlbQNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjk5LCAwLjk5KSwgICAgICAjIOWPs+S4iih4PTAuOTUsIHk9MC45NSnjgavphY3nva4NCiAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoInJpZ2h0IiwgInRvcCIpLCAjIOWHoeS+i+OBruWPs+S4iuinkuOCkuWfuua6lueCueOBq+OBmeOCiw0KICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuMykgIyDlh6HkvovjgavmnqDnt5rjgpLku5jkuI4NCiAgKQ0KYGBgDQoNCiMjIFc0LjQgbG9n5q+U44GMLTHjgYvjgokx44Gu56+E5Zuy44Gu54q25rOBDQrku6XkuIvjgaflrprnvqnjgZnjgovplqLmlbDjga/jgIHnlJ/miJBBSeOBrjHjgaTjgafjgYLjgotbR2VtaW5pXShodHRwczovL2dlbWluaS5nb29nbGUuY29tL2FwcCnjgatbSlNMQUIyOF9yZXMuY3N2XShKU0xBQjI4X3Jlcy5jc3Yp44KS5LiO44GI44Gf44Gu44Gh44CB44CMPGZvbnQgY29sb3I9Im1hZ2VudGEiPuOBk+OBruODleOCoeOCpOODq+OCkuiqreOBv+i+vOOCk+OBp+OAgWxvZ3JhdGlv5YiX44GMLTHjgYvjgokx44Gu56+E5Zuy44Gr44GC44KL6KGM44KS5oqc44GN5Ye644GX44CBSzMsIEs0LCBLNeWIl+OBq+WvvuOBl+OBplLjga50YWJsZemWouaVsOOCkuWun+ihjOOBmeOCi+OCueOCr+ODquODl+ODiOOCkuaVmeOBiOOBpuOAgjwvZm9udD7jgI3jgajjgYTjgYbmjIfku6TvvIjjg5fjg63jg7Pjg5fjg4jvvInjgpLlh7rjgZfjgablvpfjgZ/ntZDmnpzjgpLnsKHmvZTjgavjgZfjgZ/jgoLjga7jgafjgZnjgILjgYTjgZrjgozjga7liJfjgavjgYrjgYTjgabjgoLjgIHmnaHku7bjgpLmuoDjgZ/jgZnoqIg0Mjcz6YG65Lyd5a2Q5LitNDI3MeWAi+OBjGNsdXN0ZXIz44Gr5Ymy44KK5b2T44Gm44KJ44KM44Gm44GE44KL44GT44Go44GM5YiG44GL44KK44G+44GZ44CCDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgY29tbWVudD0iIn0NCiMgMS4g44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQojIENTVuOBrjHliJfnm67jgYzpgbrkvJ3lrZDlkI3vvIjooYzlkI3vvInjga7jgojjgYbjgarjga7jgacgcm93Lm5hbWVzID0gMSDjgpLmjIflrprjgZfjgabjgYTjgb7jgZkNCmRhdGEgPC0gcmVhZC5jc3YoIkpTTEFCMjhfcmVzLmNzdiIsIHJvdy5uYW1lcyA9IDEpDQoNCiMgMi4gbG9ncmF0aW/jgYwgLTEg44GL44KJIDEg44Gu56+E5Zuy44Gr44GC44KL6KGM44KS5oq95Ye6DQojIOKAuyBJbmYg44KEIC1JbmYg44KS6Zmk5aSW44GZ44KL44Gf44KB44Gr5pyJ6ZmQ5YCk5Yik5a6a44KS5YWl44KM44KL44Gu44GM5LiA6Iis55qE44Gn44GZDQpmaWx0ZXJlZF9kYXRhIDwtIHN1YnNldChkYXRhLCBsb2dyYXRpbyA+PSAtMSAmIGxvZ3JhdGlvIDw9IDEpDQoNCiMgMy4gSzMsIEs0LCBLNeWIl+OBq+WvvuOBl+OBpiB0YWJsZSDplqLmlbDjgpLlrp/ooYwNCmxhcHBseShmaWx0ZXJlZF9kYXRhWywgYygiSzMiLCAiSzQiLCAiSzUiKV0sIHRhYmxlKQ0KYGBgDQoNCiMgVzUg44K144Oz44Kt44O85ZuzDQoNCiMjIFc1LjEg5piH6aCG77yI5ZuzNGHvvIkNCuWFpeWKm+ODleOCoeOCpOODq+OBr1tKU0xBQjI4X3Jlcy5jc3ZdKEpTTEFCMjhfcmVzLmNzdinjgafjgZnjgIINCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1UUlVFLCB3YXJuaW5nPUZBTFNFLCBldmFsPVRSVUUsIGNvbW1lbnQ9IiIsIHJlc3VsdHM9VFJVRX0NCmluX2YgPC0gIkpTTEFCMjhfcmVzLmNzdiIgICAgICAgICAgICAgICAgICAgICAgICAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KcGFyYW1fb3JkZXIgPC0gImFzY2VuZGluZyIgICAgICAgICAgICAgICAgICAgICAgICMg44OO44O844OJ44Gu5Lim44Gz77yI44OH44OV44Kp44Or44OI44GvImFzY2VuZGluZyLvvIkNCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIlRydXRoIiwgIkszIiwgIks0IiwgIks1IiksICMg5o+P55S744GV44Gb44Gf44GE44Kr44OG44K044Oq5ZCN5oOF5aCxDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gIkZyZXF1ZW5jeSIpICAgICAgICAgIyDpoLvluqbjgpLjgqvjgqbjg7Pjg4jjgZfjgZ/jgYTliJflkI3mg4XloLENCg0KIyDkvZzlm7Mx77yI44K144Oz44Kt44O85Zuz44Gu5Z+65pys5b2i44G+44Gn5L2c5oiQ44GX44Gf57WQ5p6c44KSZ+OBq+agvOe0je+8iQ0KcG9zIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIpICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxdWVuY3ksICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlcWVuY3nliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjga9ub2Rl5YiX44CBZmlsbOOBr3N0YWdl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSBzdW0oZGF0YSRGcmVxdWVuY3kpKjAuMDIwICAgICAgICAgIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIsICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcXVlbmN5KSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOOCsOODquODg+ODiee3muOCkua2iOOBmQ0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLCAgICAgICAgICAgICMg5Yeh5L6L44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCiMjIFc1LjIg6ZmN6aCG77yI5ZuzNGLvvIkNCuWFpeWKm+ODleOCoeOCpOODq+OBr1tKU0xBQjI4X3Jlcy5jc3ZdKEpTTEFCMjhfcmVzLmNzdinjgafjgZnjgIINCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1UUlVFLCB3YXJuaW5nPUZBTFNFLCBldmFsPVRSVUUsIGNvbW1lbnQ9IiIsIHJlc3VsdHM9VFJVRX0NCmluX2YgPC0gIkpTTEFCMjhfcmVzLmNzdiIgICAgICAgICAgICAgICAgICAgICAgICAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KcGFyYW1fb3JkZXIgPC0gImRlc2NlbmRpbmciICAgICAgICAgICAgICAgICAgICAgICMg44OO44O844OJ44Gu5Lim44Gz77yI44OH44OV44Kp44Or44OI44GvImFzY2VuZGluZyLvvIkNCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIlRydXRoIiwgIkszIiwgIks0IiwgIks1IiksICMg5o+P55S744GV44Gb44Gf44GE44Kr44OG44K044Oq5ZCN5oOF5aCxDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gIkZyZXF1ZW5jeSIpICAgICAgICAgIyDpoLvluqbjgpLjgqvjgqbjg7Pjg4jjgZfjgZ/jgYTliJflkI3mg4XloLENCg0KIyDkvZzlm7Mx77yI44K144Oz44Kt44O85Zuz44Gu5Z+65pys5b2i44G+44Gn5L2c5oiQ44GX44Gf57WQ5p6c44KSZ+OBq+agvOe0je+8iQ0KcG9zIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIpICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxdWVuY3ksICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlcWVuY3nliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjgahmaWxs44Gv44CBbWF0b21l5YaF44Gubm9kZeWIl+OBp+ihjOOBhu+8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGVkZ2VfaWQgPSBlZGdlX2lkLCAgICAgICAgICAgICAgICMgZWRnZV9pZOOBr21hdG9tZeWGheOBrmVkZ2VfaWTliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBjb25uZWN0b3IgPSBjb25uZWN0b3IpKSArICAgICAgICAjIGNvbm5lY3RvcuOBr21hdG9tZeWGheOBrmNvbm5lY3RvcuWIl++8iOWkieabtOS4jeimge+8iQ0KICBnZW9tX3NhbmtleW5vZGUocG9zaXRpb24gPSBwb3MpICsgICAgICAgICAgICAgICMg44OO44O844OJ5oOF5aCx44KS6L+95YqgDQogIGdlb21fc2Fua2V5ZWRnZShwb3NpdGlvbiA9IHBvcykgICAgICAgICAgICAgICAgIyDjgqjjg4Pjgrjmg4XloLHjgpLov73liqANCg0KIyDkvZzlm7MyLTHvvIjjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLmj4/nlLvjgZnjgovpmpvjgavliKnnlKjjgZnjgovlvq7oqr/mlbTnlKjjga7jg5Hjg6njg6Hjg7zjgr/kvZzmiJDvvIkNCiMgeei7uOOBrumrmOOBleOBr+WFpeWKm+ODleOCoeOCpOODq+OBruihjOaVsOasoeesrOOBquOBruOBp+OAgW5yb3coZGF0YSnjga7kvZUl56iL5bqm5LiK5LiL44Gr44Ga44KJ44GZ44GL44Go44GE44GG5oSf44GY44Gu6KiI566X44KS44GX44Gm44GE44KLDQojIG51ZGdlX3jjgahudWRnZV9544Gv44CBeOi7uOOBqHnou7jjgZ3jgozjgZ7jgozjga7mlrnlkJHjgavlsJHjgZfjgZrjgonjgZfjgZ/jgYTlgKTjgafjgZnvvIhudWRnZeOBr+Wwj+eqgeOBj+OBqOOBhOOBhuaEj+WRs++8iQ0KbnVkZ2VfdmFsX3kgPC0gc3VtKGRhdGEkRnJlcXVlbmN5KSowLjAyMCAgICAgICAgICMgeei7uOS4iuOBruaPj+eUu+S9jee9ruOCkuODmeODvOOCueODqeOCpOODs+OBi+OCieS4iuS4i+OBq+OBmuOCieOBl+OBn+OBhOmrmOOBleOBruW5heaDheWgsQ0KcG9zMSA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gbnVkZ2VfdmFsX3kpICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIrjgavjgZrjgonjgZnvvIkNCnBvczIgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlciwgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ44Gu5Lim44Gz77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV94ID0gMC4wNiwgICAgICAgICAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh46Lu45oOF5aCx44Gu5L2N572u44KSMC4wNuWPs+OBq+OBmuOCieOBme+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IC1udWRnZV92YWxfeSkgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeei7uOaDheWgseOBruS9jee9ruOCkm51ZGdlX3ZhbF955LiL44Gr44Ga44KJ44GZ77yJDQoNCiMg5L2c5ZuzMi0y77yI5Z+65pys5b2iZ+OCkuODmeODvOOCueOBqOOBl+OBpuOAgeODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkui/veWKoOOBl+OBn+e1kOaenOOCkmcy44Gr5qC857SN77yJDQojIHN0YXQgPSAic2Fua2V5bm9kZSLjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nmg4XloLHjgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBub2Rl44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5ZCN44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gRnJlceOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieOBq+S7mOmaj+OBmeOCi+mgu+W6puWApOOBoOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczHjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3Mx44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMuOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczLjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgaGp1c3QgPSAw44Gv44CB5paH5a2X44KS5bem5o+D44GI44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5Luk77yI44OH44OV44Kp44Or44OI44Gv5Lit5aSu5o+D44GI77yJDQojIHNpemUgPSA044Gv44CB44K144Kk44K6NOOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOOBk+OBruWApOOBq+W/nOOBmOOBpm51ZGdlX3njgoLpganlrpzoqr/mlbTjgZnjgovvvIkNCmcyIDwtIGcgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBub2RlKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MxLCBoanVzdCA9IDAsIHNpemUgPSA0KSArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IEZyZXF1ZW5jeSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMiwgaGp1c3QgPSAwLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQojIyBXNS4zIOOCr+ODreOCuembhuioiOihqA0K44K144Oz44Kt44O85Zuz5Lit44GuSzPjgahLNOOAgeOBiuOCiOOBs0s044GoSzXplpPjga7jgq/jg63jgrnpm4boqIjooajjgpLlvpfjgovjgZ/jgoHjga7jgrnjgq/jg6rjg5fjg4jjgafjgZnjgIINCuWFpeWKm+ODleOCoeOCpOODq+OBr1tKU0xBQjI4X3Jlcy5jc3ZdKEpTTEFCMjhfcmVzLmNzdinjgIHlh7rlipvjg5XjgqHjgqTjg6vjga9bSlNMQUIyOF9LM19LNC5jc3ZdKEpTTEFCMjhfSzNfSzQuY3N2KeOBqFtKU0xBQjI4X0s0X0s1LmNzdl0oSlNMQUIyOF9LNF9LNS5jc3Yp44Gn44GZ44CCDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgZXZhbD1UUlVFLCBjb21tZW50PSIiLCByZXN1bHRzPVRSVUV9DQppbl9mIDwtICJKU0xBQjI4X3Jlcy5jc3YiICAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjg5XjgqHjgqTjg6vlkI0NCg0KIyBLM+OBqEs06ZaT44Gu44Kv44Ot44K56ZuG6KiI6KGoDQpob2dlIDwtIHRhYmxlKGRmJEszLCBkZiRLNCkgICAgICAgICAgICAgICAgICAgICAgIyBLM+WIl+OBqEs05YiX44Gu44Kv44Ot44K56ZuG6KiI6KGoDQpUb3RhbCA8LSBjb2xTdW1zKGhvZ2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDliJfjgZTjgajjga7jg4jjg7zjgr/jg6vmg4XloLHjga7lj5blvpcNCmhvZ2UgPC0gcmJpbmQoaG9nZSwgVG90YWwpICAgICAgICAgICAgICAgICAgICAgICAjIOODiOODvOOCv+ODq+aDheWgseOCkuacgOS4i+ihjOOBp+mAo+e1kA0KVG90YWwgPC0gcm93U3Vtcyhob2dlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICMg6KGM44GU44Go44Gu44OI44O844K/44Or5oOF5aCx44Gu5Y+W5b6XDQpob2dlIDwtIGNiaW5kKGhvZ2UsIFRvdGFsKSAgICAgICAgICAgICAgICAgICAgICAgIyDjg4jjg7zjgr/jg6vmg4XloLHjgpLmnIDlj7PliJfjgafpgKPntZANCnRtcCA8LSBjYmluZChyb3duYW1lcyhob2dlKSwgaG9nZSkgICAgICAgICAgICAgICAjIOihjOWQjeaDheWgseOCkui/veWKoA0Kd3JpdGUuY3N2KHRtcCwgIkpTTEFCMjhfSzNfSzQuY3N2Iiwgcm93Lm5hbWVzPUYpICMg44OV44Kh44Kk44Or5Ye65YqbDQoNCiMgSzTjgahLNemWk+OBruOCr+ODreOCuembhuioiOihqA0KaG9nZSA8LSB0YWJsZShkZiRLNCwgZGYkSzUpICAgICAgICAgICAgICAgICAgICAgICMgSzTliJfjgahLNeWIl+OBruOCr+ODreOCuembhuioiOihqA0KVG90YWwgPC0gY29sU3Vtcyhob2dlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICMg5YiX44GU44Go44Gu44OI44O844K/44Or5oOF5aCx44Gu5Y+W5b6XDQpob2dlIDwtIHJiaW5kKGhvZ2UsIFRvdGFsKSAgICAgICAgICAgICAgICAgICAgICAgIyDjg4jjg7zjgr/jg6vmg4XloLHjgpLmnIDkuIvooYzjgafpgKPntZANClRvdGFsIDwtIHJvd1N1bXMoaG9nZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOihjOOBlOOBqOOBruODiOODvOOCv+ODq+aDheWgseOBruWPluW+lw0KaG9nZSA8LSBjYmluZChob2dlLCBUb3RhbCkgICAgICAgICAgICAgICAgICAgICAgICMg44OI44O844K/44Or5oOF5aCx44KS5pyA5Y+z5YiX44Gn6YCj57WQDQp0bXAgPC0gY2JpbmQocm93bmFtZXMoaG9nZSksIGhvZ2UpICAgICAgICAgICAgICAgIyDooYzlkI3mg4XloLHjgpLov73liqANCndyaXRlLmNzdih0bXAsICJKU0xBQjI4X0s0X0s1LmNzdiIsIHJvdy5uYW1lcz1GKSAjIOODleOCoeOCpOODq+WHuuWKmw0KYGBgDQoNCiMjIFc1LjQg5Ye654++6aCG77yI5ZuzNWHvvIkNCuWFpeWKm+ODleOCoeOCpOODq+OBr1tKU0xBQjI4X3Jlcy5jc3ZdKEpTTEFCMjhfcmVzLmNzdinjgafjgZnjgIINCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1UUlVFLCB3YXJuaW5nPUZBTFNFLCBldmFsPVRSVUUsIGNvbW1lbnQ9IiIsIHJlc3VsdHM9VFJVRX0NCmluX2YgPC0gIkpTTEFCMjhfcmVzLmNzdiIgICAgICAgICAgICAgICAgICAgICAgICAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KcGFyYW1fb3JkZXIgPC0gImFzX2lzIiAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OO44O844OJ44Gu5Lim44Gz77yI44OH44OV44Kp44Or44OI44GvImFzY2VuZGluZyLvvIkNCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIlRydXRoIiwgIkszIiwgIks0IiwgIks1IiksICMg5o+P55S744GV44Gb44Gf44GE44Kr44OG44K044Oq5ZCN5oOF5aCxDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gIkZyZXF1ZW5jeSIpICAgICAgICAgIyDpoLvluqbjgpLjgqvjgqbjg7Pjg4jjgZfjgZ/jgYTliJflkI3mg4XloLENCg0KIyDkvZzlm7Mx77yI44K144Oz44Kt44O85Zuz44Gu5Z+65pys5b2i44G+44Gn5L2c5oiQ44GX44Gf57WQ5p6c44KSZ+OBq+agvOe0je+8iQ0KcG9zIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIpICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxdWVuY3ksICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlcWVuY3nliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjgahmaWxs44Gv44CBbWF0b21l5YaF44Gubm9kZeWIl+OBp+ihjOOBhu+8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGVkZ2VfaWQgPSBlZGdlX2lkLCAgICAgICAgICAgICAgICMgZWRnZV9pZOOBr21hdG9tZeWGheOBrmVkZ2VfaWTliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBjb25uZWN0b3IgPSBjb25uZWN0b3IpKSArICAgICAgICAjIGNvbm5lY3RvcuOBr21hdG9tZeWGheOBrmNvbm5lY3RvcuWIl++8iOWkieabtOS4jeimge+8iQ0KICBnZW9tX3NhbmtleW5vZGUocG9zaXRpb24gPSBwb3MpICsgICAgICAgICAgICAgICMg44OO44O844OJ5oOF5aCx44KS6L+95YqgDQogIGdlb21fc2Fua2V5ZWRnZShwb3NpdGlvbiA9IHBvcykgICAgICAgICAgICAgICAgIyDjgqjjg4Pjgrjmg4XloLHjgpLov73liqANCg0KIyDkvZzlm7MyLTHvvIjjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLmj4/nlLvjgZnjgovpmpvjgavliKnnlKjjgZnjgovlvq7oqr/mlbTnlKjjga7jg5Hjg6njg6Hjg7zjgr/kvZzmiJDvvIkNCiMgeei7uOOBrumrmOOBleOBr+WFpeWKm+ODleOCoeOCpOODq+OBruihjOaVsOasoeesrOOBquOBruOBp+OAgW5yb3coZGF0YSnjga7kvZUl56iL5bqm5LiK5LiL44Gr44Ga44KJ44GZ44GL44Go44GE44GG5oSf44GY44Gu6KiI566X44KS44GX44Gm44GE44KLDQojIG51ZGdlX3jjgahudWRnZV9544Gv44CBeOi7uOOBqHnou7jjgZ3jgozjgZ7jgozjga7mlrnlkJHjgavlsJHjgZfjgZrjgonjgZfjgZ/jgYTlgKTjgafjgZnvvIhudWRnZeOBr+Wwj+eqgeOBj+OBqOOBhOOBhuaEj+WRs++8iQ0KbnVkZ2VfdmFsX3kgPC0gc3VtKGRhdGEkRnJlcXVlbmN5KSowLjAyMCAgICAgICAgICMgeei7uOS4iuOBruaPj+eUu+S9jee9ruOCkuODmeODvOOCueODqeOCpOODs+OBi+OCieS4iuS4i+OBq+OBmuOCieOBl+OBn+OBhOmrmOOBleOBruW5heaDheWgsQ0KcG9zMSA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gbnVkZ2VfdmFsX3kpICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIrjgavjgZrjgonjgZnvvIkNCnBvczIgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlciwgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ44Gu5Lim44Gz77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV94ID0gMC4wNiwgICAgICAgICAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh46Lu45oOF5aCx44Gu5L2N572u44KSMC4wNuWPs+OBq+OBmuOCieOBme+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IC1udWRnZV92YWxfeSkgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeei7uOaDheWgseOBruS9jee9ruOCkm51ZGdlX3ZhbF955LiL44Gr44Ga44KJ44GZ77yJDQoNCiMg5L2c5ZuzMi0y77yI5Z+65pys5b2iZ+OCkuODmeODvOOCueOBqOOBl+OBpuOAgeODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkui/veWKoOOBl+OBn+e1kOaenOOCkmcy44Gr5qC857SN77yJDQojIHN0YXQgPSAic2Fua2V5bm9kZSLjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nmg4XloLHjgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBub2Rl44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5ZCN44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gRnJlceOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieOBq+S7mOmaj+OBmeOCi+mgu+W6puWApOOBoOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczHjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3Mx44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMuOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczLjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgaGp1c3QgPSAw44Gv44CB5paH5a2X44KS5bem5o+D44GI44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5Luk77yI44OH44OV44Kp44Or44OI44Gv5Lit5aSu5o+D44GI77yJDQojIHNpemUgPSA044Gv44CB44K144Kk44K6NOOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOOBk+OBruWApOOBq+W/nOOBmOOBpm51ZGdlX3njgoLpganlrpzoqr/mlbTjgZnjgovvvIkNCmcyIDwtIGcgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBub2RlKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MxLCBoanVzdCA9IDAsIHNpemUgPSA0KSArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IEZyZXF1ZW5jeSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMiwgaGp1c3QgPSAwLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQojIyBXNS41IOODleOCoeOCpOODq+OBruWGkumgremDqOWIhuOCkuihqOekug0K5YWl5Yqb44OV44Kh44Kk44Or77yIW0pTTEFCMjhfcmVzLmNzdl0oSlNMQUIyOF9yZXMuY3N2Ke+8ieOCkuiqreOBv+i+vOOCk+OBp+OAgeacgOWIneOBrjE16KGM5YiG44KS6KGo56S644GV44Gb44Gm44GE44KL44Gg44GR44Gn44GZ44CCDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgZXZhbD1UUlVFLCBjb21tZW50PSIiLCByZXN1bHRzPVRSVUV9DQppbl9mIDwtICJKU0xBQjI4X3Jlcy5jc3YiICAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjg5XjgqHjgqTjg6vlkI0NCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KDQojIOWFpeWKm+ODleOCoeOCpOODq+OBruiqreOBv+i+vOOBvw0KZGF0YSA8LSByZWFkX2Nzdihpbl9mKSAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaW5fZuOBp+aMh+WumuOBl+OBn+ODleOCoeOCpOODq+OBruiqrei+vA0KDQojIOacgOWIneOBrjE16KGM5YiG44KS6KGo56S6DQpoZWFkKGRhdGEsIG4gPSAxNSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBoZWFk6Zai5pWw44Gu5a6f6KGMDQpgYGANCg0KIyMgVzUuNiDlh7rnj77poIbvvIjlm7M1Yu+8iQ0K5YWl5Yqb44OV44Kh44Kk44Or44KS44GvW0pTTEFCMjhfcmVzLmNzdl0oSlNMQUIyOF9yZXMuY3N2KeOBi+OCieOAgVtKU0xBQjI4X3JlczIuY3N2XShKU0xBQjI4X3JlczIuY3N2KeOBq+WkieOBiOOBn+OBoOOBkeOBp+OBmeOAguOBk+OCjOOBr+OAgVRydXRo5YiX44GM5pyA5Yid44GrREVHX0LjgajjgarjgotnZW5lXzI1MDHjga7ooYzjgpLjg5jjg4Pjg4Djg7zooYzjgahnZW5lXzHjga7plpPjgavnp7vli5XjgZXjgZvjgZ/jgaDjgZHjgafjgZnjgIINCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1UUlVFLCB3YXJuaW5nPUZBTFNFLCBldmFsPVRSVUUsIGNvbW1lbnQ9IiIsIHJlc3VsdHM9VFJVRX0NCmluX2YgPC0gIkpTTEFCMjhfcmVzMi5jc3YiICAgICAgICAgICAgICAgICAgICAgICAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KcGFyYW1fb3JkZXIgPC0gImFzX2lzIiAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OO44O844OJ44Gu5Lim44Gz77yI44OH44OV44Kp44Or44OI44GvImFzY2VuZGluZyLvvIkNCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIlRydXRoIiwgIkszIiwgIks0IiwgIks1IiksICMg5o+P55S744GV44Gb44Gf44GE44Kr44OG44K044Oq5ZCN5oOF5aCxDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gIkZyZXF1ZW5jeSIpICAgICAgICAgIyDpoLvluqbjgpLjgqvjgqbjg7Pjg4jjgZfjgZ/jgYTliJflkI3mg4XloLENCg0KIyDkvZzlm7Mx77yI44K144Oz44Kt44O85Zuz44Gu5Z+65pys5b2i44G+44Gn5L2c5oiQ44GX44Gf57WQ5p6c44KSZ+OBq+agvOe0je+8iQ0KcG9zIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIpICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxdWVuY3ksICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlcWVuY3nliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjgahmaWxs44Gv44CBbWF0b21l5YaF44Gubm9kZeWIl+OBp+ihjOOBhu+8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGVkZ2VfaWQgPSBlZGdlX2lkLCAgICAgICAgICAgICAgICMgZWRnZV9pZOOBr21hdG9tZeWGheOBrmVkZ2VfaWTliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBjb25uZWN0b3IgPSBjb25uZWN0b3IpKSArICAgICAgICAjIGNvbm5lY3RvcuOBr21hdG9tZeWGheOBrmNvbm5lY3RvcuWIl++8iOWkieabtOS4jeimge+8iQ0KICBnZW9tX3NhbmtleW5vZGUocG9zaXRpb24gPSBwb3MpICsgICAgICAgICAgICAgICMg44OO44O844OJ5oOF5aCx44KS6L+95YqgDQogIGdlb21fc2Fua2V5ZWRnZShwb3NpdGlvbiA9IHBvcykgICAgICAgICAgICAgICAgIyDjgqjjg4Pjgrjmg4XloLHjgpLov73liqANCg0KIyDkvZzlm7MyLTHvvIjjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLmj4/nlLvjgZnjgovpmpvjgavliKnnlKjjgZnjgovlvq7oqr/mlbTnlKjjga7jg5Hjg6njg6Hjg7zjgr/kvZzmiJDvvIkNCiMgeei7uOOBrumrmOOBleOBr+WFpeWKm+ODleOCoeOCpOODq+OBruihjOaVsOasoeesrOOBquOBruOBp+OAgW5yb3coZGF0YSnjga7kvZUl56iL5bqm5LiK5LiL44Gr44Ga44KJ44GZ44GL44Go44GE44GG5oSf44GY44Gu6KiI566X44KS44GX44Gm44GE44KLDQojIG51ZGdlX3jjgahudWRnZV9544Gv44CBeOi7uOOBqHnou7jjgZ3jgozjgZ7jgozjga7mlrnlkJHjgavlsJHjgZfjgZrjgonjgZfjgZ/jgYTlgKTjgafjgZnvvIhudWRnZeOBr+Wwj+eqgeOBj+OBqOOBhOOBhuaEj+WRs++8iQ0KbnVkZ2VfdmFsX3kgPC0gc3VtKGRhdGEkRnJlcXVlbmN5KSowLjAyMCAgICAgICAgICMgeei7uOS4iuOBruaPj+eUu+S9jee9ruOCkuODmeODvOOCueODqeOCpOODs+OBi+OCieS4iuS4i+OBq+OBmuOCieOBl+OBn+OBhOmrmOOBleOBruW5heaDheWgsQ0KcG9zMSA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gbnVkZ2VfdmFsX3kpICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIrjgavjgZrjgonjgZnvvIkNCnBvczIgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlciwgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ44Gu5Lim44Gz77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV94ID0gMC4wNiwgICAgICAgICAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh46Lu45oOF5aCx44Gu5L2N572u44KSMC4wNuWPs+OBq+OBmuOCieOBme+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IC1udWRnZV92YWxfeSkgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeei7uOaDheWgseOBruS9jee9ruOCkm51ZGdlX3ZhbF955LiL44Gr44Ga44KJ44GZ77yJDQoNCiMg5L2c5ZuzMi0y77yI5Z+65pys5b2iZ+OCkuODmeODvOOCueOBqOOBl+OBpuOAgeODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkui/veWKoOOBl+OBn+e1kOaenOOCkmcy44Gr5qC857SN77yJDQojIHN0YXQgPSAic2Fua2V5bm9kZSLjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nmg4XloLHjgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBub2Rl44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5ZCN44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gRnJlceOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieOBq+S7mOmaj+OBmeOCi+mgu+W6puWApOOBoOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczHjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3Mx44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMuOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczLjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgaGp1c3QgPSAw44Gv44CB5paH5a2X44KS5bem5o+D44GI44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5Luk77yI44OH44OV44Kp44Or44OI44Gv5Lit5aSu5o+D44GI77yJDQojIHNpemUgPSA044Gv44CB44K144Kk44K6NOOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOOBk+OBruWApOOBq+W/nOOBmOOBpm51ZGdlX3njgoLpganlrpzoqr/mlbTjgZnjgovvvIkNCmcyIDwtIGcgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBub2RlKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MxLCBoanVzdCA9IDAsIHNpemUgPSA0KSArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IEZyZXF1ZW5jeSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMiwgaGp1c3QgPSAwLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQojIFc2IOOCteODs+OCreODvOWbs+OBruS4jeWFt+WQiOS+iw0KDQojIyBXNi4xIOWHuuePvumghu+8iOe4pjXDl+aoqjXjgqTjg7Pjg4HvvJvlm7M2Ye+8iQ0K5YWl5Yqb44OV44Kh44Kk44Or44GvW0pTTEFCMjhfcmVzLmNzdl0oSlNMQUIyOF9yZXMuY3N2KeOBp+OBmeOAguWfuuacrOeahOOBq1c1LjTjgajlkIzjgZjjgafjgZnjgYzjgIHmnIDntYLjga7kvZzlm7PmrrXpmo7jgavjgYrjgYTjgabjgIHmqKrluYXjgajnuKbluYXjgpLjgajjgoLjgas144Kk44Oz44OB44GX44Gm44GE44G+44GZ44CCaHRtbOOCkuimi+OCi+mZkOOCiuOBp+OBr+OAgVc1LjTvvIjlm7M1Ye+8ieOBruOCueOCr+ODquODl+ODiOOBqOWQjOS4gOOBp+OBmeOBjOOAgeOBk+OBrmh0bWzkvZzmiJDmmYLjgavliKnnlKjjgZfjgabjgYTjgotSbWTjg5XjgqHjgqTjg6vjga7kuK3jgatS44OB44Oj44Oz44Kv44Kq44OX44K344On44Oz44Go44GX44Gm44CMZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NeOAjeOBjOi/veWKoOOBleOCjOOBpuOBhOOBvuOBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFLCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD01fQ0KaW5fZiA8LSAiSlNMQUIyOF9yZXMuY3N2IiAgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQpwYXJhbV9vcmRlciA8LSAiYXNfaXMiICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg47jg7zjg4njga7kuKbjgbPvvIjjg4fjg5Xjgqnjg6vjg4jjga8iYXNjZW5kaW5nIu+8iQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygiVHJ1dGgiLCAiSzMiLCAiSzQiLCAiSzUiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcXVlbmN5IikgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlcikgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IG1hdG9tZSwgICAgICAgICAgICAgICAgICAgICAgICMgZ2dwbG906Zai5pWw5a6f6KGM57WQ5p6c44KSZ+OBq+agvOe0jeOAguWFpeWKm+OBr21hdG9tZeOCquODluOCuOOCp+OCr+ODiA0KICBtYXBwaW5nID0gYWVzKHggPSBzdGFnZSwgeSA9IEZyZXF1ZW5jeSwgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgahGcmVxZW5jeeWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSBzdW0oZGF0YSRGcmVxdWVuY3kpKjAuMDIwICAgICAgICAgIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIsICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcXVlbmN5KSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOOCsOODquODg+ODiee3muOCkua2iOOBmQ0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLCAgICAgICAgICAgICMg5Yeh5L6L44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCiMjIFc2LjIg5Ye654++6aCG77yI57imNcOX5qiqNeOCpOODs+ODge+8m+WbszZi77yJDQrlhaXlipvjg5XjgqHjgqTjg6vjga/jgIFbSlNMQUIyOF9yZXMyLmNzdl0oSlNMQUIyOF9yZXMyLmNzdinjgafjgZnjgILln7rmnKznmoTjgatXNS4244Go5ZCM44GY44Gn44GZ44GM44CB5pyA57WC44Gu5L2c5Zuz5q616ZqO44Gr44GK44GE44Gm44CB5qiq5bmF44Go57im5bmF44KS44Go44KC44GrNeOCpOODs+ODgeOBl+OBpuOBhOOBvuOBmeOAgmh0bWzjgpLopovjgovpmZDjgorjgafjga/jgIFXNS4277yI5ZuzNWLvvInjga7jgrnjgq/jg6rjg5fjg4jjgajlkIzkuIDjgafjgZnjgYzjgIHjgZPjga5odG1s5L2c5oiQ5pmC44Gr5Yip55So44GX44Gm44GE44KLUm1k44OV44Kh44Kk44Or44Gu5Lit44GrUuODgeODo+ODs+OCr+OCquODl+OCt+ODp+ODs+OBqOOBl+OBpuOAjGZpZy53aWR0aD01LCBmaWcuaGVpZ2h0PTXjgI3jgYzov73liqDjgZXjgozjgabjgYTjgb7jgZnjgIINCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1UUlVFLCB3YXJuaW5nPUZBTFNFLCBldmFsPVRSVUUsIGNvbW1lbnQ9IiIsIHJlc3VsdHM9VFJVRSwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NX0NCmluX2YgPC0gIkpTTEFCMjhfcmVzMi5jc3YiICAgICAgICAgICAgICAgICAgICAgICAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KcGFyYW1fb3JkZXIgPC0gImFzX2lzIiAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OO44O844OJ44Gu5Lim44Gz77yI44OH44OV44Kp44Or44OI44GvImFzY2VuZGluZyLvvIkNCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIlRydXRoIiwgIkszIiwgIks0IiwgIks1IiksICMg5o+P55S744GV44Gb44Gf44GE44Kr44OG44K044Oq5ZCN5oOF5aCxDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gIkZyZXF1ZW5jeSIpICAgICAgICAgIyDpoLvluqbjgpLjgqvjgqbjg7Pjg4jjgZfjgZ/jgYTliJflkI3mg4XloLENCg0KIyDkvZzlm7Mx77yI44K144Oz44Kt44O85Zuz44Gu5Z+65pys5b2i44G+44Gn5L2c5oiQ44GX44Gf57WQ5p6c44KSZ+OBq+agvOe0je+8iQ0KcG9zIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIpICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxdWVuY3ksICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlcWVuY3nliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjgahmaWxs44Gv44CBbWF0b21l5YaF44Gubm9kZeWIl+OBp+ihjOOBhu+8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGVkZ2VfaWQgPSBlZGdlX2lkLCAgICAgICAgICAgICAgICMgZWRnZV9pZOOBr21hdG9tZeWGheOBrmVkZ2VfaWTliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBjb25uZWN0b3IgPSBjb25uZWN0b3IpKSArICAgICAgICAjIGNvbm5lY3RvcuOBr21hdG9tZeWGheOBrmNvbm5lY3RvcuWIl++8iOWkieabtOS4jeimge+8iQ0KICBnZW9tX3NhbmtleW5vZGUocG9zaXRpb24gPSBwb3MpICsgICAgICAgICAgICAgICMg44OO44O844OJ5oOF5aCx44KS6L+95YqgDQogIGdlb21fc2Fua2V5ZWRnZShwb3NpdGlvbiA9IHBvcykgICAgICAgICAgICAgICAgIyDjgqjjg4Pjgrjmg4XloLHjgpLov73liqANCg0KIyDkvZzlm7MyLTHvvIjjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLmj4/nlLvjgZnjgovpmpvjgavliKnnlKjjgZnjgovlvq7oqr/mlbTnlKjjga7jg5Hjg6njg6Hjg7zjgr/kvZzmiJDvvIkNCiMgeei7uOOBrumrmOOBleOBr+WFpeWKm+ODleOCoeOCpOODq+OBruihjOaVsOasoeesrOOBquOBruOBp+OAgW5yb3coZGF0YSnjga7kvZUl56iL5bqm5LiK5LiL44Gr44Ga44KJ44GZ44GL44Go44GE44GG5oSf44GY44Gu6KiI566X44KS44GX44Gm44GE44KLDQojIG51ZGdlX3jjgahudWRnZV9544Gv44CBeOi7uOOBqHnou7jjgZ3jgozjgZ7jgozjga7mlrnlkJHjgavlsJHjgZfjgZrjgonjgZfjgZ/jgYTlgKTjgafjgZnvvIhudWRnZeOBr+Wwj+eqgeOBj+OBqOOBhOOBhuaEj+WRs++8iQ0KbnVkZ2VfdmFsX3kgPC0gc3VtKGRhdGEkRnJlcXVlbmN5KSowLjAyMCAgICAgICAgICMgeei7uOS4iuOBruaPj+eUu+S9jee9ruOCkuODmeODvOOCueODqeOCpOODs+OBi+OCieS4iuS4i+OBq+OBmuOCieOBl+OBn+OBhOmrmOOBleOBruW5heaDheWgsQ0KcG9zMSA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gbnVkZ2VfdmFsX3kpICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIrjgavjgZrjgonjgZnvvIkNCnBvczIgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlciwgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ44Gu5Lim44Gz77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV94ID0gMC4wNiwgICAgICAgICAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh46Lu45oOF5aCx44Gu5L2N572u44KSMC4wNuWPs+OBq+OBmuOCieOBme+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IC1udWRnZV92YWxfeSkgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeei7uOaDheWgseOBruS9jee9ruOCkm51ZGdlX3ZhbF955LiL44Gr44Ga44KJ44GZ77yJDQoNCiMg5L2c5ZuzMi0y77yI5Z+65pys5b2iZ+OCkuODmeODvOOCueOBqOOBl+OBpuOAgeODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkui/veWKoOOBl+OBn+e1kOaenOOCkmcy44Gr5qC857SN77yJDQojIHN0YXQgPSAic2Fua2V5bm9kZSLjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nmg4XloLHjgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBub2Rl44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5ZCN44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gRnJlceOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieOBq+S7mOmaj+OBmeOCi+mgu+W6puWApOOBoOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczHjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3Mx44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMuOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczLjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgaGp1c3QgPSAw44Gv44CB5paH5a2X44KS5bem5o+D44GI44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5Luk77yI44OH44OV44Kp44Or44OI44Gv5Lit5aSu5o+D44GI77yJDQojIHNpemUgPSA044Gv44CB44K144Kk44K6NOOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOOBk+OBruWApOOBq+W/nOOBmOOBpm51ZGdlX3njgoLpganlrpzoqr/mlbTjgZnjgovvvIkNCmcyIDwtIGcgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBub2RlKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MxLCBoanVzdCA9IDAsIHNpemUgPSA0KSArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IEZyZXF1ZW5jeSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMiwgaGp1c3QgPSAwLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQojIyBXNi4zIOWHuuePvumghu+8iOe4pjjDl+aoqjjjgqTjg7Pjg4HvvIkNCuWFpeWKm+ODleOCoeOCpOODq+OBr1tKU0xBQjI4X3Jlcy5jc3ZdKEpTTEFCMjhfcmVzLmNzdinjgafjgZnjgILln7rmnKznmoTjgatXNi4x44Go5ZCM44GY44Gn44GZ44GM44CB5pyA57WC44Gu5L2c5Zuz5q616ZqO44Gr44GK44GE44Gm44CB5qiq5bmF44Go57im5bmF44KS44Go44KC44GrOOOCpOODs+ODgeOBl+OBpuOBhOOBvuOBmeOAgmh0bWzjgpLopovjgovpmZDjgorjgafjga/jgIFXNi4x77yI5ZuzNmHvvInjga7jgrnjgq/jg6rjg5fjg4jjgajlkIzkuIDjgafjgZnjgYzjgIHjgZPjga5odG1s5L2c5oiQ5pmC44Gr5Yip55So44GX44Gm44GE44KLUm1k44OV44Kh44Kk44Or44Gu5Lit44GrUuODgeODo+ODs+OCr+OCquODl+OCt+ODp+ODs+OBqOOBl+OBpuOAjGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTjjgI3jgYzov73liqDjgZXjgozjgabjgYTjgb7jgZnjgIINCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1UUlVFLCB3YXJuaW5nPUZBTFNFLCBldmFsPVRSVUUsIGNvbW1lbnQ9IiIsIHJlc3VsdHM9VFJVRSwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OH0NCmluX2YgPC0gIkpTTEFCMjhfcmVzLmNzdiIgICAgICAgICAgICAgICAgICAgICAgICAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KcGFyYW1fb3JkZXIgPC0gImFzX2lzIiAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OO44O844OJ44Gu5Lim44Gz77yI44OH44OV44Kp44Or44OI44GvImFzY2VuZGluZyLvvIkNCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIlRydXRoIiwgIkszIiwgIks0IiwgIks1IiksICMg5o+P55S744GV44Gb44Gf44GE44Kr44OG44K044Oq5ZCN5oOF5aCxDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gIkZyZXF1ZW5jeSIpICAgICAgICAgIyDpoLvluqbjgpLjgqvjgqbjg7Pjg4jjgZfjgZ/jgYTliJflkI3mg4XloLENCg0KIyDkvZzlm7Mx77yI44K144Oz44Kt44O85Zuz44Gu5Z+65pys5b2i44G+44Gn5L2c5oiQ44GX44Gf57WQ5p6c44KSZ+OBq+agvOe0je+8iQ0KcG9zIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIpICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxdWVuY3ksICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlcWVuY3nliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjgahmaWxs44Gv44CBbWF0b21l5YaF44Gubm9kZeWIl+OBp+ihjOOBhu+8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGVkZ2VfaWQgPSBlZGdlX2lkLCAgICAgICAgICAgICAgICMgZWRnZV9pZOOBr21hdG9tZeWGheOBrmVkZ2VfaWTliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBjb25uZWN0b3IgPSBjb25uZWN0b3IpKSArICAgICAgICAjIGNvbm5lY3RvcuOBr21hdG9tZeWGheOBrmNvbm5lY3RvcuWIl++8iOWkieabtOS4jeimge+8iQ0KICBnZW9tX3NhbmtleW5vZGUocG9zaXRpb24gPSBwb3MpICsgICAgICAgICAgICAgICMg44OO44O844OJ5oOF5aCx44KS6L+95YqgDQogIGdlb21fc2Fua2V5ZWRnZShwb3NpdGlvbiA9IHBvcykgICAgICAgICAgICAgICAgIyDjgqjjg4Pjgrjmg4XloLHjgpLov73liqANCg0KIyDkvZzlm7MyLTHvvIjjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLmj4/nlLvjgZnjgovpmpvjgavliKnnlKjjgZnjgovlvq7oqr/mlbTnlKjjga7jg5Hjg6njg6Hjg7zjgr/kvZzmiJDvvIkNCiMgeei7uOOBrumrmOOBleOBr+WFpeWKm+ODleOCoeOCpOODq+OBruihjOaVsOasoeesrOOBquOBruOBp+OAgW5yb3coZGF0YSnjga7kvZUl56iL5bqm5LiK5LiL44Gr44Ga44KJ44GZ44GL44Go44GE44GG5oSf44GY44Gu6KiI566X44KS44GX44Gm44GE44KLDQojIG51ZGdlX3jjgahudWRnZV9544Gv44CBeOi7uOOBqHnou7jjgZ3jgozjgZ7jgozjga7mlrnlkJHjgavlsJHjgZfjgZrjgonjgZfjgZ/jgYTlgKTjgafjgZnvvIhudWRnZeOBr+Wwj+eqgeOBj+OBqOOBhOOBhuaEj+WRs++8iQ0KbnVkZ2VfdmFsX3kgPC0gc3VtKGRhdGEkRnJlcXVlbmN5KSowLjAyMCAgICAgICAgICMgeei7uOS4iuOBruaPj+eUu+S9jee9ruOCkuODmeODvOOCueODqeOCpOODs+OBi+OCieS4iuS4i+OBq+OBmuOCieOBl+OBn+OBhOmrmOOBleOBruW5heaDheWgsQ0KcG9zMSA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gbnVkZ2VfdmFsX3kpICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIrjgavjgZrjgonjgZnvvIkNCnBvczIgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlciwgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ44Gu5Lim44Gz77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV94ID0gMC4wNiwgICAgICAgICAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh46Lu45oOF5aCx44Gu5L2N572u44KSMC4wNuWPs+OBq+OBmuOCieOBme+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IC1udWRnZV92YWxfeSkgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeei7uOaDheWgseOBruS9jee9ruOCkm51ZGdlX3ZhbF955LiL44Gr44Ga44KJ44GZ77yJDQoNCiMg5L2c5ZuzMi0y77yI5Z+65pys5b2iZ+OCkuODmeODvOOCueOBqOOBl+OBpuOAgeODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkui/veWKoOOBl+OBn+e1kOaenOOCkmcy44Gr5qC857SN77yJDQojIHN0YXQgPSAic2Fua2V5bm9kZSLjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nmg4XloLHjgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBub2Rl44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5ZCN44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gRnJlceOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieOBq+S7mOmaj+OBmeOCi+mgu+W6puWApOOBoOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczHjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3Mx44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMuOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczLjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgaGp1c3QgPSAw44Gv44CB5paH5a2X44KS5bem5o+D44GI44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5Luk77yI44OH44OV44Kp44Or44OI44Gv5Lit5aSu5o+D44GI77yJDQojIHNpemUgPSA044Gv44CB44K144Kk44K6NOOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOOBk+OBruWApOOBq+W/nOOBmOOBpm51ZGdlX3njgoLpganlrpzoqr/mlbTjgZnjgovvvIkNCmcyIDwtIGcgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBub2RlKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MxLCBoanVzdCA9IDAsIHNpemUgPSA0KSArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IEZyZXF1ZW5jeSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMiwgaGp1c3QgPSAwLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQojIyBXNi40IOWHuuePvumghu+8iOe4pjjDl+aoqjjjgqTjg7Pjg4HvvIkNCuWFpeWKm+ODleOCoeOCpOODq+OBr+OAgVtKU0xBQjI4X3JlczIuY3N2XShKU0xBQjI4X3JlczIuY3N2KeOBp+OBmeOAguWfuuacrOeahOOBq1c2LjLjgajlkIzjgZjjgafjgZnjgYzjgIHmnIDntYLjga7kvZzlm7PmrrXpmo7jgavjgYrjgYTjgabjgIHmqKrluYXjgajnuKbluYXjgpLjgajjgoLjgas444Kk44Oz44OB44GX44Gm44GE44G+44GZ44CCaHRtbOOCkuimi+OCi+mZkOOCiuOBp+OBr+OAgVc2LjLvvIjlm7M2Yu+8ieOBruOCueOCr+ODquODl+ODiOOBqOWQjOS4gOOBp+OBmeOBjOOAgeOBk+OBrmh0bWzkvZzmiJDmmYLjgavliKnnlKjjgZfjgabjgYTjgotSbWTjg5XjgqHjgqTjg6vjga7kuK3jgatS44OB44Oj44Oz44Kv44Kq44OX44K344On44Oz44Go44GX44Gm44CMZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OOOAjeOBjOi/veWKoOOBleOCjOOBpuOBhOOBvuOBmeOAgg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQ0KaW5fZiA8LSAiSlNMQUIyOF9yZXMyLmNzdiIgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQpwYXJhbV9vcmRlciA8LSAiYXNfaXMiICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg47jg7zjg4njga7kuKbjgbPvvIjjg4fjg5Xjgqnjg6vjg4jjga8iYXNjZW5kaW5nIu+8iQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygiVHJ1dGgiLCAiSzMiLCAiSzQiLCAiSzUiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcXVlbmN5IikgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlcikgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IG1hdG9tZSwgICAgICAgICAgICAgICAgICAgICAgICMgZ2dwbG906Zai5pWw5a6f6KGM57WQ5p6c44KSZ+OBq+agvOe0jeOAguWFpeWKm+OBr21hdG9tZeOCquODluOCuOOCp+OCr+ODiA0KICBtYXBwaW5nID0gYWVzKHggPSBzdGFnZSwgeSA9IEZyZXF1ZW5jeSwgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgahGcmVxZW5jeeWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSBzdW0oZGF0YSRGcmVxdWVuY3kpKjAuMDIwICAgICAgICAgIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIsICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcXVlbmN5KSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOOCsOODquODg+ODiee3muOCkua2iOOBmQ0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLCAgICAgICAgICAgICMg5Yeh5L6L44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCiMjIFc2LjUg5piH6aCG77yI57imNcOX5qiqNeOCpOODs+ODge+8iQ0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFLCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD01fQ0KaW5fZiA8LSAiSlNMQUIyOF9yZXMuY3N2IiAgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQpwYXJhbV9vcmRlciA8LSAiYXNjZW5kaW5nIiAgICAgICAgICAgICAgICAgICAgICAgIyDjg47jg7zjg4njga7kuKbjgbPvvIjjg4fjg5Xjgqnjg6vjg4jjga8iYXNjZW5kaW5nIu+8iQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygiVHJ1dGgiLCAiSzMiLCAiSzQiLCAiSzUiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcXVlbmN5IikgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlcikgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IG1hdG9tZSwgICAgICAgICAgICAgICAgICAgICAgICMgZ2dwbG906Zai5pWw5a6f6KGM57WQ5p6c44KSZ+OBq+agvOe0jeOAguWFpeWKm+OBr21hdG9tZeOCquODluOCuOOCp+OCr+ODiA0KICBtYXBwaW5nID0gYWVzKHggPSBzdGFnZSwgeSA9IEZyZXF1ZW5jeSwgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgahGcmVxZW5jeeWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSBzdW0oZGF0YSRGcmVxdWVuY3kpKjAuMDIwICAgICAgICAgIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIsICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcXVlbmN5KSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOOCsOODquODg+ODiee3muOCkua2iOOBmQ0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLCAgICAgICAgICAgICMg5Yeh5L6L44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCiMjIFc2LjYg5piH6aCG77yI57imOMOX5qiqOOOCpOODs+ODge+8iQ0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQ0KaW5fZiA8LSAiSlNMQUIyOF9yZXMuY3N2IiAgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQpwYXJhbV9vcmRlciA8LSAiYXNjZW5kaW5nIiAgICAgICAgICAgICAgICAgICAgICAgIyDjg47jg7zjg4njga7kuKbjgbPvvIjjg4fjg5Xjgqnjg6vjg4jjga8iYXNjZW5kaW5nIu+8iQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygiVHJ1dGgiLCAiSzMiLCAiSzQiLCAiSzUiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcXVlbmN5IikgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlcikgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IG1hdG9tZSwgICAgICAgICAgICAgICAgICAgICAgICMgZ2dwbG906Zai5pWw5a6f6KGM57WQ5p6c44KSZ+OBq+agvOe0jeOAguWFpeWKm+OBr21hdG9tZeOCquODluOCuOOCp+OCr+ODiA0KICBtYXBwaW5nID0gYWVzKHggPSBzdGFnZSwgeSA9IEZyZXF1ZW5jeSwgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgahGcmVxZW5jeeWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSBzdW0oZGF0YSRGcmVxdWVuY3kpKjAuMDIwICAgICAgICAgIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIsICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcXVlbmN5KSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOOCsOODquODg+ODiee3muOCkua2iOOBmQ0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLCAgICAgICAgICAgICMg5Yeh5L6L44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCiMjIFc2Ljcg6ZmN6aCG77yI57imNcOX5qiqNeOCpOODs+ODge+8iQ0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFLCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD01fQ0KaW5fZiA8LSAiSlNMQUIyOF9yZXMuY3N2IiAgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQpwYXJhbV9vcmRlciA8LSAiZGVzY2VuZGluZyIgICAgICAgICAgICAgICAgICAgICAgIyDjg47jg7zjg4njga7kuKbjgbPvvIjjg4fjg5Xjgqnjg6vjg4jjga8iYXNjZW5kaW5nIu+8iQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygiVHJ1dGgiLCAiSzMiLCAiSzQiLCAiSzUiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcXVlbmN5IikgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlcikgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IG1hdG9tZSwgICAgICAgICAgICAgICAgICAgICAgICMgZ2dwbG906Zai5pWw5a6f6KGM57WQ5p6c44KSZ+OBq+agvOe0jeOAguWFpeWKm+OBr21hdG9tZeOCquODluOCuOOCp+OCr+ODiA0KICBtYXBwaW5nID0gYWVzKHggPSBzdGFnZSwgeSA9IEZyZXF1ZW5jeSwgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgahGcmVxZW5jeeWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSBzdW0oZGF0YSRGcmVxdWVuY3kpKjAuMDIwICAgICAgICAgIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIsICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcXVlbmN5KSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOOCsOODquODg+ODiee3muOCkua2iOOBmQ0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLCAgICAgICAgICAgICMg5Yeh5L6L44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCiMjIFc2Ljgg6ZmN6aCG77yI57imOMOX5qiqOOOCpOODs+ODge+8iQ0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQ0KaW5fZiA8LSAiSlNMQUIyOF9yZXMuY3N2IiAgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQpwYXJhbV9vcmRlciA8LSAiZGVzY2VuZGluZyIgICAgICAgICAgICAgICAgICAgICAgIyDjg47jg7zjg4njga7kuKbjgbPvvIjjg4fjg5Xjgqnjg6vjg4jjga8iYXNjZW5kaW5nIu+8iQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygiVHJ1dGgiLCAiSzMiLCAiSzQiLCAiSzUiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcXVlbmN5IikgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlcikgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IG1hdG9tZSwgICAgICAgICAgICAgICAgICAgICAgICMgZ2dwbG906Zai5pWw5a6f6KGM57WQ5p6c44KSZ+OBq+agvOe0jeOAguWFpeWKm+OBr21hdG9tZeOCquODluOCuOOCp+OCr+ODiA0KICBtYXBwaW5nID0gYWVzKHggPSBzdGFnZSwgeSA9IEZyZXF1ZW5jeSwgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgahGcmVxZW5jeeWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSBzdW0oZGF0YSRGcmVxdWVuY3kpKjAuMDIwICAgICAgICAgIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIsICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcXVlbmN5KSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOOCsOODquODg+ODiee3muOCkua2iOOBmQ0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLCAgICAgICAgICAgICMg5Yeh5L6L44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCiMjIFc2Ljkg5Ye654++6aCG77yI57imNcOX5qiqN+OCpOODs+ODge+8iQ0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGVycm9yPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGV2YWw9VFJVRSwgY29tbWVudD0iIiwgcmVzdWx0cz1UUlVFLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD01fQ0KaW5fZiA8LSAiSlNMQUIyOF9yZXMuY3N2IiAgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44OV44Kh44Kk44Or5ZCNDQpwYXJhbV9vcmRlciA8LSAiYXNfaXMiICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg47jg7zjg4njga7kuKbjgbPvvIjjg4fjg5Xjgqnjg6vjg4jjga8iYXNjZW5kaW5nIu+8iQ0KDQojIOW/heimgeOBquODkeODg+OCseODvOOCuOOCkuODreODvOODiQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQpsaWJyYXJ5KGdnc2Fua2V5ZmllcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCg0KIyDlhaXlipvjg5XjgqHjgqTjg6vjga7oqq3jgb/ovrzjgb8NCmRhdGEgPC0gcmVhZF9jc3YoaW5fZikgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluX2bjgafmjIflrprjgZfjgZ/jg5XjgqHjgqTjg6vjga7oqq3ovrwNCg0KIyDliY3lh6bnkIbvvIjmj4/nlLvjgZXjgZvjgZ/jgYTliJfmg4XloLHjga7mir3lh7rjgahsb25n5Z6L44G444Gu5aSJ5o+bDQptYXRvbWUgPC0gcGl2b3Rfc3RhZ2VzX2xvbmdlciggICAgICAgICAgICAgICAgICAgIyBsb25n5Z6L44OH44O844K/44G444Gu5aSJ5o+bDQogICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjga9kYXRh44Kq44OW44K444Kn44Kv44OIICAgDQogICAgICAgICAgICAgIHN0YWdlc19mcm9tID0gYygiVHJ1dGgiLCAiSzMiLCAiSzQiLCAiSzUiKSwgIyDmj4/nlLvjgZXjgZvjgZ/jgYTjgqvjg4bjgrTjg6rlkI3mg4XloLENCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSAiRnJlcXVlbmN5IikgICAgICAgICAjIOmgu+W6puOCkuOCq+OCpuODs+ODiOOBl+OBn+OBhOWIl+WQjeaDheWgsQ0KDQojIOS9nOWbszHvvIjjgrXjg7Pjgq3jg7zlm7Pjga7ln7rmnKzlvaLjgb7jgafkvZzmiJDjgZfjgZ/ntZDmnpzjgpJn44Gr5qC857SN77yJDQpwb3MgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlcikgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KZyA8LSBnZ3Bsb3QoZGF0YSA9IG1hdG9tZSwgICAgICAgICAgICAgICAgICAgICAgICMgZ2dwbG906Zai5pWw5a6f6KGM57WQ5p6c44KSZ+OBq+agvOe0jeOAguWFpeWKm+OBr21hdG9tZeOCquODluOCuOOCp+OCr+ODiA0KICBtYXBwaW5nID0gYWVzKHggPSBzdGFnZSwgeSA9IEZyZXF1ZW5jeSwgICAgICAgICMgbWF0b21l44Guc3RhZ2XliJfjgahGcmVxZW5jeeWIl+OCknjou7jjgah56Lu444Go44GX44Gm5Yip55SoDQogICAgICAgICAgICAgICAgZ3JvdXAgPSBub2RlLCBmaWxsID0gbm9kZSwgICAgICAgIyBncm91cOOBqGZpbGzjga/jgIFtYXRvbWXlhoXjga5ub2Rl5YiX44Gn6KGM44GG77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgZWRnZV9pZCA9IGVkZ2VfaWQsICAgICAgICAgICAgICAgIyBlZGdlX2lk44GvbWF0b21l5YaF44GuZWRnZV9pZOWIl++8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGNvbm5lY3RvcikpICsgICAgICAgICMgY29ubmVjdG9y44GvbWF0b21l5YaF44GuY29ubmVjdG9y5YiX77yI5aSJ5pu05LiN6KaB77yJDQogIGdlb21fc2Fua2V5bm9kZShwb3NpdGlvbiA9IHBvcykgKyAgICAgICAgICAgICAgIyDjg47jg7zjg4nmg4XloLHjgpLov73liqANCiAgZ2VvbV9zYW5rZXllZGdlKHBvc2l0aW9uID0gcG9zKSAgICAgICAgICAgICAgICAjIOOCqOODg+OCuOaDheWgseOCkui/veWKoA0KDQojIOS9nOWbszItMe+8iOODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkuaPj+eUu+OBmeOCi+mam+OBq+WIqeeUqOOBmeOCi+W+ruiqv+aVtOeUqOOBruODkeODqeODoeODvOOCv+S9nOaIkO+8iQ0KIyB56Lu444Gu6auY44GV44Gv5YWl5Yqb44OV44Kh44Kk44Or44Gu6KGM5pWw5qyh56ys44Gq44Gu44Gn44CBbnJvdyhkYXRhKeOBruS9lSXnqIvluqbkuIrkuIvjgavjgZrjgonjgZnjgYvjgajjgYTjgYbmhJ/jgZjjga7oqIjnrpfjgpLjgZfjgabjgYTjgosNCiMgbnVkZ2VfeOOBqG51ZGdlX3njga/jgIF46Lu444Goeei7uOOBneOCjOOBnuOCjOOBruaWueWQkeOBq+WwkeOBl+OBmuOCieOBl+OBn+OBhOWApOOBp+OBme+8iG51ZGdl44Gv5bCP56qB44GP44Go44GE44GG5oSP5ZGz77yJDQpudWRnZV92YWxfeSA8LSBzdW0oZGF0YSRGcmVxdWVuY3kpKjAuMDIwICAgICAgICAgIyB56Lu45LiK44Gu5o+P55S75L2N572u44KS44OZ44O844K544Op44Kk44Oz44GL44KJ5LiK5LiL44Gr44Ga44KJ44GX44Gf44GE6auY44GV44Gu5bmF5oOF5aCxDQpwb3MxIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIsICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSBudWRnZV92YWxfeSkgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4iuOBq+OBmuOCieOBme+8iQ0KcG9zMiA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gLW51ZGdlX3ZhbF95KSAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIvjgavjgZrjgonjgZnvvIkNCg0KIyDkvZzlm7MyLTLvvIjln7rmnKzlvaJn44KS44OZ44O844K544Go44GX44Gm44CB44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS6L+95Yqg44GX44Gf57WQ5p6c44KSZzLjgavmoLzntI3vvIkNCiMgc3RhdCA9ICJzYW5rZXlub2RlIuOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieaDheWgseOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IG5vZGXjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nlkI3jgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBGcmVx44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ44Gr5LuY6ZqP44GZ44KL6aC75bqm5YCk44Gg44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMeOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczHjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3My44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMuOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBoanVzdCA9IDDjga/jgIHmloflrZfjgpLlt6bmj4PjgYjjgafmj4/nlLvjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjg4fjg5Xjgqnjg6vjg4jjga/kuK3lpK7mj4PjgYjvvIkNCiMgc2l6ZSA9IDTjga/jgIHjgrXjgqTjgro044Gr44Gb44KI44Go44GE44GG5oyH5Luk77yI44GT44Gu5YCk44Gr5b+c44GY44GmbnVkZ2VfeeOCgumBqeWunOiqv+aVtOOBmeOCi++8iQ0KZzIgPC0gZyArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczEsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gRnJlcXVlbmN5KSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MyLCBoanVzdCA9IDAsIHNpemUgPSA0KQ0KDQojIOS9nOWbszPvvIhnMuOCkuODmeODvOOCueOBqOOBl+OBpuOAgeiDjOaZr+OChOWHoeS+i+OBquOBqeOCkua2iOOBmeOBquOBqeOBruiqv+aVtOOCkuihjOOBo+OBn+e1kOaenOOCkmcz44Gr5qC857SN77yJDQpnMyA8LSBnMiArIHRoZW1lX21pbmltYWwoKSArICAgICAgICAgICAgICAgICAgICAgIyDog4zmma/jgpLnmb3jgavlpInmm7QNCiAgICAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOOCsOODquODg+ODiee3muOCkua2iOOBmQ0KICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLCAgICAgICAgICAgICMg5Yeh5L6L44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDou7jjga7jgr/jgqTjg4jjg6vjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAjIHnou7jjga7jg6Hjg6Ljg6rooajnpLrjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICMgeOi7uO+8iOOCq+ODhuOCtOODquWQje+8ieOBr+OCteOCpOOCujE144Gr44Gb44KIDQpnMw0KYGBgDQoNCiMjIFc2LjEwIOaYh+mghu+8iOe4pjfDl+aoqjXjgqTjg7Pjg4HvvIkNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1UUlVFLCB3YXJuaW5nPUZBTFNFLCBldmFsPVRSVUUsIGNvbW1lbnQ9IiIsIHJlc3VsdHM9VFJVRSwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9N30NCmluX2YgPC0gIkpTTEFCMjhfcmVzLmNzdiIgICAgICAgICAgICAgICAgICAgICAgICAjIOWFpeWKm+ODleOCoeOCpOODq+WQjQ0KcGFyYW1fb3JkZXIgPC0gImFzY2VuZGluZyIgICAgICAgICAgICAgICAgICAgICAgICMg44OO44O844OJ44Gu5Lim44Gz77yI44OH44OV44Kp44Or44OI44GvImFzY2VuZGluZyLvvIkNCg0KIyDlv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLjg63jg7zjg4kNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KbGlicmFyeShnZ3NhbmtleWZpZXIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICMg44OR44OD44Kx44O844K444Gu6Kqt6L68DQoNCiMg5YWl5Yqb44OV44Kh44Kk44Or44Gu6Kqt44G/6L6844G/DQpkYXRhIDwtIHJlYWRfY3N2KGluX2YpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbl9m44Gn5oyH5a6a44GX44Gf44OV44Kh44Kk44Or44Gu6Kqt6L68DQoNCiMg5YmN5Yem55CG77yI5o+P55S744GV44Gb44Gf44GE5YiX5oOF5aCx44Gu5oq95Ye644GobG9uZ+Wei+OBuOOBruWkieaPmw0KbWF0b21lIDwtIHBpdm90X3N0YWdlc19sb25nZXIoICAgICAgICAgICAgICAgICAgICMgbG9uZ+Wei+ODh+ODvOOCv+OBuOOBruWkieaPmw0KICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgICAgICAgICAgICAgICAgICAgICAgICMg5YWl5Yqb44GvZGF0YeOCquODluOCuOOCp+OCr+ODiCAgIA0KICAgICAgICAgICAgICBzdGFnZXNfZnJvbSA9IGMoIlRydXRoIiwgIkszIiwgIks0IiwgIks1IiksICMg5o+P55S744GV44Gb44Gf44GE44Kr44OG44K044Oq5ZCN5oOF5aCxDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gIkZyZXF1ZW5jeSIpICAgICAgICAgIyDpoLvluqbjgpLjgqvjgqbjg7Pjg4jjgZfjgZ/jgYTliJflkI3mg4XloLENCg0KIyDkvZzlm7Mx77yI44K144Oz44Kt44O85Zuz44Gu5Z+65pys5b2i44G+44Gn5L2c5oiQ44GX44Gf57WQ5p6c44KSZ+OBq+agvOe0je+8iQ0KcG9zIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIpICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCmcgPC0gZ2dwbG90KGRhdGEgPSBtYXRvbWUsICAgICAgICAgICAgICAgICAgICAgICAjIGdncGxvdOmWouaVsOWun+ihjOe1kOaenOOCkmfjgavmoLzntI3jgILlhaXlipvjga9tYXRvbWXjgqrjg5bjgrjjgqfjgq/jg4gNCiAgbWFwcGluZyA9IGFlcyh4ID0gc3RhZ2UsIHkgPSBGcmVxdWVuY3ksICAgICAgICAjIG1hdG9tZeOBrnN0YWdl5YiX44GoRnJlcWVuY3nliJfjgpJ46Lu444Goeei7uOOBqOOBl+OBpuWIqeeUqA0KICAgICAgICAgICAgICAgIGdyb3VwID0gbm9kZSwgZmlsbCA9IG5vZGUsICAgICAgICMgZ3JvdXDjgahmaWxs44Gv44CBbWF0b21l5YaF44Gubm9kZeWIl+OBp+ihjOOBhu+8iOWkieabtOS4jeimge+8iQ0KICAgICAgICAgICAgICAgIGVkZ2VfaWQgPSBlZGdlX2lkLCAgICAgICAgICAgICAgICMgZWRnZV9pZOOBr21hdG9tZeWGheOBrmVkZ2VfaWTliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBjb25uZWN0b3IgPSBjb25uZWN0b3IpKSArICAgICAgICAjIGNvbm5lY3RvcuOBr21hdG9tZeWGheOBrmNvbm5lY3RvcuWIl++8iOWkieabtOS4jeimge+8iQ0KICBnZW9tX3NhbmtleW5vZGUocG9zaXRpb24gPSBwb3MpICsgICAgICAgICAgICAgICMg44OO44O844OJ5oOF5aCx44KS6L+95YqgDQogIGdlb21fc2Fua2V5ZWRnZShwb3NpdGlvbiA9IHBvcykgICAgICAgICAgICAgICAgIyDjgqjjg4Pjgrjmg4XloLHjgpLov73liqANCg0KIyDkvZzlm7MyLTHvvIjjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLmj4/nlLvjgZnjgovpmpvjgavliKnnlKjjgZnjgovlvq7oqr/mlbTnlKjjga7jg5Hjg6njg6Hjg7zjgr/kvZzmiJDvvIkNCiMgeei7uOOBrumrmOOBleOBr+WFpeWKm+ODleOCoeOCpOODq+OBruihjOaVsOasoeesrOOBquOBruOBp+OAgW5yb3coZGF0YSnjga7kvZUl56iL5bqm5LiK5LiL44Gr44Ga44KJ44GZ44GL44Go44GE44GG5oSf44GY44Gu6KiI566X44KS44GX44Gm44GE44KLDQojIG51ZGdlX3jjgahudWRnZV9544Gv44CBeOi7uOOBqHnou7jjgZ3jgozjgZ7jgozjga7mlrnlkJHjgavlsJHjgZfjgZrjgonjgZfjgZ/jgYTlgKTjgafjgZnvvIhudWRnZeOBr+Wwj+eqgeOBj+OBqOOBhOOBhuaEj+WRs++8iQ0KbnVkZ2VfdmFsX3kgPC0gc3VtKGRhdGEkRnJlcXVlbmN5KSowLjAyMCAgICAgICAgICMgeei7uOS4iuOBruaPj+eUu+S9jee9ruOCkuODmeODvOOCueODqeOCpOODs+OBi+OCieS4iuS4i+OBq+OBmuOCieOBl+OBn+OBhOmrmOOBleOBruW5heaDheWgsQ0KcG9zMSA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ6ZaT44Gu57im5bmF6ZaT6ZqU44Gv6Ieq5YuV77yJDQogICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyLCAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4njga7kuKbjgbPvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3ggPSAwLjA2LCAgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHjou7jmg4XloLHjga7kvY3nva7jgpIwLjA25Y+z44Gr44Ga44KJ44GZ77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV95ID0gbnVkZ2VfdmFsX3kpICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh56Lu45oOF5aCx44Gu5L2N572u44KSbnVkZ2VfdmFsX3nkuIrjgavjgZrjgonjgZnvvIkNCnBvczIgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlciwgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ44Gu5Lim44Gz77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV94ID0gMC4wNiwgICAgICAgICAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh46Lu45oOF5aCx44Gu5L2N572u44KSMC4wNuWPs+OBq+OBmuOCieOBme+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IC1udWRnZV92YWxfeSkgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeei7uOaDheWgseOBruS9jee9ruOCkm51ZGdlX3ZhbF955LiL44Gr44Ga44KJ44GZ77yJDQoNCiMg5L2c5ZuzMi0y77yI5Z+65pys5b2iZ+OCkuODmeODvOOCueOBqOOBl+OBpuOAgeODjuODvOODieOBq+S7mOmaj+OBmeOCi+aDheWgseOCkui/veWKoOOBl+OBn+e1kOaenOOCkmcy44Gr5qC857SN77yJDQojIHN0YXQgPSAic2Fua2V5bm9kZSLjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4nmg4XloLHjgaDjgajjgYTjgYbmjIfku6QNCiMgbGFiZWwgPSBub2Rl44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5ZCN44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gRnJlceOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieOBq+S7mOmaj+OBmeOCi+mgu+W6puWApOOBoOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczHjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3Mx44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIHBvc2l0aW9uID0gcG9zMuOBr+OAgeW+ruiqv+aVtOeUqOaDheWgseOBqOOBl+OBpnBvczLjgpLliKnnlKjjgZvjgojjgajjgYTjgYbmjIfku6QNCiMgaGp1c3QgPSAw44Gv44CB5paH5a2X44KS5bem5o+D44GI44Gn5o+P55S744Gb44KI44Go44GE44GG5oyH5Luk77yI44OH44OV44Kp44Or44OI44Gv5Lit5aSu5o+D44GI77yJDQojIHNpemUgPSA044Gv44CB44K144Kk44K6NOOBq+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOOBk+OBruWApOOBq+W/nOOBmOOBpm51ZGdlX3njgoLpganlrpzoqr/mlbTjgZnjgovvvIkNCmcyIDwtIGcgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBub2RlKSwgc3RhdCA9ICJzYW5rZXlub2RlIiwgcG9zaXRpb24gPSBwb3MxLCBoanVzdCA9IDAsIHNpemUgPSA0KSArIA0KICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IEZyZXF1ZW5jeSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMiwgaGp1c3QgPSAwLCBzaXplID0gNCkNCg0KIyDkvZzlm7Mz77yIZzLjgpLjg5njg7zjgrnjgajjgZfjgabjgIHog4zmma/jgoTlh6HkvovjgarjganjgpLmtojjgZnjgarjganjga7oqr/mlbTjgpLooYzjgaPjgZ/ntZDmnpzjgpJnM+OBq+agvOe0je+8iQ0KZzMgPC0gZzIgKyB0aGVtZV9taW5pbWFsKCkgKyAgICAgICAgICAgICAgICAgICAgICMg6IOM5pmv44KS55m944Gr5aSJ5pu0DQogICAgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgICAgICAgIyDjgrDjg6rjg4Pjg4nnt5rjgpLmtojjgZkNCiAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJywgICAgICAgICAgICAjIOWHoeS+i+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg6Lu444Gu44K/44Kk44OI44Or44KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgIyB56Lu444Gu44Oh44Oi44Oq6KGo56S644KS5raI44GZDQogICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSAjIHjou7jvvIjjgqvjg4bjgrTjg6rlkI3vvInjga/jgrXjgqTjgroxNeOBq+OBm+OCiA0KZzMNCmBgYA0KDQojIyBXNi4xMSDmmIfpoIbvvIjnuKY5w5fmqKo144Kk44Oz44OB77yJDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9VFJVRSwgd2FybmluZz1GQUxTRSwgZXZhbD1UUlVFLCBjb21tZW50PSIiLCByZXN1bHRzPVRSVUUsIGZpZy53aWR0aD01LCBmaWcuaGVpZ2h0PTl9DQppbl9mIDwtICJKU0xBQjI4X3Jlcy5jc3YiICAgICAgICAgICAgICAgICAgICAgICAgIyDlhaXlipvjg5XjgqHjgqTjg6vlkI0NCnBhcmFtX29yZGVyIDwtICJhc2NlbmRpbmciICAgICAgICAgICAgICAgICAgICAgICAjIOODjuODvOODieOBruS4puOBs++8iOODh+ODleOCqeODq+ODiOOBryJhc2NlbmRpbmci77yJDQoNCiMg5b+F6KaB44Gq44OR44OD44Kx44O844K444KS44Ot44O844OJDQpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyDjg5Hjg4PjgrHjg7zjgrjjga7oqq3ovrwNCmxpYnJhcnkoZ2dzYW5rZXlmaWVyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIOODkeODg+OCseODvOOCuOOBruiqrei+vA0KDQojIOWFpeWKm+ODleOCoeOCpOODq+OBruiqreOBv+i+vOOBvw0KZGF0YSA8LSByZWFkX2Nzdihpbl9mKSAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaW5fZuOBp+aMh+WumuOBl+OBn+ODleOCoeOCpOODq+OBruiqrei+vA0KDQojIOWJjeWHpueQhu+8iOaPj+eUu+OBleOBm+OBn+OBhOWIl+aDheWgseOBruaKveWHuuOBqGxvbmflnovjgbjjga7lpInmj5sNCm1hdG9tZSA8LSBwaXZvdF9zdGFnZXNfbG9uZ2VyKCAgICAgICAgICAgICAgICAgICAjIGxvbmflnovjg4fjg7zjgr/jgbjjga7lpInmj5sNCiAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsICAgICAgICAgICAgICAgICAgICAgICAjIOWFpeWKm+OBr2RhdGHjgqrjg5bjgrjjgqfjgq/jg4ggICANCiAgICAgICAgICAgICAgc3RhZ2VzX2Zyb20gPSBjKCJUcnV0aCIsICJLMyIsICJLNCIsICJLNSIpLCAjIOaPj+eUu+OBleOBm+OBn+OBhOOCq+ODhuOCtOODquWQjeaDheWgsQ0KICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9ICJGcmVxdWVuY3kiKSAgICAgICAgICMg6aC75bqm44KS44Kr44Km44Oz44OI44GX44Gf44GE5YiX5ZCN5oOF5aCxDQoNCiMg5L2c5ZuzMe+8iOOCteODs+OCreODvOWbs+OBruWfuuacrOW9ouOBvuOBp+S9nOaIkOOBl+OBn+e1kOaenOOCkmfjgavmoLzntI3vvIkNCnBvcyA8LSBwb3NpdGlvbl9zYW5rZXkodl9zcGFjZSA9ICJhdXRvIiwgICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IHBhcmFtX29yZGVyKSAgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ44Gu5Lim44Gz77yJDQpnIDwtIGdncGxvdChkYXRhID0gbWF0b21lLCAgICAgICAgICAgICAgICAgICAgICAgIyBnZ3Bsb3TplqLmlbDlrp/ooYzntZDmnpzjgpJn44Gr5qC857SN44CC5YWl5Yqb44GvbWF0b21l44Kq44OW44K444Kn44Kv44OIDQogIG1hcHBpbmcgPSBhZXMoeCA9IHN0YWdlLCB5ID0gRnJlcXVlbmN5LCAgICAgICAgIyBtYXRvbWXjga5zdGFnZeWIl+OBqEZyZXFlbmN55YiX44KSeOi7uOOBqHnou7jjgajjgZfjgabliKnnlKgNCiAgICAgICAgICAgICAgICBncm91cCA9IG5vZGUsIGZpbGwgPSBub2RlLCAgICAgICAjIGdyb3Vw44GoZmlsbOOBr+OAgW1hdG9tZeWGheOBrm5vZGXliJfjgafooYzjgYbvvIjlpInmm7TkuI3opoHvvIkNCiAgICAgICAgICAgICAgICBlZGdlX2lkID0gZWRnZV9pZCwgICAgICAgICAgICAgICAjIGVkZ2VfaWTjga9tYXRvbWXlhoXjga5lZGdlX2lk5YiX77yI5aSJ5pu05LiN6KaB77yJDQogICAgICAgICAgICAgICAgY29ubmVjdG9yID0gY29ubmVjdG9yKSkgKyAgICAgICAgIyBjb25uZWN0b3Ljga9tYXRvbWXlhoXjga5jb25uZWN0b3LliJfvvIjlpInmm7TkuI3opoHvvIkNCiAgZ2VvbV9zYW5rZXlub2RlKHBvc2l0aW9uID0gcG9zKSArICAgICAgICAgICAgICAjIOODjuODvOODieaDheWgseOCkui/veWKoA0KICBnZW9tX3NhbmtleWVkZ2UocG9zaXRpb24gPSBwb3MpICAgICAgICAgICAgICAgICMg44Ko44OD44K45oOF5aCx44KS6L+95YqgDQoNCiMg5L2c5ZuzMi0x77yI44OO44O844OJ44Gr5LuY6ZqP44GZ44KL5oOF5aCx44KS5o+P55S744GZ44KL6Zqb44Gr5Yip55So44GZ44KL5b6u6Kq/5pW055So44Gu44OR44Op44Oh44O844K/5L2c5oiQ77yJDQojIHnou7jjga7pq5jjgZXjga/lhaXlipvjg5XjgqHjgqTjg6vjga7ooYzmlbDmrKHnrKzjgarjga7jgafjgIFucm93KGRhdGEp44Gu5L2VJeeoi+W6puS4iuS4i+OBq+OBmuOCieOBmeOBi+OBqOOBhOOBhuaEn+OBmOOBruioiOeul+OCkuOBl+OBpuOBhOOCiw0KIyBudWRnZV9444GobnVkZ2VfeeOBr+OAgXjou7jjgah56Lu444Gd44KM44Ge44KM44Gu5pa55ZCR44Gr5bCR44GX44Ga44KJ44GX44Gf44GE5YCk44Gn44GZ77yIbnVkZ2Xjga/lsI/nqoHjgY/jgajjgYTjgYbmhI/lkbPvvIkNCm51ZGdlX3ZhbF95IDwtIHN1bShkYXRhJEZyZXF1ZW5jeSkqMC4wMjAgICAgICAgICAjIHnou7jkuIrjga7mj4/nlLvkvY3nva7jgpLjg5njg7zjgrnjg6njgqTjg7PjgYvjgonkuIrkuIvjgavjgZrjgonjgZfjgZ/jgYTpq5jjgZXjga7luYXmg4XloLENCnBvczEgPC0gcG9zaXRpb25fc2Fua2V5KHZfc3BhY2UgPSAiYXV0byIsICAgICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODiemWk+OBrue4puW5hemWk+malOOBr+iHquWLle+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBwYXJhbV9vcmRlciwgICAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yI44OO44O844OJ44Gu5Lim44Gz77yJDQogICAgICAgICAgICAgICAgICAgICAgICBudWRnZV94ID0gMC4wNiwgICAgICAgICAgIyDjg47jg7zjg4nlkI3mg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIh46Lu45oOF5aCx44Gu5L2N572u44KSMC4wNuWPs+OBq+OBmuOCieOBme+8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeSA9IG51ZGdlX3ZhbF95KSAgICMg44OO44O844OJ5ZCN5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeei7uOaDheWgseOBruS9jee9ruOCkm51ZGdlX3ZhbF955LiK44Gr44Ga44KJ44GZ77yJDQpwb3MyIDwtIHBvc2l0aW9uX3NhbmtleSh2X3NwYWNlID0gImF1dG8iLCAgICAgICAgIyDpoLvluqbmg4XloLHmj4/nlLvmmYLjga7kvY3nva7mg4XloLHvvIjjg47jg7zjg4nplpPjga7nuKbluYXplpPpmpTjga/oh6rli5XvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gcGFyYW1fb3JkZXIsICAgICAjIOODjuODvOODieWQjeaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iOODjuODvOODieOBruS4puOBs++8iQ0KICAgICAgICAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IDAuMDYsICAgICAgICAgICMg6aC75bqm5oOF5aCx5o+P55S75pmC44Gu5L2N572u5oOF5aCx77yIeOi7uOaDheWgseOBruS9jee9ruOCkjAuMDblj7PjgavjgZrjgonjgZnvvIkNCiAgICAgICAgICAgICAgICAgICAgICAgIG51ZGdlX3kgPSAtbnVkZ2VfdmFsX3kpICAjIOmgu+W6puaDheWgseaPj+eUu+aZguOBruS9jee9ruaDheWgse+8iHnou7jmg4XloLHjga7kvY3nva7jgpJudWRnZV92YWxfeeS4i+OBq+OBmuOCieOBme+8iQ0KDQojIOS9nOWbszItMu+8iOWfuuacrOW9omfjgpLjg5njg7zjgrnjgajjgZfjgabjgIHjg47jg7zjg4njgavku5jpmo/jgZnjgovmg4XloLHjgpLov73liqDjgZfjgZ/ntZDmnpzjgpJnMuOBq+agvOe0je+8iQ0KIyBzdGF0ID0gInNhbmtleW5vZGUi44Gv44CB5o+P55S744GZ44KL44Gu44GM44OO44O844OJ5oOF5aCx44Gg44Go44GE44GG5oyH5LukDQojIGxhYmVsID0gbm9kZeOBr+OAgeaPj+eUu+OBmeOCi+OBruOBjOODjuODvOODieWQjeOBoOOBqOOBhOOBhuaMh+S7pA0KIyBsYWJlbCA9IEZyZXHjga/jgIHmj4/nlLvjgZnjgovjga7jgYzjg47jg7zjg4njgavku5jpmo/jgZnjgovpoLvluqblgKTjgaDjgajjgYTjgYbmjIfku6QNCiMgcG9zaXRpb24gPSBwb3Mx44Gv44CB5b6u6Kq/5pW055So5oOF5aCx44Go44GX44GmcG9zMeOCkuWIqeeUqOOBm+OCiOOBqOOBhOOBhuaMh+S7pA0KIyBwb3NpdGlvbiA9IHBvczLjga/jgIHlvq7oqr/mlbTnlKjmg4XloLHjgajjgZfjgaZwb3My44KS5Yip55So44Gb44KI44Go44GE44GG5oyH5LukDQojIGhqdXN0ID0gMOOBr+OAgeaWh+Wtl+OCkuW3puaPg+OBiOOBp+aPj+eUu+OBm+OCiOOBqOOBhOOBhuaMh+S7pO+8iOODh+ODleOCqeODq+ODiOOBr+S4reWkruaPg+OBiO+8iQ0KIyBzaXplID0gNOOBr+OAgeOCteOCpOOCujTjgavjgZvjgojjgajjgYTjgYbmjIfku6TvvIjjgZPjga7lgKTjgavlv5zjgZjjgaZudWRnZV9544KC6YGp5a6c6Kq/5pW044GZ44KL77yJDQpnMiA8LSBnICsgDQogICAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbm9kZSksIHN0YXQgPSAic2Fua2V5bm9kZSIsIHBvc2l0aW9uID0gcG9zMSwgaGp1c3QgPSAwLCBzaXplID0gNCkgKyANCiAgICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBGcmVxdWVuY3kpLCBzdGF0ID0gInNhbmtleW5vZGUiLCBwb3NpdGlvbiA9IHBvczIsIGhqdXN0ID0gMCwgc2l6ZSA9IDQpDQoNCiMg5L2c5ZuzM++8iGcy44KS44OZ44O844K544Go44GX44Gm44CB6IOM5pmv44KE5Yeh5L6L44Gq44Gp44KS5raI44GZ44Gq44Gp44Gu6Kq/5pW044KS6KGM44Gj44Gf57WQ5p6c44KSZzPjgavmoLzntI3vvIkNCmczIDwtIGcyICsgdGhlbWVfbWluaW1hbCgpICsgICAgICAgICAgICAgICAgICAgICAjIOiDjOaZr+OCkueZveOBq+WkieabtA0KICAgICAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwgICAgICAgICMg44Kw44Oq44OD44OJ57ea44KS5raI44GZDQogICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAnbm9uZScsICAgICAgICAgICAgIyDlh6HkvovjgpLmtojjgZkNCiAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICAjIOi7uOOBruOCv+OCpOODiOODq+OCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksICAgICAgICMgeei7uOOBruODoeODouODquihqOekuuOCkua2iOOBmQ0KICAgICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgIyB46Lu477yI44Kr44OG44K044Oq5ZCN77yJ44Gv44K144Kk44K6MTXjgavjgZvjgogNCmczDQpgYGANCg==