dsh-plugin-usage 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -9
- package/image-1.png +0 -0
- package/image.png +0 -0
- package/lib/client/index.js +1566 -99
- package/lib/host/fold-cache.js +117 -0
- package/lib/host/fold.js +11 -0
- package/lib/host/holidays.js +104 -0
- package/lib/host/index.js +335 -30
- package/lib/host/peak.js +107 -0
- package/lib/host/prices.js +876 -0
- package/lib/host/pricing.js +349 -0
- package/lib/host/query.js +60 -2
- package/lib/host/rpc.js +69 -36
- package/lib/host/scan.js +231 -12
- package/lib/host/settings.js +119 -76
- package/lib/host/state.js +18 -2
- package/lib/host/typert.js +221 -0
- package/package.json +11 -5
- package/screenshots.json +4 -0
- package/lib/host/client-source.js +0 -34
package/lib/client/index.js
CHANGED
|
@@ -22,6 +22,7 @@ window.__ModuleLoader__.load({
|
|
|
22
22
|
const CSS = `
|
|
23
23
|
/* ============ 布局 ============ */
|
|
24
24
|
.tsd-section {
|
|
25
|
+
position: relative;
|
|
25
26
|
width: 100%;
|
|
26
27
|
display: flex;
|
|
27
28
|
flex-direction: column;
|
|
@@ -29,6 +30,38 @@ const CSS = `
|
|
|
29
30
|
color: var(--dsw-alias-label-primary);
|
|
30
31
|
animation: tsd-fade-in 0.4s var(--ds-ease-in-out);
|
|
31
32
|
}
|
|
33
|
+
/* 刷新中的那条细进度条:贴在本节顶部,绝对定位所以不推动版面、不碰任何数字。
|
|
34
|
+
用它而不是把整块内容压暗 —— 已有数字本来就是对的,压暗只让人以为在重算。 */
|
|
35
|
+
.tsd-progress {
|
|
36
|
+
position: absolute;
|
|
37
|
+
inset: -6px 0 auto 0;
|
|
38
|
+
height: 2px;
|
|
39
|
+
overflow: hidden;
|
|
40
|
+
border-radius: 2px;
|
|
41
|
+
background: color-mix(in srgb, var(--dsw-alias-brand-primary) 18%, transparent);
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
}
|
|
44
|
+
.tsd-progress::after {
|
|
45
|
+
content: '';
|
|
46
|
+
position: absolute;
|
|
47
|
+
inset: 0 auto 0 0;
|
|
48
|
+
width: 35%;
|
|
49
|
+
border-radius: inherit;
|
|
50
|
+
background: var(--dsw-alias-brand-primary);
|
|
51
|
+
animation: tsd-indeterminate 1.2s var(--ds-ease-in-out) infinite;
|
|
52
|
+
}
|
|
53
|
+
/* 知道分母时改成确定进度:宽度就是 done/total,不再来回扫 —— 用户看到的
|
|
54
|
+
"算到哪了"是真的,而不是一个装忙的动画。 */
|
|
55
|
+
.tsd-progress[data-determinate=true]::after {
|
|
56
|
+
width: var(--tsd-progress, 0%);
|
|
57
|
+
animation: none;
|
|
58
|
+
transform: none;
|
|
59
|
+
transition: width 240ms var(--ds-ease-in-out);
|
|
60
|
+
}
|
|
61
|
+
@keyframes tsd-indeterminate {
|
|
62
|
+
from { transform: translateX(-40%); }
|
|
63
|
+
to { transform: translateX(300%); }
|
|
64
|
+
}
|
|
32
65
|
@keyframes tsd-fade-in {
|
|
33
66
|
from { opacity: 0; transform: translateY(8px); }
|
|
34
67
|
to { opacity: 1; transform: none; }
|
|
@@ -549,6 +582,49 @@ const CSS = `
|
|
|
549
582
|
text-overflow: ellipsis;
|
|
550
583
|
white-space: nowrap;
|
|
551
584
|
}
|
|
585
|
+
/* 标题带提示时给一个可发现的记号:虚线底边 + 感叹号按钮(见 HintTip)。
|
|
586
|
+
悬浮用原生 title,点击展开浮层;两段规则都在这一个组件里,别处不再各画一份。 */
|
|
587
|
+
.tsd-card-label[title] {
|
|
588
|
+
cursor: help;
|
|
589
|
+
text-decoration: underline dotted;
|
|
590
|
+
text-underline-offset: 2px;
|
|
591
|
+
}
|
|
592
|
+
.tsd-hint {
|
|
593
|
+
display: inline-flex;
|
|
594
|
+
align-items: center;
|
|
595
|
+
}
|
|
596
|
+
.tsd-hint-btn {
|
|
597
|
+
display: inline-flex;
|
|
598
|
+
align-items: center;
|
|
599
|
+
justify-content: center;
|
|
600
|
+
width: 16px;
|
|
601
|
+
height: 16px;
|
|
602
|
+
padding: 0;
|
|
603
|
+
border: none;
|
|
604
|
+
border-radius: 50%;
|
|
605
|
+
background: transparent;
|
|
606
|
+
color: var(--dsw-alias-label-tertiary);
|
|
607
|
+
cursor: help;
|
|
608
|
+
}
|
|
609
|
+
.tsd-hint-btn:hover,
|
|
610
|
+
.tsd-hint-btn-open {
|
|
611
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
612
|
+
color: var(--dsw-alias-label-primary);
|
|
613
|
+
}
|
|
614
|
+
.tsd-hint-btn:focus-visible {
|
|
615
|
+
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
616
|
+
outline-offset: 1px;
|
|
617
|
+
}
|
|
618
|
+
/* 浮层里两段规则分段读;行的左右内边距由 .tsd-popover 给,这里只补段间距 */
|
|
619
|
+
.tsd-hint-line {
|
|
620
|
+
margin: 0;
|
|
621
|
+
font-size: 12px;
|
|
622
|
+
line-height: 1.5;
|
|
623
|
+
color: var(--dsw-alias-label-secondary);
|
|
624
|
+
}
|
|
625
|
+
.tsd-hint-line + .tsd-hint-line {
|
|
626
|
+
margin-top: 6px;
|
|
627
|
+
}
|
|
552
628
|
.tsd-card-value {
|
|
553
629
|
margin-top: 8px;
|
|
554
630
|
font-size: 20px;
|
|
@@ -568,8 +644,41 @@ const CSS = `
|
|
|
568
644
|
.tsd-card-note {
|
|
569
645
|
margin-top: 4px;
|
|
570
646
|
font-size: 11px;
|
|
647
|
+
color: var(--dsw-alias-label-tertiary);
|
|
648
|
+
line-height: 1.35;
|
|
649
|
+
}
|
|
650
|
+
/* 未定价是「少算了钱」,不是普通提示:其余脚注用三级灰,这一行用警示色 */
|
|
651
|
+
.tsd-card-note-warn {
|
|
571
652
|
color: var(--dsw-alias-state-warn-primary);
|
|
572
653
|
}
|
|
654
|
+
.tsd-card-notes {
|
|
655
|
+
display: flex;
|
|
656
|
+
flex-direction: column;
|
|
657
|
+
gap: 2px;
|
|
658
|
+
}
|
|
659
|
+
/* 参考成本卡的入口按钮:跟着标题走,不抢数值行的位置 */
|
|
660
|
+
.tsd-card-action {
|
|
661
|
+
margin-left: auto;
|
|
662
|
+
display: inline-flex;
|
|
663
|
+
align-items: center;
|
|
664
|
+
justify-content: center;
|
|
665
|
+
width: 20px;
|
|
666
|
+
height: 20px;
|
|
667
|
+
padding: 0;
|
|
668
|
+
border: none;
|
|
669
|
+
border-radius: 5px;
|
|
670
|
+
background: transparent;
|
|
671
|
+
color: var(--dsw-alias-label-tertiary);
|
|
672
|
+
cursor: pointer;
|
|
673
|
+
}
|
|
674
|
+
.tsd-card-action:hover {
|
|
675
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
676
|
+
color: var(--dsw-alias-label-primary);
|
|
677
|
+
}
|
|
678
|
+
.tsd-card-action:focus-visible {
|
|
679
|
+
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
680
|
+
outline-offset: 1px;
|
|
681
|
+
}
|
|
573
682
|
|
|
574
683
|
/* ============ 卡片头部(图表 / 表格共用) ============ */
|
|
575
684
|
.tsd-card-header {
|
|
@@ -929,13 +1038,23 @@ const CSS = `
|
|
|
929
1038
|
}
|
|
930
1039
|
|
|
931
1040
|
/* ============ 刷新时的内容态 ============ */
|
|
1041
|
+
/* 不再 opacity: .55:那会让每次轮询都闪一下,且暗示"数字正在重算" ——
|
|
1042
|
+
事实上数字是上一轮的正确答案。刷新的信号交给顶部那条 2px 进度条与按钮转圈。 */
|
|
932
1043
|
.tsd-content {
|
|
933
1044
|
display: flex;
|
|
934
1045
|
flex-direction: column;
|
|
935
1046
|
gap: 16px;
|
|
936
|
-
transition: opacity var(--ds-transition-duration) var(--ds-ease-in-out);
|
|
937
1047
|
}
|
|
938
|
-
|
|
1048
|
+
|
|
1049
|
+
/* ============ 减少动态效果 ============ */
|
|
1050
|
+
/* 官方客户端同样这么写(spinner / skeletonFill 都在 prefers-reduced-motion 下关动画),
|
|
1051
|
+
我们这两个无限动画(呼吸、旋转)此前一条都没关。 */
|
|
1052
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1053
|
+
.tsd-section { animation: none; }
|
|
1054
|
+
.tsd-spinning svg { animation: none; }
|
|
1055
|
+
.tsd-skeleton, .tsd-skeleton-row { animation: none; }
|
|
1056
|
+
.tsd-progress::after { animation: none; width: 100%; opacity: 0.55; }
|
|
1057
|
+
}
|
|
939
1058
|
|
|
940
1059
|
/* ============ 无障碍 ============ */
|
|
941
1060
|
.tsd-visually-hidden {
|
|
@@ -1159,6 +1278,394 @@ const CSS = `
|
|
|
1159
1278
|
font-variant-numeric: tabular-nums;
|
|
1160
1279
|
color: var(--dsw-alias-label-primary);
|
|
1161
1280
|
}
|
|
1281
|
+
/* ============ 定价匹配弹窗 ============ */
|
|
1282
|
+
/* 遮罩铺满视口:设置面板是 overflow:hidden 的裁剪容器,弹窗不能挂在面板内部,
|
|
1283
|
+
否则宽屏下左右各被切掉一块。层级压过 popover(40),低于任何系统级浮窗。 */
|
|
1284
|
+
.tsd-price-overlay {
|
|
1285
|
+
position: fixed;
|
|
1286
|
+
inset: 0;
|
|
1287
|
+
z-index: 60;
|
|
1288
|
+
display: flex;
|
|
1289
|
+
align-items: center;
|
|
1290
|
+
justify-content: center;
|
|
1291
|
+
padding: 24px;
|
|
1292
|
+
background: var(--dsw-alias-bg-mask, rgba(0, 0, 0, 0.4));
|
|
1293
|
+
}
|
|
1294
|
+
.tsd-price-dialog {
|
|
1295
|
+
display: flex;
|
|
1296
|
+
flex-direction: column;
|
|
1297
|
+
width: min(760px, 100%);
|
|
1298
|
+
max-height: 100%;
|
|
1299
|
+
padding: 16px 18px 14px;
|
|
1300
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
1301
|
+
border-radius: 14px;
|
|
1302
|
+
background: var(--dsw-alias-bg-layer-1);
|
|
1303
|
+
box-shadow: var(--dsw-shadow-lv3);
|
|
1304
|
+
color: var(--dsw-alias-label-primary);
|
|
1305
|
+
font-size: 13px;
|
|
1306
|
+
}
|
|
1307
|
+
.tsd-price-head {
|
|
1308
|
+
display: flex;
|
|
1309
|
+
align-items: center;
|
|
1310
|
+
gap: 8px;
|
|
1311
|
+
}
|
|
1312
|
+
.tsd-price-title {
|
|
1313
|
+
margin: 0;
|
|
1314
|
+
font-size: 15px;
|
|
1315
|
+
font-weight: 600;
|
|
1316
|
+
}
|
|
1317
|
+
.tsd-price-close {
|
|
1318
|
+
margin-left: auto;
|
|
1319
|
+
display: inline-flex;
|
|
1320
|
+
align-items: center;
|
|
1321
|
+
justify-content: center;
|
|
1322
|
+
width: 24px;
|
|
1323
|
+
height: 24px;
|
|
1324
|
+
padding: 0;
|
|
1325
|
+
border: none;
|
|
1326
|
+
border-radius: 6px;
|
|
1327
|
+
background: transparent;
|
|
1328
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1329
|
+
cursor: pointer;
|
|
1330
|
+
}
|
|
1331
|
+
.tsd-price-close:hover {
|
|
1332
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
1333
|
+
color: var(--dsw-alias-label-primary);
|
|
1334
|
+
}
|
|
1335
|
+
.tsd-price-desc {
|
|
1336
|
+
margin: 6px 0 10px;
|
|
1337
|
+
font-size: 12px;
|
|
1338
|
+
line-height: 1.5;
|
|
1339
|
+
color: var(--dsw-alias-label-secondary);
|
|
1340
|
+
}
|
|
1341
|
+
/* 只有中段滚动:标题与底部按钮必须常驻,否则长表里够不到「确定」 */
|
|
1342
|
+
.tsd-price-body {
|
|
1343
|
+
flex: 1 1 auto;
|
|
1344
|
+
min-height: 0;
|
|
1345
|
+
overflow: auto;
|
|
1346
|
+
}
|
|
1347
|
+
.tsd-price-meta {
|
|
1348
|
+
display: flex;
|
|
1349
|
+
flex-wrap: wrap;
|
|
1350
|
+
align-items: baseline;
|
|
1351
|
+
gap: 4px 12px;
|
|
1352
|
+
margin-bottom: 8px;
|
|
1353
|
+
font-size: 11px;
|
|
1354
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1355
|
+
}
|
|
1356
|
+
.tsd-price-counts { color: var(--dsw-alias-label-secondary); }
|
|
1357
|
+
.tsd-price-table {
|
|
1358
|
+
width: 100%;
|
|
1359
|
+
border-collapse: collapse;
|
|
1360
|
+
font-size: 12px;
|
|
1361
|
+
}
|
|
1362
|
+
.tsd-price-table-sub {
|
|
1363
|
+
margin-top: 10px;
|
|
1364
|
+
}
|
|
1365
|
+
.tsd-price-table th {
|
|
1366
|
+
position: sticky;
|
|
1367
|
+
top: 0;
|
|
1368
|
+
z-index: 1;
|
|
1369
|
+
padding: 6px 8px;
|
|
1370
|
+
background: var(--dsw-alias-bg-layer-1);
|
|
1371
|
+
border-bottom: 1px solid var(--dsw-alias-border-l2);
|
|
1372
|
+
font-weight: 500;
|
|
1373
|
+
font-size: 11px;
|
|
1374
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1375
|
+
text-align: left;
|
|
1376
|
+
white-space: nowrap;
|
|
1377
|
+
}
|
|
1378
|
+
.tsd-price-table td {
|
|
1379
|
+
padding: 6px 8px;
|
|
1380
|
+
border-bottom: 1px solid var(--dsw-alias-border-l2);
|
|
1381
|
+
vertical-align: middle;
|
|
1382
|
+
}
|
|
1383
|
+
.tsd-price-row[data-dirty='true'] td {
|
|
1384
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
1385
|
+
}
|
|
1386
|
+
.tsd-price-model {
|
|
1387
|
+
max-width: 240px;
|
|
1388
|
+
overflow: hidden;
|
|
1389
|
+
text-overflow: ellipsis;
|
|
1390
|
+
white-space: nowrap;
|
|
1391
|
+
}
|
|
1392
|
+
.tsd-price-model-name {
|
|
1393
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
1394
|
+
font-size: 11.5px;
|
|
1395
|
+
font-weight: 500;
|
|
1396
|
+
}
|
|
1397
|
+
.tsd-price-model-provider {
|
|
1398
|
+
margin-left: 6px;
|
|
1399
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
1400
|
+
font-size: 10.5px;
|
|
1401
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1402
|
+
}
|
|
1403
|
+
/* 匹配目标格:整格是一颗紧凑的「选择」按钮(未匹配时虚线、文案是提示语),
|
|
1404
|
+
比每行摊两颗文字按钮安静得多;可搜索的下拉挂在它下面展开。 */
|
|
1405
|
+
.tsd-price-target { max-width: 230px; }
|
|
1406
|
+
.tsd-price-target-btn {
|
|
1407
|
+
display: inline-flex;
|
|
1408
|
+
align-items: center;
|
|
1409
|
+
gap: 4px;
|
|
1410
|
+
max-width: 100%;
|
|
1411
|
+
padding: 3px 6px;
|
|
1412
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
1413
|
+
border-radius: 6px;
|
|
1414
|
+
background: var(--dsw-alias-bg-layer-2);
|
|
1415
|
+
color: var(--dsw-alias-label-secondary);
|
|
1416
|
+
font: inherit;
|
|
1417
|
+
font-size: 12px;
|
|
1418
|
+
cursor: pointer;
|
|
1419
|
+
}
|
|
1420
|
+
.tsd-price-target-btn:hover {
|
|
1421
|
+
border-color: var(--dsw-alias-label-tertiary);
|
|
1422
|
+
color: var(--dsw-alias-label-primary);
|
|
1423
|
+
}
|
|
1424
|
+
.tsd-price-target-btn:focus-visible {
|
|
1425
|
+
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
1426
|
+
outline-offset: 1px;
|
|
1427
|
+
}
|
|
1428
|
+
.tsd-price-target-btn[data-empty='true'] {
|
|
1429
|
+
border-style: dashed;
|
|
1430
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1431
|
+
}
|
|
1432
|
+
.tsd-price-target-id {
|
|
1433
|
+
min-width: 0;
|
|
1434
|
+
overflow: hidden;
|
|
1435
|
+
text-overflow: ellipsis;
|
|
1436
|
+
white-space: nowrap;
|
|
1437
|
+
}
|
|
1438
|
+
.tsd-price-target-chev { flex: none; opacity: 0.7; }
|
|
1439
|
+
/* 参考模型的来源标签:DeepSeek / Zen / 自定义。10px、无边框、只在格尾占一点点,
|
|
1440
|
+
免得把 id 挤掉 —— id 自己已经会 ellipsis。 */
|
|
1441
|
+
.tsd-price-src {
|
|
1442
|
+
margin-left: 4px;
|
|
1443
|
+
padding: 0 3px;
|
|
1444
|
+
border-radius: 4px;
|
|
1445
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
1446
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1447
|
+
font-size: 10px;
|
|
1448
|
+
white-space: nowrap;
|
|
1449
|
+
}
|
|
1450
|
+
.tsd-price-src[data-source='deepseek'] { color: var(--dsw-static-blue-500); }
|
|
1451
|
+
.tsd-price-src[data-source='custom'] { color: var(--dsw-static-green-500); }
|
|
1452
|
+
/* 候选列表里的分组表头:粘在滚动容器顶部,滚到哪都知道自己在看哪一类。 */
|
|
1453
|
+
.tsd-price-pick-group {
|
|
1454
|
+
position: sticky;
|
|
1455
|
+
top: 0;
|
|
1456
|
+
padding: 4px 4px 2px;
|
|
1457
|
+
background: var(--dsw-alias-bg-layer-1);
|
|
1458
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1459
|
+
font-size: 10.5px;
|
|
1460
|
+
letter-spacing: 0.02em;
|
|
1461
|
+
}
|
|
1462
|
+
/* 空组(目前只有「自定义」)给一行说明,别让这一类隐形。 */
|
|
1463
|
+
.tsd-price-pick-sep {
|
|
1464
|
+
margin: 4px 0;
|
|
1465
|
+
border-top: 1px solid var(--dsw-alias-border-l2);
|
|
1466
|
+
}
|
|
1467
|
+
/* 「自定义」选项:顶部固定的一条,带一行说明。 */
|
|
1468
|
+
.tsd-price-pick-custom {
|
|
1469
|
+
display: flex;
|
|
1470
|
+
flex-direction: column;
|
|
1471
|
+
align-items: flex-start;
|
|
1472
|
+
gap: 2px;
|
|
1473
|
+
border: 1px dashed var(--dsw-alias-border-l2);
|
|
1474
|
+
}
|
|
1475
|
+
.tsd-price-pick-custom-label { font-weight: 500; color: var(--dsw-alias-label-primary); }
|
|
1476
|
+
.tsd-price-pick-custom-hint { font-size: 11px; color: var(--dsw-alias-label-tertiary); }
|
|
1477
|
+
/* 手填单价的三格:一行一个字段,输入框占满剩余宽度。 */
|
|
1478
|
+
.tsd-price-custom-box { gap: 8px; }
|
|
1479
|
+
.tsd-price-custom-title { font-weight: 500; }
|
|
1480
|
+
.tsd-price-custom-field {
|
|
1481
|
+
display: flex;
|
|
1482
|
+
align-items: center;
|
|
1483
|
+
gap: 8px;
|
|
1484
|
+
}
|
|
1485
|
+
.tsd-price-custom-field > span {
|
|
1486
|
+
flex: none;
|
|
1487
|
+
width: 52px;
|
|
1488
|
+
color: var(--dsw-alias-label-secondary);
|
|
1489
|
+
}
|
|
1490
|
+
.tsd-price-custom-input {
|
|
1491
|
+
box-sizing: border-box;
|
|
1492
|
+
flex: 1 1 auto;
|
|
1493
|
+
min-width: 0;
|
|
1494
|
+
height: 26px;
|
|
1495
|
+
padding: 0 8px;
|
|
1496
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
1497
|
+
border-radius: 6px;
|
|
1498
|
+
background: var(--dsw-alias-bg-layer-1);
|
|
1499
|
+
color: var(--dsw-alias-label-primary);
|
|
1500
|
+
font: inherit;
|
|
1501
|
+
font-size: 12px;
|
|
1502
|
+
}
|
|
1503
|
+
.tsd-price-custom-hint { color: var(--dsw-alias-label-tertiary); font-size: 11px; }
|
|
1504
|
+
.tsd-price-stale {
|
|
1505
|
+
margin-left: 6px;
|
|
1506
|
+
font-size: 11px;
|
|
1507
|
+
color: var(--dsw-alias-state-warn-primary);
|
|
1508
|
+
}
|
|
1509
|
+
.tsd-price-rate {
|
|
1510
|
+
font-variant-numeric: tabular-nums;
|
|
1511
|
+
white-space: nowrap;
|
|
1512
|
+
color: var(--dsw-alias-label-secondary);
|
|
1513
|
+
}
|
|
1514
|
+
/* 操作格:默认空着,只有「自定义 / 有改动」的行才给一颗还原图标。
|
|
1515
|
+
注意别给 td 设 display:flex —— 那会把单元格块级化,整列失去对齐。 */
|
|
1516
|
+
.tsd-price-ops {
|
|
1517
|
+
width: 34px;
|
|
1518
|
+
text-align: right;
|
|
1519
|
+
white-space: nowrap;
|
|
1520
|
+
}
|
|
1521
|
+
.tsd-price-reset {
|
|
1522
|
+
display: inline-flex;
|
|
1523
|
+
align-items: center;
|
|
1524
|
+
justify-content: center;
|
|
1525
|
+
width: 22px;
|
|
1526
|
+
height: 22px;
|
|
1527
|
+
padding: 0;
|
|
1528
|
+
border: 1px solid transparent;
|
|
1529
|
+
border-radius: 6px;
|
|
1530
|
+
background: none;
|
|
1531
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1532
|
+
cursor: pointer;
|
|
1533
|
+
}
|
|
1534
|
+
.tsd-price-reset:hover {
|
|
1535
|
+
border-color: var(--dsw-alias-border-l2);
|
|
1536
|
+
color: var(--dsw-alias-label-primary);
|
|
1537
|
+
}
|
|
1538
|
+
.tsd-price-reset:focus-visible {
|
|
1539
|
+
outline: 2px solid var(--dsw-alias-brand-primary);
|
|
1540
|
+
outline-offset: 1px;
|
|
1541
|
+
}
|
|
1542
|
+
.tsd-btn-xs {
|
|
1543
|
+
height: 24px;
|
|
1544
|
+
padding: 0 8px;
|
|
1545
|
+
font-size: 12px;
|
|
1546
|
+
border-radius: 6px;
|
|
1547
|
+
}
|
|
1548
|
+
/* 带图标的按钮:图标与文字同一行,间距由 gap 给,别在文案里塞空格 */
|
|
1549
|
+
.tsd-btn-icon-label {
|
|
1550
|
+
display: inline-flex;
|
|
1551
|
+
align-items: center;
|
|
1552
|
+
gap: 6px;
|
|
1553
|
+
}
|
|
1554
|
+
/* 参考模型候选是一座浮层(DSH 自己的模型选择器就是这种交互),不再塞进表格里:
|
|
1555
|
+
内联面板会把所在行撑高、把下面的行整体推走,看起来像表格坏了。 */
|
|
1556
|
+
.tsd-price-pick-box {
|
|
1557
|
+
display: flex;
|
|
1558
|
+
flex-direction: column;
|
|
1559
|
+
gap: 6px;
|
|
1560
|
+
min-height: 0;
|
|
1561
|
+
padding: 6px;
|
|
1562
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
1563
|
+
border-radius: 10px;
|
|
1564
|
+
background: var(--dsw-alias-bg-layer-1);
|
|
1565
|
+
box-shadow: var(--dsw-shadow-lv3);
|
|
1566
|
+
}
|
|
1567
|
+
/* 四态徽标:精确(蓝) / 模糊(琥珀) / 未匹配(灰) / 自定义(绿),颜色族都用真实 token */
|
|
1568
|
+
.tsd-price-badge {
|
|
1569
|
+
display: inline-block;
|
|
1570
|
+
padding: 1px 7px;
|
|
1571
|
+
border-radius: 10px;
|
|
1572
|
+
font-size: 11px;
|
|
1573
|
+
line-height: 16px;
|
|
1574
|
+
white-space: nowrap;
|
|
1575
|
+
background: var(--dsw-static-neutral-200, rgba(128, 128, 128, 0.14));
|
|
1576
|
+
color: var(--dsw-alias-label-secondary);
|
|
1577
|
+
}
|
|
1578
|
+
.tsd-price-badge[data-state='exact'] {
|
|
1579
|
+
background: color-mix(in oklab, var(--dsw-static-deepseek-500) 16%, transparent);
|
|
1580
|
+
color: var(--dsw-static-deepseek-500);
|
|
1581
|
+
}
|
|
1582
|
+
.tsd-price-badge[data-state='fuzzy'] {
|
|
1583
|
+
background: color-mix(in oklab, var(--dsw-static-amber-500) 18%, transparent);
|
|
1584
|
+
color: var(--dsw-static-amber-500);
|
|
1585
|
+
}
|
|
1586
|
+
.tsd-price-badge[data-state='custom'] {
|
|
1587
|
+
background: color-mix(in oklab, var(--dsw-static-green-500) 16%, transparent);
|
|
1588
|
+
color: var(--dsw-static-green-500);
|
|
1589
|
+
}
|
|
1590
|
+
/* 未匹配态没有主题色可用:容器那层 background: none 把徽标底色抹掉了,只剩
|
|
1591
|
+
白字压在白底上。这里给它自己的底与字色,四态才都能看见。 */
|
|
1592
|
+
.tsd-price-row[data-state='none'] .tsd-price-badge {
|
|
1593
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
1594
|
+
color: var(--dsw-alias-label-secondary);
|
|
1595
|
+
}
|
|
1596
|
+
.tsd-price-pick-input {
|
|
1597
|
+
box-sizing: border-box;
|
|
1598
|
+
width: 100%;
|
|
1599
|
+
height: 28px;
|
|
1600
|
+
padding: 0 8px;
|
|
1601
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
1602
|
+
border-radius: 6px;
|
|
1603
|
+
background: var(--dsw-alias-bg-layer-1);
|
|
1604
|
+
color: var(--dsw-alias-label-primary);
|
|
1605
|
+
font: inherit;
|
|
1606
|
+
font-size: 12px;
|
|
1607
|
+
}
|
|
1608
|
+
/* 候选列表自己滚,且必须自己封顶:useFixedPanel 只给位置和宽度,不给高度,
|
|
1609
|
+
89 个 id 摊开有近 2000px,不封顶就是一个超出视口的浮层。 */
|
|
1610
|
+
.tsd-price-pick-list {
|
|
1611
|
+
display: flex;
|
|
1612
|
+
flex-direction: column;
|
|
1613
|
+
min-height: 0;
|
|
1614
|
+
max-height: 260px;
|
|
1615
|
+
overflow: auto;
|
|
1616
|
+
}
|
|
1617
|
+
.tsd-price-pick-item {
|
|
1618
|
+
padding: 4px 8px;
|
|
1619
|
+
border: none;
|
|
1620
|
+
border-radius: 6px;
|
|
1621
|
+
background: transparent;
|
|
1622
|
+
color: var(--dsw-alias-label-primary);
|
|
1623
|
+
font: inherit;
|
|
1624
|
+
font-size: 12px;
|
|
1625
|
+
text-align: left;
|
|
1626
|
+
cursor: pointer;
|
|
1627
|
+
}
|
|
1628
|
+
.tsd-price-pick-item:hover { background: var(--dsw-alias-interactive-bg-hover); }
|
|
1629
|
+
.tsd-price-pick-item-active { color: var(--dsw-static-deepseek-500); font-weight: 600; }
|
|
1630
|
+
.tsd-price-history {
|
|
1631
|
+
margin-top: 14px;
|
|
1632
|
+
padding-top: 10px;
|
|
1633
|
+
border-top: 1px solid var(--dsw-alias-border-l2);
|
|
1634
|
+
}
|
|
1635
|
+
.tsd-price-history-toggle {
|
|
1636
|
+
display: inline-flex;
|
|
1637
|
+
align-items: center;
|
|
1638
|
+
gap: 6px;
|
|
1639
|
+
padding: 2px 0;
|
|
1640
|
+
border: none;
|
|
1641
|
+
background: transparent;
|
|
1642
|
+
color: var(--dsw-alias-label-secondary);
|
|
1643
|
+
font: inherit;
|
|
1644
|
+
font-size: 12px;
|
|
1645
|
+
cursor: pointer;
|
|
1646
|
+
}
|
|
1647
|
+
.tsd-price-history-chev { transition: transform 0.15s ease; }
|
|
1648
|
+
.tsd-price-history-chev-open { transform: rotate(180deg); }
|
|
1649
|
+
.tsd-price-empty,
|
|
1650
|
+
.tsd-price-loading {
|
|
1651
|
+
padding: 18px 0;
|
|
1652
|
+
font-size: 12px;
|
|
1653
|
+
color: var(--dsw-alias-label-tertiary);
|
|
1654
|
+
text-align: center;
|
|
1655
|
+
}
|
|
1656
|
+
.tsd-price-foot {
|
|
1657
|
+
display: flex;
|
|
1658
|
+
align-items: center;
|
|
1659
|
+
gap: 8px;
|
|
1660
|
+
margin-top: 12px;
|
|
1661
|
+
padding-top: 10px;
|
|
1662
|
+
border-top: 1px solid var(--dsw-alias-border-l2);
|
|
1663
|
+
}
|
|
1664
|
+
.tsd-price-hint {
|
|
1665
|
+
margin-left: auto;
|
|
1666
|
+
font-size: 11px;
|
|
1667
|
+
color: var(--dsw-alias-state-warn-primary);
|
|
1668
|
+
}
|
|
1162
1669
|
`
|
|
1163
1670
|
|
|
1164
1671
|
// 0.2+ host transport: POST /api/<channel>/<endpoint>, args as the JSON body,
|
|
@@ -1183,43 +1690,147 @@ function callFetch(channel, endpoint, args) {
|
|
|
1183
1690
|
}
|
|
1184
1691
|
return res.json().then((body) => {
|
|
1185
1692
|
if (body && body.ok) return body.value
|
|
1186
|
-
throw
|
|
1693
|
+
throw rpcError(body && body.error, 'RPC ' + endpoint + ' failed')
|
|
1187
1694
|
})
|
|
1188
1695
|
})
|
|
1189
1696
|
}
|
|
1190
1697
|
|
|
1698
|
+
/**
|
|
1699
|
+
* 把宿主返回的 `{code, message}` 变成可显示的错误。
|
|
1700
|
+
*
|
|
1701
|
+
* 宿主对未处理的异常只发稳定的 `internal`,细节写在宿主日志里;界面上显示本插件的
|
|
1702
|
+
* 一句话,而不是原始堆栈(原始错误不上页面)。
|
|
1703
|
+
*/
|
|
1704
|
+
function rpcError(error, fallback) {
|
|
1705
|
+
const code = error && error.code
|
|
1706
|
+
const message = code === 'internal' ? fallbackT('rpcInternalError') : ((error && error.message) || fallback)
|
|
1707
|
+
const wrapped = new Error(message)
|
|
1708
|
+
if (code) wrapped.code = code
|
|
1709
|
+
return wrapped
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1191
1712
|
// RPC bridge: dynamic-plugin runs provide a `host` global; static (bundle)
|
|
1192
1713
|
// installs provide ctx.get('connection'). Keep one UI source for both.
|
|
1714
|
+
//
|
|
1715
|
+
// Channel preference, native first: the plugin's own typert Remote namespace
|
|
1716
|
+
// (`remote['dsh-plugin-usage']`, registered by src/host/typert.js), then the
|
|
1717
|
+
// Fetch routes on Connection's shared /api channel, then the legacy /usage
|
|
1718
|
+
// prefix channel. A Remote namespace that exists but fails (host restarted
|
|
1719
|
+
// mid-flight, receiver gone) must fall through instead of bricking the page.
|
|
1720
|
+
const USAGE_REMOTE_NAMESPACE = 'dsh-plugin-usage'
|
|
1721
|
+
|
|
1722
|
+
/**
|
|
1723
|
+
* Descriptors for the client-side mount.
|
|
1724
|
+
*
|
|
1725
|
+
* The gateway's browser half wants a `src-json` result (a direct invocation is
|
|
1726
|
+
* not result-decoded), while the host contribution declares a strict codec.
|
|
1727
|
+
* Everything else must match the host field for field.
|
|
1728
|
+
*/
|
|
1729
|
+
function remoteDescriptors(packageName, names) {
|
|
1730
|
+
const argsCodec = () => ({
|
|
1731
|
+
mode: 'strict',
|
|
1732
|
+
typeSymbol: packageName + '/typert#EndpointArgs',
|
|
1733
|
+
create: () => ({ parse: (value) => value }),
|
|
1734
|
+
})
|
|
1735
|
+
return names.map((name) => ({
|
|
1736
|
+
id: packageName + '#' + packageName + '/' + name,
|
|
1737
|
+
service: packageName,
|
|
1738
|
+
namespace: packageName,
|
|
1739
|
+
method: name,
|
|
1740
|
+
invocation: { kind: 'direct' },
|
|
1741
|
+
parameters: [{ name: 'args', wire: 'args', source: 'json', codec: argsCodec() }],
|
|
1742
|
+
result: { mode: 'src-json' },
|
|
1743
|
+
}))
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
/**
|
|
1747
|
+
* Join the native Remote channel on the browser side.
|
|
1748
|
+
*
|
|
1749
|
+
* A face registered at runtime on the host is invisible to the client's `remote`
|
|
1750
|
+
* proxy until the consumer mounts it. Until the mount lands — or if it never
|
|
1751
|
+
* does — hostCall keeps using the Fetch routes, so this is an optimization,
|
|
1752
|
+
* never a hard dependency.
|
|
1753
|
+
*/
|
|
1754
|
+
function mountRemoteChannel(scope) {
|
|
1755
|
+
let remote = null
|
|
1756
|
+
try {
|
|
1757
|
+
remote = scope.get('remote')
|
|
1758
|
+
} catch (e) {
|
|
1759
|
+
return
|
|
1760
|
+
}
|
|
1761
|
+
if (!remote || typeof remote.$mount !== 'function') return
|
|
1762
|
+
fetchCall('usage/contract', {}).then((contract) => {
|
|
1763
|
+
const names = contract && Array.isArray(contract.names) ? contract.names : []
|
|
1764
|
+
if (names.length === 0) return null
|
|
1765
|
+
const packageName = contract.package || USAGE_REMOTE_NAMESPACE
|
|
1766
|
+
return Promise.resolve(remote.$mount({ package: packageName, descriptors: remoteDescriptors(packageName, names) }))
|
|
1767
|
+
}).catch(() => {
|
|
1768
|
+
// Stay on the Fetch routes; the host reports which channel it opened.
|
|
1769
|
+
})
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
function remoteCall(scope, method, args) {
|
|
1773
|
+
const name = String(method)
|
|
1774
|
+
const slash = name.indexOf('/')
|
|
1775
|
+
const endpoint = slash === -1 ? name : name.slice(slash + 1)
|
|
1776
|
+
const camel = endpoint.replace(/-([a-z])/g, (m, c) => c.toUpperCase())
|
|
1777
|
+
for (const service of [USAGE_REMOTE_NAMESPACE, 'usage']) {
|
|
1778
|
+
// `ctx.get('remote.<namespace>')` is the service key the gateway creates per
|
|
1779
|
+
// face (dsh-api-gateway client: remoteServiceKey). The `remote[namespace]`
|
|
1780
|
+
// property is the older shape and throws on the strict proxy, so it is a
|
|
1781
|
+
// guarded second choice.
|
|
1782
|
+
let namespace = null
|
|
1783
|
+
try {
|
|
1784
|
+
namespace = scope.get('remote.' + service)
|
|
1785
|
+
} catch (e) {
|
|
1786
|
+
namespace = null
|
|
1787
|
+
}
|
|
1788
|
+
if (!namespace) {
|
|
1789
|
+
try {
|
|
1790
|
+
const remote = scope.get('remote')
|
|
1791
|
+
namespace = remote ? remote[service] : null
|
|
1792
|
+
} catch (e) {
|
|
1793
|
+
namespace = null
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
if (!namespace) continue
|
|
1797
|
+
const fn = (typeof namespace[camel] === 'function' && namespace[camel])
|
|
1798
|
+
|| (typeof namespace[endpoint] === 'function' && namespace[endpoint])
|
|
1799
|
+
if (!fn) continue
|
|
1800
|
+
return Promise.resolve()
|
|
1801
|
+
.then(() => fn(args))
|
|
1802
|
+
.then((res) => {
|
|
1803
|
+
if (res && res.ok) return res.value
|
|
1804
|
+
throw rpcError(res && res.error, 'RPC ' + method + ' failed')
|
|
1805
|
+
})
|
|
1806
|
+
}
|
|
1807
|
+
return null
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1193
1810
|
function hostCall(method, args) {
|
|
1194
|
-
// P0-3: prefer the official `remote` service when it exposes the usage API;
|
|
1195
|
-
// otherwise fall through to the host/connection fallbacks unchanged.
|
|
1196
1811
|
const remoteScope = (typeof ctx !== 'undefined' && ctx && typeof ctx.get === 'function')
|
|
1197
1812
|
? ctx
|
|
1198
1813
|
: (typeof _usageCtx !== 'undefined' && _usageCtx && typeof _usageCtx.get === 'function' ? _usageCtx : null)
|
|
1199
1814
|
if (remoteScope && typeof remoteScope.get === 'function') {
|
|
1815
|
+
let pending = null
|
|
1200
1816
|
try {
|
|
1201
|
-
|
|
1202
|
-
if (remote && remote.usage) {
|
|
1203
|
-
const rName = String(method)
|
|
1204
|
-
const rSlash = rName.indexOf('/')
|
|
1205
|
-
const rEp = rSlash === -1 ? rName : rName.slice(rSlash + 1)
|
|
1206
|
-
const rCamel = rEp.replace(/-([a-z])/g, (m, c) => c.toUpperCase())
|
|
1207
|
-
const fn = (typeof remote.usage[rCamel] === 'function' && remote.usage[rCamel])
|
|
1208
|
-
|| (typeof remote.usage[rEp] === 'function' && remote.usage[rEp])
|
|
1209
|
-
if (fn) {
|
|
1210
|
-
return Promise.resolve().then(() => fn(args)).then((res) => {
|
|
1211
|
-
if (res && res.ok) return res.value
|
|
1212
|
-
throw new Error((res && res.error && res.error.message) || ('RPC ' + method + ' failed'))
|
|
1213
|
-
})
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1817
|
+
pending = remoteCall(remoteScope, method, args)
|
|
1216
1818
|
} catch (e) {
|
|
1217
|
-
|
|
1819
|
+
pending = null
|
|
1820
|
+
}
|
|
1821
|
+
if (pending !== null) {
|
|
1822
|
+
// Fall through to the Fetch routes when the Remote namespace turns out to
|
|
1823
|
+
// be unreachable — the two channels answer the same question.
|
|
1824
|
+
return pending.catch(() => fetchCall(method, args))
|
|
1218
1825
|
}
|
|
1219
1826
|
}
|
|
1220
1827
|
if (typeof host !== 'undefined' && host && typeof host.call === 'function') {
|
|
1221
1828
|
return Promise.resolve(host.call(method, args))
|
|
1222
1829
|
}
|
|
1830
|
+
return fetchCall(method, args)
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
function fetchCall(method, args) {
|
|
1223
1834
|
// Static bundle installs have no ctx/host globals: the entry apply() stores
|
|
1224
1835
|
// the real context in _usageCtx (declared by the build wrapper).
|
|
1225
1836
|
const scope = (typeof ctx !== 'undefined' && ctx && typeof ctx.get === 'function')
|
|
@@ -1241,7 +1852,7 @@ function hostCall(method, args) {
|
|
|
1241
1852
|
}
|
|
1242
1853
|
return connection.rpc.call('/' + channel.replace(/^\/+/, ''), endpoint, args).then((res) => {
|
|
1243
1854
|
if (res && res.ok) return res.value
|
|
1244
|
-
throw
|
|
1855
|
+
throw rpcError(res && res.error, 'RPC ' + method + ' failed')
|
|
1245
1856
|
})
|
|
1246
1857
|
}
|
|
1247
1858
|
// Prefer the shared-channel Fetch route; an older host answers "route
|
|
@@ -1259,6 +1870,20 @@ function hostCall(method, args) {
|
|
|
1259
1870
|
* 设置域定价:官方 `ctx.configForms.get('usage')`(dsh-client-ui-settings)优先,
|
|
1260
1871
|
* 不可用时回退 usage/prices RPC。绑定只做一次,读写共用同一 form。
|
|
1261
1872
|
* ------------------------------------------------------------------------- */
|
|
1873
|
+
/**
|
|
1874
|
+
* 原生日志通道:宿主有 logger 就写它(官方插件都走 ctx.logger),否则退回 console。
|
|
1875
|
+
* ctx 是严格代理,未注入的属性能抛,所以整段包在 try 里。
|
|
1876
|
+
*/
|
|
1877
|
+
function logWarn(message, detail) {
|
|
1878
|
+
try {
|
|
1879
|
+
const scope = (typeof _usageCtx !== 'undefined' && _usageCtx) ? _usageCtx : null
|
|
1880
|
+
const logger = scope && typeof scope.get === 'function' ? scope.get('logger') : null
|
|
1881
|
+
if (logger && typeof logger.warn === 'function') { logger.warn(message, detail); return }
|
|
1882
|
+
if (scope && scope.logger && typeof scope.logger.warn === 'function') { scope.logger.warn(message, detail); return }
|
|
1883
|
+
} catch (e) { /* no logger on this composition */ }
|
|
1884
|
+
console.warn(message, detail)
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1262
1887
|
let usageCtx = null
|
|
1263
1888
|
let _usagePricesScope = null
|
|
1264
1889
|
|
|
@@ -1358,6 +1983,55 @@ const ZH = {
|
|
|
1358
1983
|
cost: '参考成本',
|
|
1359
1984
|
approxIO: '≈ 输入+输出',
|
|
1360
1985
|
unpricedNote: '{count} 次调用未定价',
|
|
1986
|
+
// 参考成本卡上的常驻脚注:口径(卡片是估算而不是账单)+ 高峰规则(单价按
|
|
1987
|
+
// 北京时间分峰谷,不说清楚就等于藏了一条计价条件)。
|
|
1988
|
+
costSourceNote: '按 opencode Zen 和 DeepSeek 最新定价口径估算',
|
|
1989
|
+
peakRuleShort: '北京时间周一至周五 9:00-12:00、14:00-18:00 为高峰,法定节假日除外',
|
|
1990
|
+
holidayNote: '节假日数据:{range}',
|
|
1991
|
+
holidayNoteUnpublished: '节假日数据:{range};{years} 尚未公布,该年按周末判定(落在高峰窗口的节假日可能被算高)',
|
|
1992
|
+
pricingOpen: '拉取最新定价匹配',
|
|
1993
|
+
pricingTitle: '定价匹配',
|
|
1994
|
+
pricingDesc: '本会话出现过的模型会按名称逐级匹配到定价表;未匹配的按 0 计价,计入「未定价」。',
|
|
1995
|
+
pricingPull: '更新匹配表',
|
|
1996
|
+
pricingHistory: '历史匹配({n})',
|
|
1997
|
+
pricingHistoryEmpty: '还没有确认过的匹配',
|
|
1998
|
+
pricingColModel: '模型',
|
|
1999
|
+
pricingColMatch: '匹配到',
|
|
2000
|
+
pricingColState: '状态',
|
|
2001
|
+
pricingColPrice: '单价({unit} / 1M)',
|
|
2002
|
+
pricingSave: '确定',
|
|
2003
|
+
pricingClear: '恢复自动匹配',
|
|
2004
|
+
pricingApplyHint: '改完点「确定」才生效',
|
|
2005
|
+
pricingHowAlias: '按别名',
|
|
2006
|
+
// 模糊态的徽标:别名、孪生、变体后缀(-fast / -1017 / -free)都落在这一态,
|
|
2007
|
+
// 所以文案说「推测」而不是某一种推断的名字;具体依据看徽标的 tooltip。
|
|
2008
|
+
pricingHowTwin: '按名称推测',
|
|
2009
|
+
pricingHowLiteral: '按名称精确',
|
|
2010
|
+
pricingHowCustom: '用户指定',
|
|
2011
|
+
// 未匹配态的徽标文案。原来 MATCH_STATE_LABEL 指向一个不存在的键
|
|
2012
|
+
// 'unmatched',t() 缺键时原样返回 key,于是徽标上印着英文 "unmatched"。
|
|
2013
|
+
pricingHowNone: '未匹配',
|
|
2014
|
+
pricingStale: '定价表里已没有这个模型',
|
|
2015
|
+
pricingTableMeta: '数据源 {source} · 读取于 {date}',
|
|
2016
|
+
pricingCounts: '精确 {exact} · 模糊 {fuzzy} · 未匹配 {none} · 自定义 {custom}',
|
|
2017
|
+
pricingBothTiers: '高峰 {peak} · 空闲 {off}',
|
|
2018
|
+
pricingSourceDeepseek: 'DeepSeek',
|
|
2019
|
+
pricingSourceZen: 'Zen',
|
|
2020
|
+
pricingSourceCustom: '自定义',
|
|
2021
|
+
// 「自定义」是选择器顶部的一个选项,不是一组参考模型:选它就直接给这一行填三个单价。
|
|
2022
|
+
pricingCustomOption: '自定义',
|
|
2023
|
+
pricingCustomHint: '直接填每百万 Token 的单价',
|
|
2024
|
+
pricingCustomInput: '输入',
|
|
2025
|
+
pricingCustomOutput: '输出',
|
|
2026
|
+
pricingCustomCacheRead: '缓存读',
|
|
2027
|
+
pricingCustomUnit: '单位:{unit} / 1M Token',
|
|
2028
|
+
pricingCustomPending: '待填写',
|
|
2029
|
+
rpcInternalError: '统计服务出错了,细节已写进宿主日志',
|
|
2030
|
+
done: '完成',
|
|
2031
|
+
pricingCardNoteTip: '参考成本的算法、匹配范围与高峰时段规则',
|
|
2032
|
+
askEmpty: '暂无待匹配的模型',
|
|
2033
|
+
askPick: '选择参考模型',
|
|
2034
|
+
pricingFailed: '定价表拉取失败:{message}',
|
|
1361
2035
|
dailyTrend: '每日用量趋势',
|
|
1362
2036
|
barView: '柱状图',
|
|
1363
2037
|
lineView: '折线图',
|
|
@@ -1393,14 +2067,16 @@ const ZH = {
|
|
|
1393
2067
|
unpriced: '未定价',
|
|
1394
2068
|
unpricedRowHint: '该模型未配置定价,按 0 计价',
|
|
1395
2069
|
noData: '暂无数据',
|
|
2070
|
+
loading: '正在加载用量数据…',
|
|
2071
|
+
computing: '正在统计 {done}/{total} 个会话…',
|
|
1396
2072
|
emptyDesc: '该时间段内没有调用记录',
|
|
1397
2073
|
emptyFiltered: '当前筛选条件下没有数据,试试调整时间范围或模型',
|
|
1398
2074
|
resetFilters: '重置筛选',
|
|
1399
2075
|
loadFailed: '数据加载失败:{message}',
|
|
1400
2076
|
loadFailedTitle: '数据加载失败',
|
|
1401
2077
|
retry: '重试',
|
|
1402
|
-
barAria: '{key},输入 {in} Token,输出 {out} Token,合计 {tot} Token',
|
|
1403
|
-
hmTitle: '{key}:{tokens} Token{calls}',
|
|
2078
|
+
barAria: '{key},输入 {in} Token,输出 {out} Token,合计 {tot} Token,参考成本 {cost}',
|
|
2079
|
+
hmTitle: '{key}:{tokens} Token{calls},参考成本 {cost}',
|
|
1404
2080
|
hmCalls: ',{count} 次调用',
|
|
1405
2081
|
wd0: '周日',
|
|
1406
2082
|
wd1: '周一',
|
|
@@ -1449,6 +2125,48 @@ const EN = {
|
|
|
1449
2125
|
cost: 'Est. cost',
|
|
1450
2126
|
approxIO: '≈ input+output',
|
|
1451
2127
|
unpricedNote: '{count} calls unpriced',
|
|
2128
|
+
costSourceNote: 'Estimated from the current opencode Zen and DeepSeek price lists',
|
|
2129
|
+
peakRuleShort: 'Peak: Mon-Fri 09:00-12:00 and 14:00-18:00 Beijing time, excluding public holidays',
|
|
2130
|
+
holidayNote: 'Holiday calendar: {range}',
|
|
2131
|
+
holidayNoteUnpublished: 'Holiday calendar: {range}; {years} is not published yet, so that year falls back to the weekend rule (a holiday inside a peak window may be billed high)',
|
|
2132
|
+
pricingOpen: 'Pull the latest price matching',
|
|
2133
|
+
pricingTitle: 'Price matching',
|
|
2134
|
+
pricingDesc: 'Models seen in this session are matched to the price list by name, one level at a time. Anything unmatched is billed at 0 and listed under unpriced.',
|
|
2135
|
+
pricingPull: 'Update matches',
|
|
2136
|
+
pricingHistory: 'Confirmed matches ({n})',
|
|
2137
|
+
pricingHistoryEmpty: 'No match has been confirmed yet',
|
|
2138
|
+
pricingColModel: 'Model',
|
|
2139
|
+
pricingColMatch: 'Matched to',
|
|
2140
|
+
pricingColState: 'State',
|
|
2141
|
+
pricingColPrice: 'Rate ({unit} / 1M)',
|
|
2142
|
+
pricingSave: 'Apply',
|
|
2143
|
+
pricingClear: 'Back to automatic',
|
|
2144
|
+
pricingApplyHint: 'Nothing changes until you press Apply',
|
|
2145
|
+
pricingHowAlias: 'by alias',
|
|
2146
|
+
pricingHowTwin: 'inferred from the name',
|
|
2147
|
+
pricingHowLiteral: 'by exact name',
|
|
2148
|
+
pricingHowCustom: 'set by you',
|
|
2149
|
+
pricingHowNone: 'unmatched',
|
|
2150
|
+
pricingStale: 'This model is no longer in the price list',
|
|
2151
|
+
pricingTableMeta: 'Sources {source} · read {date}',
|
|
2152
|
+
pricingCounts: 'exact {exact} · fuzzy {fuzzy} · unmatched {none} · custom {custom}',
|
|
2153
|
+
pricingBothTiers: 'Peak {peak} · off-peak {off}',
|
|
2154
|
+
pricingSourceDeepseek: 'DeepSeek',
|
|
2155
|
+
pricingSourceZen: 'Zen',
|
|
2156
|
+
pricingSourceCustom: 'Custom',
|
|
2157
|
+
pricingCustomOption: 'Custom',
|
|
2158
|
+
pricingCustomHint: 'Type the per-million rates by hand',
|
|
2159
|
+
pricingCustomInput: 'Input',
|
|
2160
|
+
pricingCustomOutput: 'Output',
|
|
2161
|
+
pricingCustomCacheRead: 'Cache read',
|
|
2162
|
+
pricingCustomUnit: 'Unit: {unit} per 1M tokens',
|
|
2163
|
+
pricingCustomPending: 'not set',
|
|
2164
|
+
rpcInternalError: 'The usage service failed — details are in the host log',
|
|
2165
|
+
done: 'Done',
|
|
2166
|
+
pricingCardNoteTip: 'How the reference cost is estimated, which models it covers, and the peak-hour rule',
|
|
2167
|
+
askEmpty: 'No model is waiting to be matched',
|
|
2168
|
+
askPick: 'Choose a reference model',
|
|
2169
|
+
pricingFailed: 'Could not load the price lists: {message}',
|
|
1452
2170
|
dailyTrend: 'Daily usage trend',
|
|
1453
2171
|
barView: 'Bars',
|
|
1454
2172
|
lineView: 'Line',
|
|
@@ -1484,14 +2202,16 @@ const EN = {
|
|
|
1484
2202
|
unpriced: 'Unpriced',
|
|
1485
2203
|
unpricedRowHint: 'No pricing configured; counted as 0',
|
|
1486
2204
|
noData: 'No data',
|
|
2205
|
+
loading: 'Loading usage data…',
|
|
2206
|
+
computing: 'Computing {done}/{total} sessions…',
|
|
1487
2207
|
emptyDesc: 'No calls in this period',
|
|
1488
2208
|
emptyFiltered: 'No data for the current filters, try adjusting the range or models',
|
|
1489
2209
|
resetFilters: 'Reset filters',
|
|
1490
2210
|
loadFailed: 'Failed to load data: {message}',
|
|
1491
2211
|
loadFailedTitle: 'Failed to load data',
|
|
1492
2212
|
retry: 'Retry',
|
|
1493
|
-
barAria: '{key}, input {in} tokens, output {out} tokens, total {tot} tokens',
|
|
1494
|
-
hmTitle: '{key}: {tokens} tokens{calls}',
|
|
2213
|
+
barAria: '{key}, input {in} tokens, output {out} tokens, total {tot} tokens, {cost} reference cost',
|
|
2214
|
+
hmTitle: '{key}: {tokens} tokens{calls}, {cost} reference cost',
|
|
1495
2215
|
hmCalls: ', {count} calls',
|
|
1496
2216
|
wd0: 'Sun',
|
|
1497
2217
|
wd1: 'Mon',
|
|
@@ -1678,6 +2398,31 @@ const ICON_PATHS = {
|
|
|
1678
2398
|
// 饼图(占比):外圈 + 楔形,与卡片标题的「占比」语义一致
|
|
1679
2399
|
share: 'M21.21 15.89A10 10 0 118 2.83M22 12A10 10 0 0012 2v10z',
|
|
1680
2400
|
check: 'M20 6L9 17l-5-5',
|
|
2401
|
+
x: 'M6 6l12 12M18 6L6 18',
|
|
2402
|
+
// 拉取匹配表按钮的图标:DSH 原生 icon-context-injection-outline。16 网格、
|
|
2403
|
+
// 线宽 1.5;图形是「剪贴板 + 从顶部穿入的下载箭头 + 一条内容线」,描边沿用
|
|
2404
|
+
// 外层的 currentColor,所以每条 path 只给 d。
|
|
2405
|
+
contextInjection: {
|
|
2406
|
+
viewBox: '0 0 16 16',
|
|
2407
|
+
strokeWidth: 1.5,
|
|
2408
|
+
paths: [
|
|
2409
|
+
'M5 2.5H3.5C3.23478 2.5 2.98043 2.60536 2.79289 2.79289C2.60536 2.98043 2.5 3.23478 2.5 3.5V13.5C2.5 13.7652 2.60536 14.0196 2.79289 14.2071C2.98043 14.3946 3.23478 14.5 3.5 14.5H12.5C12.7652 14.5 13.0196 14.3946 13.2071 14.2071C13.3946 14.0196 13.5 13.7652 13.5 13.5V3.5C13.5 3.23478 13.3946 2.98043 13.2071 2.79289C13.0196 2.60536 12.7652 2.5 12.5 2.5H11',
|
|
2410
|
+
'M8 0.5V7.5',
|
|
2411
|
+
'M5.5 5L8 7.5L10.5 5',
|
|
2412
|
+
'M5.5 11H10.5',
|
|
2413
|
+
],
|
|
2414
|
+
},
|
|
2415
|
+
// 提示记号:圆圈 + 感叹号(16 网格、线宽 1.5)。原来用一个 CSS 伪元素画「?」,
|
|
2416
|
+
// 字重太小、缩到 10px 后几乎看不见,也不能点;换成真图标后可以当按钮用。
|
|
2417
|
+
hint: {
|
|
2418
|
+
viewBox: '0 0 16 16',
|
|
2419
|
+
strokeWidth: 1.5,
|
|
2420
|
+
paths: [
|
|
2421
|
+
'M8 1.75a6.25 6.25 0 1 1 0 12.5a6.25 6.25 0 1 1 0-12.5Z',
|
|
2422
|
+
'M8 4.9v3.5',
|
|
2423
|
+
'M8 11.15h.01',
|
|
2424
|
+
],
|
|
2425
|
+
},
|
|
1681
2426
|
}
|
|
1682
2427
|
function SvgIcon(props) {
|
|
1683
2428
|
const { name, size, className } = props
|
|
@@ -1771,18 +2516,25 @@ function useFixedPanel(anchorRef, open, width, gap = 6, margin = 12) {
|
|
|
1771
2516
|
* Header:标题 + 副标题 + 刷新按钮
|
|
1772
2517
|
* ------------------------------------------------------------------------- */
|
|
1773
2518
|
function StatsHeader(props) {
|
|
1774
|
-
|
|
2519
|
+
// `computing` 表示"统计还没算完"(宿主 backfill.status === 'running'),
|
|
2520
|
+
// 和 `busy`(这一轮请求在飞)不是一回事:请求几十毫秒就结束,而全量统计要几秒。
|
|
2521
|
+
// 只在请求在飞时转圈,用户就会看到"页面明明没算完却什么都不动"。
|
|
2522
|
+
const { busy, onRefresh, computing, computeDone, computeTotal } = props
|
|
1775
2523
|
const t = useT()
|
|
2524
|
+
const subtitle = computing
|
|
2525
|
+
? t('computing', { done: formatInt(computeDone || 0), total: formatInt(computeTotal || 0) })
|
|
2526
|
+
: t('subtitle')
|
|
1776
2527
|
return h('div', { className: 'tsd-header' },
|
|
1777
2528
|
h('div', { className: 'tsd-header-text' },
|
|
1778
2529
|
h('h2', { className: 'tsd-title' }, t('nav')),
|
|
1779
|
-
|
|
2530
|
+
// 副标题这一句直接换成进度句:同一个位置、同样的行高,所以不算完→算完不跳版。
|
|
2531
|
+
h('p', { className: 'tsd-subtitle', role: computing ? 'status' : null }, subtitle)),
|
|
1780
2532
|
h('button', {
|
|
1781
2533
|
type: 'button',
|
|
1782
|
-
className: 'tsd-icon-btn' + (busy ? ' tsd-spinning' : ''),
|
|
2534
|
+
className: 'tsd-icon-btn' + (busy || computing ? ' tsd-spinning' : ''),
|
|
1783
2535
|
onClick: onRefresh,
|
|
1784
2536
|
disabled: busy,
|
|
1785
|
-
'aria-busy': busy || undefined,
|
|
2537
|
+
'aria-busy': busy || computing || undefined,
|
|
1786
2538
|
title: t('refresh'),
|
|
1787
2539
|
'aria-label': t('refresh'),
|
|
1788
2540
|
}, h(SvgIcon, { name: 'refresh' })))
|
|
@@ -2089,6 +2841,20 @@ function shortModelName(key) {
|
|
|
2089
2841
|
const i = s.lastIndexOf('/')
|
|
2090
2842
|
return i === -1 ? s : s.slice(i + 1)
|
|
2091
2843
|
}
|
|
2844
|
+
/**
|
|
2845
|
+
* 「读取于」要的是真实时刻,不是日期。
|
|
2846
|
+
*
|
|
2847
|
+
* 价目表里存的是抓取那一刻的 ISO 时间(带秒、UTC);这里换成浏览器本地时区
|
|
2848
|
+
* 显示,精确到秒。早期只有日期(`2026-10-19`)的表也认得,补 00:00:00。
|
|
2849
|
+
*/
|
|
2850
|
+
function stampText(v) {
|
|
2851
|
+
if (!v) return '—'
|
|
2852
|
+
const d = new Date(v)
|
|
2853
|
+
if (Number.isNaN(d.getTime())) return String(v)
|
|
2854
|
+
const p = (n) => (n < 10 ? '0' + n : String(n))
|
|
2855
|
+
return d.getFullYear() + '-' + p(d.getMonth() + 1) + '-' + p(d.getDate()) +
|
|
2856
|
+
' ' + p(d.getHours()) + ':' + p(d.getMinutes()) + ':' + p(d.getSeconds())
|
|
2857
|
+
}
|
|
2092
2858
|
/** 宿主行是 `totalTokens`;兼容已映射成 `total` 的形状,空行也不能抛。 */
|
|
2093
2859
|
function rowTotal(r) {
|
|
2094
2860
|
return r ? (r.totalTokens || r.total || 0) : 0
|
|
@@ -2146,7 +2912,7 @@ function ModelShareBar(props) {
|
|
|
2146
2912
|
const shown = (tip && find(tip.key)) || occ.segs[0]
|
|
2147
2913
|
const labelOf = (s) => (s.key === SHARE_REST_KEY ? t('shareOther') : s.label)
|
|
2148
2914
|
const fullOf = (s) => (s.key === SHARE_REST_KEY ? t('shareOther') : s.key)
|
|
2149
|
-
const costOf = (s) => (s.
|
|
2915
|
+
const costOf = (s) => (s.unpriced === true ? t('unpriced') : formatCost(s.cost, currency))
|
|
2150
2916
|
// 悬停/聚焦:从段的视口矩形推开,fixed 定位不受设置面板 overflow 裁剪
|
|
2151
2917
|
const showTip = (e, s) => {
|
|
2152
2918
|
const r = e.currentTarget.getBoundingClientRect()
|
|
@@ -2196,11 +2962,76 @@ function ModelShareBar(props) {
|
|
|
2196
2962
|
tipBox)
|
|
2197
2963
|
}
|
|
2198
2964
|
|
|
2965
|
+
/* ---------------------------------------------------------------------------
|
|
2966
|
+
* 标题旁的提示记号
|
|
2967
|
+
*
|
|
2968
|
+
* 「点击 / 悬浮双显示」是硬要求:
|
|
2969
|
+
* - 悬浮走原生 title(浏览器自己弹,不依赖脚本,也不会被设置面板的 overflow 裁掉);
|
|
2970
|
+
* - 点击展开同一个浮层 —— 触屏没有 hover,键盘也要能读到,且浮层里两段规则换行
|
|
2971
|
+
* 读起来比一整行 tooltip 清楚得多。
|
|
2972
|
+
* 原生 title 与浮层共用同一份文本(宿主/调用方只传一次),不维护第二份文案。
|
|
2973
|
+
* ------------------------------------------------------------------------- */
|
|
2974
|
+
function HintTip(props) {
|
|
2975
|
+
const { text, label } = props
|
|
2976
|
+
const [open, setOpen] = React.useState(false)
|
|
2977
|
+
const ref = React.useRef(null)
|
|
2978
|
+
const panelStyle = useFixedPanel(ref, open, 260)
|
|
2979
|
+
useOutsideClick(open, ref, () => setOpen(false))
|
|
2980
|
+
const lines = String(text == null ? '' : text).split('\n').filter((s) => s.trim().length > 0)
|
|
2981
|
+
return h('span', { className: 'tsd-hint', ref },
|
|
2982
|
+
h('button', {
|
|
2983
|
+
type: 'button',
|
|
2984
|
+
className: 'tsd-hint-btn' + (open ? ' tsd-hint-btn-open' : ''),
|
|
2985
|
+
title: text || null,
|
|
2986
|
+
'aria-label': label || text || '',
|
|
2987
|
+
'aria-expanded': open,
|
|
2988
|
+
onClick: () => setOpen((v) => !v),
|
|
2989
|
+
onKeyDown: (e) => {
|
|
2990
|
+
if (e.key === 'Escape' && open) { e.stopPropagation(); setOpen(false) }
|
|
2991
|
+
},
|
|
2992
|
+
}, h(SvgIcon, { name: 'hint', size: 12 })),
|
|
2993
|
+
open
|
|
2994
|
+
? h('div', {
|
|
2995
|
+
className: 'tsd-popover tsd-hint-popover',
|
|
2996
|
+
style: panelStyle,
|
|
2997
|
+
role: 'note',
|
|
2998
|
+
}, lines.map((s, i) => h('p', { key: i, className: 'tsd-hint-line' }, s)))
|
|
2999
|
+
: null)
|
|
3000
|
+
}
|
|
3001
|
+
|
|
2199
3002
|
/* ---------------------------------------------------------------------------
|
|
2200
3003
|
* 汇总指标卡 ×6
|
|
2201
3004
|
* ------------------------------------------------------------------------- */
|
|
3005
|
+
|
|
3006
|
+
/**
|
|
3007
|
+
* 节假日覆盖说明:哪些年份在手、哪一年还没公布。
|
|
3008
|
+
*
|
|
3009
|
+
* 峰谷价依赖中国法定节假日表;未公布的年份只能按「周末 + 时段」判定,节假日
|
|
3010
|
+
* 落在高峰窗口内的调用会被算高。与其让这个误差隐身,不如在「参考成本」的提示
|
|
3011
|
+
* 里把覆盖范围写清楚。
|
|
3012
|
+
*/
|
|
3013
|
+
function holidayNote(pricing, t) {
|
|
3014
|
+
const years = pricing && pricing.holidays && typeof pricing.holidays === 'object'
|
|
3015
|
+
? Object.keys(pricing.holidays).map(Number).filter((n) => Number.isFinite(n)).sort((a, b) => a - b)
|
|
3016
|
+
: []
|
|
3017
|
+
if (years.length === 0) return null
|
|
3018
|
+
const range = years.length === 1 ? String(years[0]) : years[0] + '–' + years[years.length - 1]
|
|
3019
|
+
const missing = years.filter((year) => pricing.holidays[year] && pricing.holidays[year].unpublished === true)
|
|
3020
|
+
if (missing.length === 0) return t('holidayNote', { range })
|
|
3021
|
+
return t('holidayNoteUnpublished', { range, years: missing.join('、') })
|
|
3022
|
+
}
|
|
3023
|
+
|
|
3024
|
+
/* 统计卡的槽位表:骨架屏按它画占位块。
|
|
3025
|
+
*
|
|
3026
|
+
* 这张表存在的唯一理由是**别再漂**:骨架屏曾经写死 5 个占位块,而真实卡片已经
|
|
3027
|
+
* 6 张(补了「模型占比」),结果加载态少一格、数据到达时整行重排。
|
|
3028
|
+
* 槽位顺序必须与 `SummaryCards` 里的 `cards` 数组一致 —— `tests/client-slots.test.js`
|
|
3029
|
+
* 会逐字比对两边的 key 列表,改一处漏另一处直接变红。
|
|
3030
|
+
*/
|
|
3031
|
+
const SUMMARY_CARD_SLOTS = ['total', 'input', 'output', 'calls', 'cost', 'share']
|
|
3032
|
+
|
|
2202
3033
|
function SummaryCards(props) {
|
|
2203
|
-
const { total, currency, unpricedCalls, currencyCode, onCurrencyChange, byModel } = props
|
|
3034
|
+
const { total, currency, unpricedCalls, currencyCode, onCurrencyChange, byModel, pricing, onOpenPricing } = props
|
|
2204
3035
|
const tt = useT()
|
|
2205
3036
|
const d = total || {}
|
|
2206
3037
|
const inputTotal = (d.inputTokens || 0) + (d.cacheReadTokens || 0) + (d.cacheWriteTokens || 0)
|
|
@@ -2226,11 +3057,15 @@ function SummaryCards(props) {
|
|
|
2226
3057
|
color: 'var(--dsw-static-deepseek-500)',
|
|
2227
3058
|
},
|
|
2228
3059
|
{
|
|
2229
|
-
key: 'cost', icon: 'coins', label: tt('cost'),
|
|
3060
|
+
key: 'cost', icon: 'coins', label: tt('cost'), action: true,
|
|
2230
3061
|
// 符号由 prefix 的币种切换器画(它显示当前币种符号),这里只给数字
|
|
2231
3062
|
value: costDigits(d.cost), title: formatCost(d.cost, currency),
|
|
2232
3063
|
color: 'var(--dsw-static-green-500)',
|
|
2233
3064
|
prefix: h(CurrencyPicker, { code: currencyCode, onChange: onCurrencyChange }),
|
|
3065
|
+
// 「这个数怎么来的」:口径句与高峰规则原本是两行常驻小字,把小卡挤满了,
|
|
3066
|
+
// 改成标题的悬浮提示 —— 不在视野里占位,指一下就能读到全文。
|
|
3067
|
+
// 未定价条数仍然留在卡面上:它是一条待办,不是解释。
|
|
3068
|
+
tip: [tt('costSourceNote'), tt('peakRuleShort'), holidayNote(pricing, tt)].filter(Boolean).join('\n'),
|
|
2234
3069
|
},
|
|
2235
3070
|
{
|
|
2236
3071
|
key: 'share', icon: 'share', label: tt('modelShare'),
|
|
@@ -2244,21 +3079,602 @@ function SummaryCards(props) {
|
|
|
2244
3079
|
h('div', { className: 'tsd-card-head' },
|
|
2245
3080
|
h('span', { className: 'tsd-card-icon', style: { color: c.color } },
|
|
2246
3081
|
h(SvgIcon, { name: c.icon, size: 14 })),
|
|
2247
|
-
h('span', { className: 'tsd-card-label' }, c.label)
|
|
3082
|
+
h('span', { className: 'tsd-card-label', title: c.tip || null }, c.label),
|
|
3083
|
+
// 提示记号是独立按钮:悬浮有原生 title,点击展开浮层。
|
|
3084
|
+
c.tip ? h(HintTip, { text: c.tip, label: tt('pricingCardNoteTip') }) : null,
|
|
3085
|
+
// 参考成本卡的「怎么算出来的」入口:打开匹配弹窗。图标与弹窗里的
|
|
3086
|
+
// 「更新匹配表」同款(剪贴板),一眼看出两者是同一件事。
|
|
3087
|
+
c.action
|
|
3088
|
+
? h('button', {
|
|
3089
|
+
type: 'button',
|
|
3090
|
+
className: 'tsd-card-action',
|
|
3091
|
+
title: tt('pricingOpen'),
|
|
3092
|
+
'aria-label': tt('pricingOpen'),
|
|
3093
|
+
onClick: onOpenPricing,
|
|
3094
|
+
}, h(SvgIcon, { name: 'contextInjection', size: 12 }))
|
|
3095
|
+
: null),
|
|
2248
3096
|
c.content
|
|
2249
3097
|
? c.content
|
|
2250
3098
|
: h('div', { className: 'tsd-card-value', title: c.title }, c.prefix || null, c.value),
|
|
2251
|
-
|
|
3099
|
+
// 参考成本卡的脚注:口径与高峰规则已移到标题的悬浮提示,这里只剩
|
|
3100
|
+
// 「还有几次调用没定价」这条待办(有事才出现)。
|
|
2252
3101
|
c.key === 'cost' && unpricedCalls > 0
|
|
2253
|
-
? h('div', { className: 'tsd-card-
|
|
2254
|
-
|
|
3102
|
+
? h('div', { className: 'tsd-card-notes' },
|
|
3103
|
+
h('div', { className: 'tsd-card-note tsd-card-note-warn' }, tt('unpricedNote', { count: formatInt(unpricedCalls) })))
|
|
3104
|
+
: null,
|
|
3105
|
+
c.sub ? h('div', { className: 'tsd-card-sub' }, c.sub) : null)))
|
|
3106
|
+
}
|
|
3107
|
+
|
|
3108
|
+
/* ---------------------------------------------------------------------------
|
|
3109
|
+
* 定价匹配弹窗
|
|
3110
|
+
*
|
|
3111
|
+
* 解决的是「参考成本为什么是这个数」:每个模型按名称逐级匹配到定价表,匹配
|
|
3112
|
+
* 结果分四态(精确 / 模糊 / 未匹配 / 自定义),四态都能改、都能收回。
|
|
3113
|
+
*
|
|
3114
|
+
* 两条硬规则写在这里,别处不要各写一份:
|
|
3115
|
+
* 1. 打开弹窗、拉取匹配表都**不落盘**。只有「确定」才写,写入的是脏行和被
|
|
3116
|
+
* 收回的 key —— 没动过的行不写,免得把别人刚确认的匹配覆盖掉。
|
|
3117
|
+
* 2. 候选来自当前定价表的 id(宿主 propose 一并带回),不在前端另存一份名单。
|
|
3118
|
+
* ------------------------------------------------------------------------- */
|
|
3119
|
+
const MATCH_STATE_LABEL = { exact: 'pricingHowLiteral', fuzzy: 'pricingHowTwin', none: 'pricingHowNone', custom: 'pricingHowCustom' }
|
|
3120
|
+
|
|
3121
|
+
/*
|
|
3122
|
+
* 四态由宿主给(priceRow.state),前端不再解释 how。
|
|
3123
|
+
* 这里曾经有一份 matchStateOf(row),把 how 映射成四态;它写死了一个阶梯里不存在
|
|
3124
|
+
* 的值('literal'),于是所有精确命中都显示成「未匹配」——两个词表,两处维护,
|
|
3125
|
+
* 一处错就全错。现在只有一处:pricing.js 的 resolvePrice。
|
|
3126
|
+
*/
|
|
3127
|
+
|
|
3128
|
+
/** 弹窗里改动的草稿:key → { target, cleared, dirty }。 */
|
|
3129
|
+
function mergeDraft(prev, key, patch) {
|
|
3130
|
+
const next = { ...prev }
|
|
3131
|
+
const cur = next[key] || { target: null, cleared: false, dirty: false }
|
|
3132
|
+
next[key] = { ...cur, ...patch, dirty: true }
|
|
3133
|
+
return next
|
|
3134
|
+
}
|
|
3135
|
+
|
|
3136
|
+
/** 一行提交时会带什么:`undefined` = 没动过,不提交。 */
|
|
3137
|
+
function decisionOf(draft) {
|
|
3138
|
+
if (!draft || !draft.dirty) return undefined
|
|
3139
|
+
if (draft.cleared) return { key: draft.key, clear: true }
|
|
3140
|
+
if (typeof draft.target === 'string' && draft.target !== '') return { key: draft.key, target: draft.target }
|
|
3141
|
+
return undefined
|
|
3142
|
+
}
|
|
3143
|
+
|
|
3144
|
+
function PricingDialog(props) {
|
|
3145
|
+
const { onClose, onApplied, currency } = props
|
|
3146
|
+
const t = useT()
|
|
3147
|
+
const [rows, setRows] = React.useState([])
|
|
3148
|
+
const [table, setTable] = React.useState(null)
|
|
3149
|
+
const [saved, setSaved] = React.useState({})
|
|
3150
|
+
const [draft, setDraft] = React.useState({})
|
|
3151
|
+
const [status, setStatus] = React.useState('loading') // loading | ready | error
|
|
3152
|
+
const [error, setError] = React.useState(null)
|
|
3153
|
+
const [saving, setSaving] = React.useState(false)
|
|
3154
|
+
const [pickFor, setPickFor] = React.useState(null) // 正在选参考模型的 key
|
|
3155
|
+
const [pickText, setPickText] = React.useState('')
|
|
3156
|
+
const [editFor, setEditFor] = React.useState(null) // 正在手填单价的 key(自定义选项)
|
|
3157
|
+
const [historyOpen, setHistoryOpen] = React.useState(false)
|
|
3158
|
+
// 候选列表挂在行内「匹配到」那一格上:浮层是 position: fixed,撑不开表格;
|
|
3159
|
+
// 但 DOM 上仍留在那一格里 —— useOutsideClick 用 contains 判内外,必须这样挂。
|
|
3160
|
+
const pickAnchor = React.useRef(null)
|
|
3161
|
+
const closePick = React.useCallback(() => {
|
|
3162
|
+
setPickFor(null)
|
|
3163
|
+
setPickText('')
|
|
3164
|
+
}, [])
|
|
3165
|
+
const pickStyle = useFixedPanel(pickAnchor, pickFor !== null, 300, 4, 12)
|
|
3166
|
+
const customStyle = useFixedPanel(pickAnchor, editFor !== null, 280, 4, 12)
|
|
3167
|
+
useOutsideClick(pickFor !== null, pickAnchor, closePick)
|
|
3168
|
+
|
|
3169
|
+
const pull = React.useCallback(() => {
|
|
3170
|
+
setStatus('loading')
|
|
3171
|
+
setError(null)
|
|
3172
|
+
hostCall('usage/query', { fill: false, models: [], heatmap: false, backfill: false })
|
|
3173
|
+
.then((r) => {
|
|
3174
|
+
const seen = Array.isArray(r && r.models) ? r.models : []
|
|
3175
|
+
return hostCall('usage/pricing', { action: 'propose', models: seen })
|
|
3176
|
+
})
|
|
3177
|
+
.then((v) => {
|
|
3178
|
+
setRows(Array.isArray(v && v.rows) ? v.rows : [])
|
|
3179
|
+
setTable(v && v.table ? v.table : null)
|
|
3180
|
+
setSaved(v && v.matchMap ? v.matchMap : {})
|
|
3181
|
+
setDraft({})
|
|
3182
|
+
setStatus('ready')
|
|
3183
|
+
}, (e) => {
|
|
3184
|
+
setError(e)
|
|
3185
|
+
setStatus('error')
|
|
3186
|
+
})
|
|
3187
|
+
}, [])
|
|
3188
|
+
|
|
3189
|
+
React.useEffect(() => { pull() }, [pull])
|
|
3190
|
+
|
|
3191
|
+
const counts = React.useMemo(() => {
|
|
3192
|
+
const n = { exact: 0, fuzzy: 0, none: 0, custom: 0 }
|
|
3193
|
+
// 每一行都自带 state(宿主 priceRow 给的),前端不再从 how 反推 —— 反推过
|
|
3194
|
+
// 一次,写死的 'literal' 阶梯里根本不存在,所有精确命中都显示成「未匹配」。
|
|
3195
|
+
for (const r of rows) n[r.state] += 1
|
|
3196
|
+
return n
|
|
3197
|
+
}, [rows])
|
|
3198
|
+
|
|
3199
|
+
// 单价本身是美元价(价目表就是美元),显示时套用当前展示币种,和卡片同一个数。
|
|
3200
|
+
const moneyPerUsd = React.useCallback(() => (currency && currency.code === 'USD' ? 1 : 7), [currency])
|
|
3201
|
+
const moneyOf = React.useCallback((usd) => {
|
|
3202
|
+
const code = currency && currency.code === 'USD' ? 'USD' : 'CNY'
|
|
3203
|
+
const symbol = currency && currency.symbol ? currency.symbol : (CURRENCY_SYMBOLS[code] || '¥')
|
|
3204
|
+
return typeof usd === 'number' ? formatCost(usd * (code === 'USD' ? 1 : 7), symbol) : '—'
|
|
3205
|
+
}, [currency])
|
|
3206
|
+
// 表头单位必须和单元格用的是同一个符号,否则会出现「单价($ / 1M)」配「¥2.10」。
|
|
3207
|
+
const priceUnit = (currency && currency.symbol) || '¥'
|
|
3208
|
+
|
|
3209
|
+
// 待选 = 阶梯没找到价的行。判据用 state 而不是 unpriced:`unpriced` 是查询那边
|
|
3210
|
+
// 「某条记录没价」的字段,propose 的行从来没有它 —— 拿它当过滤条件的后果是待选
|
|
3211
|
+
// 表永远是空的,未匹配的模型一行都露不出来。
|
|
3212
|
+
const pending = rows.filter((r) => r.state === 'none')
|
|
3213
|
+
// 历史表 = 已经写进 matchMap 的 confirmed 记录。判据只看 matchMap:目标若已从
|
|
3214
|
+
// 价目表下线,这一行仍然留在这里(还能收回),主表里则按「未匹配」显示并标 stale。
|
|
3215
|
+
const historyRows = rows.filter((r) => saved[r.key] !== undefined)
|
|
3216
|
+
const pendingRows = pending.filter((r) => !historyRows.includes(r))
|
|
3217
|
+
const matchedRows = rows.filter((r) => r.state !== 'none' && !historyRows.includes(r))
|
|
3218
|
+
// 空状态判的是主表有没有行。此前判的是 `pending.length` —— 只要有模型按阶梯
|
|
3219
|
+
// 命中了价,第一张表就整块消失,于是「精确 / 模糊」两种状态永远没机会露面。
|
|
3220
|
+
const hasMainRows = pendingRows.length > 0 || matchedRows.length > 0
|
|
3221
|
+
|
|
3222
|
+
// 注意:组件里的 `setDraft` 是 useState 的 setter,不是上面那个纯函数。
|
|
3223
|
+
// 写成 setDraft((prev) => setDraft(prev, ...)) 会递归调自己(初值 undefined),
|
|
3224
|
+
// 所以这里用纯函数的名字 `mergeDraft` 区分开。
|
|
3225
|
+
const choose = (key, target) => {
|
|
3226
|
+
setDraft((prev) => mergeDraft(prev, key, { target, cleared: false, custom: null, key }))
|
|
3227
|
+
setEditFor(null)
|
|
3228
|
+
closePick()
|
|
3229
|
+
}
|
|
3230
|
+
const clearRow = (key) => {
|
|
3231
|
+
setDraft((prev) => mergeDraft(prev, key, { target: null, cleared: true, custom: null, key }))
|
|
3232
|
+
setEditFor((k) => (k === key ? null : k))
|
|
3233
|
+
}
|
|
3234
|
+
|
|
3235
|
+
/** 手填单价:三格,都是「每百万 Token」的展示币种金额。 */
|
|
3236
|
+
const CUSTOM_FIELDS = [['input', 'pricingCustomInput'], ['output', 'pricingCustomOutput'], ['cacheRead', 'pricingCustomCacheRead']]
|
|
3237
|
+
/** 某个 key 当前的手填值(草稿优先,其次宿主已有的自定义价)。 */
|
|
3238
|
+
const customOf = (r) => {
|
|
3239
|
+
const d = draft[r.key]
|
|
3240
|
+
if (d && d.custom) return d.custom
|
|
3241
|
+
// 宿主已按自定义价计过账:用它当前的费率回填,方便改。
|
|
3242
|
+
if (r.how === 'custom' && r.rates) {
|
|
3243
|
+
const per = moneyPerUsd()
|
|
3244
|
+
const at = r.rates.peak || r.rates.offPeak
|
|
3245
|
+
return {
|
|
3246
|
+
input: String(Number((at.input * per).toFixed(4))),
|
|
3247
|
+
output: String(Number((at.output * per).toFixed(4))),
|
|
3248
|
+
cacheRead: String(Number((at.cacheRead * per).toFixed(4))),
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
return { input: '', output: '', cacheRead: '' }
|
|
3252
|
+
}
|
|
3253
|
+
/** 开始手填:把这一行切成编辑态,草稿里先放一份可编辑的值。 */
|
|
3254
|
+
const startCustom = (key) => {
|
|
3255
|
+
const row = rows.find((x) => x.key === key)
|
|
3256
|
+
const seed = row ? customOf(row) : { input: '', output: '', cacheRead: '' }
|
|
3257
|
+
setDraft((prev) => mergeDraft(prev, key, { target: null, cleared: false, custom: seed, key }))
|
|
3258
|
+
setEditFor(key)
|
|
3259
|
+
closePick()
|
|
3260
|
+
}
|
|
3261
|
+
const setCustomField = (key, field, value) => {
|
|
3262
|
+
setDraft((prev) => {
|
|
3263
|
+
const cur = (prev[key] && prev[key].custom) || { input: '', output: '', cacheRead: '' }
|
|
3264
|
+
return mergeDraft(prev, key, { target: null, cleared: false, custom: { ...cur, [field]: value }, key })
|
|
3265
|
+
})
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
const dirtyKeys = Object.keys(draft).filter((k) => draft[k].dirty)
|
|
3269
|
+
/** 三格都能读成非负数字才算一条手填价,否则不发出去(避免把空串写成 0)。 */
|
|
3270
|
+
const customOfDraft = (d) => {
|
|
3271
|
+
if (!d || !d.custom) return null
|
|
3272
|
+
const out = {}
|
|
3273
|
+
for (const [field] of CUSTOM_FIELDS) {
|
|
3274
|
+
const raw = String(d.custom[field] == null ? '' : d.custom[field]).trim()
|
|
3275
|
+
if (raw === '') return null
|
|
3276
|
+
const v = Number(raw)
|
|
3277
|
+
if (!Number.isFinite(v) || v < 0) return null
|
|
3278
|
+
out[field] = v
|
|
3279
|
+
}
|
|
3280
|
+
return out
|
|
3281
|
+
}
|
|
3282
|
+
const submit = () => {
|
|
3283
|
+
if (dirtyKeys.length === 0 || saving) { if (dirtyKeys.length === 0) onClose(); return }
|
|
3284
|
+
const decisions = []
|
|
3285
|
+
const cleared = []
|
|
3286
|
+
const customs = []
|
|
3287
|
+
for (const k of dirtyKeys) {
|
|
3288
|
+
const d = draft[k]
|
|
3289
|
+
if (d.cleared) cleared.push(k)
|
|
3290
|
+
else if (d.custom) {
|
|
3291
|
+
const rate = customOfDraft(d)
|
|
3292
|
+
if (rate !== null) customs.push({ key: k, ...rate })
|
|
3293
|
+
} else if (typeof d.target === 'string' && d.target !== '') decisions.push({ key: k, target: d.target })
|
|
3294
|
+
}
|
|
3295
|
+
setSaving(true)
|
|
3296
|
+
hostCall('usage/pricing', { action: 'commit', decisions, cleared, customs, currency: currency && currency.code ? currency.code : 'CNY' })
|
|
3297
|
+
.then((v) => {
|
|
3298
|
+
setSaving(false)
|
|
3299
|
+
setDraft({})
|
|
3300
|
+
setEditFor(null)
|
|
3301
|
+
if (onApplied) onApplied(v)
|
|
3302
|
+
onClose()
|
|
3303
|
+
}, (e) => {
|
|
3304
|
+
setSaving(false)
|
|
3305
|
+
setError(e)
|
|
3306
|
+
setStatus('error')
|
|
3307
|
+
})
|
|
3308
|
+
}
|
|
3309
|
+
|
|
3310
|
+
const onKeyDown = (e) => {
|
|
3311
|
+
if (e.key === 'Escape') {
|
|
3312
|
+
// 一路退出:先收候选列表,再关弹窗
|
|
3313
|
+
if (pickFor !== null) { closePick(); return }
|
|
3314
|
+
onClose()
|
|
3315
|
+
}
|
|
3316
|
+
}
|
|
3317
|
+
|
|
3318
|
+
// 单价:宿主给的是两档费率(rates),tier 是它自己算的「现在按哪档显示」。
|
|
3319
|
+
// 前端只查表、不猜档 —— 之前宿主把档折成一行再发过来,另一档就凭空消失了。
|
|
3320
|
+
const rateLine = (rates) => [rates.input, rates.output, rates.cacheRead].map(moneyOf).join(' / ')
|
|
3321
|
+
const priceLine = (r) => {
|
|
3322
|
+
// 手填价:三格都填好就照填的印(它们本来就是展示币种),否则提示还没填完。
|
|
3323
|
+
const d = r ? draft[r.key] : null
|
|
3324
|
+
if (d && d.custom) {
|
|
3325
|
+
const vals = CUSTOM_FIELDS.map(([field]) => String(d.custom[field] == null ? '' : d.custom[field]).trim())
|
|
3326
|
+
if (vals.every((v) => v !== '' && Number.isFinite(Number(v)))) {
|
|
3327
|
+
return vals.map((v) => priceUnit + Number(v).toFixed(2)).join(' / ')
|
|
3328
|
+
}
|
|
3329
|
+
return t('pricingCustomPending')
|
|
3330
|
+
}
|
|
3331
|
+
return r && r.rates ? rateLine(r.rates[r.tier] || r.rates.peak) : t('unpriced')
|
|
3332
|
+
}
|
|
3333
|
+
/** 悬停时把两档都列出来:同一格只印一档,但不能让另一半价格看不见。 */
|
|
3334
|
+
const priceTitle = (r) => {
|
|
3335
|
+
if (!r || !r.rates) return null
|
|
3336
|
+
return t('pricingBothTiers', { peak: rateLine(r.rates.peak), off: rateLine(r.rates.offPeak) })
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3339
|
+
// 参考模型候选按来源分组:DeepSeek 官方、opencode Zen。「自定义」不是一个组,
|
|
3340
|
+
// 而是列表顶部的一个单独选项 —— 选它不是挑一个参考模型,而是直接给这一行填
|
|
3341
|
+
// 三个单价(输入 / 输出 / 缓存读),存进 `prices`。
|
|
3342
|
+
const SOURCE_LABEL = { deepseek: 'pricingSourceDeepseek', zen: 'pricingSourceZen', custom: 'pricingSourceCustom' }
|
|
3343
|
+
const candidateGroups = () => {
|
|
3344
|
+
if (!table || !Array.isArray(table.groups)) return []
|
|
3345
|
+
const q = pickText.trim().toLowerCase()
|
|
3346
|
+
let budget = 80
|
|
3347
|
+
const out = []
|
|
3348
|
+
for (const group of table.groups) {
|
|
3349
|
+
const all = Array.isArray(group.ids) ? group.ids : []
|
|
3350
|
+
const ids = all.filter((id) => (q === '' ? true : id.toLowerCase().includes(q)))
|
|
3351
|
+
if (ids.length === 0) continue
|
|
3352
|
+
const kept = ids.slice(0, Math.max(0, budget))
|
|
3353
|
+
budget -= kept.length
|
|
3354
|
+
out.push({ source: group.source, ids: kept })
|
|
3355
|
+
if (budget <= 0) break
|
|
3356
|
+
}
|
|
3357
|
+
return out
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3360
|
+
/** 某组里的 id 属于哪个来源(草稿刚选的目标也查得到)。 */
|
|
3361
|
+
const sourceOf = (id) => {
|
|
3362
|
+
if (!id || !table || !Array.isArray(table.groups)) return null
|
|
3363
|
+
for (const group of table.groups) {
|
|
3364
|
+
if (Array.isArray(group.ids) && group.ids.includes(id)) return group.source
|
|
3365
|
+
}
|
|
3366
|
+
return null
|
|
3367
|
+
}
|
|
3368
|
+
|
|
3369
|
+
/**
|
|
3370
|
+
* 当前行要显示的匹配目标:草稿优先于宿主的答案。
|
|
3371
|
+
*
|
|
3372
|
+
* 用户刚选完目标就要立刻看见,否则读起来像「点了没反应」;已收回的显示为空。
|
|
3373
|
+
*/
|
|
3374
|
+
const shownOf = (r) => {
|
|
3375
|
+
const d = draft[r.key]
|
|
3376
|
+
if (!d) return r.target
|
|
3377
|
+
if (d.cleared) return null
|
|
3378
|
+
if (d.custom) return null // 手填价没有参考模型 id,格子显示「自定义」
|
|
3379
|
+
return d.target
|
|
3380
|
+
}
|
|
3381
|
+
|
|
3382
|
+
/** 一行的四态:收回即未匹配,选了目标或手填价即自定义,其余用宿主给的 state。 */
|
|
3383
|
+
const stateOf = (r) => {
|
|
3384
|
+
const d = draft[r.key]
|
|
3385
|
+
if (d && d.cleared) return 'none'
|
|
3386
|
+
if (d && (d.target || d.custom)) return 'custom'
|
|
3387
|
+
return r.state
|
|
3388
|
+
}
|
|
3389
|
+
|
|
3390
|
+
/**
|
|
3391
|
+
* 选择器本体。
|
|
3392
|
+
*
|
|
3393
|
+
* 未匹配的行不再要求先点一次「选择参考模型」:展开的那一刻输入框就带焦点,
|
|
3394
|
+
* 选完直接落进草稿(仍然要按「确定」才写盘)。
|
|
3395
|
+
*/
|
|
3396
|
+
const pickerFor = (key) => {
|
|
3397
|
+
const row = rows.find((x) => x.key === key)
|
|
3398
|
+
const cur = row ? shownOf(row) : null
|
|
3399
|
+
return [
|
|
3400
|
+
h('input', {
|
|
3401
|
+
key: 'q',
|
|
3402
|
+
type: 'text',
|
|
3403
|
+
className: 'tsd-price-pick-input',
|
|
3404
|
+
value: pickText,
|
|
3405
|
+
placeholder: t('askPick'),
|
|
3406
|
+
autoFocus: true,
|
|
3407
|
+
onChange: (e) => setPickText(e.target.value),
|
|
3408
|
+
}),
|
|
3409
|
+
h('div', { key: 'l', className: 'tsd-price-pick-list', role: 'listbox' },
|
|
3410
|
+
// 顶部固定一条「自定义」:选它不是挑参考模型,而是给这一行手填三个单价。
|
|
3411
|
+
h('button', {
|
|
3412
|
+
key: 'custom',
|
|
3413
|
+
type: 'button',
|
|
3414
|
+
role: 'option',
|
|
3415
|
+
'aria-selected': 'false',
|
|
3416
|
+
className: 'tsd-price-pick-item tsd-price-pick-custom',
|
|
3417
|
+
onClick: () => startCustom(key),
|
|
3418
|
+
},
|
|
3419
|
+
h('span', { className: 'tsd-price-pick-custom-label' }, t('pricingCustomOption')),
|
|
3420
|
+
h('span', { className: 'tsd-price-pick-custom-hint' }, t('pricingCustomHint'))),
|
|
3421
|
+
h('div', { key: 'sep', className: 'tsd-price-pick-sep', role: 'presentation' }),
|
|
3422
|
+
// 一组一个表头 + 若干选项。role 保持 listbox/option,表头只是分组标签。
|
|
3423
|
+
candidateGroups().map((group) => [
|
|
3424
|
+
h('div', {
|
|
3425
|
+
key: 'g:' + group.source,
|
|
3426
|
+
className: 'tsd-price-pick-group',
|
|
3427
|
+
role: 'presentation',
|
|
3428
|
+
}, t(SOURCE_LABEL[group.source] || group.source)),
|
|
3429
|
+
...group.ids.map((id) => h('button', {
|
|
3430
|
+
key: id,
|
|
3431
|
+
type: 'button',
|
|
3432
|
+
role: 'option',
|
|
3433
|
+
'aria-selected': id === (cur || ''),
|
|
3434
|
+
className: 'tsd-price-pick-item' + (id === cur ? ' tsd-price-pick-item-active' : ''),
|
|
3435
|
+
onClick: () => choose(key, id),
|
|
3436
|
+
}, id)),
|
|
3437
|
+
])),
|
|
3438
|
+
]
|
|
3439
|
+
}
|
|
3440
|
+
|
|
3441
|
+
const bindPickAnchor = (el) => { if (el) pickAnchor.current = el }
|
|
3442
|
+
|
|
3443
|
+
const renderRow = (r) => {
|
|
3444
|
+
const d = draft[r.key]
|
|
3445
|
+
const state = stateOf(r)
|
|
3446
|
+
const shown = shownOf(r)
|
|
3447
|
+
const picking = pickFor === r.key
|
|
3448
|
+
const editing = editFor === r.key
|
|
3449
|
+
const openPick = () => { if (picking) { closePick(); return } setEditFor(null); setPickFor(r.key); setPickText('') }
|
|
3450
|
+
// 还原只在真的改过(或历史确认过)的行上出现:精确/模糊命中的行本来就没有
|
|
3451
|
+
// 可还原的东西,每行都挂一颗按钮只会把表格挤成表单。
|
|
3452
|
+
const canReset = state === 'custom' || (d && d.dirty)
|
|
3453
|
+
// 弹窗遮罩是 z-index 60,浮层必须压在它上面;其余定位(上翻、封高)交给 hook。
|
|
3454
|
+
const pickPanel = picking
|
|
3455
|
+
? h('div', {
|
|
3456
|
+
className: 'tsd-price-pick-box',
|
|
3457
|
+
style: Object.assign({}, pickStyle, { zIndex: 70 }),
|
|
3458
|
+
onKeyDown: (e) => { if (e.key === 'Escape') { e.stopPropagation(); closePick() } },
|
|
3459
|
+
}, pickerFor(r.key))
|
|
3460
|
+
: null
|
|
3461
|
+
// 手填单价的浮层:三格(输入 / 输出 / 缓存读),单位就是表格的展示币种。
|
|
3462
|
+
const cur = editing ? customOf(r) : null
|
|
3463
|
+
const customPanel = editing
|
|
3464
|
+
? h('div', {
|
|
3465
|
+
className: 'tsd-price-pick-box tsd-price-custom-box',
|
|
3466
|
+
style: Object.assign({}, customStyle, { zIndex: 70 }),
|
|
3467
|
+
onKeyDown: (e) => { if (e.key === 'Escape') { e.stopPropagation(); setEditFor(null) } },
|
|
3468
|
+
},
|
|
3469
|
+
h('div', { className: 'tsd-price-custom-title' }, t('pricingCustomOption')),
|
|
3470
|
+
...CUSTOM_FIELDS.map(([field, label]) => h('label', { key: field, className: 'tsd-price-custom-field' },
|
|
3471
|
+
h('span', null, t(label)),
|
|
3472
|
+
h('input', {
|
|
3473
|
+
type: 'number',
|
|
3474
|
+
min: '0',
|
|
3475
|
+
step: '0.001',
|
|
3476
|
+
className: 'tsd-price-custom-input',
|
|
3477
|
+
'data-field': field,
|
|
3478
|
+
value: cur[field],
|
|
3479
|
+
autoFocus: field === 'input',
|
|
3480
|
+
onChange: (e) => setCustomField(r.key, field, e.target.value),
|
|
3481
|
+
}))),
|
|
3482
|
+
h('div', { className: 'tsd-price-custom-hint' }, t('pricingCustomUnit', { unit: priceUnit })),
|
|
3483
|
+
h('button', {
|
|
3484
|
+
type: 'button',
|
|
3485
|
+
className: 'tsd-btn tsd-btn-ghost tsd-btn-xs',
|
|
3486
|
+
onClick: () => setEditFor(null),
|
|
3487
|
+
}, t('done')))
|
|
3488
|
+
: null
|
|
3489
|
+
// 这一行匹配到的参考模型属于哪一类(DeepSeek / Zen / 自定义)。草稿里刚选的
|
|
3490
|
+
// 目标也查得到:候选名单本来就按来源分好了组,不用再问宿主一次。
|
|
3491
|
+
// 「自定义」不仅指草稿:从 `prices` 计价的行也没有参考模型 id(target 为空),
|
|
3492
|
+
// 它的目标格要写「自定义」,不然会显示成待选。
|
|
3493
|
+
const isCustom = Boolean(d && d.custom) || (r.how === 'custom' && !r.target)
|
|
3494
|
+
const src = shown ? (sourceOf(shown) || r.source) : (isCustom ? 'custom' : null)
|
|
3495
|
+
return h('tr', { key: r.key, className: 'tsd-price-row', 'data-state': state, 'data-model': r.key, 'data-dirty': d && d.dirty ? 'true' : undefined },
|
|
3496
|
+
h('td', { className: 'tsd-price-model', title: r.key },
|
|
3497
|
+
h('span', { className: 'tsd-price-model-name' }, shortModelName(r.key)),
|
|
3498
|
+
r.provider ? h('span', { className: 'tsd-price-model-provider' }, r.provider) : null),
|
|
3499
|
+
// 匹配目标格本身就是选择器入口:一颗紧凑按钮,未匹配时虚线 + 提示语。
|
|
3500
|
+
h('td', { className: 'tsd-price-target', ref: picking || editing ? bindPickAnchor : undefined },
|
|
3501
|
+
h('button', {
|
|
3502
|
+
type: 'button',
|
|
3503
|
+
className: 'tsd-price-target-btn',
|
|
3504
|
+
'data-empty': shown || isCustom ? undefined : 'true',
|
|
3505
|
+
'aria-expanded': picking || editing ? 'true' : 'false',
|
|
3506
|
+
'aria-haspopup': 'listbox',
|
|
3507
|
+
title: shown ? shown + (src ? ' · ' + t(SOURCE_LABEL[src] || src) : '') : null,
|
|
3508
|
+
onClick: openPick,
|
|
3509
|
+
},
|
|
3510
|
+
h('span', { className: 'tsd-price-target-id' }, shown || (isCustom ? t('pricingCustomOption') : t('askPick'))),
|
|
3511
|
+
h(SvgIcon, { name: 'chevron', size: 12, className: 'tsd-price-target-chev' })),
|
|
3512
|
+
src
|
|
3513
|
+
? h('span', { className: 'tsd-price-src', 'data-source': src }, t(SOURCE_LABEL[src] || src))
|
|
3514
|
+
: null,
|
|
3515
|
+
state !== 'none' && !r.rates && !isCustom
|
|
3516
|
+
? h('span', { className: 'tsd-price-stale' }, t('pricingStale'))
|
|
3517
|
+
: null,
|
|
3518
|
+
pickPanel,
|
|
3519
|
+
customPanel),
|
|
3520
|
+
h('td', null, h('span', { className: 'tsd-price-badge', 'data-state': state, title: r.why || null }, t(MATCH_STATE_LABEL[state]))),
|
|
3521
|
+
h('td', { className: 'tsd-price-rate', title: priceTitle(r) }, priceLine(r)),
|
|
3522
|
+
h('td', { className: 'tsd-price-ops' },
|
|
3523
|
+
canReset
|
|
3524
|
+
? h('button', {
|
|
3525
|
+
type: 'button',
|
|
3526
|
+
className: 'tsd-price-reset',
|
|
3527
|
+
title: t('pricingClear'),
|
|
3528
|
+
'aria-label': t('pricingClear'),
|
|
3529
|
+
onClick: () => clearRow(r.key),
|
|
3530
|
+
}, h(SvgIcon, { name: 'refresh', size: 12 }))
|
|
3531
|
+
: null))
|
|
3532
|
+
}
|
|
3533
|
+
|
|
3534
|
+
const body = status === 'loading'
|
|
3535
|
+
? h('div', { className: 'tsd-price-loading' }, t('loading'))
|
|
3536
|
+
: status === 'error'
|
|
3537
|
+
? h('div', { className: 'tsd-alert-banner', role: 'alert' },
|
|
3538
|
+
h('span', null, t('pricingFailed', { message: String((error && error.message) || error) })),
|
|
3539
|
+
h('button', { type: 'button', className: 'tsd-btn tsd-btn-ghost', onClick: pull }, t('retry')))
|
|
3540
|
+
: h('div', { className: 'tsd-price-body' },
|
|
3541
|
+
h('div', { className: 'tsd-price-meta' },
|
|
3542
|
+
table && table.source
|
|
3543
|
+
? t('pricingTableMeta', { source: table.source, date: stampText(table.capturedAt) })
|
|
3544
|
+
: null,
|
|
3545
|
+
h('span', { className: 'tsd-price-counts' }, t('pricingCounts', {
|
|
3546
|
+
exact: counts.exact, fuzzy: counts.fuzzy, none: counts.none, custom: counts.custom,
|
|
3547
|
+
}))),
|
|
3548
|
+
// 一张表装两段行:待选的未定价行在前,已按阶梯命中的行在后。
|
|
3549
|
+
// 分成两张表会出现两行表头,看起来像两份数据。
|
|
3550
|
+
!hasMainRows
|
|
3551
|
+
? h('div', { className: 'tsd-price-empty' }, t('askEmpty'))
|
|
3552
|
+
: h('table', { className: 'tsd-price-table' },
|
|
3553
|
+
h('thead', null, h('tr', null,
|
|
3554
|
+
h('th', null, t('pricingColModel')),
|
|
3555
|
+
h('th', null, t('pricingColMatch')),
|
|
3556
|
+
h('th', null, t('pricingColState')),
|
|
3557
|
+
h('th', null, t('pricingColPrice', { unit: priceUnit })),
|
|
3558
|
+
h('th', null, ''))),
|
|
3559
|
+
h('tbody', null,
|
|
3560
|
+
pendingRows.map((r) => renderRow(r)),
|
|
3561
|
+
matchedRows.map((r) => renderRow(r)))),
|
|
3562
|
+
h('div', { className: 'tsd-price-history' },
|
|
3563
|
+
h('button', {
|
|
3564
|
+
type: 'button',
|
|
3565
|
+
className: 'tsd-price-history-toggle',
|
|
3566
|
+
'aria-expanded': historyOpen,
|
|
3567
|
+
onClick: () => setHistoryOpen((v) => !v),
|
|
3568
|
+
},
|
|
3569
|
+
h(SvgIcon, { name: 'chevron', size: 12, className: 'tsd-price-history-chev' + (historyOpen ? ' tsd-price-history-chev-open' : '') }),
|
|
3570
|
+
h('span', null, t('pricingHistory', { n: historyRows.length }))),
|
|
3571
|
+
historyOpen
|
|
3572
|
+
? historyRows.length === 0
|
|
3573
|
+
? h('div', { className: 'tsd-price-empty' }, t('pricingHistoryEmpty'))
|
|
3574
|
+
: h('div', null,
|
|
3575
|
+
h('table', { className: 'tsd-price-table tsd-price-table-sub' },
|
|
3576
|
+
h('thead', null, h('tr', null,
|
|
3577
|
+
h('th', null, t('pricingColModel')),
|
|
3578
|
+
h('th', null, t('pricingColMatch')),
|
|
3579
|
+
h('th', null, t('pricingColState')),
|
|
3580
|
+
h('th', null, t('pricingColPrice', { unit: priceUnit })),
|
|
3581
|
+
h('th', null, ''))),
|
|
3582
|
+
h('tbody', null, historyRows.map((r) => renderRow(r)))))
|
|
3583
|
+
: null))
|
|
3584
|
+
|
|
3585
|
+
return h('div', { className: 'tsd-price-overlay', role: 'presentation', onMouseDown: (e) => { if (e.target === e.currentTarget) onClose() } },
|
|
3586
|
+
h('div', {
|
|
3587
|
+
className: 'tsd-price-dialog',
|
|
3588
|
+
role: 'dialog',
|
|
3589
|
+
'aria-modal': 'true',
|
|
3590
|
+
'aria-label': t('pricingTitle'),
|
|
3591
|
+
onKeyDown,
|
|
3592
|
+
},
|
|
3593
|
+
h('div', { className: 'tsd-price-head' },
|
|
3594
|
+
h('h3', { className: 'tsd-price-title' }, t('pricingTitle')),
|
|
3595
|
+
h('button', {
|
|
3596
|
+
type: 'button',
|
|
3597
|
+
className: 'tsd-price-close',
|
|
3598
|
+
title: t('cancel'),
|
|
3599
|
+
'aria-label': t('cancel'),
|
|
3600
|
+
onClick: onClose,
|
|
3601
|
+
}, h(SvgIcon, { name: 'x', size: 14 }))),
|
|
3602
|
+
h('p', { className: 'tsd-price-desc' }, t('pricingDesc')),
|
|
3603
|
+
body,
|
|
3604
|
+
h('div', { className: 'tsd-price-foot' },
|
|
3605
|
+
h('button', {
|
|
3606
|
+
type: 'button',
|
|
3607
|
+
className: 'tsd-btn tsd-btn-ghost tsd-btn-icon-label',
|
|
3608
|
+
onClick: pull,
|
|
3609
|
+
disabled: status === 'loading' || saving,
|
|
3610
|
+
},
|
|
3611
|
+
h(SvgIcon, { name: 'contextInjection', size: 14 }),
|
|
3612
|
+
h('span', null, t('pricingPull'))),
|
|
3613
|
+
h('span', { className: 'tsd-price-hint' }, dirtyKeys.length > 0 ? t('pricingApplyHint') : ''),
|
|
3614
|
+
h('button', { type: 'button', className: 'tsd-btn tsd-btn-ghost', onClick: onClose, disabled: saving }, t('cancel')),
|
|
3615
|
+
h('button', {
|
|
3616
|
+
type: 'button',
|
|
3617
|
+
className: 'tsd-btn tsd-btn-primary',
|
|
3618
|
+
onClick: submit,
|
|
3619
|
+
disabled: saving,
|
|
3620
|
+
}, saving ? t('loading') : t('pricingSave')))))
|
|
2255
3621
|
}
|
|
2256
3622
|
|
|
2257
3623
|
/* ---------------------------------------------------------------------------
|
|
2258
3624
|
* 每日用量柱状图(手写 div 堆叠柱:下段输入蓝 / 上段输出绿)
|
|
2259
3625
|
* ------------------------------------------------------------------------- */
|
|
3626
|
+
/**
|
|
3627
|
+
* One hover-tip content block, shared by the trend chart (bar + line) and the
|
|
3628
|
+
* yearly heatmap: date, input, output, total, reference cost.
|
|
3629
|
+
*
|
|
3630
|
+
* Cost comes from the host bucket (`cost`, already converted to the display
|
|
3631
|
+
* currency), so all three tips show the same number as the summary card and the
|
|
3632
|
+
* model table. A zero is printed as ¥0.00 — "0" is a price, "unpriced" is a
|
|
3633
|
+
* different verdict, and it is the host's to give.
|
|
3634
|
+
*/
|
|
3635
|
+
function TipRows(props) {
|
|
3636
|
+
const { row, t, currency, withSplit } = props
|
|
3637
|
+
const inT = row.inputTokens || 0
|
|
3638
|
+
const outT = row.outputTokens || 0
|
|
3639
|
+
const totT = row.totalTokens || 0
|
|
3640
|
+
return [
|
|
3641
|
+
withSplit
|
|
3642
|
+
? h('div', { key: 'in', className: 'tsd-tooltip-row' },
|
|
3643
|
+
h('span', { className: 'tsd-tooltip-dot tsd-legend-in' }),
|
|
3644
|
+
h('span', null, t('legendInput')),
|
|
3645
|
+
h('span', { className: 'tsd-tooltip-val' }, formatInt(inT)))
|
|
3646
|
+
: h('div', { key: 'in', className: 'tsd-tooltip-row' },
|
|
3647
|
+
h('span', { className: 'tsd-tooltip-dot', style: { background: 'var(--dsw-static-deepseek-500)' } }),
|
|
3648
|
+
h('span', null, t('totalTokens')),
|
|
3649
|
+
h('span', { className: 'tsd-tooltip-val' }, formatInt(totT))),
|
|
3650
|
+
withSplit
|
|
3651
|
+
? h('div', { key: 'out', className: 'tsd-tooltip-row' },
|
|
3652
|
+
h('span', { className: 'tsd-tooltip-dot tsd-legend-out' }),
|
|
3653
|
+
h('span', null, t('legendOutput')),
|
|
3654
|
+
h('span', { className: 'tsd-tooltip-val' }, formatInt(outT)))
|
|
3655
|
+
: null,
|
|
3656
|
+
// 成本与调用次数没有对应图例,所以只留 10px 的空白占位(.tsd-tooltip-dot 本身无底色),
|
|
3657
|
+
// 不画色块:色块的含义是「这一行对应图例里的哪个颜色」。
|
|
3658
|
+
h('div', { key: 'cost', className: 'tsd-tooltip-row' },
|
|
3659
|
+
h('span', { className: 'tsd-tooltip-dot', 'aria-hidden': 'true' }),
|
|
3660
|
+
h('span', null, t('cost')),
|
|
3661
|
+
h('span', { className: 'tsd-tooltip-val' }, formatCost(row.cost || 0, currency))),
|
|
3662
|
+
row.calls > 0
|
|
3663
|
+
? h('div', { key: 'calls', className: 'tsd-tooltip-row' },
|
|
3664
|
+
h('span', { className: 'tsd-tooltip-dot', 'aria-hidden': 'true' }),
|
|
3665
|
+
h('span', null, t('calls')),
|
|
3666
|
+
h('span', { className: 'tsd-tooltip-val' }, formatInt(row.calls)))
|
|
3667
|
+
: null,
|
|
3668
|
+
withSplit
|
|
3669
|
+
? h('div', { key: 'total', className: 'tsd-tooltip-total' },
|
|
3670
|
+
h('span', null, t('tooltipTotal')),
|
|
3671
|
+
h('span', null, formatInt(totT)))
|
|
3672
|
+
: null,
|
|
3673
|
+
]
|
|
3674
|
+
}
|
|
3675
|
+
|
|
2260
3676
|
function DailyChart(props) {
|
|
2261
|
-
const { daily, gran, stepDays, granLabel } = props
|
|
3677
|
+
const { daily, gran, stepDays, granLabel, currency } = props
|
|
2262
3678
|
const t = useT()
|
|
2263
3679
|
const chartRef = React.useRef(null)
|
|
2264
3680
|
const [tip, setTip] = React.useState(null) // { row, x }
|
|
@@ -2308,21 +3724,11 @@ function DailyChart(props) {
|
|
|
2308
3724
|
const barTip = tip
|
|
2309
3725
|
? h('div', { className: 'tsd-tooltip', style: { left: tip.x + 'px' } },
|
|
2310
3726
|
h('div', { className: 'tsd-tooltip-date' }, tip.row.key + ' ' + weekdayName(tip.row.key, t)),
|
|
2311
|
-
h(
|
|
2312
|
-
h('span', { className: 'tsd-tooltip-dot tsd-legend-in' }),
|
|
2313
|
-
h('span', null, t('legendInput')),
|
|
2314
|
-
h('span', { className: 'tsd-tooltip-val' }, formatInt(inOf(tip.row)))),
|
|
2315
|
-
h('div', { className: 'tsd-tooltip-row' },
|
|
2316
|
-
h('span', { className: 'tsd-tooltip-dot tsd-legend-out' }),
|
|
2317
|
-
h('span', null, t('legendOutput')),
|
|
2318
|
-
h('span', { className: 'tsd-tooltip-val' }, formatInt(outOf(tip.row)))),
|
|
2319
|
-
h('div', { className: 'tsd-tooltip-total' },
|
|
2320
|
-
h('span', null, t('tooltipTotal')),
|
|
2321
|
-
h('span', null, formatInt(totOf(tip.row)))))
|
|
3727
|
+
h(TipRows, { row: tip.row, t, currency, withSplit: true }))
|
|
2322
3728
|
: null
|
|
2323
3729
|
|
|
2324
3730
|
const body = view === 'line'
|
|
2325
|
-
? h(LineChart, { rows, gran, stepDays, showTip, tip, setTip, chartRef })
|
|
3731
|
+
? h(LineChart, { rows, gran, stepDays, showTip, tip, setTip, chartRef, currency })
|
|
2326
3732
|
: h('div', { className: 'tsd-chart', ref: chartRef },
|
|
2327
3733
|
rows.map((row, i) => {
|
|
2328
3734
|
const inT = inOf(row)
|
|
@@ -2339,7 +3745,7 @@ function DailyChart(props) {
|
|
|
2339
3745
|
onMouseLeave: () => setTip(null),
|
|
2340
3746
|
onFocus: (e) => showTip(e, row),
|
|
2341
3747
|
onBlur: () => setTip(null),
|
|
2342
|
-
'aria-label': t('barAria', { key: row.key, in: formatInt(inT), out: formatInt(outT), tot: formatInt(totT) }),
|
|
3748
|
+
'aria-label': t('barAria', { key: row.key, in: formatInt(inT), out: formatInt(outT), tot: formatInt(totT), cost: formatCost(row.cost || 0, currency) }),
|
|
2343
3749
|
},
|
|
2344
3750
|
h('div', { className: 'tsd-chart-plot' },
|
|
2345
3751
|
h('div', { className: 'tsd-chart-stack' },
|
|
@@ -2390,7 +3796,7 @@ function smoothPath(pts) {
|
|
|
2390
3796
|
}
|
|
2391
3797
|
|
|
2392
3798
|
function LineChart(props) {
|
|
2393
|
-
const { rows, gran, stepDays, showTip, tip, setTip, chartRef } = props
|
|
3799
|
+
const { rows, gran, stepDays, showTip, tip, setTip, chartRef, currency } = props
|
|
2394
3800
|
const t = useT()
|
|
2395
3801
|
const W = 620
|
|
2396
3802
|
const H = 240
|
|
@@ -2508,17 +3914,7 @@ function LineChart(props) {
|
|
|
2508
3914
|
tip
|
|
2509
3915
|
? h('div', { className: 'tsd-tooltip', style: { left: tip.x + 'px' } },
|
|
2510
3916
|
h('div', { className: 'tsd-tooltip-date' }, tip.row.key + (stepDays > 1 ? ' ' + t('startNDays', { n: stepDays }) : '') + ' ' + weekdayName(tip.row.key, t)),
|
|
2511
|
-
h(
|
|
2512
|
-
h('span', { className: 'tsd-tooltip-dot tsd-legend-in' }),
|
|
2513
|
-
h('span', null, t('legendInput')),
|
|
2514
|
-
h('span', { className: 'tsd-tooltip-val' }, formatInt(inOf(tip.row)))),
|
|
2515
|
-
h('div', { className: 'tsd-tooltip-row' },
|
|
2516
|
-
h('span', { className: 'tsd-tooltip-dot tsd-legend-out' }),
|
|
2517
|
-
h('span', null, t('legendOutput')),
|
|
2518
|
-
h('span', { className: 'tsd-tooltip-val' }, formatInt(outOf(tip.row)))),
|
|
2519
|
-
h('div', { className: 'tsd-tooltip-total' },
|
|
2520
|
-
h('span', null, t('tooltipTotal')),
|
|
2521
|
-
h('span', null, formatInt(totOf(tip.row)))))
|
|
3917
|
+
h(TipRows, { row: tip.row, t, currency, withSplit: true }))
|
|
2522
3918
|
: null)
|
|
2523
3919
|
}
|
|
2524
3920
|
|
|
@@ -2526,7 +3922,7 @@ function LineChart(props) {
|
|
|
2526
3922
|
* 年度用量热力图(GitHub 风格)
|
|
2527
3923
|
* ------------------------------------------------------------------------- */
|
|
2528
3924
|
function HeatmapCard(props) {
|
|
2529
|
-
const { days } = props
|
|
3925
|
+
const { days, currency } = props
|
|
2530
3926
|
const t = useT()
|
|
2531
3927
|
const [htip, setHtip] = React.useState(null) // { cell, left, top } in viewport coords
|
|
2532
3928
|
const grid = React.useMemo(() => {
|
|
@@ -2575,16 +3971,7 @@ function HeatmapCard(props) {
|
|
|
2575
3971
|
style: { position: 'fixed', left: htip.left + 'px', top: htip.top + 'px', transform: 'translate(-50%, -110%)' },
|
|
2576
3972
|
},
|
|
2577
3973
|
h('div', { className: 'tsd-tooltip-date' }, htip.cell.key + ' ' + weekdayName(htip.cell.key, t)),
|
|
2578
|
-
h(
|
|
2579
|
-
h('span', { className: 'tsd-tooltip-dot', style: { background: 'var(--dsw-static-deepseek-500)' } }),
|
|
2580
|
-
h('span', null, t('totalTokens')),
|
|
2581
|
-
h('span', { className: 'tsd-tooltip-val' }, formatInt(htip.cell.totalTokens || 0))),
|
|
2582
|
-
htip.cell.calls > 0
|
|
2583
|
-
? h('div', { className: 'tsd-tooltip-row' },
|
|
2584
|
-
h('span', { className: 'tsd-tooltip-dot', style: { background: 'var(--dsw-alias-label-tertiary)' } }),
|
|
2585
|
-
h('span', null, t('calls')),
|
|
2586
|
-
h('span', { className: 'tsd-tooltip-val' }, formatInt(htip.cell.calls)))
|
|
2587
|
-
: null)
|
|
3974
|
+
h(TipRows, { row: htip.cell, t, currency, withSplit: false }))
|
|
2588
3975
|
: null
|
|
2589
3976
|
|
|
2590
3977
|
const dayNames = ['', t('weekdayMon'), '', t('weekdayWed'), '', t('weekdayFri'), '']
|
|
@@ -2616,7 +4003,7 @@ function HeatmapCard(props) {
|
|
|
2616
4003
|
key: c.key,
|
|
2617
4004
|
className: 'tsd-heatmap-cell',
|
|
2618
4005
|
style: { background: heatColor(c.totalTokens || 0, grid.max) },
|
|
2619
|
-
title: t('hmTitle', { key: c.key, tokens: formatInt(c.totalTokens || 0), calls: c.calls ? t('hmCalls', { count: formatInt(c.calls) }) : '' }),
|
|
4006
|
+
title: t('hmTitle', { key: c.key, tokens: formatInt(c.totalTokens || 0), calls: c.calls ? t('hmCalls', { count: formatInt(c.calls) }) : '', cost: formatCost(c.cost || 0, currency) }),
|
|
2620
4007
|
onMouseEnter: (e) => showCellTip(e, c),
|
|
2621
4008
|
onMouseLeave: () => setHtip(null),
|
|
2622
4009
|
onFocus: (e) => showCellTip(e, c),
|
|
@@ -2653,7 +4040,11 @@ function ModelTable(props) {
|
|
|
2653
4040
|
output: r.outputTokens || 0,
|
|
2654
4041
|
total: r.totalTokens || 0,
|
|
2655
4042
|
cost: r.cost || 0,
|
|
2656
|
-
|
|
4043
|
+
// The verdict comes from the host, which knows whether a price was found.
|
|
4044
|
+
// This used to be re-derived here as `tokens > 0 && !(cost > 0)`, which
|
|
4045
|
+
// labels every 0-cost row 未定价 — including a model the user explicitly
|
|
4046
|
+
// priced at 0 (a real price, cost 0, so ¥0.00 is the honest answer).
|
|
4047
|
+
unpriced: r.unpriced === true,
|
|
2657
4048
|
})), [all])
|
|
2658
4049
|
|
|
2659
4050
|
const sumTotal = React.useMemo(() => view.reduce((s, r) => s + r.total, 0), [view])
|
|
@@ -2736,12 +4127,19 @@ function ModelTable(props) {
|
|
|
2736
4127
|
/* ---------------------------------------------------------------------------
|
|
2737
4128
|
* 三态:加载 / 错误 / 空
|
|
2738
4129
|
* ------------------------------------------------------------------------- */
|
|
2739
|
-
function LoadingState() {
|
|
4130
|
+
function LoadingState(props) {
|
|
2740
4131
|
const t = useT()
|
|
2741
|
-
|
|
4132
|
+
// 统计中(computing)时头部副标题已经在播报进度,这里就不再做第二个 live 区域,
|
|
4133
|
+
// 否则屏幕阅读器会把「正在加载」和「正在统计 12/258」各念一遍。
|
|
4134
|
+
const announce = !props || props.announce !== false
|
|
4135
|
+
return h('div', { className: 'tsd-loading', role: 'status', 'aria-live': announce ? 'polite' : 'off' },
|
|
4136
|
+
// 骨架屏对眼睛是"正在来",对屏幕阅读器什么都不是:给它一句可读的状态。
|
|
4137
|
+
announce ? h('span', { className: 'tsd-visually-hidden' }, t('loading')) : null,
|
|
2742
4138
|
h('div', { className: 'tsd-cards' },
|
|
2743
|
-
|
|
2744
|
-
|
|
4139
|
+
// 一张卡一个占位块,张数取自 SUMMARY_CARD_SLOTS —— 与真实卡片同一份顺序表,
|
|
4140
|
+
// 所以补卡片时骨架自动跟上(这里曾经写死 5 个,真实是 6 个)。
|
|
4141
|
+
SUMMARY_CARD_SLOTS.map((slot) =>
|
|
4142
|
+
h('div', { key: slot, className: 'tsd-card tsd-card-skeleton' },
|
|
2745
4143
|
h('div', { className: 'tsd-skeleton', style: { width: '40%', height: 12 } }),
|
|
2746
4144
|
h('div', { className: 'tsd-skeleton', style: { width: '70%', height: 22, marginTop: 10 } })))),
|
|
2747
4145
|
h('div', { className: 'tsd-card' },
|
|
@@ -2790,10 +4188,17 @@ function StatsDashboard(props) {
|
|
|
2790
4188
|
// 展示币种:宿主按它换算成本,所以换币种必须重查;选择记在本地(展示偏好,
|
|
2791
4189
|
// 不写插件设置,免得每次取数都在改写用户配置)。
|
|
2792
4190
|
const [displayCurrency, setDisplayCurrency] = React.useState(readStoredCurrency)
|
|
4191
|
+
// 定价匹配弹窗:只在这里开着,关掉即卸载(它的内部状态随之丢弃,
|
|
4192
|
+
// 所以「不确定就不生效」不需要额外清理逻辑)。
|
|
4193
|
+
const [pricingOpen, setPricingOpen] = React.useState(false)
|
|
2793
4194
|
// P1-6 backfill 轮询状态:queryKey 变化时重置,仅对同一查询串轮询
|
|
2794
4195
|
const queryKeyRef = React.useRef(null)
|
|
2795
4196
|
const backfillSeenRef = React.useRef(false)
|
|
2796
4197
|
const finalRefreshRef = React.useRef(false)
|
|
4198
|
+
// 轮询节奏:统计窗口短则快问、长则慢问。固定 3 s 时,暖缓存 ~0.8 s 就跑完,
|
|
4199
|
+
// 客户端要等 3 s 才更新 —— 进度条先躺着再跳一格,比没有更糟。
|
|
4200
|
+
const pollStepRef = React.useRef(0)
|
|
4201
|
+
const POLL_DELAYS = [600, 1500, 3000]
|
|
2797
4202
|
|
|
2798
4203
|
const eff = React.useMemo(() => rangeFor(range, custom), [range, custom])
|
|
2799
4204
|
// Fixed step policy: today = hourly; 7d/30d/custom = daily, custom uses a
|
|
@@ -2812,6 +4217,7 @@ function StatsDashboard(props) {
|
|
|
2812
4217
|
queryKeyRef.current = queryKey
|
|
2813
4218
|
backfillSeenRef.current = false
|
|
2814
4219
|
finalRefreshRef.current = false
|
|
4220
|
+
pollStepRef.current = 0
|
|
2815
4221
|
}
|
|
2816
4222
|
const isFinalRun = finalRefreshRef.current
|
|
2817
4223
|
finalRefreshRef.current = false
|
|
@@ -2835,10 +4241,14 @@ function StatsDashboard(props) {
|
|
|
2835
4241
|
const bs = r && r.backfill ? r.backfill.status : null
|
|
2836
4242
|
if (bs === 'running') {
|
|
2837
4243
|
backfillSeenRef.current = true
|
|
2838
|
-
// 同一 effect 至多挂一个定时器;重查复用 retry 计数器触发 effect
|
|
4244
|
+
// 同一 effect 至多挂一个定时器;重查复用 retry 计数器触发 effect 重跑。
|
|
4245
|
+
// 先快后慢:600 ms 起步能跟上 0.8 s 的暖缓存窗口,长任务再退到 3 s,
|
|
4246
|
+
// 不至于把宿主问成压力测试。
|
|
4247
|
+
const delay = POLL_DELAYS[Math.min(pollStepRef.current, POLL_DELAYS.length - 1)]
|
|
4248
|
+
pollStepRef.current += 1
|
|
2839
4249
|
backfillTimer = setTimeout(() => {
|
|
2840
4250
|
if (current) setRetry((v) => v + 1)
|
|
2841
|
-
},
|
|
4251
|
+
}, delay)
|
|
2842
4252
|
} else if (bs === 'done' && backfillSeenRef.current && !isFinalRun) {
|
|
2843
4253
|
// 回填收尾:恰好再查一次拿到完整数据后停止
|
|
2844
4254
|
finalRefreshRef.current = true
|
|
@@ -2917,10 +4327,38 @@ function StatsDashboard(props) {
|
|
|
2917
4327
|
const ready = data !== null
|
|
2918
4328
|
const isError = status === 'error'
|
|
2919
4329
|
const isEmpty = ready && data.daily.length === 0 && data.byModel.length === 0
|
|
4330
|
+
// "统计没算完":宿主还在回填历史(backfill.status === 'running')。
|
|
4331
|
+
// 它比 busy 长得多(全量 258 个会话要几秒),所以进度条与文案都以它为准;
|
|
4332
|
+
// 请求在飞(busy)只是刷新,不该被当成"在算"。
|
|
4333
|
+
const backfill = (data && data.backfill) || null
|
|
4334
|
+
const computing = Boolean(backfill && backfill.status === 'running')
|
|
4335
|
+
const computeTotal = (backfill && backfill.total) || 0
|
|
4336
|
+
const computeDone = (backfill && backfill.done) || 0
|
|
4337
|
+
const computePct = computing && computeTotal > 0
|
|
4338
|
+
? Math.min(100, Math.round((computeDone / computeTotal) * 100))
|
|
4339
|
+
: null
|
|
4340
|
+
const showProgress = computing || (busy && ready && !isError)
|
|
2920
4341
|
|
|
2921
4342
|
return h(T.Provider, { value: t },
|
|
2922
|
-
h('div', { className: 'tsd-section', 'aria-busy': busy || undefined },
|
|
2923
|
-
|
|
4343
|
+
h('div', { className: 'tsd-section', 'aria-busy': busy || computing || undefined },
|
|
4344
|
+
// 首屏走后骨架屏(见 LoadingState);这里管"有数据但没算完"与"正在刷新":
|
|
4345
|
+
// 一条 2px 的细进度条,绝对定位,不推动版面也不碰任何数字。
|
|
4346
|
+
// 算得完的时候它是确定进度(宽度 = done/total),否则是不确定扫动。
|
|
4347
|
+
showProgress
|
|
4348
|
+
? h('div', {
|
|
4349
|
+
className: 'tsd-progress',
|
|
4350
|
+
'aria-hidden': 'true',
|
|
4351
|
+
'data-determinate': computePct === null ? undefined : 'true',
|
|
4352
|
+
style: computePct === null ? undefined : { '--tsd-progress': computePct + '%' },
|
|
4353
|
+
})
|
|
4354
|
+
: null,
|
|
4355
|
+
h(StatsHeader, {
|
|
4356
|
+
busy,
|
|
4357
|
+
computing,
|
|
4358
|
+
computeDone,
|
|
4359
|
+
computeTotal,
|
|
4360
|
+
onRefresh: reload,
|
|
4361
|
+
}),
|
|
2924
4362
|
h(FilterBar, {
|
|
2925
4363
|
range,
|
|
2926
4364
|
custom,
|
|
@@ -2936,19 +4374,27 @@ function StatsDashboard(props) {
|
|
|
2936
4374
|
isError && !ready
|
|
2937
4375
|
? h(ErrorState, { error, onRetry: reload })
|
|
2938
4376
|
: null,
|
|
2939
|
-
|
|
2940
|
-
|
|
4377
|
+
// **从 DSH 启动到统计算完,整段都是加载态。**
|
|
4378
|
+
// 覆盖两种"还没东西可看":
|
|
4379
|
+
// ① 首屏请求还没回来(!ready);
|
|
4380
|
+
// ② 宿主还在回填历史(computing)—— 哪怕是第二次进来、手里已经有半份数据。
|
|
4381
|
+
// 半份数字比骨架更误导:它看起来像"你只有这么多用量",而且会一格一格往上爬。
|
|
4382
|
+
// 这也正是「数字一点点往上爬」那个抱怨的来源,所以宁可等,也不要给残缺的答案。
|
|
4383
|
+
(!ready || computing) && !isError
|
|
4384
|
+
? h(LoadingState, { announce: !computing })
|
|
2941
4385
|
: null,
|
|
2942
4386
|
ready && isError
|
|
2943
4387
|
? h('div', { className: 'tsd-alert-banner', role: 'alert' },
|
|
2944
4388
|
h('span', null, t('loadFailed', { message: String((error && error.message) || error) })),
|
|
2945
4389
|
h('button', { type: 'button', className: 'tsd-btn tsd-btn-ghost', onClick: reload }, t('retry')))
|
|
2946
4390
|
: null,
|
|
2947
|
-
|
|
4391
|
+
// 空态只在"确实算完了还没有记录"时出现。统计中不落到空态。
|
|
4392
|
+
ready && !isError && isEmpty && !computing
|
|
2948
4393
|
? h(EmptyState, { filtered: models.length > 0, onReset: resetFilters })
|
|
2949
4394
|
: null,
|
|
2950
|
-
|
|
2951
|
-
|
|
4395
|
+
// 数据区同理:算完之前不渲染,免得残缺数字先出现再跳变。
|
|
4396
|
+
ready && !isError && !isEmpty && !computing
|
|
4397
|
+
? h('div', { className: 'tsd-content' },
|
|
2952
4398
|
h(SummaryCards, {
|
|
2953
4399
|
total: data.total,
|
|
2954
4400
|
currency: currencySymbol,
|
|
@@ -2956,26 +4402,44 @@ function StatsDashboard(props) {
|
|
|
2956
4402
|
currencyCode: displayCurrency,
|
|
2957
4403
|
onCurrencyChange: changeCurrency,
|
|
2958
4404
|
byModel: data.byModel,
|
|
4405
|
+
pricing: data.pricing,
|
|
4406
|
+
onOpenPricing: () => setPricingOpen(true),
|
|
2959
4407
|
}),
|
|
2960
4408
|
h(DailyChart, {
|
|
2961
4409
|
daily: data.daily,
|
|
2962
4410
|
gran: effGran,
|
|
2963
4411
|
stepDays,
|
|
2964
4412
|
granLabel,
|
|
4413
|
+
currency: currencySymbol,
|
|
2965
4414
|
}),
|
|
2966
|
-
h(HeatmapCard, { days: data.heatmap || [] }),
|
|
4415
|
+
h(HeatmapCard, { days: data.heatmap || [], currency: currencySymbol }),
|
|
2967
4416
|
h(ModelTable, { rows: data.byModel, currency: currencySymbol }))
|
|
4417
|
+
: null,
|
|
4418
|
+
pricingOpen
|
|
4419
|
+
? h(PricingDialog, {
|
|
4420
|
+
currency: { code: displayCurrency, symbol: currencySymbol },
|
|
4421
|
+
onClose: () => setPricingOpen(false),
|
|
4422
|
+
// 确定后重查一次:匹配改了,卡片上的数字必须跟着变,否则用户会以为没保存成功。
|
|
4423
|
+
onApplied: reload,
|
|
4424
|
+
})
|
|
2968
4425
|
: null))
|
|
2969
4426
|
}
|
|
2970
4427
|
|
|
2971
4428
|
/* ---------------------------------------------------------------------------
|
|
2972
4429
|
* 设置页导航图标
|
|
2973
4430
|
*
|
|
2974
|
-
*
|
|
2975
|
-
*
|
|
2976
|
-
*
|
|
2977
|
-
*
|
|
2978
|
-
*
|
|
4431
|
+
* 原生确实没有这个插口 —— 取证过的,不是"我觉得":
|
|
4432
|
+
* · 官方设置页把 `settings.section` 的条目投影成 `{id, order, label}` 三字段,
|
|
4433
|
+
* 没有 icon(`@deepseek-ai/dsh-client-ui-settings-general` 的 nav rows
|
|
4434
|
+
* getSnapshot:`ctx.slots.entries("settings.section").map(e => ({id, order,
|
|
4435
|
+
* label: resolveSlotLabel(e.options.label)}))`);
|
|
4436
|
+
* · 图标由该包自己的 `navIcon(id)` 按 id 白名单选,未列出的 id 回落到设置齿轮
|
|
4437
|
+
* (同包 `function navIcon(id)`,其注释原文 "unknown ids fall back to the
|
|
4438
|
+
* settings gear")。
|
|
4439
|
+
* 所以第三方只能给自己的那一行打属性标记、用 CSS mask 换字形:不替换节点、不碰
|
|
4440
|
+
* React 管的 svg(替换会让 React 卸载时抛 NotFoundError),只加属性、只用 ::before
|
|
4441
|
+
* 画字形。官方一旦给 `settings.section` 加上 icon 字段,这个模块应整体删除 ——
|
|
4442
|
+
* 那时它是可引用的 L0,不该再留 L2 补缺。
|
|
2979
4443
|
*
|
|
2980
4444
|
* 认行只能按可见文本:类名是 CSS Modules 哈希,账号行还会条件出现。
|
|
2981
4445
|
* 官方一旦给 settings.section 加上 icon 字段,这个模块应整体删除。
|
|
@@ -3014,7 +4478,7 @@ function installSettingsNavIcon(label) {
|
|
|
3014
4478
|
styleEl.textContent = NAV_ICON_CSS
|
|
3015
4479
|
document.head.appendChild(styleEl)
|
|
3016
4480
|
} catch (e) {
|
|
3017
|
-
|
|
4481
|
+
logWarn('[usage] settings nav icon: styles unavailable')
|
|
3018
4482
|
return null
|
|
3019
4483
|
}
|
|
3020
4484
|
const mark = () => {
|
|
@@ -3034,7 +4498,7 @@ function installSettingsNavIcon(label) {
|
|
|
3034
4498
|
observer = new MutationObserver(() => { try { mark() } catch (e) {} })
|
|
3035
4499
|
observer.observe(document.body, { childList: true, subtree: true })
|
|
3036
4500
|
} catch (e) {
|
|
3037
|
-
|
|
4501
|
+
logWarn('[usage] settings nav icon: observer unavailable', e)
|
|
3038
4502
|
}
|
|
3039
4503
|
return () => {
|
|
3040
4504
|
if (observer) observer.disconnect()
|
|
@@ -3140,6 +4604,9 @@ function CostPill(props) {
|
|
|
3140
4604
|
* ------------------------------------------------------------------------- */
|
|
3141
4605
|
function apply(ctx) {
|
|
3142
4606
|
usageCtx = ctx
|
|
4607
|
+
// Mount the native Remote face once the page is up; the Fetch routes carry
|
|
4608
|
+
// every call until it lands.
|
|
4609
|
+
mountRemoteChannel(ctx)
|
|
3143
4610
|
_usagePricesScope = null // 每次激活重绑,避免复用已释放的 scope
|
|
3144
4611
|
ctx.effect(() => {
|
|
3145
4612
|
if (typeof styles !== 'undefined' && styles && typeof styles.insert === 'function') {
|
|
@@ -3175,7 +4642,7 @@ function apply(ctx) {
|
|
|
3175
4642
|
}
|
|
3176
4643
|
}
|
|
3177
4644
|
if (!slots || typeof slots.inject !== 'function' || typeof slots.register !== 'function') {
|
|
3178
|
-
|
|
4645
|
+
logWarn('[usage] settings.section slot unavailable')
|
|
3179
4646
|
return
|
|
3180
4647
|
}
|
|
3181
4648
|
slots.inject('settings.section', () => slots.register(
|
|
@@ -3206,4 +4673,4 @@ return { inject: ['locale', 'slots'], apply }
|
|
|
3206
4673
|
return module.exports;
|
|
3207
4674
|
}
|
|
3208
4675
|
});
|
|
3209
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbIi9Vc2Vycy9ydWFuYncvcHJvamVjdHMvZHNoLXBsdWdpbi11c2FnZS9zcmMvY2xpZW50L2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRva2VuIOeUqOmHj+e7n+iuoSDigJQgc2V0dGluZ3Muc2VjdGlvbiBDbGllbnQgVUnvvIjnuq8gSlPvvIzliqjmgIHmj5Lku7bmspnnrrHvvIlcbi8vIOWPr+eUqOWFqOWxgO+8mlJlYWN0IC8gY3R4IC8gc3R5bGVzIC8gaG9zdCAvIGNvbnNvbGXvvJvmtY/op4jlmajlhajlsYAgRGF0ZSAvIEludGwg562J44CCXG4vLyBDU1Mg5bi46YeP5YaF6IGU6IeqIHN0eWxlcy5qc++8iOWKqOaAgeaPkuS7tuaymeeuseaXoCBpbXBvcnTvvIzmoLflvI/pmo/mnKzmlofku7bliqDovb3vvInjgIJcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmNvbnN0IENTUyA9IGBcbi8qID09PT09PT09PT09PSDluIPlsYAgPT09PT09PT09PT09ICovXG4udHNkLXNlY3Rpb24ge1xuICB3aWR0aDogMTAwJTtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiAxNnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBhbmltYXRpb246IHRzZC1mYWRlLWluIDAuNHMgdmFyKC0tZHMtZWFzZS1pbi1vdXQpO1xufVxuQGtleWZyYW1lcyB0c2QtZmFkZS1pbiB7XG4gIGZyb20geyBvcGFjaXR5OiAwOyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoOHB4KTsgfVxuICB0byB7IG9wYWNpdHk6IDE7IHRyYW5zZm9ybTogbm9uZTsgfVxufVxuXG4vKiA9PT09PT09PT09PT0gSGVhZGVyID09PT09PT09PT09PSAqL1xuLnRzZC1oZWFkZXIge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgZ2FwOiAxMnB4O1xuICBmbGV4LXdyYXA6IHdyYXA7XG59XG4udHNkLXRpdGxlIHtcbiAgbWFyZ2luOiAwO1xuICBmb250LXNpemU6IDI0cHg7XG4gIGZvbnQtd2VpZ2h0OiA3MDA7XG4gIGxldHRlci1zcGFjaW5nOiAtMC4wMmVtO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xufVxuLnRzZC1zdWJ0aXRsZSB7XG4gIG1hcmdpbjogNHB4IDAgMDtcbiAgZm9udC1zaXplOiAxNHB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG59XG4udHNkLWljb24tYnRuIHtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICB3aWR0aDogMjhweDtcbiAgaGVpZ2h0OiAyOHB4O1xuICBwYWRkaW5nOiAwO1xuICBib3JkZXI6IDFweCBzb2xpZCB0cmFuc3BhcmVudDtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIGZvbnQ6IGluaGVyaXQ7XG59XG4udHNkLWljb24tYnRuOmhvdmVyIHtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTtcbn1cbi50c2QtaWNvbi1idG46ZGlzYWJsZWQge1xuICBjdXJzb3I6IGRlZmF1bHQ7XG4gIG9wYWNpdHk6IDAuNjtcbn1cbi50c2QtaWNvbi1idG46ZGlzYWJsZWQ6aG92ZXIge1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xufVxuLnRzZC1zcGlubmluZyBzdmcge1xuICBhbmltYXRpb246IHRzZC1zcGluIDAuOXMgbGluZWFyIGluZmluaXRlO1xufVxuQGtleWZyYW1lcyB0c2Qtc3BpbiB7XG4gIHRvIHsgdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTsgfVxufVxuXG4vKiA9PT09PT09PT09PT0g562b6YCJ5qCPID09PT09PT09PT09PSAqL1xuLnRzZC1maWx0ZXJiYXIge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDhweDtcbiAgZmxleC13cmFwOiB3cmFwO1xufVxuLnRzZC1zZWctd3JhcCB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG59XG4udHNkLXNlZyB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBnYXA6IDJweDtcbiAgcGFkZGluZzogNHB4O1xuICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KSAxMiUsIHRyYW5zcGFyZW50KTtcbn1cbi50c2Qtc2VnLWJ0biB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBoZWlnaHQ6IDI4cHg7XG4gIHBhZGRpbmc6IDAgMTJweDtcbiAgYm9yZGVyOiBub25lO1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgbGluZS1oZWlnaHQ6IDE7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi50c2Qtc2VnLWJ0bjpob3ZlciB7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7XG59XG4udHNkLXNlZy1hY3RpdmUge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctYmFzZSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGJveC1zaGFkb3c6IHZhcigtLWRzdy1zaGFkb3ctbHYxKTtcbn1cbi50c2Qtc2VnLWN1c3RvbSB7XG4gIG1heC13aWR0aDogMjIwcHg7XG59XG4udHNkLXNlZy1jdXN0b20gLnRzZC1zZWctbGFiZWwge1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi50c2Qtc2VnLWN1c3RvbS50c2Qtc2VnLWFjdGl2ZSB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5LWludmVydGVkLCAjZmZmKTtcbn1cbi50c2Qtc2VnLWN1c3RvbS50c2Qtc2VnLWFjdGl2ZTpob3ZlciB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1idXR0b24tcHJpbWFyeS1ob3Zlcik7XG59XG5cbi8qID09PT09PT09PT09PSDpgJrnlKjmjInpkq4gPT09PT09PT09PT09ICovXG4udHNkLWJ0biB7XG4gIGhlaWdodDogMzBweDtcbiAgcGFkZGluZzogMCAxNHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTEpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuLnRzZC1idG46aG92ZXIgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpOyB9XG4udHNkLWJ0bjpkaXNhYmxlZCB7IG9wYWNpdHk6IDAuNTsgY3Vyc29yOiBub3QtYWxsb3dlZDsgfVxuLnRzZC1idG4tcHJpbWFyeSB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1idXR0b24tcHJpbWFyeS1maWxsKTtcbiAgYm9yZGVyLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5LWludmVydGVkLCAjZmZmKTtcbn1cbi50c2QtYnRuLXByaW1hcnk6aG92ZXIgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYnV0dG9uLXByaW1hcnktaG92ZXIpOyB9XG4udHNkLWJ0bi1naG9zdCB7IGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OyB9XG4udHNkLWJ0bi1naG9zdDpob3ZlciB7IGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7IH1cblxuLyogPT09PT09PT09PT09IOa1ruWxgiBQb3BvdmVyID09PT09PT09PT09PSAqL1xuLnRzZC1wb3BvdmVyLWFuY2hvciB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG59XG4udHNkLXBvcG92ZXIge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogY2FsYygxMDAlICsgNnB4KTtcbiAgbGVmdDogMDtcbiAgei1pbmRleDogNDA7XG4gIHBhZGRpbmc6IDEycHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctb3ZlcmxheSk7XG4gIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gIGJveC1zaGFkb3c6IHZhcigtLWRzdy1zaGFkb3ctbHYzKTtcbn1cbi50c2QtbW9kZWwtcG9wb3ZlciB7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIHdpZHRoOiAzMjBweDtcbiAgbWF4LXdpZHRoOiBjYWxjKDEwMHZ3IC0gMjRweCk7XG59XG4vKiDmta7lsYLpq5jluqbnlLEgdXNlRml4ZWRQYW5lbCDnmoQgbWF4SGVpZ2h0IOWGs+Wumu+8muWPquacieWIl+ihqOWPr+S8uOe8qe+8jOWFtuS9memDqOWIhuS4jeWOi+e8qSAqL1xuLnRzZC1tb2RlbC1wb3BvdmVyID4gLnRzZC1wb3BvdmVyLXRvb2xzLFxuLnRzZC1tb2RlbC1wb3BvdmVyID4gLnRzZC1zZWFyY2gsXG4udHNkLW1vZGVsLXBvcG92ZXIgPiAudHNkLXBvcG92ZXItbm90ZSxcbi50c2QtbW9kZWwtcG9wb3ZlciA+IC50c2QtcG9wb3Zlci1lbXB0eSB7IGZsZXg6IG5vbmU7IH1cbi50c2QtcmFuZ2UtcG9wb3ZlciB7XG4gIHdpZHRoOiAzMDBweDtcbiAgbWF4LXdpZHRoOiBjYWxjKDEwMHZ3IC0gMjRweCk7XG59XG4udHNkLXBvcG92ZXItdGl0bGUge1xuICBmb250LXNpemU6IDE0cHg7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIG1hcmdpbjogMCAwIDEwcHg7XG59XG4udHNkLXBvcG92ZXItdG9vbHMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIG1hcmdpbi1ib3R0b206IDhweDtcbn1cbi50c2QtbGluay1idG4ge1xuICBib3JkZXI6IG5vbmU7XG4gIGJhY2tncm91bmQ6IG5vbmU7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtYnVzaW5lc3MtcHJpbWFyeSk7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBwYWRkaW5nOiAycHggNHB4O1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG59XG4udHNkLWxpbmstYnRuOmhvdmVyIHsgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTsgfVxuLnRzZC1wb3BvdmVyLWFjdGlvbnMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xuICBnYXA6IDhweDtcbiAgbWFyZ2luLXRvcDogMTJweDtcbn1cbi50c2QtcG9wb3Zlci1ub3RlIHtcbiAgbWFyZ2luOiA4cHggMCAwO1xuICBmb250LXNpemU6IDExcHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xufVxuLnRzZC1wb3BvdmVyLWVtcHR5IHtcbiAgbWFyZ2luOiAwO1xuICBwYWRkaW5nOiAxMHB4IDA7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbn1cblxuLyogPT09PT09PT09PT09IOaooeWei+S4i+aLieaQnOe0oiA9PT09PT09PT09PT0gKi9cbi50c2Qtc2VsZWN0LWJ0biB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDZweDtcbiAgbWluLXdpZHRoOiAxMjBweDtcbiAgbWF4LXdpZHRoOiAyNjBweDtcbiAgaGVpZ2h0OiAzNnB4O1xuICBwYWRkaW5nOiAwIDEwcHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgZm9udDogaW5oZXJpdDtcbiAgZm9udC1zaXplOiAxM3B4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG4udHNkLXNlbGVjdC1idG46aG92ZXIgeyBib3JkZXItY29sb3I6IHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDMpOyB9XG4udHNkLXNlbGVjdC1oYXMgeyBib3JkZXItY29sb3I6IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSkgNDUlLCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKSk7IH1cbi50c2Qtc2VsZWN0LWxhYmVsIHtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIG1pbi13aWR0aDogMDtcbn1cbi50c2QtY2hldnJvbiB7XG4gIGZsZXg6IG5vbmU7XG4gIHRyYW5zaXRpb246IHRyYW5zZm9ybSB2YXIoLS1kcy10cmFuc2l0aW9uLWR1cmF0aW9uLWZhc3QpIHZhcigtLWRzLWVhc2UtaW4tb3V0KTtcbn1cbi50c2QtY2hldnJvbi1vcGVuIHsgdHJhbnNmb3JtOiByb3RhdGUoMTgwZGVnKTsgfVxuLnRzZC1zZWFyY2gge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIG1hcmdpbi1ib3R0b206IDhweDtcbn1cbi50c2Qtc2VhcmNoLWljb24ge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGxlZnQ6IDhweDtcbiAgdG9wOiA1MCU7XG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNTAlKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuLnRzZC1zZWFyY2ggaW5wdXQge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAzMnB4O1xuICBwYWRkaW5nOiAwIDhweCAwIDI4cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgZm9udDogaW5oZXJpdDtcbiAgZm9udC1zaXplOiAxM3B4O1xuICBvdXRsaW5lOiBub25lO1xufVxuLnRzZC1zZWFyY2ggaW5wdXQ6Zm9jdXMge1xuICBib3JkZXItY29sb3I6IHZhcigtLWRzdy1hbGlhcy1zdGF0ZS1idXNpbmVzcy1wcmltYXJ5KTtcbiAgYm94LXNoYWRvdzogMCAwIDAgMnB4IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtYnVzaW5lc3MtcHJpbWFyeSkgMTglLCB0cmFuc3BhcmVudCk7XG59XG4udHNkLW1vZGVsLWxpc3Qge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBmbGV4OiAxIDEgYXV0bztcbiAgbWluLWhlaWdodDogMDtcbiAgZ2FwOiAycHg7XG4gIG1heC1oZWlnaHQ6IDI0MHB4O1xuICBvdmVyZmxvdy15OiBhdXRvO1xuICAtLWRzaC1zY3JvbGxiYXItdGh1bWI6IHZhcigtLWRzdy1hbGlhcy1zY3JvbGxiYXItYmctbDIpO1xuICAtLWRzaC1zY3JvbGxiYXItdGh1bWItaG92ZXI6IHZhcigtLWRzdy1hbGlhcy1zY3JvbGxiYXItaG92ZXItbDIpO1xufVxuLnRzZC1tb2RlbC1pdGVtIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA4cHg7XG4gIHBhZGRpbmc6IDVweCA2cHg7XG4gIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBmb250LXNpemU6IDEzcHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIG1pbi13aWR0aDogMDtcbn1cbi50c2QtbW9kZWwtaXRlbTpob3ZlciB7IGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7IH1cbi50c2QtbW9kZWwtaXRlbSBpbnB1dCB7IG1hcmdpbjogMDsgYWNjZW50LWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7IH1cbi50c2QtbW9kZWwtbmFtZSB7XG4gIGZvbnQtZmFtaWx5OiB2YXIoLS1kcy1mb250LWZhbWlseS1jb2RlKTtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgbWluLXdpZHRoOiAwO1xufVxuXG4vKiA9PT09PT09PT09PT0g5biB56eN5YiH5o2i77yI5Y+C6ICD5oiQ5pys5Y2h5pWw5YC86KGM5YaF77yJID09PT09PT09PT09PSAqL1xuLyog5pWw5YC86KGM5pyA5YmN5Y+q5pS+5LiA5Liq44CM56ym5Y+3ICsg5bCP566t5aS044CN55qE5Zu+5qCH5byP6Kem5Y+R5Zmo77ya56ym5Y+35pys6Lqr5bCx5piv6K+75pWw55qE5LiA6YOo5YiG77yMXG4gICDlsLrlr7gv5a2X6YeNL+Wfuue6v+e7p+aJv+aVsOWAvOihjO+8jOivu+i1t+adpeWDj+aVsOWtl+WJjee8gOiAjOS4jeaYr+S4gOS4quaOp+S7tuOAglxuICAg56ym5Y+35Y+q5Zyo6L+Z6YeM55S75LiA5qyh77yMZm9ybWF0Q29zdCDkuI3lho3ph43lpI3luKbnrKblj7fjgIIgKi9cbi50c2QtY3VyLWFuY2hvciB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG59XG4udHNkLWN1ci1idG4ge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgYWxpZ24taXRlbXM6IGJhc2VsaW5lO1xuICBnYXA6IDNweDtcbiAgbWFyZ2luOiAwIDJweCAwIDA7XG4gIHBhZGRpbmc6IDAgMnB4O1xuICBib3JkZXI6IG5vbmU7XG4gIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gIGNvbG9yOiBpbmhlcml0O1xuICBmb250OiBpbmhlcml0O1xuICBsaW5lLWhlaWdodDogaW5oZXJpdDtcbiAgdmVydGljYWwtYWxpZ246IGJhc2VsaW5lO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIHRyYW5zaXRpb246IGNvbG9yIDAuMTVzIGVhc2UsIGJhY2tncm91bmQgMC4xNXMgZWFzZTtcbn1cbi50c2QtY3VyLWJ0bjpob3Zlcixcbi50c2QtY3VyLWJ0bi1vcGVuIHtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTtcbn1cbi50c2QtY3VyLWJ0bjpmb2N1cy12aXNpYmxlIHtcbiAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTtcbiAgb3V0bGluZS1vZmZzZXQ6IDFweDtcbn1cbi50c2QtY3VyLWNoZXZyb24ge1xuICBmbGV4OiBub25lO1xuICBhbGlnbi1zZWxmOiBjZW50ZXI7XG4gIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjE1cyBlYXNlO1xufVxuLnRzZC1jdXItYnRuLW9wZW4gLnRzZC1jdXItY2hldnJvbiB7IHRyYW5zZm9ybTogcm90YXRlKDE4MGRlZyk7IH1cbi50c2QtY3VyLXBvcG92ZXIge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICB3aWR0aDogMTgwcHg7XG4gIG1heC13aWR0aDogY2FsYygxMDB2dyAtIDI0cHgpO1xuICBwYWRkaW5nOiA2cHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogMnB4O1xuICAvKiDmta7lsYLmjILlnKggLnRzZC1jYXJkLXZhbHVlIOmHjO+8jOmCo+i+ueS4uuS6huaVsOWAvOihjOWGmeS6hiBub3dyYXDvvJtcbiAgICAg5rWu5bGC6YeM55qE6I+c5Y2V6aG55LiO6K+05piO5b+F6aG75oGi5aSN5o2i6KGM77yM5ZCm5YiZ6ZW/5paH5qGI5Lya5qiq552A5rqi5Ye65rWu5bGC44CCICovXG4gIHdoaXRlLXNwYWNlOiBub3JtYWw7XG59XG4udHNkLWN1ci1vcHRpb24ge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDhweDtcbiAgcGFkZGluZzogN3B4IDlweDtcbiAgYm9yZGVyOiBub25lO1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBmb250OiBpbmhlcml0O1xuICBmb250LXNpemU6IDEzcHg7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cbi50c2QtY3VyLW9wdGlvbjpob3ZlciB7IGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7IH1cbi50c2QtY3VyLW9wdGlvbjpmb2N1cy12aXNpYmxlIHtcbiAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTtcbiAgb3V0bGluZS1vZmZzZXQ6IDFweDtcbn1cbi50c2QtY3VyLXN5bWJvbCB7XG4gIGZsZXg6IG5vbmU7XG4gIHdpZHRoOiAyMHB4O1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG59XG4udHNkLWN1ci1uYW1lIHtcbiAgbWluLXdpZHRoOiAwO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBmb250LXNpemU6IDEycHg7XG59XG4udHNkLWN1ci1vcHRpb24tYWN0aXZlIHsgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTsgfVxuLnRzZC1jdXItY2hlY2sge1xuICBtYXJnaW4tbGVmdDogYXV0bztcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTtcbn1cblxuLyogPT09PT09PT09PT09IOaooeWei+WNoOavlO+8iEtQSSDljaHnrKwgNiDmoLzvvIkgPT09PT09PT09PT09ICovXG4vKiDkuLvkvZPmmK/ljaDmr5TmnaHvvIzkuIvmlrnmqKHlnovlkI3kuI7nmb7liIbmr5TljovmiJDohJrms6jvvIgxMXB4IHRlcnRpYXJ577yJ77yMXG4gICDkuI7lhbblroPljaHnmoTlpKfmlbDlrZflvaLmiJDlsYLnuqflt67vvIzkuI3miqIgS1BJIOeahOivu+aVsOS9jee9ruOAgiAqL1xuLnRzZC1jYXJkLXNoYXJlLWJvZHkge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBnYXA6IDhweDtcbiAgbWluLXdpZHRoOiAwO1xuICAvKiDlr7npvZAgLnRzZC1jYXJkLXZhbHVlIOeahOS4iui+uei3ne+8jOWFreW8oOWNoeS/neaMgeWQjOS4gOWfuue6vyAqL1xuICBtYXJnaW4tdG9wOiA4cHg7XG59XG4udHNkLXNoYXJlLXRyYWNrIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IHN0cmV0Y2g7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwcHg7XG4gIGJvcmRlci1yYWRpdXM6IDk5OXB4O1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpO1xufVxuLnRzZC1zaGFyZS1zZWcge1xuICBoZWlnaHQ6IDEwMCU7XG4gIG1pbi13aWR0aDogMnB4O1xuICBvdXRsaW5lOiBub25lO1xuICBvcGFjaXR5OiAwLjk7XG4gIHRyYW5zaXRpb246IG9wYWNpdHkgMC4xMnMgZWFzZTtcbn1cbi50c2Qtc2hhcmUtc2VnOmhvdmVyLFxuLnRzZC1zaGFyZS1zZWc6Zm9jdXMtdmlzaWJsZSxcbi50c2Qtc2hhcmUtc2VnW2RhdGEtYWN0aXZlPSd0cnVlJ10geyBvcGFjaXR5OiAxOyB9XG4udHNkLXNoYXJlLWNhcHRpb24ge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogYmFzZWxpbmU7XG4gIGdhcDogNnB4O1xuICBmb250LXNpemU6IDExcHg7XG4gIGxpbmUtaGVpZ2h0OiAxNnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbn1cbi50c2Qtc2hhcmUtY2FwLW5hbWUge1xuICBtaW4td2lkdGg6IDA7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuLnRzZC1zaGFyZS1jYXAtcGN0IHtcbiAgZmxleDogbm9uZTtcbiAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbn1cbi50c2Qtc2hhcmUtZW1wdHkge1xuICBmb250LXNpemU6IDE0cHg7XG4gIGZvbnQtd2VpZ2h0OiA0MDA7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xufVxuXG4vKiA9PT09PT09PT09PT0g6Ieq5a6a5LmJ5pel5pyf5rWu5bGCID09PT09PT09PT09PSAqL1xuLnRzZC1yYW5nZS1maWVsZHMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBnYXA6IDEwcHg7XG59XG4udHNkLWZpZWxkIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiA0cHg7XG59XG4udHNkLWZpZWxkLWxhYmVsIHtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG59XG4udHNkLWZpZWxkIGlucHV0IHtcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMzJweDtcbiAgcGFkZGluZzogMCA4cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgZm9udDogaW5oZXJpdDtcbiAgZm9udC1zaXplOiAxM3B4O1xuICBvdXRsaW5lOiBub25lO1xufVxuLnRzZC1maWVsZCBpbnB1dDpmb2N1cyB7XG4gIGJvcmRlci1jb2xvcjogdmFyKC0tZHN3LWFsaWFzLXN0YXRlLWJ1c2luZXNzLXByaW1hcnkpO1xuICBib3gtc2hhZG93OiAwIDAgMCAycHggY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWRzdy1hbGlhcy1zdGF0ZS1idXNpbmVzcy1wcmltYXJ5KSAxOCUsIHRyYW5zcGFyZW50KTtcbn1cbi50c2QtZmllbGQtZXJyb3Ige1xuICBtYXJnaW46IDZweCAwIDA7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1zdGF0ZS1lcnJvci1wcmltYXJ5KTtcbn1cbi50c2QtZmllbGQtaGludCB7XG4gIG1hcmdpbjogNnB4IDAgMDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbn1cblxuLyogPT09PT09PT09PT09IOaxh+aAu+aMh+agh+WNoSA9PT09PT09PT09PT0gKi9cbi50c2QtY2FyZHMge1xuICBkaXNwbGF5OiBncmlkO1xuICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IHJlcGVhdChhdXRvLWZpdCwgbWlubWF4KDE1MHB4LCAxZnIpKTtcbiAgZ2FwOiAxMHB4O1xufVxuLnRzZC1jYXJkIHtcbiAgbWluLXdpZHRoOiAwO1xuICBwYWRkaW5nOiAxNHB4IDE2cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMyk7XG4gIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gIGJveC1zaGFkb3c6IHZhcigtLWRzdy1zaGFkb3ctbHYxKTtcbn1cbi50c2QtY2FyZC1oZWFkIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA2cHg7XG59XG4udHNkLWNhcmQtaWNvbiB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xufVxuLnRzZC1jYXJkLWxhYmVsIHtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuLnRzZC1jYXJkLXZhbHVlIHtcbiAgbWFyZ2luLXRvcDogOHB4O1xuICBmb250LXNpemU6IDIwcHg7XG4gIGZvbnQtd2VpZ2h0OiA3MDA7XG4gIGxldHRlci1zcGFjaW5nOiAtMC4wMWVtO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBmb250LXZhcmlhbnQtbnVtZXJpYzogdGFidWxhci1udW1zO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi50c2QtY2FyZC1zdWIge1xuICBtYXJnaW4tdG9wOiA0cHg7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG59XG4udHNkLWNhcmQtbm90ZSB7XG4gIG1hcmdpbi10b3A6IDRweDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLXN0YXRlLXdhcm4tcHJpbWFyeSk7XG59XG5cbi8qID09PT09PT09PT09PSDljaHniYflpLTpg6jvvIjlm77ooaggLyDooajmoLzlhbHnlKjvvIkgPT09PT09PT09PT09ICovXG4udHNkLWNhcmQtaGVhZGVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBnYXA6IDhweDtcbiAgbWFyZ2luLWJvdHRvbTogMTJweDtcbn1cbi50c2QtY2FyZC10aXRsZSB7XG4gIG1hcmdpbjogMDtcbiAgZm9udC1zaXplOiAxNXB4O1xuICBmb250LXdlaWdodDogNjAwO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xufVxuLnRzZC1jYXJkLXRhZyB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIGZvbnQtdmFyaWFudC1udW1lcmljOiB0YWJ1bGFyLW51bXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xufVxuXG4vKiA9PT09PT09PT09PT0g5q+P5pel55So6YeP5p+x54q25Zu+ID09PT09PT09PT09PSAqL1xuLnRzZC1jaGFydC1jYXJkIHsgcGFkZGluZzogMTRweCAxNnB4IDEwcHg7IH1cbi50c2QtbGVnZW5kIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZ2FwOiAxNHB4O1xuICBtYXJnaW4tYm90dG9tOiA4cHg7XG59XG4udHNkLWxlZ2VuZC1pdGVtIHtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogNnB4O1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbn1cbi50c2QtbGVnZW5kLWRvdCxcbi50c2QtdG9vbHRpcC1kb3Qge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIHdpZHRoOiAxMHB4O1xuICBoZWlnaHQ6IDEwcHg7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgZmxleDogbm9uZTtcbn1cbi50c2QtbGVnZW5kLWluIHsgYmFja2dyb3VuZDogdmFyKC0tZHN3LXN0YXRpYy1kZWVwc2Vlay01MDApOyB9XG4udHNkLWxlZ2VuZC1vdXQgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctc3RhdGljLWdyZWVuLTUwMCk7IH1cbi50c2QtbGVnZW5kLXRvdGFsIHsgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7IH1cblxuLnRzZC1jaGFydCB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IHN0cmV0Y2g7XG4gIGdhcDogMnB4O1xuICBoZWlnaHQ6IDI0MHB4O1xuICBwYWRkaW5nOiAwIDRweDtcbn1cbi50c2QtY2hhcnQtY29sIHtcbiAgZmxleDogMTtcbiAgbWluLXdpZHRoOiAwO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIGN1cnNvcjogZGVmYXVsdDtcbiAgdHJhbnNpdGlvbjogb3BhY2l0eSB2YXIoLS1kcy10cmFuc2l0aW9uLWR1cmF0aW9uLWZhc3QpIHZhcigtLWRzLWVhc2UtaW4tb3V0KTtcbn1cbi50c2QtY2hhcnQtY29sOmZvY3VzLXZpc2libGUge1xuICBvdXRsaW5lOiAycHggc29saWQgdmFyKC0tZHN3LWFsaWFzLXN0YXRlLWJ1c2luZXNzLXByaW1hcnkpO1xuICBvdXRsaW5lLW9mZnNldDogMnB4O1xufVxuLnRzZC1jaGFydDpob3ZlciAudHNkLWNoYXJ0LWNvbCB7IG9wYWNpdHk6IDAuNDsgfVxuLnRzZC1jaGFydDpob3ZlciAudHNkLWNoYXJ0LWNvbDpob3Zlcixcbi50c2QtY2hhcnQ6Zm9jdXMtd2l0aGluIC50c2QtY2hhcnQtY29sOmZvY3VzIHsgb3BhY2l0eTogMTsgfVxuXG4udHNkLWNoYXJ0LXBsb3Qge1xuICBmbGV4OiAxO1xuICB3aWR0aDogMTAwJTtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gdG9wLCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwxKSAxcHgsIHRyYW5zcGFyZW50IDFweCk7XG4gIGJhY2tncm91bmQtc2l6ZTogMTAwJSAyNSU7XG4gIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG59XG4udHNkLWNoYXJ0LXN0YWNrIHtcbiAgd2lkdGg6IDYyJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xufVxuLnRzZC1jaGFydC1zZWcge1xuICB3aWR0aDogMTAwJTtcbn1cbi50c2Qtc2VnLWluIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LXN0YXRpYy1kZWVwc2Vlay01MDApO1xufVxuLnRzZC1zZWctb3V0IHtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LXN0YXRpYy1ncmVlbi01MDApO1xuICBib3JkZXItcmFkaXVzOiAzcHggM3B4IDAgMDtcbn1cbi50c2QtY2hhcnQtbGFiZWwge1xuICBoZWlnaHQ6IDE0cHg7XG4gIGxpbmUtaGVpZ2h0OiAxNHB4O1xuICBtYXJnaW4tdG9wOiA2cHg7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIGZvbnQtdmFyaWFudC1udW1lcmljOiB0YWJ1bGFyLW51bXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG4udHNkLWNoYXJ0LWxhYmVsLWhpZGRlbiB7IHZpc2liaWxpdHk6IGhpZGRlbjsgfVxuXG4vKiB0b29sdGlwICovXG4udHNkLXRvb2x0aXAge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMTBweDtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC01MCUpO1xuICB6LWluZGV4OiA2O1xuICBtaW4td2lkdGg6IDE1NnB4O1xuICBwYWRkaW5nOiA4cHggMTBweDtcbiAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1vdmVybGF5KTtcbiAgYmFja2Ryb3AtZmlsdGVyOiBibHVyKDhweCk7XG4gIGJvcmRlci1yYWRpdXM6IDhweDtcbiAgYm94LXNoYWRvdzogdmFyKC0tZHN3LXNoYWRvdy1sdjMpO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cbi50c2QtdG9vbHRpcC1kYXRlIHtcbiAgbWFyZ2luLWJvdHRvbTogNnB4O1xuICBmb250LXNpemU6IDEycHg7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG59XG4udHNkLXRvb2x0aXAtcm93IHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA2cHg7XG4gIG1hcmdpbjogMnB4IDA7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBmb250LXZhcmlhbnQtbnVtZXJpYzogdGFidWxhci1udW1zO1xufVxuLnRzZC10b29sdGlwLXZhbCB7XG4gIG1hcmdpbi1sZWZ0OiBhdXRvO1xuICBwYWRkaW5nLWxlZnQ6IDEycHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG59XG4udHNkLXRvb2x0aXAtdG90YWwge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIG1hcmdpbi10b3A6IDZweDtcbiAgcGFkZGluZy10b3A6IDZweDtcbiAgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBmb250LXNpemU6IDEycHg7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGZvbnQtdmFyaWFudC1udW1lcmljOiB0YWJ1bGFyLW51bXM7XG59XG5cbi8qID09PT09PT09PT09PSDmjInmqKHlnovmmI7nu4booaggPT09PT09PT09PT09ICovXG4udHNkLXRhYmxlLWNhcmQgeyBwYWRkaW5nOiAwOyB9XG4udHNkLXRhYmxlLWNhcmQgLnRzZC1jYXJkLWhlYWRlciB7IHBhZGRpbmc6IDE0cHggMTZweCAwOyB9XG4udHNkLXRhYmxlLXdyYXAge1xuICBvdmVyZmxvdy14OiBhdXRvO1xuICAtLWRzaC1zY3JvbGxiYXItdGh1bWI6IHZhcigtLWRzdy1hbGlhcy1zY3JvbGxiYXItYmctbDIpO1xuICAtLWRzaC1zY3JvbGxiYXItdGh1bWItaG92ZXI6IHZhcigtLWRzdy1hbGlhcy1zY3JvbGxiYXItaG92ZXItbDIpO1xufVxuLnRzZC10YWJsZSB7XG4gIHdpZHRoOiAxMDAlO1xuICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlO1xuICBmb250LXNpemU6IDEzcHg7XG59XG4udHNkLXRoIHtcbiAgcGFkZGluZzogMTBweCAxMnB4O1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBmb250LXNpemU6IDEycHg7XG4gIGZvbnQtd2VpZ2h0OiA1MDA7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuLnRzZC10aC1udW0geyB0ZXh0LWFsaWduOiByaWdodDsgfVxuLnRzZC1zb3J0LWJ0biB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDJweDtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyOiBub25lO1xuICBiYWNrZ3JvdW5kOiBub25lO1xuICBmb250OiBpbmhlcml0O1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiBpbmhlcml0O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG4udHNkLXNvcnQtYnRuOmhvdmVyIHsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTsgfVxuLnRzZC1zb3J0LWFjdGl2ZSB7IGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7IH1cbi50c2Qtc29ydC1hcnJvdyB7XG4gIGZvbnQtc2l6ZTogMTBweDtcbiAgbGluZS1oZWlnaHQ6IDE7XG59XG4udHNkLXRyOmhvdmVyIHsgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTsgfVxuLnRzZC10ZCB7XG4gIHBhZGRpbmc6IDlweCAxMnB4O1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi50c2QtdGQtbW9kZWwgeyBtYXgtd2lkdGg6IDI0MHB4OyB9XG4udHNkLW1vZGVsLW1vbm8ge1xuICBkaXNwbGF5OiBibG9jaztcbiAgbWF4LXdpZHRoOiAyMjBweDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIGZvbnQtZmFtaWx5OiB2YXIoLS1kcy1mb250LWZhbWlseS1jb2RlKTtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xufVxuLnRzZC1udW0ge1xuICB0ZXh0LWFsaWduOiByaWdodDtcbiAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbn1cbi50c2QtdG90YWwge1xuICBmb250LXdlaWdodDogNjAwO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xufVxuLnRzZC11bnByaWNlZCB7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xuICBmb250LXN0eWxlOiBpdGFsaWM7XG59XG4udHNkLXRkLXJhdGlvIHsgdGV4dC1hbGlnbjogcmlnaHQ7IH1cbi50c2QtcmF0aW8ge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbiAgZ2FwOiA4cHg7XG59XG4udHNkLXJhdGlvLWJhciB7XG4gIHdpZHRoOiA2MHB4O1xuICBoZWlnaHQ6IDZweDtcbiAgYm9yZGVyLXJhZGl1czogM3B4O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMSk7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIGZsZXg6IG5vbmU7XG59XG4udHNkLXJhdGlvLWZpbGwge1xuICBoZWlnaHQ6IDEwMCU7XG4gIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDkwZGVnLCB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCksIGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCkgNTUlLCB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTMwMCkpKTtcbn1cbi50c2QtcmF0aW8tcGN0IHtcbiAgbWluLXdpZHRoOiA0MnB4O1xuICB0ZXh0LWFsaWduOiByaWdodDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIGZvbnQtdmFyaWFudC1udW1lcmljOiB0YWJ1bGFyLW51bXM7XG59XG5cbi8qID09PT09PT09PT09PSDkuInmgIHvvJrnqbogLyDplJnor68gLyDliqDovb0gPT09PT09PT09PT09ICovXG4udHNkLWVtcHR5IHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA2cHg7XG4gIHBhZGRpbmc6IDQwcHggMTZweDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xufVxuLnRzZC1lbXB0eS1pY29uIHtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIG1hcmdpbi1ib3R0b206IDRweDtcbn1cbi50c2QtZW1wdHktdGl0bGUge1xuICBtYXJnaW46IDA7XG4gIGZvbnQtc2l6ZTogMTVweDtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbn1cbi50c2QtZW1wdHktZGVzYyB7XG4gIG1hcmdpbjogMDtcbiAgZm9udC1zaXplOiAxM3B4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG59XG4udHNkLWVtcHR5LWJsb2NrIHtcbiAgcGFkZGluZzogMjRweDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBmb250LXNpemU6IDEzcHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xufVxuXG4udHNkLWVycm9yIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiAxMnB4O1xuICBwYWRkaW5nOiAyMHB4IDE2cHg7XG4gIGJvcmRlci1jb2xvcjogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWRzdy1hbGlhcy1zdGF0ZS1lcnJvci1wcmltYXJ5KSA0MCUsIHRyYW5zcGFyZW50KTtcbiAgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWRzdy1hbGlhcy1zdGF0ZS1lcnJvci1zZWNvbmRhcnkpIDMwJSwgdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTMpKTtcbn1cbi50c2QtZXJyb3ItaWNvbiB7XG4gIGZsZXg6IG5vbmU7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtZXJyb3ItcHJpbWFyeSk7XG59XG4udHNkLWVycm9yLXRleHQge1xuICBmbGV4OiAxO1xuICBtaW4td2lkdGg6IDA7XG59XG4udHNkLWVycm9yLXRpdGxlIHtcbiAgbWFyZ2luOiAwO1xuICBmb250LXNpemU6IDE0cHg7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG59XG4udHNkLWVycm9yLWRldGFpbCB7XG4gIG1hcmdpbjogMnB4IDAgMDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuXG4udHNkLWFsZXJ0LWJhbm5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogMTBweDtcbiAgcGFkZGluZzogMTBweCAxNHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZHN3LWFsaWFzLXN0YXRlLWVycm9yLXByaW1hcnkpIDQwJSwgdHJhbnNwYXJlbnQpO1xuICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZHN3LWFsaWFzLXN0YXRlLWVycm9yLXNlY29uZGFyeSkgMzAlLCB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMykpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLXN0YXRlLWVycm9yLXByaW1hcnkpO1xuICBmb250LXNpemU6IDEzcHg7XG59XG5cbi50c2QtbG9hZGluZyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogMTZweDtcbn1cbi50c2QtY2FyZC1za2VsZXRvbiB7IG1pbi1oZWlnaHQ6IDg0cHg7IH1cbi50c2Qtc2tlbGV0b24ge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctc2tlbGV0b24pO1xuICBib3JkZXItcmFkaXVzOiA2cHg7XG4gIGFuaW1hdGlvbjogdHNkLXB1bHNlIDEuNnMgdmFyKC0tZHMtZWFzZS1pbi1vdXQpIGluZmluaXRlO1xufVxuLnRzZC1za2VsZXRvbi1yb3cge1xuICBoZWlnaHQ6IDE0cHg7XG4gIG1hcmdpbjogMTJweCAwO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctc2tlbGV0b24pO1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIGFuaW1hdGlvbjogdHNkLXB1bHNlIDEuNnMgdmFyKC0tZHMtZWFzZS1pbi1vdXQpIGluZmluaXRlO1xufVxuQGtleWZyYW1lcyB0c2QtcHVsc2Uge1xuICAwJSwgMTAwJSB7IG9wYWNpdHk6IDE7IH1cbiAgNTAlIHsgb3BhY2l0eTogMC40NTsgfVxufVxuXG4vKiA9PT09PT09PT09PT0g5Yi35paw5pe255qE5YaF5a655oCBID09PT09PT09PT09PSAqL1xuLnRzZC1jb250ZW50IHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiAxNnB4O1xuICB0cmFuc2l0aW9uOiBvcGFjaXR5IHZhcigtLWRzLXRyYW5zaXRpb24tZHVyYXRpb24pIHZhcigtLWRzLWVhc2UtaW4tb3V0KTtcbn1cbi50c2QtY29udGVudFtkYXRhLWJ1c3k9dHJ1ZV0geyBvcGFjaXR5OiAwLjU1OyB9XG5cbi8qID09PT09PT09PT09PSDml6Dpmpznoo0gPT09PT09PT09PT09ICovXG4udHNkLXZpc3VhbGx5LWhpZGRlbiB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgd2lkdGg6IDFweDtcbiAgaGVpZ2h0OiAxcHg7XG4gIHBhZGRpbmc6IDA7XG4gIG1hcmdpbjogLTFweDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgY2xpcDogcmVjdCgwIDAgMCAwKTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgYm9yZGVyOiAwO1xufVxuLnRzZC1pY29uIHtcbiAgZmxleDogbm9uZTtcbn1cbi50c2Qtc2VnLWJ0bjpmb2N1cy12aXNpYmxlLFxuLnRzZC1zZWxlY3QtYnRuOmZvY3VzLXZpc2libGUsXG4udHNkLWJ0bjpmb2N1cy12aXNpYmxlLFxuLnRzZC1pY29uLWJ0bjpmb2N1cy12aXNpYmxlLFxuLnRzZC1saW5rLWJ0bjpmb2N1cy12aXNpYmxlLFxuLnRzZC1zb3J0LWJ0bjpmb2N1cy12aXNpYmxlIHtcbiAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1zdGF0ZS1idXNpbmVzcy1wcmltYXJ5KTtcbiAgb3V0bGluZS1vZmZzZXQ6IDJweDtcbn1cbi8qID09PT09PT09PT09PSDnspLluqbliIfmjaIgPT09PT09PT09PT09ICovXG4udHNkLWNhcmQtYWN0aW9ucyB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDhweDtcbn1cbi50c2QtZ3JhbiB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBnYXA6IDJweDtcbiAgcGFkZGluZzogMnB4O1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0xKTtcbn1cbi50c2QtZ3Jhbi1idG4ge1xuICBib3JkZXI6IG5vbmU7XG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgZm9udDogaW5oZXJpdDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBsaW5lLWhlaWdodDogMTZweDtcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xuICBwYWRkaW5nOiAycHggOHB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG4udHNkLWdyYW4tYnRuW2RhdGEtYWN0aXZlPVwidHJ1ZVwiXSB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0zKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbiAgYm94LXNoYWRvdzogdmFyKC0tZHN3LXNoYWRvdy1sdjEpO1xufVxuLnRzZC1ncmFuLWJ0bjpkaXNhYmxlZCB7XG4gIG9wYWNpdHk6IDAuNDtcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbn1cbi8qID09PT09PT09PT09PSDmipjnur/lm74gPT09PT09PT09PT09ICovXG4udHNkLWxpbmVjaGFydCB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgcGFkZGluZzogNnB4IDEwcHggOHB4O1xufVxuLnRzZC1saW5lY2hhcnQgc3ZnIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IGF1dG87XG59XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtZ3JpZCB7XG4gIHN0cm9rZTogdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIHN0cm9rZS13aWR0aDogMTtcbiAgc3Ryb2tlLWRhc2hhcnJheTogMyAzO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLWF4aXMge1xuICBzdHJva2U6IHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBzdHJva2Utd2lkdGg6IDE7XG59XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtaW4ge1xuICBzdHJva2U6IHZhcigtLWRzdy1zdGF0aWMtZGVlcHNlZWstNTAwKTtcbiAgc3Ryb2tlLXdpZHRoOiAyO1xuICBmaWxsOiBub25lO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLW91dCB7XG4gIHN0cm9rZTogdmFyKC0tZHN3LXN0YXRpYy1ncmVlbi01MDApO1xuICBzdHJva2Utd2lkdGg6IDI7XG4gIGZpbGw6IG5vbmU7XG59XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtdG90YWwge1xuICBzdHJva2U6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBzdHJva2Utd2lkdGg6IDEuNTtcbiAgc3Ryb2tlLWRhc2hhcnJheTogNCAzO1xuICBmaWxsOiBub25lO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLWRvdCB7XG4gIGZpbGw6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0yKTtcbiAgc3Ryb2tlOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgc3Ryb2tlLXdpZHRoOiAxO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLWhvdmVyIHtcbiAgZmlsbDogdHJhbnNwYXJlbnQ7XG4gIGN1cnNvcjogY3Jvc3NoYWlyO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLWN1cnNvciB7XG4gIHN0cm9rZTogdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMyk7XG4gIHN0cm9rZS13aWR0aDogMTtcbiAgc3Ryb2tlLWRhc2hhcnJheTogMyAzO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cbi50c2QtbGluZWNoYXJ0IC50c2QtbGluZS1obCB7XG4gIHN0cm9rZTogdmFyKC0tZHN3LWFsaWFzLWJnLWJhc2UpO1xuICBzdHJva2Utd2lkdGg6IDEuNTtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtaGwtaW4geyBmaWxsOiB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCk7IH1cbi50c2QtbGluZWNoYXJ0IC50c2QtbGluZS1obC1vdXQgeyBmaWxsOiB2YXIoLS1kc3ctc3RhdGljLWdyZWVuLTUwMCk7IH1cbi50c2QtbGluZWNoYXJ0IC50c2QtbGluZS1obC10b3RhbCB7IGZpbGw6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpOyB9XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtdGV4dCB7XG4gIGZpbGw6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIGZvbnQtc2l6ZTogMTBweDtcbn1cbi8qID09PT09PT09PT09PSDlubTluqbng63lipvlm74gPT09PT09PT09PT09ICovXG4udHNkLWhlYXRtYXAge1xuICBwYWRkaW5nOiA2cHggMTRweCAxNHB4O1xuICBvdmVyZmxvdy14OiBhdXRvO1xufVxuLnRzZC1oZWF0bWFwLWlubmVyIHtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogNHB4O1xuICBtaW4td2lkdGg6IG1pbi1jb250ZW50O1xufVxuLnRzZC1oZWF0bWFwLW1vbnRocyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIG1hcmdpbi1sZWZ0OiAyNnB4O1xuICBoZWlnaHQ6IDE0cHg7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cbi50c2QtaGVhdG1hcC1tb250aCB7XG4gIGZvbnQtc2l6ZTogOXB4O1xuICBsaW5lLWhlaWdodDogMTRweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAwO1xufVxuLnRzZC1oZWF0bWFwLWJvZHkge1xuICBkaXNwbGF5OiBmbGV4O1xuICBnYXA6IDRweDtcbn1cbi50c2QtaGVhdG1hcC1kYXlzIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiAycHg7XG4gIHdpZHRoOiAyMnB4O1xuICBmbGV4OiBub25lO1xufVxuLnRzZC1oZWF0bWFwLWRheSB7XG4gIGhlaWdodDogMTBweDtcbiAgZm9udC1zaXplOiA5cHg7XG4gIGxpbmUtaGVpZ2h0OiAxMHB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gIHBhZGRpbmctcmlnaHQ6IDRweDtcbn1cbi50c2QtaGVhdG1hcC1ncmlkIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZ2FwOiAycHg7XG59XG4udHNkLWhlYXRtYXAtY29sIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiAycHg7XG59XG4udHNkLWhlYXRtYXAtY2VsbCB7XG4gIHdpZHRoOiAxMHB4O1xuICBoZWlnaHQ6IDEwcHg7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTtcbiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIHZhcigtLWRzLXRyYW5zaXRpb24tZHVyYXRpb24tZmFzdCkgdmFyKC0tZHMtZWFzZS1pbi1vdXQpLCBib3gtc2hhZG93IHZhcigtLWRzLXRyYW5zaXRpb24tZHVyYXRpb24tZmFzdCkgdmFyKC0tZHMtZWFzZS1pbi1vdXQpO1xufVxuLnRzZC1oZWF0bWFwLWNlbGw6aG92ZXIge1xuICBvdXRsaW5lOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIHRyYW5zZm9ybTogc2NhbGUoMS4zNSk7XG4gIGJveC1zaGFkb3c6IHZhcigtLWRzdy1zaGFkb3ctbHYyKTtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB6LWluZGV4OiAyO1xufVxuLnRzZC1oZWF0bWFwLWxlZ2VuZCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogNHB4O1xuICBtYXJnaW46IDhweCAxNHB4IDA7XG4gIHBhZGRpbmctdG9wOiA4cHg7XG4gIGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgZm9udC1zaXplOiAxMHB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbn1cblxuLyogPT09PT09PT09PT09IOi+k+WFpeWMuuaIkOacrCBwaWxs77yIY29tcG9zZXIgZG9ja++8iT09PT09PT09PT09PSAqL1xuLnRzZC1kb2NrIHtcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogNHB4O1xuICBoZWlnaHQ6IDIycHg7XG4gIHBhZGRpbmc6IDAgOHB4O1xuICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgYm9yZGVyOiAwLjVweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwxKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWJhc2UpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgbGluZS1oZWlnaHQ6IDE7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIGN1cnNvcjogZGVmYXVsdDtcbn1cbi50c2QtZG9jay1sYWJlbCB7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xufVxuLnRzZC1kb2NrLXZhbHVlIHtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbn1cbmBcblxuLy8gMC4yKyBob3N0IHRyYW5zcG9ydDogUE9TVCAvYXBpLzxjaGFubmVsPi88ZW5kcG9pbnQ+LCBhcmdzIGFzIHRoZSBKU09OIGJvZHksXG4vLyBhbnN3ZXJpbmcgeyBvaywgdmFsdWUgfSB8IHsgb2ssIGVycm9yIH0gKHNlZSBzcmMvaG9zdC9ycGMuanMpLiBUaGUgcm91dGUgaXNcbi8vIG1vdW50ZWQgb24gQ29ubmVjdGlvbidzIHNoYXJlZCBBUEkgY2hhbm5lbCwgc28gaXQgbmV2ZXIgbmVlZHMgdGhlIHBsdWdpbidzXG4vLyBmaWJlciB0byBvd24gYHdlYlNlcnZlcmAuXG5mdW5jdGlvbiBjYWxsRmV0Y2goY2hhbm5lbCwgZW5kcG9pbnQsIGFyZ3MpIHtcbiAgY29uc3QgcGF0aCA9ICcvYXBpLycgKyBTdHJpbmcoY2hhbm5lbCkucmVwbGFjZSgvXlxcLysvLCAnJykgKyAnLycgKyBlbmRwb2ludFxuICByZXR1cm4gZmV0Y2gocGF0aCwge1xuICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nLFxuICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGFyZ3MgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmdzKSxcbiAgfSkudGhlbigocmVzKSA9PiB7XG4gICAgY29uc3QgdHlwZSA9IHJlcy5oZWFkZXJzLmdldCgnY29udGVudC10eXBlJykgfHwgJydcbiAgICAvLyBSb3V0ZSBtaXNzaW5nIG9uIHRoaXMgaG9zdDogNDA0LzQwNSBmcm9tIHRoZSBzaGFyZWQgZGlzcGF0Y2hlciwgb3IgdGhlXG4gICAgLy8gU1BBIEhUTUwgd2hlbiBubyB0cmFuc3BvcnQgcm91dGUgbWF0Y2hlZCB0aGUgcGF0aCBhdCBhbGwuXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwNCB8fCByZXMuc3RhdHVzID09PSA0MDUgfHwgdHlwZS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgPT09IC0xKSB7XG4gICAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigndXNhZ2UgRmV0Y2ggcm91dGUgdW5hdmFpbGFibGUgKEhUVFAgJyArIHJlcy5zdGF0dXMgKyAnKScpXG4gICAgICBlcnJvci5jb2RlID0gJ3VzYWdlLXJvdXRlLW1pc3NpbmcnXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cbiAgICByZXR1cm4gcmVzLmpzb24oKS50aGVuKChib2R5KSA9PiB7XG4gICAgICBpZiAoYm9keSAmJiBib2R5Lm9rKSByZXR1cm4gYm9keS52YWx1ZVxuICAgICAgdGhyb3cgbmV3IEVycm9yKChib2R5ICYmIGJvZHkuZXJyb3IgJiYgYm9keS5lcnJvci5tZXNzYWdlKSB8fCAoJ1JQQyAnICsgZW5kcG9pbnQgKyAnIGZhaWxlZCcpKVxuICAgIH0pXG4gIH0pXG59XG5cbi8vIFJQQyBicmlkZ2U6IGR5bmFtaWMtcGx1Z2luIHJ1bnMgcHJvdmlkZSBhIGBob3N0YCBnbG9iYWw7IHN0YXRpYyAoYnVuZGxlKVxuLy8gaW5zdGFsbHMgcHJvdmlkZSBjdHguZ2V0KCdjb25uZWN0aW9uJykuIEtlZXAgb25lIFVJIHNvdXJjZSBmb3IgYm90aC5cbmZ1bmN0aW9uIGhvc3RDYWxsKG1ldGhvZCwgYXJncykge1xuICAvLyBQMC0zOiBwcmVmZXIgdGhlIG9mZmljaWFsIGByZW1vdGVgIHNlcnZpY2Ugd2hlbiBpdCBleHBvc2VzIHRoZSB1c2FnZSBBUEk7XG4gIC8vIG90aGVyd2lzZSBmYWxsIHRocm91Z2ggdG8gdGhlIGhvc3QvY29ubmVjdGlvbiBmYWxsYmFja3MgdW5jaGFuZ2VkLlxuICBjb25zdCByZW1vdGVTY29wZSA9ICh0eXBlb2YgY3R4ICE9PSAndW5kZWZpbmVkJyAmJiBjdHggJiYgdHlwZW9mIGN0eC5nZXQgPT09ICdmdW5jdGlvbicpXG4gICAgPyBjdHhcbiAgICA6ICh0eXBlb2YgX3VzYWdlQ3R4ICE9PSAndW5kZWZpbmVkJyAmJiBfdXNhZ2VDdHggJiYgdHlwZW9mIF91c2FnZUN0eC5nZXQgPT09ICdmdW5jdGlvbicgPyBfdXNhZ2VDdHggOiBudWxsKVxuICBpZiAocmVtb3RlU2NvcGUgJiYgdHlwZW9mIHJlbW90ZVNjb3BlLmdldCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZW1vdGUgPSByZW1vdGVTY29wZS5nZXQoJ3JlbW90ZScpXG4gICAgICBpZiAocmVtb3RlICYmIHJlbW90ZS51c2FnZSkge1xuICAgICAgICBjb25zdCByTmFtZSA9IFN0cmluZyhtZXRob2QpXG4gICAgICAgIGNvbnN0IHJTbGFzaCA9IHJOYW1lLmluZGV4T2YoJy8nKVxuICAgICAgICBjb25zdCByRXAgPSByU2xhc2ggPT09IC0xID8gck5hbWUgOiByTmFtZS5zbGljZShyU2xhc2ggKyAxKVxuICAgICAgICBjb25zdCByQ2FtZWwgPSByRXAucmVwbGFjZSgvLShbYS16XSkvZywgKG0sIGMpID0+IGMudG9VcHBlckNhc2UoKSlcbiAgICAgICAgY29uc3QgZm4gPSAodHlwZW9mIHJlbW90ZS51c2FnZVtyQ2FtZWxdID09PSAnZnVuY3Rpb24nICYmIHJlbW90ZS51c2FnZVtyQ2FtZWxdKVxuICAgICAgICAgIHx8ICh0eXBlb2YgcmVtb3RlLnVzYWdlW3JFcF0gPT09ICdmdW5jdGlvbicgJiYgcmVtb3RlLnVzYWdlW3JFcF0pXG4gICAgICAgIGlmIChmbikge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IGZuKGFyZ3MpKS50aGVuKChyZXMpID0+IHtcbiAgICAgICAgICAgIGlmIChyZXMgJiYgcmVzLm9rKSByZXR1cm4gcmVzLnZhbHVlXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKHJlcyAmJiByZXMuZXJyb3IgJiYgcmVzLmVycm9yLm1lc3NhZ2UpIHx8ICgnUlBDICcgKyBtZXRob2QgKyAnIGZhaWxlZCcpKVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyByZW1vdGUgcHJvYmluZyBmYWlsZWQg4oCUIGZhbGwgdGhyb3VnaCB0byB0aGUgZXhpc3RpbmcgZmFsbGJhY2tzXG4gICAgfVxuICB9XG4gIGlmICh0eXBlb2YgaG9zdCAhPT0gJ3VuZGVmaW5lZCcgJiYgaG9zdCAmJiB0eXBlb2YgaG9zdC5jYWxsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShob3N0LmNhbGwobWV0aG9kLCBhcmdzKSlcbiAgfVxuICAvLyBTdGF0aWMgYnVuZGxlIGluc3RhbGxzIGhhdmUgbm8gY3R4L2hvc3QgZ2xvYmFsczogdGhlIGVudHJ5IGFwcGx5KCkgc3RvcmVzXG4gIC8vIHRoZSByZWFsIGNvbnRleHQgaW4gX3VzYWdlQ3R4IChkZWNsYXJlZCBieSB0aGUgYnVpbGQgd3JhcHBlcikuXG4gIGNvbnN0IHNjb3BlID0gKHR5cGVvZiBjdHggIT09ICd1bmRlZmluZWQnICYmIGN0eCAmJiB0eXBlb2YgY3R4LmdldCA9PT0gJ2Z1bmN0aW9uJylcbiAgICA/IGN0eFxuICAgIDogKHR5cGVvZiBfdXNhZ2VDdHggIT09ICd1bmRlZmluZWQnID8gX3VzYWdlQ3R4IDogbnVsbClcbiAgaWYgKHNjb3BlID09PSBudWxsIHx8IHR5cGVvZiBzY29wZS5nZXQgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdjb250ZXh0IHVuYXZhaWxhYmxlJykpXG4gIH1cbiAgY29uc3QgbmFtZSA9IFN0cmluZyhtZXRob2QpXG4gIGNvbnN0IHNsYXNoID0gbmFtZS5pbmRleE9mKCcvJylcbiAgY29uc3QgY2hhbm5lbCA9IHNsYXNoID09PSAtMSA/IG5hbWUgOiBuYW1lLnNsaWNlKDAsIHNsYXNoKVxuICBjb25zdCBlbmRwb2ludCA9IHNsYXNoID09PSAtMSA/IG5hbWUgOiBuYW1lLnNsaWNlKHNsYXNoICsgMSlcbiAgLy8gTGVnYWN5IHByZS0wLjIgdHJhbnNwb3J0OiBhIGAvdXNhZ2VgIHByZWZpeCBSUEMgY2hhbm5lbCBvd25lZCBieSB0aGUgaG9zdFxuICAvLyBwbHVnaW4gaXRzZWxmLlxuICBjb25zdCBjYWxsUnBjID0gKCkgPT4ge1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBzY29wZS5nZXQoJ2Nvbm5lY3Rpb24nKVxuICAgIGlmIChjb25uZWN0aW9uID09PSB1bmRlZmluZWQgfHwgY29ubmVjdGlvbi5ycGMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignY29ubmVjdGlvbiBzZXJ2aWNlIHVuYXZhaWxhYmxlJykpXG4gICAgfVxuICAgIHJldHVybiBjb25uZWN0aW9uLnJwYy5jYWxsKCcvJyArIGNoYW5uZWwucmVwbGFjZSgvXlxcLysvLCAnJyksIGVuZHBvaW50LCBhcmdzKS50aGVuKChyZXMpID0+IHtcbiAgICAgIGlmIChyZXMgJiYgcmVzLm9rKSByZXR1cm4gcmVzLnZhbHVlXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoKHJlcyAmJiByZXMuZXJyb3IgJiYgcmVzLmVycm9yLm1lc3NhZ2UpIHx8ICgnUlBDICcgKyBtZXRob2QgKyAnIGZhaWxlZCcpKVxuICAgIH0pXG4gIH1cbiAgLy8gUHJlZmVyIHRoZSBzaGFyZWQtY2hhbm5lbCBGZXRjaCByb3V0ZTsgYW4gb2xkZXIgaG9zdCBhbnN3ZXJzIFwicm91dGVcbiAgLy8gbWlzc2luZ1wiIGFuZCB3ZSBmYWxsIGJhY2sgdG8gdGhlIGxlZ2FjeSBjaGFubmVsIGl0IGRvZXMgaW1wbGVtZW50LlxuICBjb25zdCBmZXRjaFVzYWJsZSA9IHR5cGVvZiBmZXRjaCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmICEodHlwZW9mIGxvY2F0aW9uICE9PSAndW5kZWZpbmVkJyAmJiBsb2NhdGlvbi5wcm90b2NvbCA9PT0gJ2ZpbGU6JylcbiAgaWYgKCFmZXRjaFVzYWJsZSkgcmV0dXJuIGNhbGxScGMoKVxuICByZXR1cm4gY2FsbEZldGNoKGNoYW5uZWwsIGVuZHBvaW50LCBhcmdzKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICBpZiAoZXJyb3IgJiYgZXJyb3IuY29kZSA9PT0gJ3VzYWdlLXJvdXRlLW1pc3NpbmcnKSByZXR1cm4gY2FsbFJwYygpXG4gICAgdGhyb3cgZXJyb3JcbiAgfSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDorr7nva7ln5/lrprku7fvvJrlrpjmlrkgYGN0eC5jb25maWdGb3Jtcy5nZXQoJ3VzYWdlJylg77yIZHNoLWNsaWVudC11aS1zZXR0aW5nc++8ieS8mOWFiO+8jFxuICog5LiN5Y+v55So5pe25Zue6YCAIHVzYWdlL3ByaWNlcyBSUEPjgILnu5Hlrprlj6rlgZrkuIDmrKHvvIzor7vlhpnlhbHnlKjlkIzkuIAgZm9ybeOAglxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xubGV0IHVzYWdlQ3R4ID0gbnVsbFxubGV0IF91c2FnZVByaWNlc1Njb3BlID0gbnVsbFxuXG5mdW5jdGlvbiByZXNvbHZlVXNhZ2VDdHgoKSB7XG4gIGlmICh1c2FnZUN0eCAmJiB0eXBlb2YgdXNhZ2VDdHguZ2V0ID09PSAnZnVuY3Rpb24nKSByZXR1cm4gdXNhZ2VDdHhcbiAgaWYgKHR5cGVvZiBfdXNhZ2VDdHggIT09ICd1bmRlZmluZWQnICYmIF91c2FnZUN0eCAmJiB0eXBlb2YgX3VzYWdlQ3R4LmdldCA9PT0gJ2Z1bmN0aW9uJykgcmV0dXJuIF91c2FnZUN0eFxuICByZXR1cm4gbnVsbFxufVxuXG5mdW5jdGlvbiBnZXRVc2FnZVByaWNlc1Njb3BlKCkge1xuICBpZiAoX3VzYWdlUHJpY2VzU2NvcGUpIHJldHVybiBfdXNhZ2VQcmljZXNTY29wZVxuICBjb25zdCBjID0gcmVzb2x2ZVVzYWdlQ3R4KClcbiAgaWYgKCFjIHx8IHR5cGVvZiBjLmdldCAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIG51bGxcbiAgdHJ5IHtcbiAgICAvLyAwLjIueDogdGhlIG9mZmljaWFsIGNvbmZpZy1mb3JtIHN1cmZhY2UgZm9yIHRoaXMgcGx1Z2luJ3MgZW50cnkgaWRcbiAgICAvLyAoYHVzYWdlYCwgdGhlIGJ1bmRsZSBwYXRjaCByb3cgaWQpLiBgc2V0dGluZ3NTY29wZWAgZnJvbSAwLjEueCBkb2VzIG5vdFxuICAgIC8vIGV4aXN0IGluIHRoZSBzaGlwcGVkIGNsaWVudCwgc28gcHJvYmluZyBpdCBvbmx5IGV2ZXIgcmV0dXJuZWQgbnVsbC5cbiAgICBjb25zdCBmb3JtcyA9IGMuZ2V0KCdjb25maWdGb3JtcycpXG4gICAgaWYgKCFmb3JtcyB8fCB0eXBlb2YgZm9ybXMuZ2V0ICE9PSAnZnVuY3Rpb24nKSByZXR1cm4gbnVsbFxuICAgIF91c2FnZVByaWNlc1Njb3BlID0gZm9ybXMuZ2V0KCd1c2FnZScpXG4gICAgcmV0dXJuIF91c2FnZVByaWNlc1Njb3BlXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbi8vIOS7t+agvOWGmeWFpeWPo++8mnNldHRpbmdzIHNjb3BlIOWPr+eUqOaXtuWGmSB1c2FnZS5wcmljZXMg5ZG95ZCN56m66Ze05a2X5q6177yMXG4vLyDlkKbliJnlm57pgIAgdXNhZ2UvcHJpY2VzIFJQQ++8iOW9k+WJjSBVSSDml6Dku7fmoLznvJbovpHlmajvvIzkv53nlZnmraTlhpnlhaUgc2VhbSDkvpvlkI7nu63kvb/nlKjvvInjgIJcbmZ1bmN0aW9uIHVzYWdlU2F2ZVByaWNlcyhuZXh0KSB7XG4gIGNvbnN0IGFyZ3MgPSB7fVxuICBpZiAobmV4dCAmJiB0eXBlb2YgbmV4dCA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAobmV4dC5wcmljZXMgIT09IHVuZGVmaW5lZCkgYXJncy5wcmljZXMgPSBuZXh0LnByaWNlc1xuICAgIGlmIChuZXh0LmN1cnJlbmN5ICE9PSB1bmRlZmluZWQpIGFyZ3MuY3VycmVuY3kgPSBuZXh0LmN1cnJlbmN5XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCBzY29wZSA9IGdldFVzYWdlUHJpY2VzU2NvcGUoKVxuICAgIGlmIChzY29wZSAmJiB0eXBlb2Ygc2NvcGUuc2V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb25zdCBqb2JzID0gW11cbiAgICAgIGlmIChhcmdzLnByaWNlcyAhPT0gdW5kZWZpbmVkKSBqb2JzLnB1c2goc2NvcGUuc2V0KCdwcmljZXMnLCBhcmdzLnByaWNlcykpXG4gICAgICBpZiAoYXJncy5jdXJyZW5jeSAhPT0gdW5kZWZpbmVkKSBqb2JzLnB1c2goc2NvcGUuc2V0KCdjdXJyZW5jeScsIGFyZ3MuY3VycmVuY3kpKVxuICAgICAgaWYgKGpvYnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoam9icykudGhlbigoKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc25hcCA9IHR5cGVvZiBzY29wZS5nZXRTbmFwc2hvdCA9PT0gJ2Z1bmN0aW9uJyA/IHNjb3BlLmdldFNuYXBzaG90KCkgOiBudWxsXG4gICAgICAgICAgcmV0dXJuIHNuYXAgJiYgc25hcC52YWx1ZSA/IHNuYXAudmFsdWUgOiBudWxsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gZmFsbCB0aHJvdWdoIHRvIHRoZSBSUEMgd3JpdGUgcGF0aFxuICB9XG4gIHJldHVybiBob3N0Q2FsbCgndXNhZ2UvcHJpY2VzJywgYXJncylcbn1cblxuO1xuY29uc3QgaCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnRcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDlm73pmYXljJbvvJp6aC9lbiDlrZflhbggKyBDb250ZXh077yIbG9jYWxlIOacjeWKoee7jyBzbG90IOazqOWGjOazqOWFpSB077yM5a2Q57uE5Lu257uPIENvbnRleHQg5Y+W55So77yJXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5jb25zdCBOUyA9ICd1c2FnZSdcbmNvbnN0IFpIID0ge1xuICBuYXY6ICfnlKjph4/nu5/orqEnLFxuICBzdWJ0aXRsZTogJ+afpeeciyBBSSDmqKHlnovnmoTkvb/nlKjmg4XlhrXlkozmiJDmnKznu5/orqEnLFxuICByZWZyZXNoOiAn5Yi35pawJyxcbiAgY3VycmVuY3lIaW50OiAn5Y+C6ICD5oiQ5pys5biB56eN77yI5Zu65a6a5rGH546HIDEgVVNEID0gNyBDTlnvvIknLFxuICBjdXJyZW5jeUNOWTogJ+S6uuawkeW4gScsXG4gIGN1cnJlbmN5VVNEOiAn576O5YWDJyxcbiAgdG9kYXk6ICfku4rml6UnLFxuICBkb2NrSGludDogJ+S7iuaXpSB7Y29zdH0gwrcge2NhbGxzfSDmrKHosIPnlKggwrcge3Rva2Vuc30gVG9rZW4nLFxuICBkb2NrVW5wcmljZWQ6ICfmnKrlrprku7cnLFxuICBsYXN0N2Q6ICfov5E35aSpJyxcbiAgbGFzdDMwZDogJ+i/kTMw5aSpJyxcbiAgY3VzdG9tOiAn6Ieq5a6a5LmJJyxcbiAgYWxsOiAn5YWo6YOoJyxcbiAgYWxsTW9kZWxzOiAn5YWo6YOo5qih5Z6LJyxcbiAgc2VsZWN0ZWRNb2RlbHM6ICflt7LpgIkge2NvdW50fSDkuKrmqKHlnosnLFxuICBzZWxlY3RBbGw6ICflhajpgIknLFxuICBjbGVhcjogJ+a4heepuicsXG4gIHNlYXJjaE1vZGVsczogJ+aQnOe0ouaooeWeiycsXG4gIG5vTWF0Y2hNb2RlbHM6ICfml6DljLnphY3mqKHlnosnLFxuICBtb2RlbEZpbHRlckhpbnQ6ICfli77pgInljbPml7bnlJ/mlYjvvIzku4XliJflh7rlvZPliY3ojIPlm7TlhoXmnInmlbDmja7nmoTmqKHlnosnLFxuICBjdXN0b21SYW5nZVRpdGxlOiAn6Ieq5a6a5LmJ5pe26Ze06IyD5Zu0JyxcbiAgY3VzdG9tUmFuZ2VBcmlhOiAn6Ieq5a6a5LmJ5pel5pyf6IyD5Zu0JyxcbiAgc3RhcnRUaW1lOiAn5byA5aeL5pe26Ze0JyxcbiAgZW5kVGltZTogJ+e7k+adn+aXtumXtCcsXG4gIHJhbmdlSW52YWxpZDogJ+W8gOWni+aXtumXtOS4jeiDveaZmuS6jue7k+adn+aXtumXtCcsXG4gIHJhbmdlSGludDogJ+aUr+aMgemAieaLqeS7u+aEj+aXpeacn+iMg+WbtO+8jOS4jemZkOi3qOW6picsXG4gIGNhbmNlbDogJ+WPlua2iCcsXG4gIGNvbmZpcm06ICfnoa7lrponLFxuICBkYXRlUmFuZ2VHcm91cDogJ+aXpeacn+iMg+WbtCcsXG4gIG1vZGVsRmlsdGVyR3JvdXA6ICfmqKHlnovnrZvpgIknLFxuICBjaGFydFR5cGVHcm91cDogJ+WbvuihqOexu+WeiycsXG4gIHRvdGFsVG9rZW5zOiAn5oC7IFRva2VuJyxcbiAgaW5wdXRUb2tlbnM6ICfovpPlhaUgVG9rZW4nLFxuICBvdXRwdXRUb2tlbnM6ICfovpPlh7ogVG9rZW4nLFxuICBjYWxsczogJ+iwg+eUqOasoeaVsCcsXG4gIGNvc3Q6ICflj4LogIPmiJDmnKwnLFxuICBhcHByb3hJTzogJ+KJiCDovpPlhaUr6L6T5Ye6JyxcbiAgdW5wcmljZWROb3RlOiAne2NvdW50fSDmrKHosIPnlKjmnKrlrprku7cnLFxuICBkYWlseVRyZW5kOiAn5q+P5pel55So6YeP6LaL5Yq/JyxcbiAgYmFyVmlldzogJ+afseeKtuWbvicsXG4gIGxpbmVWaWV3OiAn5oqY57q/5Zu+JyxcbiAgYnlIb3VyOiAn5oyJ5bCP5pe2JyxcbiAgYnlEYXk6ICfmjInlpKknLFxuICBldmVyeU5EYXlzOiAn5q+PIHtufSDlpKknLFxuICBsZWdlbmRJbnB1dDogJ+i+k+WFpScsXG4gIGxlZ2VuZE91dHB1dDogJ+i+k+WHuicsXG4gIGxlZ2VuZFRvdGFsOiAn5oC7IFRva2VuJyxcbiAgdG9vbHRpcFRvdGFsOiAn5ZCI6K6hJyxcbiAgc3RhcnRORGF5czogJ+i1tyB7bn0g5aSpJyxcbiAgbGluZUNoYXJ0QXJpYTogJ1Rva2VuIOeUqOmHj+i2i+WKv+aKmOe6v+WbvicsXG4gIHllYXJseUhlYXRtYXA6ICflubTluqbnlKjph4/ng63lipvlm74nLFxuICB5ZWFyRGFpbHk6ICd7eWVhcn0g5bm05q+P5pelIFRva2VuIOeUqOmHjycsXG4gIG1vbnRoTGFiZWw6ICd7bn3mnIgnLFxuICB3ZWVrZGF5TW9uOiAn5LiAJyxcbiAgd2Vla2RheVdlZDogJ+S4iScsXG4gIHdlZWtkYXlGcmk6ICfkupQnLFxuICBsZXNzOiAn5bCRJyxcbiAgbW9yZTogJ+WkmicsXG4gIGJ5TW9kZWxUaXRsZTogJ+aMieaooeWei+aYjue7hicsXG4gIG1vZGVsQ291bnQ6ICflhbEge259IOS4quaooeWeiycsXG4gIG1vZGVsVGFibGVDYXB0aW9uOiAn5oyJ5qih5Z6L55So6YeP5piO57uGJyxcbiAgY29sTW9kZWw6ICfmqKHlnosnLFxuICBjb2xDYWxsczogJ+ivt+axguaVsCcsXG4gIGNvbElucHV0OiAn6L6T5YWlIFRva2VuJyxcbiAgY29sT3V0cHV0OiAn6L6T5Ye6IFRva2VuJyxcbiAgY29sVG90YWw6ICfmgLsgVG9rZW4nLFxuICBjb2xDb3N0OiAn5Y+C6ICD5oiQ5pysJyxcbiAgY29sU2hhcmU6ICfljaDmr5QnLFxuICBtb2RlbFNoYXJlOiAn5qih5Z6L5Y2g5q+UJyxcbiAgc2hhcmVPdGhlcjogJ+WFtuWugycsXG4gIHVucHJpY2VkOiAn5pyq5a6a5Lu3JyxcbiAgdW5wcmljZWRSb3dIaW50OiAn6K+l5qih5Z6L5pyq6YWN572u5a6a5Lu377yM5oyJIDAg6K6h5Lu3JyxcbiAgbm9EYXRhOiAn5pqC5peg5pWw5o2uJyxcbiAgZW1wdHlEZXNjOiAn6K+l5pe26Ze05q615YaF5rKh5pyJ6LCD55So6K6w5b2VJyxcbiAgZW1wdHlGaWx0ZXJlZDogJ+W9k+WJjeetm+mAieadoeS7tuS4i+ayoeacieaVsOaNru+8jOivleivleiwg+aVtOaXtumXtOiMg+WbtOaIluaooeWeiycsXG4gIHJlc2V0RmlsdGVyczogJ+mHjee9ruetm+mAiScsXG4gIGxvYWRGYWlsZWQ6ICfmlbDmja7liqDovb3lpLHotKXvvJp7bWVzc2FnZX0nLFxuICBsb2FkRmFpbGVkVGl0bGU6ICfmlbDmja7liqDovb3lpLHotKUnLFxuICByZXRyeTogJ+mHjeivlScsXG4gIGJhckFyaWE6ICd7a2V5fe+8jOi+k+WFpSB7aW59IFRva2Vu77yM6L6T5Ye6IHtvdXR9IFRva2Vu77yM5ZCI6K6hIHt0b3R9IFRva2VuJyxcbiAgaG1UaXRsZTogJ3trZXl977yae3Rva2Vuc30gVG9rZW57Y2FsbHN9JyxcbiAgaG1DYWxsczogJ++8jHtjb3VudH0g5qyh6LCD55SoJyxcbiAgd2QwOiAn5ZGo5pelJyxcbiAgd2QxOiAn5ZGo5LiAJyxcbiAgd2QyOiAn5ZGo5LqMJyxcbiAgd2QzOiAn5ZGo5LiJJyxcbiAgd2Q0OiAn5ZGo5ZubJyxcbiAgd2Q1OiAn5ZGo5LqUJyxcbiAgd2Q2OiAn5ZGo5YWtJyxcbn1cbmNvbnN0IEVOID0ge1xuICBuYXY6ICdVc2FnZSBTdGF0cycsXG4gIHN1YnRpdGxlOiAnVmlldyBBSSBtb2RlbCB1c2FnZSBhbmQgY29zdCBzdGF0aXN0aWNzJyxcbiAgcmVmcmVzaDogJ1JlZnJlc2gnLFxuICBjdXJyZW5jeUhpbnQ6ICdSZWZlcmVuY2UtY29zdCBjdXJyZW5jeSAoZml4ZWQgcmF0ZTogMSBVU0QgPSA3IENOWSknLFxuICBjdXJyZW5jeUNOWTogJ0NOWScsXG4gIGN1cnJlbmN5VVNEOiAnVVNEJyxcbiAgdG9kYXk6ICdUb2RheScsXG4gIGRvY2tIaW50OiAnVG9kYXkge2Nvc3R9IMK3IHtjYWxsc30gY2FsbHMgwrcge3Rva2Vuc30gdG9rZW5zJyxcbiAgZG9ja1VucHJpY2VkOiAndW5wcmljZWQnLFxuICBsYXN0N2Q6ICdMYXN0IDcgZGF5cycsXG4gIGxhc3QzMGQ6ICdMYXN0IDMwIGRheXMnLFxuICBjdXN0b206ICdDdXN0b20nLFxuICBhbGw6ICdBbGwnLFxuICBhbGxNb2RlbHM6ICdBbGwgbW9kZWxzJyxcbiAgc2VsZWN0ZWRNb2RlbHM6ICd7Y291bnR9IG1vZGVscyBzZWxlY3RlZCcsXG4gIHNlbGVjdEFsbDogJ1NlbGVjdCBhbGwnLFxuICBjbGVhcjogJ0NsZWFyJyxcbiAgc2VhcmNoTW9kZWxzOiAnU2VhcmNoIG1vZGVscycsXG4gIG5vTWF0Y2hNb2RlbHM6ICdObyBtYXRjaGluZyBtb2RlbHMnLFxuICBtb2RlbEZpbHRlckhpbnQ6ICdBcHBsaWVzIGluc3RhbnRseTsgbGlzdHMgb25seSBtb2RlbHMgd2l0aCBkYXRhIGluIHRoZSByYW5nZScsXG4gIGN1c3RvbVJhbmdlVGl0bGU6ICdDdXN0b20gdGltZSByYW5nZScsXG4gIGN1c3RvbVJhbmdlQXJpYTogJ0N1c3RvbSBkYXRlIHJhbmdlJyxcbiAgc3RhcnRUaW1lOiAnU3RhcnQnLFxuICBlbmRUaW1lOiAnRW5kJyxcbiAgcmFuZ2VJbnZhbGlkOiAnU3RhcnQgbXVzdCBub3QgYmUgbGF0ZXIgdGhhbiBlbmQnLFxuICByYW5nZUhpbnQ6ICdBbnkgZGF0ZSByYW5nZSDigJQgbm8gbGVuZ3RoIGxpbWl0JyxcbiAgY2FuY2VsOiAnQ2FuY2VsJyxcbiAgY29uZmlybTogJ09LJyxcbiAgZGF0ZVJhbmdlR3JvdXA6ICdEYXRlIHJhbmdlJyxcbiAgbW9kZWxGaWx0ZXJHcm91cDogJ01vZGVsIGZpbHRlcicsXG4gIGNoYXJ0VHlwZUdyb3VwOiAnQ2hhcnQgdHlwZScsXG4gIHRvdGFsVG9rZW5zOiAnVG90YWwgVG9rZW5zJyxcbiAgaW5wdXRUb2tlbnM6ICdJbnB1dCBUb2tlbnMnLFxuICBvdXRwdXRUb2tlbnM6ICdPdXRwdXQgVG9rZW5zJyxcbiAgY2FsbHM6ICdDYWxscycsXG4gIGNvc3Q6ICdFc3QuIGNvc3QnLFxuICBhcHByb3hJTzogJ+KJiCBpbnB1dCtvdXRwdXQnLFxuICB1bnByaWNlZE5vdGU6ICd7Y291bnR9IGNhbGxzIHVucHJpY2VkJyxcbiAgZGFpbHlUcmVuZDogJ0RhaWx5IHVzYWdlIHRyZW5kJyxcbiAgYmFyVmlldzogJ0JhcnMnLFxuICBsaW5lVmlldzogJ0xpbmUnLFxuICBieUhvdXI6ICdIb3VybHknLFxuICBieURheTogJ0RhaWx5JyxcbiAgZXZlcnlORGF5czogJ0V2ZXJ5IHtufSBkYXlzJyxcbiAgbGVnZW5kSW5wdXQ6ICdJbnB1dCcsXG4gIGxlZ2VuZE91dHB1dDogJ091dHB1dCcsXG4gIGxlZ2VuZFRvdGFsOiAnVG90YWwnLFxuICB0b29sdGlwVG90YWw6ICdUb3RhbCcsXG4gIHN0YXJ0TkRheXM6ICdmb3Ige259IGRheXMnLFxuICBsaW5lQ2hhcnRBcmlhOiAnVG9rZW4gdXNhZ2UgdHJlbmQgbGluZSBjaGFydCcsXG4gIHllYXJseUhlYXRtYXA6ICdZZWFybHkgaGVhdG1hcCcsXG4gIHllYXJEYWlseTogJ0RhaWx5IHRva2VucyBpbiB7eWVhcn0nLFxuICBtb250aExhYmVsOiAne259JyxcbiAgd2Vla2RheU1vbjogJ01vbicsXG4gIHdlZWtkYXlXZWQ6ICdXZWQnLFxuICB3ZWVrZGF5RnJpOiAnRnJpJyxcbiAgbGVzczogJ0xlc3MnLFxuICBtb3JlOiAnTW9yZScsXG4gIGJ5TW9kZWxUaXRsZTogJ0J5IG1vZGVsJyxcbiAgbW9kZWxDb3VudDogJ3tufSBtb2RlbHMnLFxuICBtb2RlbFRhYmxlQ2FwdGlvbjogJ1Rva2VuIHVzYWdlIGJ5IG1vZGVsJyxcbiAgY29sTW9kZWw6ICdNb2RlbCcsXG4gIGNvbENhbGxzOiAnQ2FsbHMnLFxuICBjb2xJbnB1dDogJ0lucHV0IFRva2VucycsXG4gIGNvbE91dHB1dDogJ091dHB1dCBUb2tlbnMnLFxuICBjb2xUb3RhbDogJ1RvdGFsIFRva2VucycsXG4gIGNvbENvc3Q6ICdFc3QuIGNvc3QnLFxuICBjb2xTaGFyZTogJ1NoYXJlJyxcbiAgbW9kZWxTaGFyZTogJ01vZGVsIHNoYXJlJyxcbiAgc2hhcmVPdGhlcjogJ090aGVycycsXG4gIHVucHJpY2VkOiAnVW5wcmljZWQnLFxuICB1bnByaWNlZFJvd0hpbnQ6ICdObyBwcmljaW5nIGNvbmZpZ3VyZWQ7IGNvdW50ZWQgYXMgMCcsXG4gIG5vRGF0YTogJ05vIGRhdGEnLFxuICBlbXB0eURlc2M6ICdObyBjYWxscyBpbiB0aGlzIHBlcmlvZCcsXG4gIGVtcHR5RmlsdGVyZWQ6ICdObyBkYXRhIGZvciB0aGUgY3VycmVudCBmaWx0ZXJzLCB0cnkgYWRqdXN0aW5nIHRoZSByYW5nZSBvciBtb2RlbHMnLFxuICByZXNldEZpbHRlcnM6ICdSZXNldCBmaWx0ZXJzJyxcbiAgbG9hZEZhaWxlZDogJ0ZhaWxlZCB0byBsb2FkIGRhdGE6IHttZXNzYWdlfScsXG4gIGxvYWRGYWlsZWRUaXRsZTogJ0ZhaWxlZCB0byBsb2FkIGRhdGEnLFxuICByZXRyeTogJ1JldHJ5JyxcbiAgYmFyQXJpYTogJ3trZXl9LCBpbnB1dCB7aW59IHRva2Vucywgb3V0cHV0IHtvdXR9IHRva2VucywgdG90YWwge3RvdH0gdG9rZW5zJyxcbiAgaG1UaXRsZTogJ3trZXl9OiB7dG9rZW5zfSB0b2tlbnN7Y2FsbHN9JyxcbiAgaG1DYWxsczogJywge2NvdW50fSBjYWxscycsXG4gIHdkMDogJ1N1bicsXG4gIHdkMTogJ01vbicsXG4gIHdkMjogJ1R1ZScsXG4gIHdkMzogJ1dlZCcsXG4gIHdkNDogJ1RodScsXG4gIHdkNTogJ0ZyaScsXG4gIHdkNjogJ1NhdCcsXG59XG5jb25zdCBUID0gUmVhY3QuY3JlYXRlQ29udGV4dChudWxsKVxuZnVuY3Rpb24gdXNlVCgpIHtcbiAgcmV0dXJuIFJlYWN0LnVzZUNvbnRleHQoVClcbn1cbmZ1bmN0aW9uIGZhbGxiYWNrVChrZXksIHBhcmFtcykge1xuICBsZXQgcyA9IFpIW2tleV1cbiAgaWYgKHMgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGtleVxuICBpZiAocGFyYW1zKSB7XG4gICAgcyA9IHMucmVwbGFjZSgvXFx7KFxcdyspXFx9L2csIChtLCBuKSA9PiAocGFyYW1zW25dICE9PSB1bmRlZmluZWQgPyBTdHJpbmcocGFyYW1zW25dKSA6IG0pKVxuICB9XG4gIHJldHVybiBzXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog5pWw5a2X5qC85byP5YyW77yI6KeE5qC856ysIDUg6IqC77yJXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBmb3JtYXRUb2tlbnNTaG9ydChuKSB7XG4gIGlmICghTnVtYmVyLmlzRmluaXRlKG4pKSByZXR1cm4gJy0tJ1xuICBpZiAobiA+PSAxZTYpIHJldHVybiBNYXRoLnJvdW5kKG4gLyAxZTQpIC8gMTAwICsgJ00nIC8vIDEuMjNNXG4gIGlmIChuID49IDFlMykgcmV0dXJuIE1hdGgucm91bmQobiAvIDFlMikgLyAxMCArICdLJyAvLyAxMi4zS1xuICByZXR1cm4gU3RyaW5nKE1hdGgucm91bmQobikpXG59XG5mdW5jdGlvbiBmb3JtYXRJbnQobikge1xuICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG4pID8gTWF0aC5yb3VuZChuKS50b0xvY2FsZVN0cmluZygpIDogJy0tJ1xufVxuLyoqIOWPquimgeaVsOWtl+mDqOWIhu+8muaIkOacrOWNoeeahOespuWPt+eUseW4geenjeWIh+aNouWZqOiHquW3seeUu++8jOWGjeW4puS4gOasoeWwseaIkOS6huOAjMKlIMKlMTQuNzjjgI3jgIIgKi9cbmZ1bmN0aW9uIGNvc3REaWdpdHMobikge1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZShuKSkgcmV0dXJuICctLSdcbiAgLy8gQmVsb3cgaGFsZiBhIGNlbnQgdGhlcmUgaXMgbm90aGluZyB0byBzaG93IGF0IDIgZGVjaW1hbHM7IHNheSBzbyBpbnN0ZWFkIG9mXG4gIC8vIHByaW50aW5nIGEgbWlzbGVhZGluZyAwLjAwIChhICQwLjAzIENOWSBjb3N0IGJlY29tZXMgJDAuMDA0KS5cbiAgaWYgKG4gPiAwICYmIG4gPCAwLjAwNSkgcmV0dXJuICc8MC4wMSdcbiAgcmV0dXJuIG4udG9GaXhlZCgyKVxufVxuZnVuY3Rpb24gZm9ybWF0Q29zdChuLCBjdXIpIHtcbiAgcmV0dXJuIChjdXIgfHwgJ8KlJykgKyBjb3N0RGlnaXRzKG4pXG59XG5mdW5jdGlvbiBkYXlMYWJlbChrZXkpIHtcbiAgY29uc3QgWywgbSwgZF0gPSBTdHJpbmcoa2V5IHx8ICcnKS5zcGxpdCgnLScpXG4gIGlmIChtID09PSB1bmRlZmluZWQgfHwgZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJy0tJ1xuICByZXR1cm4gbSArICctJyArIGRcbn1cbmZ1bmN0aW9uIGZtdFBjdChyYXRpbykge1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZShyYXRpbykpIHJldHVybiAnMCUnXG4gIGNvbnN0IHAgPSByYXRpbyAqIDEwMFxuICBpZiAocCA+PSA5OS45NSkgcmV0dXJuICcxMDAlJ1xuICByZXR1cm4gcC50b0ZpeGVkKDEpICsgJyUnXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog5pel5pyf5bel5YW3XG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBzdGFydE9mRGF5KGQpIHtcbiAgY29uc3QgeCA9IG5ldyBEYXRlKGQpXG4gIHguc2V0SG91cnMoMCwgMCwgMCwgMClcbiAgcmV0dXJuIHhcbn1cbmZ1bmN0aW9uIGFkZERheXMoZCwgbikge1xuICBjb25zdCB4ID0gbmV3IERhdGUoZClcbiAgeC5zZXREYXRlKHguZ2V0RGF0ZSgpICsgbilcbiAgcmV0dXJuIHhcbn1cbmZ1bmN0aW9uIGZtdERhdGVJbnB1dChkKSB7XG4gIGNvbnN0IHkgPSBkLmdldEZ1bGxZZWFyKClcbiAgY29uc3QgbSA9IFN0cmluZyhkLmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCAnMCcpXG4gIGNvbnN0IGRheSA9IFN0cmluZyhkLmdldERhdGUoKSkucGFkU3RhcnQoMiwgJzAnKVxuICByZXR1cm4geSArICctJyArIG0gKyAnLScgKyBkYXlcbn1cbmZ1bmN0aW9uIGZtdERhdGVTbGFzaChzKSB7XG4gIGNvbnN0IG0gPSBTdHJpbmcocyB8fCAnJykubWF0Y2goL14oXFxkezR9KS0oXFxkezJ9KS0oXFxkezJ9KSQvKVxuICBpZiAoIW0pIHJldHVybiAnLS0nXG4gIHJldHVybiBtWzFdICsgJy8nICsgbVsyXSArICcvJyArIG1bM11cbn1cbi8vIOmihOiuviAvIOiHquWumuS5iSDihpIgeyBmcm9tLCB0byB977yIVW5peCDmr6vnp5LvvIlcbi8vIOS7iuaXpSA9IOW9k+WkqSAwMDowMCDoh7Pku4rvvJvov5E3LzMw5aSpID0g5ZCr5LuK5aSp5b6A5YmNIE4g5Liq6Ieq54S25pelIDAwOjAwIOi1t++8m+WFqOmDqCA9IOS4jemZkOi1t+eCue+8m1xuLy8g6Ieq5a6a5LmJID0g6LW35pelIDAwOjAwIH4g5q2i5pelIDIzOjU5OjU5Ljk5OVxuZnVuY3Rpb24gcmFuZ2VGb3IocHJlc2V0LCBjdXN0b20pIHtcbiAgY29uc3Qgbm93ID0gbmV3IERhdGUoKVxuICBjb25zdCB0b2RheSA9IHN0YXJ0T2ZEYXkobm93KVxuICBpZiAocHJlc2V0ID09PSAndG9kYXknKSByZXR1cm4geyBmcm9tOiB0b2RheS5nZXRUaW1lKCksIHRvOiBub3cuZ2V0VGltZSgpIH1cbiAgaWYgKHByZXNldCA9PT0gJzdkJykgcmV0dXJuIHsgZnJvbTogYWRkRGF5cyh0b2RheSwgLTYpLmdldFRpbWUoKSwgdG86IG5vdy5nZXRUaW1lKCkgfVxuICBpZiAocHJlc2V0ID09PSAnMzBkJykgcmV0dXJuIHsgZnJvbTogYWRkRGF5cyh0b2RheSwgLTI5KS5nZXRUaW1lKCksIHRvOiBub3cuZ2V0VGltZSgpIH1cbiAgLy8g5YWo6YeP77yaMCDmmK/mnInpmZDlgLzvvIzlrr/kuLvnmoQgZmlsbCDliKTlrprorqTlroPvvJvosIPnlKjmlrnlv4XpobvlkIzml7bkvKAgZmlsbDpmYWxzZe+8jFxuICAvLyDlkKbliJnkvJrljrvpm7bloavlhYUgMTk3MCDlubToh7Pku4rjgIHmkp7kuIogTUFYX0JVQ0tFVFMg6YCA5YyW5oiQ5Y+q55yL5pyJ5pWw5o2u55qE5qG244CCXG4gIGlmIChwcmVzZXQgPT09ICdhbGwnKSByZXR1cm4geyBmcm9tOiAwLCB0bzogbm93LmdldFRpbWUoKSB9XG4gIGNvbnN0IGZyb20gPSBuZXcgRGF0ZShjdXN0b20uZnJvbSArICdUMDA6MDA6MDAnKS5nZXRUaW1lKClcbiAgY29uc3QgdG8gPSBuZXcgRGF0ZShjdXN0b20udG8gKyAnVDIzOjU5OjU5Ljk5OScpLmdldFRpbWUoKVxuICBpZiAoIU51bWJlci5pc0Zpbml0ZShmcm9tKSB8fCAhTnVtYmVyLmlzRmluaXRlKHRvKSkge1xuICAgIHJldHVybiB7IGZyb206IHRvZGF5LmdldFRpbWUoKSwgdG86IG5vdy5nZXRUaW1lKCkgfVxuICB9XG4gIHJldHVybiB7IGZyb20sIHRvIH1cbn1cbmZ1bmN0aW9uIHdlZWtkYXlPZihrZXkpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gbmV3IERhdGUoa2V5ICsgJ1QwMDowMDowMCcpLnRvTG9jYWxlRGF0ZVN0cmluZygnemgtQ04nLCB7IHdlZWtkYXk6ICdzaG9ydCcgfSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiAnJ1xuICB9XG59XG4vKiogV2Vla2RheSBmb3IgYSBkYXkvaG91ci9taW51dGUgYnVja2V0IGtleSAoYFlZWVktTU0tRERgIG9yIGBZWVlZLU1NLUREIEhIOm1tYCkuICovXG5mdW5jdGlvbiB3ZWVrZGF5TmFtZShrZXksIHQpIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBkID0gbmV3IERhdGUoU3RyaW5nKGtleSkucmVwbGFjZSgnICcsICdUJykpXG4gICAgcmV0dXJuIHQoWyd3ZDAnLCAnd2QxJywgJ3dkMicsICd3ZDMnLCAnd2Q0JywgJ3dkNScsICd3ZDYnXVtkLmdldERheSgpXSB8fCAnd2QwJylcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiAnJ1xuICB9XG59XG4vKiogWC1heGlzIGxhYmVsIGZvciBhIGJ1Y2tldCBrZXkgdW5kZXIgYSBncmFudWxhcml0eS4gKi9cbmZ1bmN0aW9uIHhMYWJlbChrZXksIGcpIHtcbiAgY29uc3QgcyA9IFN0cmluZyhrZXkpXG4gIGNvbnN0IHNwID0gcy5zcGxpdCgnICcpXG4gIGlmIChnID09PSAnbWludXRlJykgcmV0dXJuIHNwLmxlbmd0aCA+IDEgPyBzcFsxXS5zbGljZSgwLCA1KSA6IHMuc2xpY2UoNSlcbiAgaWYgKGcgPT09ICdob3VyJykgcmV0dXJuIHNwLmxlbmd0aCA+IDEgPyBzcFsxXS5zbGljZSgwLCAyKSArICc6MDAnIDogcy5zbGljZSg1KVxuICByZXR1cm4gZGF5TGFiZWwoa2V5KVxufVxuLyoqIEZpeGVkIGdyYW51bGFyaXR5IHBvbGljeTogdG9kYXkgaXMgaG91cmx5LCBldmVyeXRoaW5nIGVsc2UgaXMgZGFpbHkuICovXG5mdW5jdGlvbiBlZmZHcmFudWxhcml0eShyYW5nZSkge1xuICByZXR1cm4gcmFuZ2UgPT09ICd0b2RheScgPyAnaG91cicgOiAnZGF5Jztcbn1cbi8qKiBTdGFibGUgc3RlcCBzdHJhdGVneSBmb3IgY3VzdG9tIHJhbmdlczogdGFyZ2V0IH4xNS0yNSBidWNrZXRzLiAqL1xuZnVuY3Rpb24gcGlja1N0ZXBEYXlzKHNwYW5Ncykge1xuICBjb25zdCBkYXlzID0gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZCgoc3Bhbk1zIHx8IDApIC8gODY0MDAwMDApKVxuICBpZiAoZGF5cyA8PSAzMSkgcmV0dXJuIDFcbiAgaWYgKGRheXMgPD0gNjIpIHJldHVybiAzXG4gIGlmIChkYXlzIDw9IDE1MCkgcmV0dXJuIDVcbiAgcmV0dXJuIDdcbn1cbi8qKiBIdW1hbiBsYWJlbCBmb3IgdGhlIGN1cnJlbnQgc3RlcCBwb2xpY3kuICovXG5mdW5jdGlvbiBzdGVwTGFiZWwodCwgcmFuZ2UsIHN0ZXBEYXlzKSB7XG4gIGlmIChyYW5nZSA9PT0gJ3RvZGF5JykgcmV0dXJuIHQoJ2J5SG91cicpXG4gIHJldHVybiBzdGVwRGF5cyA+IDEgPyB0KCdldmVyeU5EYXlzJywgeyBuOiBzdGVwRGF5cyB9KSA6IHQoJ2J5RGF5Jylcbn1cbi8qKiBIZWF0bWFwIGNlbGwgY29sb3IgYnkgcmVsYXRpdmUgdG9rZW4gdm9sdW1lLiAqL1xuZnVuY3Rpb24gaGVhdENvbG9yKHRvdGFsLCBtYXgpIHtcbiAgaWYgKCF0b3RhbCkgcmV0dXJuICd2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpJ1xuICBjb25zdCByID0gdG90YWwgLyBtYXhcbiAgY29uc3QgcGN0ID0gciA8IDAuMjUgPyAyMiA6IHIgPCAwLjUgPyA0NSA6IHIgPCAwLjc1ID8gNzAgOiAxMDBcbiAgcmV0dXJuICdjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZHN3LXN0YXRpYy1kZWVwc2Vlay01MDApICcgKyBwY3QgKyAnJSwgdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTIpKSdcbn1cbmZ1bmN0aW9uIG5pY2VDZWlsKHYpIHtcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUodikgfHwgdiA8PSAwKSByZXR1cm4gMVxuICBjb25zdCBtYWcgPSBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihNYXRoLmxvZzEwKHYpKSlcbiAgY29uc3Qgbm9ybSA9IHYgLyBtYWdcbiAgY29uc3QgbmljZSA9IG5vcm0gPD0gMSA/IDEgOiBub3JtIDw9IDIgPyAyIDogbm9ybSA8PSA1ID8gNSA6IDEwXG4gIHJldHVybiBuaWNlICogbWFnXG59XG5mdW5jdGlvbiBkZWZhdWx0Q3VzdG9tKCkge1xuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpXG4gIHJldHVybiB7IGZyb206IGZtdERhdGVJbnB1dChhZGREYXlzKG5vdywgLTYpKSwgdG86IGZtdERhdGVJbnB1dChub3cpIH1cbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDlhoXogZQgU1ZHIOWbvuagh++8iOaXoOWbvuagh+W6k++8jOaJi+WGmSBmZWF0aGVyIOmjjuagvCBzdHJva2Ug5Zu+5qCH77yJXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5jb25zdCBJQ09OX1BBVEhTID0ge1xuICBsYXllcnM6ICdNMTIgMmw4IDQuNS04IDQuNS04LTQuNUwxMiAyem0wIDhsOCA0LjUtOCA0LjUtOC00LjVMMTIgMTB6bTAgOGw4IDQuNS04IDQuNS04LTQuNUwxMiAxOHonLFxuICBkb3duOiAnTTEyIDN2MTJtMCAwbC00LjUtNC41TTEyIDE1bDQuNS00LjVNNCAyMWgxNicsXG4gIHVwOiAnTTEyIDIxVjltMCAwbC00LjUgNC41TTEyIDlsNC41IDQuNU00IDNoMTYnLFxuICBhY3Rpdml0eTogJ00yIDEyaDRsMi41LTggNSAxNiAyLjUtOGg2JyxcbiAgY29pbnM6ICdNMyA5YTIgMiAwIDAxMi0yaDE0YTIgMiAwIDAxMiAydjlhMiAyIDAgMDEtMiAySDVhMiAyIDAgMDEtMi0yVjl6bTAgNWgxOE04IDUuNVY0YTIgMiAwIDAxMi0yaDRhMiAyIDAgMDEyIDJ2MS41JyxcbiAgLy8g5Yi35paw5Zu+5qCH5Y+W6IeqIERTSCDljp/nlJ/lm77lvaLvvIgxNiDnvZHmoLzjgIFzdHJva2UgMS4177yJ77yM5LiO6K6+572u6aG15YW25a6D5Zu+5qCH5ZCM5LiA6KeC5oSf77ybXG4gIC8vIOWFtuS9meWbvuagh+S7jeaYryAyNCDnvZHmoLzvvIhzdHJva2UgMu+8ie+8jFN2Z0ljb24g5Lik56eN5a6a5LmJ6YO95ZCD44CCXG4gIHJlZnJlc2g6IHtcbiAgICB2aWV3Qm94OiAnMCAwIDE2IDE2JyxcbiAgICBzdHJva2VXaWR0aDogMS41LFxuICAgIHBhdGhzOiBbXG4gICAgICAnTTE0LjUwMDEgOEMxNC41IDkuMjg1NTIgMTQuMTE4OCAxMC41NDIyIDEzLjQwNDUgMTEuNjExQzEyLjY5MDMgMTIuNjc5OSAxMS42NzUyIDEzLjUxMjkgMTAuNDg3NSAxNC4wMDQ5QzkuMjk5ODIgMTQuNDk2OCA3Ljk5Mjk1IDE0LjYyNTUgNi43MzIxMiAxNC4zNzQ3QzUuNDcxMyAxNC4xMjQgNC4zMTMxNCAxMy41MDUgMy40MDQxIDEyLjU5NkMyLjQ5NTE0IDExLjY4NyAxLjg3NjE0IDEwLjUyODggMS42MjUzNyA5LjI2Nzk4QzEuMzc0NTkgOC4wMDcxNiAxLjUwMzMxIDYuNzAwMjggMS45OTUyNSA1LjUxMjYxQzIuNDg3MTkgNC4zMjQ5NCAzLjMyMDI1IDMuMzA5ODEgNC4zODkxIDIuNTk1NTdDNS40NTc5NSAxLjg4MTM0IDYuNzE0NTggMS41MDAwOCA4LjAwMDEgMS41QzkuOTAwMSAxLjUgMTEuNzAwMSAyLjMgMTMuMDAwMSAzLjZMMTQuNTAwMSA1LjEnLFxuICAgICAgJ00xNC40OTk5IDEuNVY1LjFIMTAuODk5OScsXG4gICAgXSxcbiAgfSxcbiAgY2hldnJvbjogJ002IDlsNiA2IDYtNicsXG4gIGluYm94OiAnTTIyIDEyaC02bC0yIDNoLTRsLTItM0gybTMuNS02LjVMMiAxMnY2YTIgMiAwIDAwMiAyaDE2YTIgMiAwIDAwMi0ydi02bC0zLjUtNi41QTIgMiAwIDAwMTYuNzYgNUg3LjI0YTIgMiAwIDAwLTEuNzQgMS41eicsXG4gIGFsZXJ0OiAnTTEyIDl2NG0wIDRoLjAxTTEwLjMgMy44NkwxLjgyIDE4YTIgMiAwIDAwMS43MSAzaDE2Ljk0YTIgMiAwIDAwMS43MS0zTDEzLjcgMy44NmEyIDIgMCAwMC0zLjQgMHonLFxuICBzZWFyY2g6ICdNMjEgMjFsLTQuMzUtNC4zNU0xNyAxMC41YTYuNSA2LjUgMCAxMS0xMyAwIDYuNSA2LjUgMCAwMTEzIDB6JyxcbiAgLy8g6aW85Zu+77yI5Y2g5q+U77yJ77ya5aSW5ZyIICsg5qWU5b2i77yM5LiO5Y2h54mH5qCH6aKY55qE44CM5Y2g5q+U44CN6K+t5LmJ5LiA6Ie0XG4gIHNoYXJlOiAnTTIxLjIxIDE1Ljg5QTEwIDEwIDAgMTE4IDIuODNNMjIgMTJBMTAgMTAgMCAwMDEyIDJ2MTB6JyxcbiAgY2hlY2s6ICdNMjAgNkw5IDE3bC01LTUnLFxufVxuZnVuY3Rpb24gU3ZnSWNvbihwcm9wcykge1xuICBjb25zdCB7IG5hbWUsIHNpemUsIGNsYXNzTmFtZSB9ID0gcHJvcHNcbiAgLy8g5LiA5Liq5ZCN5a2X5a+55bqU44CM5LiA5LiyIHBhdGggKyDoh6rlt7HnmoQgdmlld0JveC/nur/lrr3jgI3vvJvlrZfnrKbkuLLmmK8gMjQg572R5qC855qE566A5YaZ77yMXG4gIC8vIOiwg+eUqOaWue+8iDMxIOWkhO+8ieaXoOmcgOWFs+W/g+W3ruWIq+OAglxuICBjb25zdCBzcGVjID0gSUNPTl9QQVRIU1tuYW1lXSB8fCBJQ09OX1BBVEhTLmFjdGl2aXR5XG4gIGNvbnN0IGljb24gPSB0eXBlb2Ygc3BlYyA9PT0gJ3N0cmluZydcbiAgICA/IHsgdmlld0JveDogJzAgMCAyNCAyNCcsIHN0cm9rZVdpZHRoOiAyLCBwYXRoczogW3NwZWNdIH1cbiAgICA6IHNwZWNcbiAgcmV0dXJuIGgoJ3N2ZycsIHtcbiAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSB8fCAndHNkLWljb24nLFxuICAgIHdpZHRoOiBzaXplIHx8IDE2LFxuICAgIGhlaWdodDogc2l6ZSB8fCAxNixcbiAgICB2aWV3Qm94OiBpY29uLnZpZXdCb3ggfHwgJzAgMCAyNCAyNCcsXG4gICAgZmlsbDogJ25vbmUnLFxuICAgIHN0cm9rZTogJ2N1cnJlbnRDb2xvcicsXG4gICAgc3Ryb2tlV2lkdGg6IGljb24uc3Ryb2tlV2lkdGggfHwgMixcbiAgICBzdHJva2VMaW5lY2FwOiAncm91bmQnLFxuICAgIHN0cm9rZUxpbmVqb2luOiAncm91bmQnLFxuICAgICdhcmlhLWhpZGRlbic6IHRydWUsXG4gIH0sIGljb24ucGF0aHMubWFwKChkLCBpKSA9PiBoKCdwYXRoJywgeyBrZXk6IGksIGQgfSkpKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOmAmueUqCBIb29r77ya5aSW6YOo54K55Ye75YWz6ZetXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiB1c2VPdXRzaWRlQ2xpY2sob3BlbiwgcmVmLCBvbkNsb3NlKSB7XG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFvcGVuKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgZnVuY3Rpb24gaGFuZGxlcihlKSB7XG4gICAgICBpZiAocmVmLmN1cnJlbnQgJiYgIXJlZi5jdXJyZW50LmNvbnRhaW5zKGUudGFyZ2V0KSkgb25DbG9zZSgpXG4gICAgfVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgaGFuZGxlcilcbiAgICByZXR1cm4gKCkgPT4gZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoYW5kbGVyKVxuICB9LCBbb3Blbiwgb25DbG9zZSwgcmVmXSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDpgJrnlKggSG9va++8mua1ruWxguWumuS9je+8iHZpZXdwb3J0IOWumuS9jSArIOepuumXtOS4jei2s+S4iue/uyArIOmrmOW6puWwgemhtu+8iVxuICpcbiAqIOiuvue9rumdouadv+acrOi6q+aYryBgb3ZlcmZsb3c6IGhpZGRlbmAg55qE6KOB5Ymq5a655Zmo77yM6LS0552A6L+H5ruk5qCP5Y+z56uv55qEIGFic29sdXRlXG4gKiDmta7lsYLkvJrooqvmlbTmnaHoo4HmjonvvIjlj7PkvqfnmoTjgIzmuIXnqbrjgI3nnIvkuI3op4HvvInjgIJDU1Mg5peg5rOV5oSf55+l56WW5YWI6KOB5Ymq77yM5Y+q6IO96YeP5LiA5qyhXG4gKiDop4blj6Plho3lrprkvY3vvJvmu5rliqjmiJbnvKnmlL7ml7bph43nrpfvvIzpgb/lhY3mta7lsYLnlZnlnKjljp/lnLDjgIJcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmNvbnN0IFBBTkVMX01JTl9ST09NID0gMjQwIC8vIOS4i+aWueepuumXtOWwj+S6juWug+S4lOS4iuaWueabtOWuveijleaXtuS4iue/u1xuY29uc3QgUEFORUxfTUlOX0hFSUdIVCA9IDE2MFxuXG5mdW5jdGlvbiB1c2VGaXhlZFBhbmVsKGFuY2hvclJlZiwgb3Blbiwgd2lkdGgsIGdhcCA9IDYsIG1hcmdpbiA9IDEyKSB7XG4gIGNvbnN0IFtzdHlsZSwgc2V0U3R5bGVdID0gUmVhY3QudXNlU3RhdGUobnVsbClcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIW9wZW4pIHtcbiAgICAgIHNldFN0eWxlKG51bGwpXG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuICAgIGZ1bmN0aW9uIG1lYXN1cmUoKSB7XG4gICAgICBjb25zdCBlbCA9IGFuY2hvclJlZi5jdXJyZW50XG4gICAgICBpZiAoIWVsKSByZXR1cm5cbiAgICAgIGNvbnN0IHIgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgY29uc3QgYm94VyA9IE1hdGgubWluKHdpZHRoLCB3aW5kb3cuaW5uZXJXaWR0aCAtIG1hcmdpbiAqIDIpXG4gICAgICBjb25zdCBsZWZ0ID0gTWF0aC5tYXgobWFyZ2luLCBNYXRoLm1pbihyLmxlZnQsIHdpbmRvdy5pbm5lcldpZHRoIC0gbWFyZ2luIC0gYm94VykpXG4gICAgICBjb25zdCBiZWxvdyA9IHdpbmRvdy5pbm5lckhlaWdodCAtIHIuYm90dG9tIC0gZ2FwIC0gbWFyZ2luXG4gICAgICBjb25zdCBhYm92ZSA9IHIudG9wIC0gZ2FwIC0gbWFyZ2luXG4gICAgICBjb25zdCBmbGlwID0gYmVsb3cgPCBQQU5FTF9NSU5fUk9PTSAmJiBhYm92ZSA+IGJlbG93XG4gICAgICBzZXRTdHlsZSh7XG4gICAgICAgIHBvc2l0aW9uOiAnZml4ZWQnLFxuICAgICAgICBsZWZ0LFxuICAgICAgICB3aWR0aDogYm94VyxcbiAgICAgICAgbWF4SGVpZ2h0OiBNYXRoLm1heChQQU5FTF9NSU5fSEVJR0hULCBmbGlwID8gYWJvdmUgOiBiZWxvdyksXG4gICAgICAgIC4uLihmbGlwXG4gICAgICAgICAgPyB7IGJvdHRvbTogd2luZG93LmlubmVySGVpZ2h0IC0gci50b3AgKyBnYXAgfVxuICAgICAgICAgIDogeyB0b3A6IHIuYm90dG9tICsgZ2FwIH0pLFxuICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgIGZsZXhEaXJlY3Rpb246ICdjb2x1bW4nLFxuICAgICAgICB6SW5kZXg6IDQwLFxuICAgICAgfSlcbiAgICB9XG4gICAgbWVhc3VyZSgpXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG1lYXN1cmUpXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIG1lYXN1cmUsIHRydWUpXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBtZWFzdXJlKVxuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIG1lYXN1cmUsIHRydWUpXG4gICAgfVxuICB9LCBbb3BlbiwgYW5jaG9yUmVmLCB3aWR0aCwgZ2FwLCBtYXJnaW5dKVxuICBpZiAoIW9wZW4pIHJldHVybiBudWxsXG4gIC8vIOmmluW4p+i/mOayoemHj+WIsOWwuuWvuO+8muWFiOiXj+i1t+adpe+8jOWQpuWImeS8mumXquWIsOW3puS4iuinklxuICByZXR1cm4gc3R5bGUgfHwgeyBwb3NpdGlvbjogJ2ZpeGVkJywgdG9wOiAwLCBsZWZ0OiAwLCB2aXNpYmlsaXR5OiAnaGlkZGVuJyB9XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogSGVhZGVy77ya5qCH6aKYICsg5Ymv5qCH6aKYICsg5Yi35paw5oyJ6ZKuXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBTdGF0c0hlYWRlcihwcm9wcykge1xuICBjb25zdCB7IGJ1c3ksIG9uUmVmcmVzaCB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtaGVhZGVyJyB9LFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWhlYWRlci10ZXh0JyB9LFxuICAgICAgaCgnaDInLCB7IGNsYXNzTmFtZTogJ3RzZC10aXRsZScgfSwgdCgnbmF2JykpLFxuICAgICAgaCgncCcsIHsgY2xhc3NOYW1lOiAndHNkLXN1YnRpdGxlJyB9LCB0KCdzdWJ0aXRsZScpKSksXG4gICAgaCgnYnV0dG9uJywge1xuICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICBjbGFzc05hbWU6ICd0c2QtaWNvbi1idG4nICsgKGJ1c3kgPyAnIHRzZC1zcGlubmluZycgOiAnJyksXG4gICAgICBvbkNsaWNrOiBvblJlZnJlc2gsXG4gICAgICBkaXNhYmxlZDogYnVzeSxcbiAgICAgICdhcmlhLWJ1c3knOiBidXN5IHx8IHVuZGVmaW5lZCxcbiAgICAgIHRpdGxlOiB0KCdyZWZyZXNoJyksXG4gICAgICAnYXJpYS1sYWJlbCc6IHQoJ3JlZnJlc2gnKSxcbiAgICB9LCBoKFN2Z0ljb24sIHsgbmFtZTogJ3JlZnJlc2gnIH0pKSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDoh6rlrprkuYnml6XmnJ/ojIPlm7Tmta7lsYJcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmZ1bmN0aW9uIEN1c3RvbVJhbmdlUG9wb3Zlcihwcm9wcykge1xuICBjb25zdCB7IGN1c3RvbSwgb25BcHBseSwgb25DbG9zZSwgYW5jaG9yUmVmIH0gPSBwcm9wc1xuICBjb25zdCB0ID0gdXNlVCgpXG4gIGNvbnN0IHBhbmVsU3R5bGUgPSB1c2VGaXhlZFBhbmVsKGFuY2hvclJlZiwgdHJ1ZSwgMzAwKVxuICBjb25zdCBbZnJvbSwgc2V0RnJvbV0gPSBSZWFjdC51c2VTdGF0ZShjdXN0b20uZnJvbSlcbiAgY29uc3QgW3RvLCBzZXRUb10gPSBSZWFjdC51c2VTdGF0ZShjdXN0b20udG8pXG4gIGNvbnN0IGludmFsaWQgPSAhZnJvbSB8fCAhdG8gfHwgZnJvbSA+IHRvXG4gIC8vIFAyLTEx77yaZGlhbG9nIOS7pSBFc2NhcGUg5YWz6ZetXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgZnVuY3Rpb24gb25LZXkoZSkge1xuICAgICAgaWYgKGUua2V5ID09PSAnRXNjYXBlJyB8fCBlLmtleSA9PT0gJ0VzYycpIG9uQ2xvc2UoKVxuICAgIH1cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXkpXG4gICAgcmV0dXJuICgpID0+IGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbktleSlcbiAgfSwgW29uQ2xvc2VdKVxuICByZXR1cm4gaCgnZGl2Jywge1xuICAgIGNsYXNzTmFtZTogJ3RzZC1wb3BvdmVyIHRzZC1yYW5nZS1wb3BvdmVyJyxcbiAgICBzdHlsZTogcGFuZWxTdHlsZSxcbiAgICByb2xlOiAnZGlhbG9nJyxcbiAgICAnYXJpYS1sYWJlbCc6IHQoJ2N1c3RvbVJhbmdlQXJpYScpLFxuICB9LFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXBvcG92ZXItdGl0bGUnIH0sIHQoJ2N1c3RvbVJhbmdlVGl0bGUnKSksXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcmFuZ2UtZmllbGRzJyB9LFxuICAgICAgaCgnbGFiZWwnLCB7IGNsYXNzTmFtZTogJ3RzZC1maWVsZCcgfSxcbiAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWZpZWxkLWxhYmVsJyB9LCB0KCdzdGFydFRpbWUnKSksXG4gICAgICAgIGgoJ2lucHV0Jywge1xuICAgICAgICAgIHR5cGU6ICdkYXRlJywgdmFsdWU6IGZyb20sICdhcmlhLWxhYmVsJzogdCgnc3RhcnRUaW1lJyksXG4gICAgICAgICAgb25DaGFuZ2U6IChlKSA9PiBzZXRGcm9tKGUudGFyZ2V0LnZhbHVlKSxcbiAgICAgICAgfSkpLFxuICAgICAgaCgnbGFiZWwnLCB7IGNsYXNzTmFtZTogJ3RzZC1maWVsZCcgfSxcbiAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWZpZWxkLWxhYmVsJyB9LCB0KCdlbmRUaW1lJykpLFxuICAgICAgICBoKCdpbnB1dCcsIHtcbiAgICAgICAgICB0eXBlOiAnZGF0ZScsIHZhbHVlOiB0bywgJ2FyaWEtbGFiZWwnOiB0KCdlbmRUaW1lJyksXG4gICAgICAgICAgb25DaGFuZ2U6IChlKSA9PiBzZXRUbyhlLnRhcmdldC52YWx1ZSksXG4gICAgICAgIH0pKSksXG4gICAgaW52YWxpZFxuICAgICAgPyBoKCdwJywgeyBjbGFzc05hbWU6ICd0c2QtZmllbGQtZXJyb3InLCByb2xlOiAnYWxlcnQnIH0sIHQoJ3JhbmdlSW52YWxpZCcpKVxuICAgICAgOiBudWxsLFxuICAgIGgoJ3AnLCB7IGNsYXNzTmFtZTogJ3RzZC1maWVsZC1oaW50JyB9LCB0KCdyYW5nZUhpbnQnKSksXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcG9wb3Zlci1hY3Rpb25zJyB9LFxuICAgICAgaCgnYnV0dG9uJywgeyB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiAndHNkLWJ0biB0c2QtYnRuLWdob3N0Jywgb25DbGljazogb25DbG9zZSB9LCB0KCdjYW5jZWwnKSksXG4gICAgICBoKCdidXR0b24nLCB7XG4gICAgICAgIHR5cGU6ICdidXR0b24nLCBjbGFzc05hbWU6ICd0c2QtYnRuIHRzZC1idG4tcHJpbWFyeScsXG4gICAgICAgIGRpc2FibGVkOiBpbnZhbGlkLFxuICAgICAgICBvbkNsaWNrOiAoKSA9PiB7IGlmICghaW52YWxpZCkgb25BcHBseSh7IGZyb20sIHRvIH0pIH0sXG4gICAgICB9LCB0KCdjb25maXJtJykpKSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDmqKHlnovlpJrpgInkuIvmi4lcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmZ1bmN0aW9uIE1vZGVsRHJvcGRvd24ocHJvcHMpIHtcbiAgY29uc3QgeyBvcHRpb25zLCBzZWxlY3RlZCwgb25DaGFuZ2UgfSA9IHByb3BzXG4gIGNvbnN0IHQgPSB1c2VUKClcbiAgY29uc3QgW29wZW4sIHNldE9wZW5dID0gUmVhY3QudXNlU3RhdGUoZmFsc2UpXG4gIGNvbnN0IFtxdWVyeSwgc2V0UXVlcnldID0gUmVhY3QudXNlU3RhdGUoJycpXG4gIGNvbnN0IGFuY2hvclJlZiA9IFJlYWN0LnVzZVJlZihudWxsKVxuICBjb25zdCBwYW5lbFN0eWxlID0gdXNlRml4ZWRQYW5lbChhbmNob3JSZWYsIG9wZW4sIDMyMClcblxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghb3BlbikgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGZ1bmN0aW9uIGhhbmRsZXIoZSkge1xuICAgICAgaWYgKGFuY2hvclJlZi5jdXJyZW50ICYmICFhbmNob3JSZWYuY3VycmVudC5jb250YWlucyhlLnRhcmdldCkpIHNldE9wZW4oZmFsc2UpXG4gICAgfVxuICAgIGZ1bmN0aW9uIG9uS2V5KGUpIHtcbiAgICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScgfHwgZS5rZXkgPT09ICdFc2MnKSBzZXRPcGVuKGZhbHNlKVxuICAgIH1cbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGhhbmRsZXIpXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5KVxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGhhbmRsZXIpXG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXkpXG4gICAgfVxuICB9LCBbb3Blbl0pXG5cbiAgLy8g5Y+q5YiX5Ye65b2T5YmN6IyD5Zu05pyJ5pWw5o2u55qE5qih5Z6L77yb5bey6YCJ5L2G5o6J5Ye65YCZ6YCJ5YiX6KGo55qE44CM6KGl5Zue44CN77yM5L+d6K+B5Y+v5riy5p+T44CB5Y+v5riF6ZmkXG4gIC8vIOWAmemAiemUruebtOaOpeeUqOWuv+S4u+e7meWlveeahCBga2V5YO+8iGNvbXBvc2l0ZU1vZGVsS2V5IOeahOe7k+aenO+8ie+8muWuouaIt+err+S4jeWGjeiHquW3seaLvFxuICAvLyBgcHJvdmlkZXIgKyAnLycgKyBtb2RlbGDvvIxwcm92aWRlciDkuLrnqbrml7bpgqPnp43mi7zms5XkvJrlvpfliLAgYC9tb2RlbGAg6ICM5rC46L+c6YCJ5LiN5Lit44CCXG4gIGNvbnN0IGNhbmRpZGF0ZXMgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBzZXQgPSBuZXcgU2V0KChvcHRpb25zIHx8IFtdKS5tYXAoKG0pID0+IG0ua2V5IHx8IChtLnByb3ZpZGVyID8gbS5wcm92aWRlciArICcvJyArIG0ubW9kZWwgOiBtLm1vZGVsKSkpXG4gICAgOyhzZWxlY3RlZCB8fCBbXSkuZm9yRWFjaCgobSkgPT4gc2V0LmFkZChtKSlcbiAgICBjb25zdCBsaXN0ID0gQXJyYXkuZnJvbShzZXQpXG4gICAgbGlzdC5zb3J0KClcbiAgICByZXR1cm4gbGlzdFxuICB9LCBbb3B0aW9ucywgc2VsZWN0ZWRdKVxuXG4gIGNvbnN0IHEgPSBxdWVyeS50cmltKCkudG9Mb2NhbGVMb3dlckNhc2UoKVxuICBjb25zdCBmaWx0ZXJlZCA9IHEgPT09ICcnID8gY2FuZGlkYXRlcyA6IGNhbmRpZGF0ZXMuZmlsdGVyKChjKSA9PiBjLnRvTG9jYWxlTG93ZXJDYXNlKCkuaW5kZXhPZihxKSA+PSAwKVxuICBjb25zdCBsYWJlbCA9IHNlbGVjdGVkLmxlbmd0aCA9PT0gMCA/IHQoJ2FsbE1vZGVscycpIDogdCgnc2VsZWN0ZWRNb2RlbHMnLCB7IGNvdW50OiBzZWxlY3RlZC5sZW5ndGggfSlcblxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcG9wb3Zlci1hbmNob3InLCByZWY6IGFuY2hvclJlZiB9LFxuICAgIGgoJ2J1dHRvbicsIHtcbiAgICAgIHR5cGU6ICdidXR0b24nLFxuICAgICAgY2xhc3NOYW1lOiAndHNkLXNlbGVjdC1idG4nICsgKHNlbGVjdGVkLmxlbmd0aCA+IDAgPyAnIHRzZC1zZWxlY3QtaGFzJyA6ICcnKSxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHsgc2V0T3BlbigodikgPT4gIXYpOyBzZXRRdWVyeSgnJykgfSxcbiAgICAgICdhcmlhLWV4cGFuZGVkJzogb3BlbixcbiAgICAgICdhcmlhLWhhc3BvcHVwJzogJ2xpc3Rib3gnLFxuICAgICAgdGl0bGU6IGxhYmVsLFxuICAgIH0sXG4gICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2Qtc2VsZWN0LWxhYmVsJyB9LCBsYWJlbCksXG4gICAgICBoKFN2Z0ljb24sIHsgbmFtZTogJ2NoZXZyb24nLCBzaXplOiAxNCwgY2xhc3NOYW1lOiAndHNkLWNoZXZyb24nICsgKG9wZW4gPyAnIHRzZC1jaGV2cm9uLW9wZW4nIDogJycpIH0pKSxcbiAgICBvcGVuXG4gICAgICA/IGgoJ2RpdicsIHtcbiAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtcG9wb3ZlciB0c2QtbW9kZWwtcG9wb3ZlcicsXG4gICAgICAgICAgc3R5bGU6IHBhbmVsU3R5bGUsXG4gICAgICAgICAgcm9sZTogJ2xpc3Rib3gnLFxuICAgICAgICAgICdhcmlhLWxhYmVsJzogdCgnbW9kZWxGaWx0ZXJHcm91cCcpLFxuICAgICAgICAgICdhcmlhLW11bHRpc2VsZWN0YWJsZSc6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcG9wb3Zlci10b29scycgfSxcbiAgICAgICAgICAgIGgoJ2J1dHRvbicsIHsgdHlwZTogJ2J1dHRvbicsIGNsYXNzTmFtZTogJ3RzZC1saW5rLWJ0bicsIG9uQ2xpY2s6ICgpID0+IG9uQ2hhbmdlKGNhbmRpZGF0ZXMuc2xpY2UoKSkgfSwgdCgnc2VsZWN0QWxsJykpLFxuICAgICAgICAgICAgaCgnYnV0dG9uJywgeyB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiAndHNkLWxpbmstYnRuJywgb25DbGljazogKCkgPT4gb25DaGFuZ2UoW10pIH0sIHQoJ2NsZWFyJykpKSxcbiAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1zZWFyY2gnIH0sXG4gICAgICAgICAgICBoKFN2Z0ljb24sIHsgbmFtZTogJ3NlYXJjaCcsIHNpemU6IDE0LCBjbGFzc05hbWU6ICd0c2Qtc2VhcmNoLWljb24nIH0pLFxuICAgICAgICAgICAgaCgnaW5wdXQnLCB7XG4gICAgICAgICAgICAgIHR5cGU6ICdzZWFyY2gnLCB2YWx1ZTogcXVlcnksIHBsYWNlaG9sZGVyOiB0KCdzZWFyY2hNb2RlbHMnKSxcbiAgICAgICAgICAgICAgJ2FyaWEtbGFiZWwnOiB0KCdzZWFyY2hNb2RlbHMnKSxcbiAgICAgICAgICAgICAgb25DaGFuZ2U6IChlKSA9PiBzZXRRdWVyeShlLnRhcmdldC52YWx1ZSksXG4gICAgICAgICAgICB9KSksXG4gICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtbW9kZWwtbGlzdCcgfSxcbiAgICAgICAgICAgIGZpbHRlcmVkLmxlbmd0aCA9PT0gMFxuICAgICAgICAgICAgICA/IGgoJ3AnLCB7IGNsYXNzTmFtZTogJ3RzZC1wb3BvdmVyLWVtcHR5JyB9LCB0KCdub01hdGNoTW9kZWxzJykpXG4gICAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgICAgIGZpbHRlcmVkLm1hcCgoa2V5KSA9PlxuICAgICAgICAgICAgICBoKCdsYWJlbCcsIHsga2V5LCBjbGFzc05hbWU6ICd0c2QtbW9kZWwtaXRlbScgfSxcbiAgICAgICAgICAgICAgICBoKCdpbnB1dCcsIHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdjaGVja2JveCcsXG4gICAgICAgICAgICAgICAgICBjaGVja2VkOiBzZWxlY3RlZC5pbmRleE9mKGtleSkgPj0gMCxcbiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiAoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0ID0gc2VsZWN0ZWQuc2xpY2UoKVxuICAgICAgICAgICAgICAgICAgICBpZiAoZS50YXJnZXQuY2hlY2tlZCkge1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0LmluZGV4T2Yoa2V5KSA8IDApIG5leHQucHVzaChrZXkpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgaSA9IG5leHQuaW5kZXhPZihrZXkpXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPj0gMCkgbmV4dC5zcGxpY2UoaSwgMSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZShuZXh0KSAvLyDli77pgInljbPml7bnlJ/mlYhcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLW1vZGVsLW5hbWUnLCB0aXRsZToga2V5IH0sIGtleSkpKSksXG4gICAgICAgICAgaCgncCcsIHsgY2xhc3NOYW1lOiAndHNkLXBvcG92ZXItbm90ZScgfSwgdCgnbW9kZWxGaWx0ZXJIaW50JykpKVxuICAgICAgOiBudWxsKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOetm+mAieagj++8muaXpeacn+mihOiuvu+8iOWIhuauteaMiemSru+8iSsg6Ieq5a6a5LmJ5rWu5bGCICsg5qih5Z6L5aSa6YCJXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBGaWx0ZXJCYXIocHJvcHMpIHtcbiAgY29uc3Qge1xuICAgIHJhbmdlLCBjdXN0b20sIG1vZGVscywgY3VzdG9tT3BlbiwgbW9kZWxPcHRpb25zLFxuICAgIG9uUHJlc2V0LCBvbkN1c3RvbU9wZW4sIG9uQ3VzdG9tQXBwbHksIG9uQ3VzdG9tQ2xvc2UsIG9uTW9kZWxzQ2hhbmdlLFxuICB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICBjb25zdCBzZWdSZWYgPSBSZWFjdC51c2VSZWYobnVsbClcbiAgY29uc3QgY3VzdG9tQnRuUmVmID0gUmVhY3QudXNlUmVmKG51bGwpXG4gIHVzZU91dHNpZGVDbGljayhjdXN0b21PcGVuLCBzZWdSZWYsIG9uQ3VzdG9tQ2xvc2UpXG5cbiAgY29uc3QgY3VzdG9tTGFiZWwgPSBmbXREYXRlU2xhc2goY3VzdG9tLmZyb20pICsgJyAtICcgKyBmbXREYXRlU2xhc2goY3VzdG9tLnRvKVxuICBjb25zdCBwcmVzZXRzID0gW1xuICAgIHsga2V5OiAndG9kYXknLCBsYWJlbDogdCgndG9kYXknKSB9LFxuICAgIHsga2V5OiAnN2QnLCBsYWJlbDogdCgnbGFzdDdkJykgfSxcbiAgICB7IGtleTogJzMwZCcsIGxhYmVsOiB0KCdsYXN0MzBkJykgfSxcbiAgICB7IGtleTogJ2FsbCcsIGxhYmVsOiB0KCdhbGwnKSB9LFxuICAgIHsga2V5OiAnY3VzdG9tJywgbGFiZWw6IHQoJ2N1c3RvbScpIH0sXG4gIF1cblxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtZmlsdGVyYmFyJyB9LFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXNlZy13cmFwJywgcmVmOiBzZWdSZWYgfSxcbiAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXNlZycsIHJvbGU6ICdncm91cCcsICdhcmlhLWxhYmVsJzogdCgnZGF0ZVJhbmdlR3JvdXAnKSB9LFxuICAgICAgICBwcmVzZXRzLm1hcCgocCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGFjdGl2ZSA9IHJhbmdlID09PSBwLmtleVxuICAgICAgICAgIGNvbnN0IGlzQ3VzdG9tID0gcC5rZXkgPT09ICdjdXN0b20nXG4gICAgICAgICAgY29uc3QgbGFiZWwgPSBpc0N1c3RvbSAmJiBhY3RpdmUgPyBjdXN0b21MYWJlbCA6IHAubGFiZWxcbiAgICAgICAgICByZXR1cm4gaCgnYnV0dG9uJywge1xuICAgICAgICAgICAga2V5OiBwLmtleSxcbiAgICAgICAgICAgIHR5cGU6ICdidXR0b24nLFxuICAgICAgICAgICAgcmVmOiBpc0N1c3RvbSA/IGN1c3RvbUJ0blJlZiA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1zZWctYnRuJyArIChhY3RpdmUgPyAnIHRzZC1zZWctYWN0aXZlJyA6ICcnKSArIChpc0N1c3RvbSA/ICcgdHNkLXNlZy1jdXN0b20nIDogJycpLFxuICAgICAgICAgICAgJ2FyaWEtcHJlc3NlZCc6IGFjdGl2ZSxcbiAgICAgICAgICAgIHRpdGxlOiBpc0N1c3RvbSAmJiBhY3RpdmUgPyBjdXN0b21MYWJlbCA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG9uQ2xpY2s6ICgpID0+IHsgaWYgKGlzQ3VzdG9tKSBvbkN1c3RvbU9wZW4oIWN1c3RvbU9wZW4pOyBlbHNlIG9uUHJlc2V0KHAua2V5KSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2Qtc2VnLWxhYmVsJyB9LCBsYWJlbCkpXG4gICAgICAgIH0pKSxcbiAgICAgIGN1c3RvbU9wZW5cbiAgICAgICAgPyBoKEN1c3RvbVJhbmdlUG9wb3ZlciwgeyBjdXN0b20sIG9uQXBwbHk6IG9uQ3VzdG9tQXBwbHksIG9uQ2xvc2U6IG9uQ3VzdG9tQ2xvc2UsIGFuY2hvclJlZjogY3VzdG9tQnRuUmVmIH0pXG4gICAgICAgIDogbnVsbCksXG4gICAgaChNb2RlbERyb3Bkb3duLCB7IG9wdGlvbnM6IG1vZGVsT3B0aW9ucywgc2VsZWN0ZWQ6IG1vZGVscywgb25DaGFuZ2U6IG9uTW9kZWxzQ2hhbmdlIH0pKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOWPguiAg+aIkOacrOW4geenjeWIh+aNou+8iOS6uuawkeW4gSAvIOe+juWFg++8jOWbuuWumiAxIFVTRCA9IDcgQ05Z77yJXG4gKlxuICog5o2i566X5Zyo5a6/5Li75L6n5a6M5oiQ77yI5Lu355uu6KGo5piv576O5YWD5Lu377yM57ud5LiN5Zue5YaZ77yJ77yM5omA5Lul6L+Z6YeM5Y+q6LSf6LSj6YCJ5oup5LiO5oyB5LmF5YyW77yaXG4gKiDmjaLluIHnp43ljbPmjaLmn6Xor6LvvIzkuI3ph43mn6XmlbDlrZfkuI3kvJrlj5jjgIJcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmNvbnN0IENVUlJFTkNZX1NZTUJPTFMgPSB7IENOWTogJ8KlJywgVVNEOiAnJCcgfVxuY29uc3QgQ1VSUkVOQ1lfU1RPUkVfS0VZID0gJ2RzaC1wbHVnaW4tdXNhZ2U6ZGlzcGxheS1jdXJyZW5jeSdcblxuZnVuY3Rpb24gcmVhZFN0b3JlZEN1cnJlbmN5KCkge1xuICB0cnkge1xuICAgIHJldHVybiB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oQ1VSUkVOQ1lfU1RPUkVfS0VZKSA9PT0gJ1VTRCcgPyAnVVNEJyA6ICdDTlknXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gJ0NOWScgLy8g5peg55eV5qih5byPIC8g5a2Y5YKo6KKr56aB77ya6YCA5Zue6buY6K6kXG4gIH1cbn1cbmZ1bmN0aW9uIHN0b3JlQ3VycmVuY3koY29kZSkge1xuICB0cnkge1xuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShDVVJSRU5DWV9TVE9SRV9LRVksIGNvZGUpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyDlrZjkuI3kuIvlsLHlj6rlvbHlk43kuIvmrKHmiZPlvIDvvIzkuI3lvbHlk43mnKzmrKHmmL7npLpcbiAgfVxufVxuXG5mdW5jdGlvbiBDdXJyZW5jeVBpY2tlcihwcm9wcykge1xuICBjb25zdCB7IGNvZGUsIG9uQ2hhbmdlIH0gPSBwcm9wc1xuICBjb25zdCB0ID0gdXNlVCgpXG4gIGNvbnN0IFtvcGVuLCBzZXRPcGVuXSA9IFJlYWN0LnVzZVN0YXRlKGZhbHNlKVxuICBjb25zdCByZWYgPSBSZWFjdC51c2VSZWYobnVsbClcbiAgY29uc3QgcGFuZWxTdHlsZSA9IHVzZUZpeGVkUGFuZWwocmVmLCBvcGVuLCAxODApXG4gIHVzZU91dHNpZGVDbGljayhvcGVuLCByZWYsICgpID0+IHNldE9wZW4oZmFsc2UpKVxuICBjb25zdCBhY3RpdmUgPSBDVVJSRU5DWV9TWU1CT0xTW2NvZGVdID8gY29kZSA6ICdDTlknXG4gIGNvbnN0IG9wdGlvbnMgPSBbJ0NOWScsICdVU0QnXVxuICAvLyDmlLbotbfml7Yg4oaR4oaTIOebtOaOpeaNouWAvO+8iOWDj+WOn+eUnyBzZWxlY3TvvInvvIzlsZXlvIDml7blnKjkuKTpobnpl7Tnp7vliqjvvJtFc2Mg5YWz6I+c5Y2V44CCXG4gIGNvbnN0IG1vdmUgPSAoc3RlcCkgPT4ge1xuICAgIGNvbnN0IGkgPSBvcHRpb25zLmluZGV4T2YoYWN0aXZlKVxuICAgIG9uQ2hhbmdlKG9wdGlvbnNbKGkgKyBzdGVwICsgb3B0aW9ucy5sZW5ndGgpICUgb3B0aW9ucy5sZW5ndGhdKVxuICB9XG4gIGNvbnN0IG9uS2V5RG93biA9IChlKSA9PiB7XG4gICAgaWYgKGUua2V5ID09PSAnRXNjYXBlJykgeyBzZXRPcGVuKGZhbHNlKTsgcmV0dXJuIH1cbiAgICBpZiAoIW9wZW4pIHtcbiAgICAgIGlmIChlLmtleSA9PT0gJ0Fycm93RG93bicgfHwgZS5rZXkgPT09ICdBcnJvd1VwJykgeyBlLnByZXZlbnREZWZhdWx0KCk7IG1vdmUoZS5rZXkgPT09ICdBcnJvd0Rvd24nID8gMSA6IC0xKTsgcmV0dXJuIH1cbiAgICAgIGlmIChlLmtleSA9PT0gJ0VudGVyJyB8fCBlLmtleSA9PT0gJyAnKSB7IGUucHJldmVudERlZmF1bHQoKTsgc2V0T3Blbih0cnVlKSB9XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGUua2V5ID09PSAnQXJyb3dEb3duJykgeyBlLnByZXZlbnREZWZhdWx0KCk7IG1vdmUoMSkgfVxuICAgIGVsc2UgaWYgKGUua2V5ID09PSAnQXJyb3dVcCcpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyBtb3ZlKC0xKSB9XG4gIH1cbiAgcmV0dXJuIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1jdXItYW5jaG9yJywgcmVmIH0sXG4gICAgaCgnYnV0dG9uJywge1xuICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICBjbGFzc05hbWU6ICd0c2QtY3VyLWJ0bicgKyAob3BlbiA/ICcgdHNkLWN1ci1idG4tb3BlbicgOiAnJyksXG4gICAgICB0aXRsZTogdCgnY3VycmVuY3lIaW50JyksXG4gICAgICAnYXJpYS1sYWJlbCc6IHQoJ2N1cnJlbmN5SGludCcpLFxuICAgICAgJ2FyaWEtaGFzcG9wdXAnOiAnbGlzdGJveCcsXG4gICAgICAnYXJpYS1leHBhbmRlZCc6IG9wZW4sXG4gICAgICBvbkNsaWNrOiAoKSA9PiBzZXRPcGVuKCh2KSA9PiAhdiksXG4gICAgICBvbktleURvd24sXG4gICAgfSxcbiAgICAgIGgoJ3NwYW4nLCBudWxsLCBDVVJSRU5DWV9TWU1CT0xTW2FjdGl2ZV0pLFxuICAgICAgaChTdmdJY29uLCB7IG5hbWU6ICdjaGV2cm9uJywgc2l6ZTogMTAsIGNsYXNzTmFtZTogJ3RzZC1jdXItY2hldnJvbicgfSkpLFxuICAgIG9wZW5cbiAgICAgID8gaCgnZGl2Jywge1xuICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1wb3BvdmVyIHRzZC1jdXItcG9wb3ZlcicsXG4gICAgICAgICAgc3R5bGU6IHBhbmVsU3R5bGUsXG4gICAgICAgICAgcm9sZTogJ2xpc3Rib3gnLFxuICAgICAgICAgICdhcmlhLWxhYmVsJzogdCgnY3VycmVuY3lIaW50JyksXG4gICAgICAgICAgb25LZXlEb3duLFxuICAgICAgICB9LFxuICAgICAgICBvcHRpb25zLm1hcCgoYykgPT4gaCgnYnV0dG9uJywge1xuICAgICAgICAgIGtleTogYyxcbiAgICAgICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgICAgICByb2xlOiAnb3B0aW9uJyxcbiAgICAgICAgICAnYXJpYS1zZWxlY3RlZCc6IGMgPT09IGFjdGl2ZSxcbiAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtY3VyLW9wdGlvbicgKyAoYyA9PT0gYWN0aXZlID8gJyB0c2QtY3VyLW9wdGlvbi1hY3RpdmUnIDogJycpLFxuICAgICAgICAgIG9uQ2xpY2s6ICgpID0+IHsgb25DaGFuZ2UoYyk7IHNldE9wZW4oZmFsc2UpIH0sXG4gICAgICAgIH0sXG4gICAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWN1ci1zeW1ib2wnIH0sIENVUlJFTkNZX1NZTUJPTFNbY10pLFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1jdXItbmFtZScgfSwgdChjID09PSAnQ05ZJyA/ICdjdXJyZW5jeUNOWScgOiAnY3VycmVuY3lVU0QnKSksXG4gICAgICAgICAgYyA9PT0gYWN0aXZlID8gaChTdmdJY29uLCB7IG5hbWU6ICdjaGVjaycsIHNpemU6IDEyLCBjbGFzc05hbWU6ICd0c2QtY3VyLWNoZWNrJyB9KSA6IG51bGwpKSxcbiAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcG9wb3Zlci1ub3RlJyB9LCB0KCdjdXJyZW5jeUhpbnQnKSkpXG4gICAgICA6IG51bGwpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog5qih5Z6L5Y2g5q+U77yIS1BJIOe9keagvOmHjOeahOesrCA2IOagvO+8iVxuICpcbiAqIOaVsOaNruebtOaOpeWQg+Wuv+S4uyBgYnlNb2RlbGAg55qE6KGM77yI5LiO44CM5oyJ5qih5Z6L5piO57uG44CN6KGo5ZCM5LiA5Lu977yJ77yM5LiN5Y+m566X5LiA6YGN44CCXG4gKiDmmI7nu4bmlL7lnKjlkITmrrXnmoTljp/nlJ8gdGl0bGUg5LiK6ICM5LiN5piv5rWu5bGC77yaS1BJIOWNoei0tOedgOiuvue9rumdouadv+eahOijgeWJqui+ueeVjO+8jFxuICog5YaN5Y+g5LiA5bGC5rWu5bGC5Y+q5Lya5oqK5LmL5YmN5L+u5aW955qE6KOB5Ymq6Zeu6aKY5bim5Zue5p2l44CCXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5jb25zdCBTSEFSRV9DT0xPUlMgPSBbXG4gIC8vIOWPqueUqOS4u+mimOmHjOecn+WunuWtmOWcqOOAgeS4lOW9vOatpOWIhuW+l+W8gOeahOW9qeiJsuaXj++8mua3seiTneOAgee7v+OAgeeQpeePgOOAgee6ouOAglxuICAvLyDkuI3nlKggbmV1dHJhbCAvIOeZvSAvIOm7kSDigJTigJQg5a6D5Lus5Zyo5rex5rWF5Lik5aWX5Li76aKY6YeM5LiA6L655Lya57OK6L+b6IOM5pmv77yM5LiA6L655Lya6KKr6K+75oiQ56aB55So5oCB44CCXG4gICd2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCknLFxuICAndmFyKC0tZHN3LXN0YXRpYy1ncmVlbi01MDApJyxcbiAgJ3ZhcigtLWRzdy1zdGF0aWMtYW1iZXItNTAwKScsXG4gICd2YXIoLS1kc3ctc3RhdGljLXJlZC00MDApJyxcbl1cbmNvbnN0IFNIQVJFX1RPUCA9IDRcbmNvbnN0IFNIQVJFX1JFU1RfS0VZID0gJ19fcmVzdF9fJ1xuXG4vKiogYHByb3ZpZGVyL21vZGVsYCDihpIg6KO45qih5Z6L5ZCN77yb6Imy5bim5qC85L2N5pS+5LiN5LiL5YWo5ZCN77yM5YWo5ZCN55WZ57uZIHRpdGxlIOS4jiBhcmlh44CCICovXG5mdW5jdGlvbiBzaG9ydE1vZGVsTmFtZShrZXkpIHtcbiAgY29uc3QgcyA9IFN0cmluZyhrZXkgPT0gbnVsbCA/ICcnIDoga2V5KVxuICBjb25zdCBpID0gcy5sYXN0SW5kZXhPZignLycpXG4gIHJldHVybiBpID09PSAtMSA/IHMgOiBzLnNsaWNlKGkgKyAxKVxufVxuLyoqIOWuv+S4u+ihjOaYryBgdG90YWxUb2tlbnNg77yb5YW85a655bey5pig5bCE5oiQIGB0b3RhbGAg55qE5b2i54q277yM56m66KGM5Lmf5LiN6IO95oqb44CCICovXG5mdW5jdGlvbiByb3dUb3RhbChyKSB7XG4gIHJldHVybiByID8gKHIudG90YWxUb2tlbnMgfHwgci50b3RhbCB8fCAwKSA6IDBcbn1cbi8qKiDpmY3luo/lj5bliY0gNCDmrrXvvIzlhbbkvZnlubbmiJDjgIzlhbblroPjgI3vvJvml6DmlbDmja7ml7bov5Tlm57nqbrmrrXjgIIgKi9cbmZ1bmN0aW9uIHNoYXJlU2VnbWVudHMocm93cykge1xuICBjb25zdCBsaXN0ID0gKHJvd3MgfHwgW10pLnNsaWNlKCkuc29ydCgoYSwgYikgPT4gcm93VG90YWwoYikgLSByb3dUb3RhbChhKSlcbiAgY29uc3QgdG90YWwgPSBsaXN0LnJlZHVjZSgocywgcikgPT4gcyArIHJvd1RvdGFsKHIpLCAwKVxuICBpZiAodG90YWwgPD0gMCkgcmV0dXJuIHsgdG90YWw6IDAsIHNlZ3M6IFtdIH1cbiAgY29uc3QgbnVtYmVycyA9IChyKSA9PiAoe1xuICAgIHRva2Vuczogcm93VG90YWwociksXG4gICAgY2FsbHM6IHIuY2FsbHMgfHwgMCxcbiAgICAvLyDkuI7mmI7nu4booajlkIzkuIDlj6PlvoTvvJrovpPlhaXlkKvnvJPlrZjor7vlhplcbiAgICBpbnB1dDogKHIuaW5wdXRUb2tlbnMgfHwgMCkgKyAoci5jYWNoZVJlYWRUb2tlbnMgfHwgMCkgKyAoci5jYWNoZVdyaXRlVG9rZW5zIHx8IDApLFxuICAgIG91dHB1dDogci5vdXRwdXRUb2tlbnMgfHwgMCxcbiAgICBjb3N0OiByLmNvc3QgfHwgMCxcbiAgfSlcbiAgY29uc3Qgc2VncyA9IGxpc3Quc2xpY2UoMCwgU0hBUkVfVE9QKS5tYXAoKHIsIGkpID0+IE9iamVjdC5hc3NpZ24oe1xuICAgIGtleTogU3RyaW5nKHIua2V5KSxcbiAgICBsYWJlbDogc2hvcnRNb2RlbE5hbWUoci5rZXkpLFxuICAgIHBjdDogcm93VG90YWwocikgLyB0b3RhbCxcbiAgICBjb2xvcjogU0hBUkVfQ09MT1JTW2kgJSBTSEFSRV9DT0xPUlMubGVuZ3RoXSxcbiAgfSwgbnVtYmVycyhyKSkpXG4gIGNvbnN0IHJlc3RSb3dzID0gbGlzdC5zbGljZShTSEFSRV9UT1ApXG4gIGNvbnN0IHJlc3RUb2tlbnMgPSByZXN0Um93cy5yZWR1Y2UoKHMsIHIpID0+IHMgKyByb3dUb3RhbChyKSwgMClcbiAgaWYgKHJlc3RUb2tlbnMgPiAwKSB7XG4gICAgY29uc3QgYWdnID0gcmVzdFJvd3MucmVkdWNlKChhLCByKSA9PiB7XG4gICAgICBjb25zdCBuID0gbnVtYmVycyhyKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9rZW5zOiBhLnRva2VucyArIG4udG9rZW5zLFxuICAgICAgICBjYWxsczogYS5jYWxscyArIG4uY2FsbHMsXG4gICAgICAgIGlucHV0OiBhLmlucHV0ICsgbi5pbnB1dCxcbiAgICAgICAgb3V0cHV0OiBhLm91dHB1dCArIG4ub3V0cHV0LFxuICAgICAgICBjb3N0OiBhLmNvc3QgKyBuLmNvc3QsXG4gICAgICB9XG4gICAgfSwgeyB0b2tlbnM6IDAsIGNhbGxzOiAwLCBpbnB1dDogMCwgb3V0cHV0OiAwLCBjb3N0OiAwIH0pXG4gICAgc2Vncy5wdXNoKE9iamVjdC5hc3NpZ24oe1xuICAgICAga2V5OiBTSEFSRV9SRVNUX0tFWSxcbiAgICAgIGxhYmVsOiBudWxsLCAvLyDjgIzlhbblroPjgI3nmoTmlofmoYjnlLHmuLLmn5PlsYLlj5bor43lhbhcbiAgICAgIHBjdDogcmVzdFRva2VucyAvIHRvdGFsLFxuICAgICAgLy8g44CM5YW25a6D44CN55So5ZCM6Imy57O755qE5reh6Imy77yI5rWF6JOd77yJ77yM5LiN55So54GwL+eZve+8mumCo+S4pOenjeWcqOa3seiJsuWNoeeJh+S4iuS8muiiq+ivu+aIkOemgeeUqFxuICAgICAgY29sb3I6ICd2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTMwMCknLFxuICAgIH0sIGFnZykpXG4gIH1cbiAgcmV0dXJuIHsgdG90YWwsIHNlZ3MgfVxufVxuXG5mdW5jdGlvbiBNb2RlbFNoYXJlQmFyKHByb3BzKSB7XG4gIGNvbnN0IHsgcm93cywgY3VycmVuY3kgfSA9IHByb3BzXG4gIGNvbnN0IHQgPSB1c2VUKClcbiAgY29uc3QgW3RpcCwgc2V0VGlwXSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpIC8vIHsga2V5LCBsZWZ0LCB0b3AgfSBpbiB2aWV3cG9ydCBjb29yZHNcbiAgY29uc3Qgb2NjID0gc2hhcmVTZWdtZW50cyhyb3dzKVxuICBpZiAob2NjLnRvdGFsIDw9IDApIHJldHVybiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXZhbHVlIHRzZC1zaGFyZS1lbXB0eScgfSwgdCgnbm9EYXRhJykpXG4gIGNvbnN0IGZpbmQgPSAoa2V5KSA9PiBvY2Muc2Vncy5maWx0ZXIoKHMpID0+IHMua2V5ID09PSBrZXkpWzBdIHx8IG51bGxcbiAgY29uc3Qgc2hvd24gPSAodGlwICYmIGZpbmQodGlwLmtleSkpIHx8IG9jYy5zZWdzWzBdXG4gIGNvbnN0IGxhYmVsT2YgPSAocykgPT4gKHMua2V5ID09PSBTSEFSRV9SRVNUX0tFWSA/IHQoJ3NoYXJlT3RoZXInKSA6IHMubGFiZWwpXG4gIGNvbnN0IGZ1bGxPZiA9IChzKSA9PiAocy5rZXkgPT09IFNIQVJFX1JFU1RfS0VZID8gdCgnc2hhcmVPdGhlcicpIDogcy5rZXkpXG4gIGNvbnN0IGNvc3RPZiA9IChzKSA9PiAocy50b2tlbnMgPiAwICYmICEocy5jb3N0ID4gMCkgPyB0KCd1bnByaWNlZCcpIDogZm9ybWF0Q29zdChzLmNvc3QsIGN1cnJlbmN5KSlcbiAgLy8g5oKs5YGcL+iBmueEpu+8muS7juauteeahOinhuWPo+efqeW9ouaOqOW8gO+8jGZpeGVkIOWumuS9jeS4jeWPl+iuvue9rumdouadvyBvdmVyZmxvdyDoo4HliapcbiAgY29uc3Qgc2hvd1RpcCA9IChlLCBzKSA9PiB7XG4gICAgY29uc3QgciA9IGUuY3VycmVudFRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIHNldFRpcCh7IGtleTogcy5rZXksIGxlZnQ6IHIubGVmdCArIHIud2lkdGggLyAyLCB0b3A6IHIudG9wIH0pXG4gIH1cbiAgY29uc3QgaGlkZVRpcCA9ICgpID0+IHNldFRpcChudWxsKVxuICBjb25zdCB0aXBCb3ggPSBzaG93biAmJiB0aXBcbiAgICA/IGgoJ2RpdicsIHtcbiAgICAgICAgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAgdHNkLXNoYXJlLXRpcCcsXG4gICAgICAgIHN0eWxlOiB7IHBvc2l0aW9uOiAnZml4ZWQnLCBsZWZ0OiB0aXAubGVmdCArICdweCcsIHRvcDogdGlwLnRvcCArICdweCcsIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZSgtNTAlLCAtMTEwJSknIH0sXG4gICAgICB9LFxuICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRhdGUnIH0sIGZ1bGxPZihzaG93bikpLFxuICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXJvdycgfSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1kb3QnLCBzdHlsZTogeyBiYWNrZ3JvdW5kOiBzaG93bi5jb2xvciB9IH0pLFxuICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCB0KCd0b3RhbFRva2VucycpKSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC12YWwnIH0sIGZvcm1hdEludChzaG93bi50b2tlbnMpKSksXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtcm93JyB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCB0KCdsZWdlbmRJbnB1dCcpKSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC12YWwnIH0sIGZvcm1hdEludChzaG93bi5pbnB1dCkpKSxcbiAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1yb3cnIH0sXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ2xlZ2VuZE91dHB1dCcpKSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC12YWwnIH0sIGZvcm1hdEludChzaG93bi5vdXRwdXQpKSksXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtcm93JyB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCB0KCdjb3N0JykpLFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgY29zdE9mKHNob3duKSkpKVxuICAgIDogbnVsbFxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC1zaGFyZS1ib2R5JyB9LFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXNoYXJlLXRyYWNrJywgb25Nb3VzZUxlYXZlOiBoaWRlVGlwIH0sXG4gICAgICBvY2Muc2Vncy5tYXAoKHMpID0+IGgoJ2RpdicsIHtcbiAgICAgICAga2V5OiBzLmtleSxcbiAgICAgICAgY2xhc3NOYW1lOiAndHNkLXNoYXJlLXNlZycsXG4gICAgICAgICdkYXRhLXNoYXJlLWtleSc6IHMua2V5LFxuICAgICAgICAnZGF0YS1hY3RpdmUnOiBzaG93biAmJiBzaG93bi5rZXkgPT09IHMua2V5ID8gJ3RydWUnIDogdW5kZWZpbmVkLFxuICAgICAgICBzdHlsZTogeyB3aWR0aDogcy5wY3QgKiAxMDAgKyAnJScsIGJhY2tncm91bmQ6IHMuY29sb3IgfSxcbiAgICAgICAgcm9sZTogJ2ltZycsXG4gICAgICAgIHRhYkluZGV4OiAwLFxuICAgICAgICAnYXJpYS1sYWJlbCc6IGZ1bGxPZihzKSArICcgwrcgJyArIGZtdFBjdChzLnBjdCkgKyAnIMK3ICcgKyBmb3JtYXRJbnQocy50b2tlbnMpICsgJyAnICsgdCgndG90YWxUb2tlbnMnKSxcbiAgICAgICAgb25Nb3VzZUVudGVyOiAoZSkgPT4gc2hvd1RpcChlLCBzKSxcbiAgICAgICAgb25Gb2N1czogKGUpID0+IHNob3dUaXAoZSwgcyksXG4gICAgICAgIG9uQmx1cjogaGlkZVRpcCxcbiAgICAgIH0pKSksXG4gICAgLy8g5p2h5LiL5Y+q55WZ5LiA6KGM5L2O6LCD6ISa5rOo77yI5b2T5YmN5oKs5rWu55qE6YKj5q6177yM5ZCm5YiZ5pyA5aSn55qE6YKj5q6177yJ77ybXG4gICAgLy8g5YWo5ZCN5LiO5piO57uG6YO95Zyo5oKs5rWu5Y2h54mH6YeM77yM5omA5Lul6L+Z6YeM5LiN5oyCIHRpdGxl44CCXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2Qtc2hhcmUtY2FwdGlvbicgfSxcbiAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1zaGFyZS1jYXAtbmFtZScgfSwgbGFiZWxPZihzaG93bikpLFxuICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXNoYXJlLWNhcC1wY3QnIH0sIGZtdFBjdChzaG93bi5wY3QpKSksXG4gICAgdGlwQm94KVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOaxh+aAu+aMh+agh+WNoSDDlzZcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmZ1bmN0aW9uIFN1bW1hcnlDYXJkcyhwcm9wcykge1xuICBjb25zdCB7IHRvdGFsLCBjdXJyZW5jeSwgdW5wcmljZWRDYWxscywgY3VycmVuY3lDb2RlLCBvbkN1cnJlbmN5Q2hhbmdlLCBieU1vZGVsIH0gPSBwcm9wc1xuICBjb25zdCB0dCA9IHVzZVQoKVxuICBjb25zdCBkID0gdG90YWwgfHwge31cbiAgY29uc3QgaW5wdXRUb3RhbCA9IChkLmlucHV0VG9rZW5zIHx8IDApICsgKGQuY2FjaGVSZWFkVG9rZW5zIHx8IDApICsgKGQuY2FjaGVXcml0ZVRva2VucyB8fCAwKVxuICBjb25zdCBjYXJkcyA9IFtcbiAgICB7XG4gICAgICBrZXk6ICd0b3RhbCcsIGljb246ICdsYXllcnMnLCBsYWJlbDogdHQoJ3RvdGFsVG9rZW5zJyksXG4gICAgICB2YWx1ZTogZm9ybWF0VG9rZW5zU2hvcnQoZC50b3RhbFRva2VucyksIHRpdGxlOiBmb3JtYXRJbnQoZC50b3RhbFRva2VucyksXG4gICAgICBzdWI6IHR0KCdhcHByb3hJTycpLCBjb2xvcjogJ3ZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KScsXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICdpbnB1dCcsIGljb246ICdkb3duJywgbGFiZWw6IHR0KCdpbnB1dFRva2VucycpLFxuICAgICAgdmFsdWU6IGZvcm1hdFRva2Vuc1Nob3J0KGlucHV0VG90YWwpLCB0aXRsZTogZm9ybWF0SW50KGlucHV0VG90YWwpLFxuICAgICAgY29sb3I6ICd2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCknLFxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnb3V0cHV0JywgaWNvbjogJ3VwJywgbGFiZWw6IHR0KCdvdXRwdXRUb2tlbnMnKSxcbiAgICAgIHZhbHVlOiBmb3JtYXRUb2tlbnNTaG9ydChkLm91dHB1dFRva2VucyksIHRpdGxlOiBmb3JtYXRJbnQoZC5vdXRwdXRUb2tlbnMpLFxuICAgICAgY29sb3I6ICd2YXIoLS1kc3ctc3RhdGljLWdyZWVuLTUwMCknLFxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnY2FsbHMnLCBpY29uOiAnYWN0aXZpdHknLCBsYWJlbDogdHQoJ2NhbGxzJyksXG4gICAgICB2YWx1ZTogZm9ybWF0SW50KGQuY2FsbHMpLCB0aXRsZTogZm9ybWF0SW50KGQuY2FsbHMpLFxuICAgICAgY29sb3I6ICd2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCknLFxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnY29zdCcsIGljb246ICdjb2lucycsIGxhYmVsOiB0dCgnY29zdCcpLFxuICAgICAgLy8g56ym5Y+355SxIHByZWZpeCDnmoTluIHnp43liIfmjaLlmajnlLvvvIjlroPmmL7npLrlvZPliY3luIHnp43nrKblj7fvvInvvIzov5nph4zlj6rnu5nmlbDlrZdcbiAgICAgIHZhbHVlOiBjb3N0RGlnaXRzKGQuY29zdCksIHRpdGxlOiBmb3JtYXRDb3N0KGQuY29zdCwgY3VycmVuY3kpLFxuICAgICAgY29sb3I6ICd2YXIoLS1kc3ctc3RhdGljLWdyZWVuLTUwMCknLFxuICAgICAgcHJlZml4OiBoKEN1cnJlbmN5UGlja2VyLCB7IGNvZGU6IGN1cnJlbmN5Q29kZSwgb25DaGFuZ2U6IG9uQ3VycmVuY3lDaGFuZ2UgfSksXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICdzaGFyZScsIGljb246ICdzaGFyZScsIGxhYmVsOiB0dCgnbW9kZWxTaGFyZScpLFxuICAgICAgY29sb3I6ICd2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSknLFxuICAgICAgY29udGVudDogaChNb2RlbFNoYXJlQmFyLCB7IHJvd3M6IGJ5TW9kZWwsIGN1cnJlbmN5IH0pLFxuICAgIH0sXG4gIF1cbiAgcmV0dXJuIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmRzJyB9LFxuICAgIGNhcmRzLm1hcCgoYykgPT5cbiAgICAgIGgoJ2RpdicsIHsga2V5OiBjLmtleSwgY2xhc3NOYW1lOiAndHNkLWNhcmQnIH0sXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtaGVhZCcgfSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC1pY29uJywgc3R5bGU6IHsgY29sb3I6IGMuY29sb3IgfSB9LFxuICAgICAgICAgICAgaChTdmdJY29uLCB7IG5hbWU6IGMuaWNvbiwgc2l6ZTogMTQgfSkpLFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLWxhYmVsJyB9LCBjLmxhYmVsKSksXG4gICAgICAgIGMuY29udGVudFxuICAgICAgICAgID8gYy5jb250ZW50XG4gICAgICAgICAgOiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXZhbHVlJywgdGl0bGU6IGMudGl0bGUgfSwgYy5wcmVmaXggfHwgbnVsbCwgYy52YWx1ZSksXG4gICAgICAgIGMuc3ViID8gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC1zdWInIH0sIGMuc3ViKSA6IG51bGwsXG4gICAgICAgIGMua2V5ID09PSAnY29zdCcgJiYgdW5wcmljZWRDYWxscyA+IDBcbiAgICAgICAgICA/IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtbm90ZScgfSwgdHQoJ3VucHJpY2VkTm90ZScsIHsgY291bnQ6IGZvcm1hdEludCh1bnByaWNlZENhbGxzKSB9KSlcbiAgICAgICAgICA6IG51bGwpKSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDmr4/ml6XnlKjph4/mn7Hnirblm77vvIjmiYvlhpkgZGl2IOWghuWPoOafse+8muS4i+autei+k+WFpeiTnSAvIOS4iuautei+k+WHuue7v++8iVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gRGFpbHlDaGFydChwcm9wcykge1xuICBjb25zdCB7IGRhaWx5LCBncmFuLCBzdGVwRGF5cywgZ3JhbkxhYmVsIH0gPSBwcm9wc1xuICBjb25zdCB0ID0gdXNlVCgpXG4gIGNvbnN0IGNoYXJ0UmVmID0gUmVhY3QudXNlUmVmKG51bGwpXG4gIGNvbnN0IFt0aXAsIHNldFRpcF0gPSBSZWFjdC51c2VTdGF0ZShudWxsKSAvLyB7IHJvdywgeCB9XG4gIGNvbnN0IFt2aWV3LCBzZXRWaWV3XSA9IFJlYWN0LnVzZVN0YXRlKCdiYXInKSAvLyBiYXIgfCBsaW5lXG4gIGNvbnN0IHJvd3MgPSBkYWlseSB8fCBbXVxuXG4gIGNvbnN0IGluT2YgPSAocikgPT4gKHIuaW5wdXRUb2tlbnMgfHwgMCkgKyAoci5jYWNoZVJlYWRUb2tlbnMgfHwgMCkgKyAoci5jYWNoZVdyaXRlVG9rZW5zIHx8IDApXG4gIGNvbnN0IG91dE9mID0gKHIpID0+IHIub3V0cHV0VG9rZW5zIHx8IDBcbiAgY29uc3QgdG90T2YgPSAocikgPT4gci50b3RhbFRva2VucyB8fCAwXG5cbiAgaWYgKHJvd3MubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQgdHNkLWNoYXJ0LWNhcmQnIH0sXG4gICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLWhlYWRlcicgfSxcbiAgICAgICAgaCgnaDMnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXRpdGxlJyB9LCB0KCdkYWlseVRyZW5kJykpLFxuICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC10YWcnIH0sIHQoJ25vRGF0YScpKSksXG4gICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1lbXB0eS1ibG9jaycgfSwgdCgnbm9EYXRhJykpKVxuICB9XG5cbiAgY29uc3QgbWF4ID0gTWF0aC5tYXgoMSwgLi4ucm93cy5tYXAoKGQpID0+IGQudG90YWxUb2tlbnMgfHwgMCkpXG4gIGNvbnN0IGxhYmVsRXZlcnkgPSByb3dzLmxlbmd0aCA+IDI4ID8gNCA6IHJvd3MubGVuZ3RoID4gMTQgPyAyIDogMVxuICBjb25zdCBmaXJzdExhYmVsID0geExhYmVsKHJvd3NbMF0ua2V5LCBncmFuKVxuICBjb25zdCBsYXN0TGFiZWwgPSB4TGFiZWwocm93c1tyb3dzLmxlbmd0aCAtIDFdLmtleSwgZ3JhbilcbiAgY29uc3QgcmFuZ2VMYWJlbCA9IGZpcnN0TGFiZWwgKyAnIC0gJyArIGxhc3RMYWJlbFxuXG4gIGZ1bmN0aW9uIHNob3dUaXAoZSwgcm93KSB7XG4gICAgY29uc3QgY2hhcnRSZWN0ID0gY2hhcnRSZWYuY3VycmVudCA/IGNoYXJ0UmVmLmN1cnJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgOiBudWxsXG4gICAgaWYgKCFjaGFydFJlY3QpIHJldHVyblxuICAgIGNvbnN0IGVsUmVjdCA9IGUuY3VycmVudFRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIGNvbnN0IHggPSBNYXRoLm1pbihNYXRoLm1heChlbFJlY3QubGVmdCArIGVsUmVjdC53aWR0aCAvIDIgLSBjaGFydFJlY3QubGVmdCwgNzIpLCBjaGFydFJlY3Qud2lkdGggLSA3MilcbiAgICBzZXRUaXAoeyByb3csIHggfSlcbiAgfVxuXG4gIGNvbnN0IHZpZXdTd2l0Y2hlciA9IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWdyYW4nLCByb2xlOiAnZ3JvdXAnLCAnYXJpYS1sYWJlbCc6IHQoJ2NoYXJ0VHlwZUdyb3VwJykgfSxcbiAgICBoKCdidXR0b24nLCB7XG4gICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgIGNsYXNzTmFtZTogJ3RzZC1ncmFuLWJ0bicsXG4gICAgICAnZGF0YS1hY3RpdmUnOiB2aWV3ID09PSAnYmFyJyA/ICd0cnVlJyA6IHVuZGVmaW5lZCxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHsgc2V0VGlwKG51bGwpOyBzZXRWaWV3KCdiYXInKSB9LFxuICAgIH0sIHQoJ2JhclZpZXcnKSksXG4gICAgaCgnYnV0dG9uJywge1xuICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICBjbGFzc05hbWU6ICd0c2QtZ3Jhbi1idG4nLFxuICAgICAgJ2RhdGEtYWN0aXZlJzogdmlldyA9PT0gJ2xpbmUnID8gJ3RydWUnIDogdW5kZWZpbmVkLFxuICAgICAgb25DbGljazogKCkgPT4geyBzZXRUaXAobnVsbCk7IHNldFZpZXcoJ2xpbmUnKSB9LFxuICAgIH0sIHQoJ2xpbmVWaWV3JykpKVxuXG4gIGNvbnN0IGJhclRpcCA9IHRpcFxuICAgID8gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcCcsIHN0eWxlOiB7IGxlZnQ6IHRpcC54ICsgJ3B4JyB9IH0sXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtZGF0ZScgfSwgdGlwLnJvdy5rZXkgKyAnICcgKyB3ZWVrZGF5TmFtZSh0aXAucm93LmtleSwgdCkpLFxuICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXJvdycgfSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1kb3QgdHNkLWxlZ2VuZC1pbicgfSksXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ2xlZ2VuZElucHV0JykpLFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0SW50KGluT2YodGlwLnJvdykpKSksXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtcm93JyB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRvdCB0c2QtbGVnZW5kLW91dCcgfSksXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ2xlZ2VuZE91dHB1dCcpKSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC12YWwnIH0sIGZvcm1hdEludChvdXRPZih0aXAucm93KSkpKSxcbiAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC10b3RhbCcgfSxcbiAgICAgICAgICBoKCdzcGFuJywgbnVsbCwgdCgndG9vbHRpcFRvdGFsJykpLFxuICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCBmb3JtYXRJbnQodG90T2YodGlwLnJvdykpKSkpXG4gICAgOiBudWxsXG5cbiAgY29uc3QgYm9keSA9IHZpZXcgPT09ICdsaW5lJ1xuICAgID8gaChMaW5lQ2hhcnQsIHsgcm93cywgZ3Jhbiwgc3RlcERheXMsIHNob3dUaXAsIHRpcCwgc2V0VGlwLCBjaGFydFJlZiB9KVxuICAgIDogaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2hhcnQnLCByZWY6IGNoYXJ0UmVmIH0sXG4gICAgICAgIHJvd3MubWFwKChyb3csIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBpblQgPSBpbk9mKHJvdylcbiAgICAgICAgICBjb25zdCBvdXRUID0gb3V0T2Yocm93KVxuICAgICAgICAgIGNvbnN0IHRvdFQgPSB0b3RPZihyb3cpXG4gICAgICAgICAgY29uc3QgcGN0SW4gPSAoaW5UIC8gbWF4KSAqIDEwMFxuICAgICAgICAgIGNvbnN0IHBjdE91dCA9IChvdXRUIC8gbWF4KSAqIDEwMFxuICAgICAgICAgIGNvbnN0IHNob3dMYWJlbCA9IGkgJSBsYWJlbEV2ZXJ5ID09PSAwIHx8IGkgPT09IHJvd3MubGVuZ3RoIC0gMVxuICAgICAgICAgIHJldHVybiBoKCdkaXYnLCB7XG4gICAgICAgICAgICBrZXk6IHJvdy5rZXksXG4gICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtY2hhcnQtY29sJyxcbiAgICAgICAgICAgIHRhYkluZGV4OiAwLFxuICAgICAgICAgICAgb25Nb3VzZUVudGVyOiAoZSkgPT4gc2hvd1RpcChlLCByb3cpLFxuICAgICAgICAgICAgb25Nb3VzZUxlYXZlOiAoKSA9PiBzZXRUaXAobnVsbCksXG4gICAgICAgICAgICBvbkZvY3VzOiAoZSkgPT4gc2hvd1RpcChlLCByb3cpLFxuICAgICAgICAgICAgb25CbHVyOiAoKSA9PiBzZXRUaXAobnVsbCksXG4gICAgICAgICAgICAnYXJpYS1sYWJlbCc6IHQoJ2JhckFyaWEnLCB7IGtleTogcm93LmtleSwgaW46IGZvcm1hdEludChpblQpLCBvdXQ6IGZvcm1hdEludChvdXRUKSwgdG90OiBmb3JtYXRJbnQodG90VCkgfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNoYXJ0LXBsb3QnIH0sXG4gICAgICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNoYXJ0LXN0YWNrJyB9LFxuICAgICAgICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNoYXJ0LXNlZyB0c2Qtc2VnLW91dCcsIHN0eWxlOiB7IGhlaWdodDogcGN0T3V0ICsgJyUnIH0gfSksXG4gICAgICAgICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2hhcnQtc2VnIHRzZC1zZWctaW4nLCBzdHlsZTogeyBoZWlnaHQ6IHBjdEluICsgJyUnIH0gfSkpKSxcbiAgICAgICAgICAgIGgoJ3NwYW4nLCB7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1jaGFydC1sYWJlbCcgKyAoc2hvd0xhYmVsID8gJycgOiAnIHRzZC1jaGFydC1sYWJlbC1oaWRkZW4nKSxcbiAgICAgICAgICAgIH0sIHhMYWJlbChyb3cua2V5LCBncmFuKSkpXG4gICAgICAgIH0pLFxuICAgICAgICBiYXJUaXApXG5cbiAgcmV0dXJuIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQgdHNkLWNoYXJ0LWNhcmQnIH0sXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC1oZWFkZXInIH0sXG4gICAgICBoKCdoMycsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtdGl0bGUnIH0sIHQoJ2RhaWx5VHJlbmQnKSksXG4gICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC1hY3Rpb25zJyB9LFxuICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC10YWcnIH0sIGdyYW5MYWJlbCArICcgwrcgJyArIHJhbmdlTGFiZWwpLFxuICAgICAgICB2aWV3U3dpdGNoZXIpKSxcbiAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1sZWdlbmQnIH0sXG4gICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtbGVnZW5kLWl0ZW0nIH0sXG4gICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1sZWdlbmQtZG90IHRzZC1sZWdlbmQtaW4nIH0pLCB0KCdsZWdlbmRJbnB1dCcpKSxcbiAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1sZWdlbmQtaXRlbScgfSxcbiAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWxlZ2VuZC1kb3QgdHNkLWxlZ2VuZC1vdXQnIH0pLCB0KCdsZWdlbmRPdXRwdXQnKSksXG4gICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtbGVnZW5kLWl0ZW0nIH0sXG4gICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1sZWdlbmQtZG90IHRzZC1sZWdlbmQtdG90YWwnIH0pLCB0KCdsZWdlbmRUb3RhbCcpKSksXG4gICAgYm9keSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDmipjnur/lm77vvIhTVkfvvJrovpPlhaUgLyDovpPlh7ogLyDmgLsgVG9rZW7vvIlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbi8qKiBDYXRtdWxsLVJvbSAtPiBjdWJpYyBiZXppZXIgc21vb3RoIHBhdGggdGhyb3VnaCB0aGUgZ2l2ZW4gcG9pbnRzLiAqL1xuZnVuY3Rpb24gc21vb3RoUGF0aChwdHMpIHtcbiAgaWYgKCFwdHMgfHwgcHRzLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICBjb25zdCBmID0gKHYpID0+IE1hdGgucm91bmQodiAqIDEwMCkgLyAxMDBcbiAgbGV0IGQgPSAnTSAnICsgZihwdHNbMF0ueCkgKyAnICcgKyBmKHB0c1swXS55KVxuICBmb3IgKGxldCBpID0gMDsgaSA8IHB0cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICBjb25zdCBwMCA9IHB0c1tpIC0gMV0gfHwgcHRzW2ldXG4gICAgY29uc3QgcDEgPSBwdHNbaV1cbiAgICBjb25zdCBwMiA9IHB0c1tpICsgMV1cbiAgICBjb25zdCBwMyA9IHB0c1tpICsgMl0gfHwgcDJcbiAgICBjb25zdCBjMXggPSBwMS54ICsgKHAyLnggLSBwMC54KSAvIDZcbiAgICBjb25zdCBjMXkgPSBwMS55ICsgKHAyLnkgLSBwMC55KSAvIDZcbiAgICBjb25zdCBjMnggPSBwMi54IC0gKHAzLnggLSBwMS54KSAvIDZcbiAgICBjb25zdCBjMnkgPSBwMi55IC0gKHAzLnkgLSBwMS55KSAvIDZcbiAgICBkICs9ICcgQyAnICsgZihjMXgpICsgJyAnICsgZihjMXkpICsgJywgJyArIGYoYzJ4KSArICcgJyArIGYoYzJ5KSArICcsICcgKyBmKHAyLngpICsgJyAnICsgZihwMi55KVxuICB9XG4gIHJldHVybiBkXG59XG5cbmZ1bmN0aW9uIExpbmVDaGFydChwcm9wcykge1xuICBjb25zdCB7IHJvd3MsIGdyYW4sIHN0ZXBEYXlzLCBzaG93VGlwLCB0aXAsIHNldFRpcCwgY2hhcnRSZWYgfSA9IHByb3BzXG4gIGNvbnN0IHQgPSB1c2VUKClcbiAgY29uc3QgVyA9IDYyMFxuICBjb25zdCBIID0gMjQwXG4gIGNvbnN0IFBBRCA9IHsgdDogMTQsIHI6IDE0LCBiOiAyNiwgbDogNDggfVxuICBjb25zdCBpbm5lclcgPSBXIC0gUEFELmwgLSBQQUQuclxuICBjb25zdCBpbm5lckggPSBIIC0gUEFELnQgLSBQQUQuYlxuICBjb25zdCBuID0gcm93cy5sZW5ndGhcblxuICBjb25zdCBpbk9mID0gKHIpID0+IChyLmlucHV0VG9rZW5zIHx8IDApICsgKHIuY2FjaGVSZWFkVG9rZW5zIHx8IDApICsgKHIuY2FjaGVXcml0ZVRva2VucyB8fCAwKVxuICBjb25zdCBvdXRPZiA9IChyKSA9PiByLm91dHB1dFRva2VucyB8fCAwXG4gIGNvbnN0IHRvdE9mID0gKHIpID0+IHIudG90YWxUb2tlbnMgfHwgMFxuICBjb25zdCBtYXggPSBNYXRoLm1heCgxLCAuLi5yb3dzLm1hcCgoZCkgPT4gZC50b3RhbFRva2VucyB8fCAwKSlcbiAgY29uc3QgbmljZU1heCA9IG5pY2VDZWlsKG1heClcblxuICBjb25zdCB4ID0gKGkpID0+IFBBRC5sICsgKG4gPT09IDEgPyBpbm5lclcgLyAyIDogKGkgLyAobiAtIDEpKSAqIGlubmVyVylcbiAgY29uc3QgeSA9ICh2KSA9PiBQQUQudCArIGlubmVySCAtICh2IC8gbmljZU1heCkgKiBpbm5lckhcbiAgY29uc3QgY29sVyA9IGlubmVyVyAvIG5cblxuICAvLyBIb3ZlciBzdGF0ZTogcGl4ZWwgeCBmb3IgdGhlIHRvb2x0aXAsIHZpZXdCb3ggeCBmb3IgdGhlIGN1cnNvciArIGRvdHMuXG4gIGZ1bmN0aW9uIHNob3dUaXBMaW5lKGUsIHJvdykge1xuICAgIGNvbnN0IHJlY3QgPSBjaGFydFJlZi5jdXJyZW50ID8gY2hhcnRSZWYuY3VycmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSA6IG51bGxcbiAgICBpZiAoIXJlY3QgfHwgcmVjdC53aWR0aCA9PT0gMCkgcmV0dXJuXG4gICAgY29uc3QgZWxSZWN0ID0gZS5jdXJyZW50VGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgY29uc3QgeFB4ID0gZWxSZWN0LmxlZnQgKyBlbFJlY3Qud2lkdGggLyAyIC0gcmVjdC5sZWZ0XG4gICAgY29uc3Qgc3ZnWCA9ICh4UHggLyByZWN0LndpZHRoKSAqIFdcbiAgICBjb25zdCB4ID0gTWF0aC5taW4oTWF0aC5tYXgoeFB4LCA3MiksIHJlY3Qud2lkdGggLSA3MilcbiAgICBzZXRUaXAoeyByb3csIHgsIHN2Z1ggfSlcbiAgfVxuICBjb25zdCB0cm93ID0gdGlwID8gdGlwLnJvdyA6IG51bGxcbiAgY29uc3QgY3Vyc29yID0gdGlwXG4gICAgPyBoKCdsaW5lJywge1xuICAgICAgICBrZXk6ICdjdXJzb3InLFxuICAgICAgICBjbGFzc05hbWU6ICd0c2QtbGluZS1jdXJzb3InLFxuICAgICAgICB4MTogdGlwLnN2Z1gsIHkxOiBQQUQudCwgeDI6IHRpcC5zdmdYLCB5MjogSCAtIFBBRC5iLFxuICAgICAgfSlcbiAgICA6IG51bGxcbiAgY29uc3QgZG90cyA9IHRpcFxuICAgID8gW1xuICAgICAgICBoKCdjaXJjbGUnLCB7IGtleTogJ2hsLWluJywgY2xhc3NOYW1lOiAndHNkLWxpbmUtaGwgdHNkLWxpbmUtaGwtaW4nLCBjeDogdGlwLnN2Z1gsIGN5OiB5KGluT2YodHJvdykpLCByOiAzLjUgfSksXG4gICAgICAgIGgoJ2NpcmNsZScsIHsga2V5OiAnaGwtb3V0JywgY2xhc3NOYW1lOiAndHNkLWxpbmUtaGwgdHNkLWxpbmUtaGwtb3V0JywgY3g6IHRpcC5zdmdYLCBjeTogeShvdXRPZih0cm93KSksIHI6IDMuNSB9KSxcbiAgICAgICAgaCgnY2lyY2xlJywgeyBrZXk6ICdobC10b3QnLCBjbGFzc05hbWU6ICd0c2QtbGluZS1obCB0c2QtbGluZS1obC10b3RhbCcsIGN4OiB0aXAuc3ZnWCwgY3k6IHkodG90T2YodHJvdykpLCByOiAzLjUgfSksXG4gICAgICBdXG4gICAgOiBudWxsXG5cbiAgY29uc3QgaW5QdHMgPSBzbW9vdGhQYXRoKHJvd3MubWFwKChyLCBpKSA9PiAoeyB4OiB4KGkpLCB5OiB5KGluT2YocikpIH0pKSlcbiAgY29uc3Qgb3V0UHRzID0gc21vb3RoUGF0aChyb3dzLm1hcCgociwgaSkgPT4gKHsgeDogeChpKSwgeTogeShvdXRPZihyKSkgfSkpKVxuICBjb25zdCB0b3RQdHMgPSBzbW9vdGhQYXRoKHJvd3MubWFwKChyLCBpKSA9PiAoeyB4OiB4KGkpLCB5OiB5KHRvdE9mKHIpKSB9KSkpXG4gIGNvbnN0IGdyaWRGID0gWzAsIDAuMjUsIDAuNSwgMC43NSwgMV1cbiAgY29uc3QgbGFiZWxFdmVyeSA9IHJvd3MubGVuZ3RoID4gMjggPyA0IDogcm93cy5sZW5ndGggPiAxNCA/IDIgOiAxXG4gIGNvbnN0IHNob3dMYWJlbCA9IChpKSA9PiBpICUgbGFiZWxFdmVyeSA9PT0gMCB8fCBpID09PSByb3dzLmxlbmd0aCAtIDFcblxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtbGluZWNoYXJ0JywgcmVmOiBjaGFydFJlZiB9LFxuICAgIGgoJ3N2ZycsIHsgdmlld0JveDogJzAgMCAnICsgVyArICcgJyArIEgsIHJvbGU6ICdpbWcnLCAnYXJpYS1sYWJlbCc6IHQoJ2xpbmVDaGFydEFyaWEnKSB9LFxuICAgICAgLy8gZ3JpZCArIGF4aXNcbiAgICAgIGdyaWRGLm1hcCgoZikgPT5cbiAgICAgICAgaCgnbGluZScsIHtcbiAgICAgICAgICBrZXk6ICdnJyArIGYsXG4gICAgICAgICAgY2xhc3NOYW1lOiAndHNkLWxpbmUtZ3JpZCcsXG4gICAgICAgICAgeDE6IFBBRC5sLCB5MTogeShmICogbmljZU1heCksIHgyOiBXIC0gUEFELnIsIHkyOiB5KGYgKiBuaWNlTWF4KSxcbiAgICAgICAgfSkpLFxuICAgICAgaCgnbGluZScsIHsgY2xhc3NOYW1lOiAndHNkLWxpbmUtYXhpcycsIHgxOiBQQUQubCwgeTE6IFBBRC50LCB4MjogUEFELmwsIHkyOiBIIC0gUEFELmIgfSksXG4gICAgICBoKCdsaW5lJywgeyBjbGFzc05hbWU6ICd0c2QtbGluZS1heGlzJywgeDE6IFBBRC5sLCB5MTogSCAtIFBBRC5iLCB4MjogVyAtIFBBRC5yLCB5MjogSCAtIFBBRC5iIH0pLFxuICAgICAgLy8geSBsYWJlbHNcbiAgICAgIGdyaWRGLm1hcCgoZikgPT5cbiAgICAgICAgaCgndGV4dCcsIHtcbiAgICAgICAgICBrZXk6ICd5dCcgKyBmLFxuICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1saW5lLXRleHQnLFxuICAgICAgICAgIHg6IFBBRC5sIC0gNixcbiAgICAgICAgICB5OiB5KGYgKiBuaWNlTWF4KSArIDMsXG4gICAgICAgICAgdGV4dEFuY2hvcjogJ2VuZCcsXG4gICAgICAgIH0sIGZvcm1hdFRva2Vuc1Nob3J0KGYgKiBuaWNlTWF4KSkpLFxuICAgICAgLy8gc2VyaWVzIChzbW9vdGggY3VydmVzKVxuICAgICAgaCgncGF0aCcsIHsgY2xhc3NOYW1lOiAndHNkLWxpbmUtdG90YWwnLCBkOiB0b3RQdHMgfSksXG4gICAgICBoKCdwYXRoJywgeyBjbGFzc05hbWU6ICd0c2QtbGluZS1pbicsIGQ6IGluUHRzIH0pLFxuICAgICAgaCgncGF0aCcsIHsgY2xhc3NOYW1lOiAndHNkLWxpbmUtb3V0JywgZDogb3V0UHRzIH0pLFxuICAgICAgY3Vyc29yLFxuICAgICAgZG90cyxcbiAgICAgIC8vIHggbGFiZWxzXG4gICAgICByb3dzLm1hcCgociwgaSkgPT5cbiAgICAgICAgc2hvd0xhYmVsKGkpXG4gICAgICAgICAgPyBoKCd0ZXh0Jywge1xuICAgICAgICAgICAgICBrZXk6ICd4bCcgKyBpLFxuICAgICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtbGluZS10ZXh0JyxcbiAgICAgICAgICAgICAgeDogeChpKSxcbiAgICAgICAgICAgICAgeTogSCAtIDgsXG4gICAgICAgICAgICAgIHRleHRBbmNob3I6IGkgPT09IDAgPyAnc3RhcnQnIDogaSA9PT0gbiAtIDEgPyAnZW5kJyA6ICdtaWRkbGUnLFxuICAgICAgICAgICAgfSwgeExhYmVsKHIua2V5LCBncmFuKSlcbiAgICAgICAgICA6IG51bGwpLFxuICAgICAgLy8gaG92ZXIgdGFyZ2V0czogYSBmdWxsLWhlaWdodCBjb2x1bW4gcGVyIGJ1Y2tldCwgbWF0Y2hpbmcgdGhlIGJhciBjaGFydCBmZWVsXG4gICAgICByb3dzLm1hcCgociwgaSkgPT5cbiAgICAgICAgaCgncmVjdCcsIHtcbiAgICAgICAgICBrZXk6ICdoJyArIGksXG4gICAgICAgICAgY2xhc3NOYW1lOiAndHNkLWxpbmUtaG92ZXInLFxuICAgICAgICAgIHg6IHgoaSkgLSBjb2xXIC8gMixcbiAgICAgICAgICB5OiBQQUQudCxcbiAgICAgICAgICB3aWR0aDogY29sVyxcbiAgICAgICAgICBoZWlnaHQ6IGlubmVySCxcbiAgICAgICAgICB0YWJJbmRleDogMCxcbiAgICAgICAgICBvbk1vdXNlRW50ZXI6IChlKSA9PiBzaG93VGlwTGluZShlLCByKSxcbiAgICAgICAgICBvbk1vdXNlTGVhdmU6ICgpID0+IHNldFRpcChudWxsKSxcbiAgICAgICAgICBvbkZvY3VzOiAoZSkgPT4gc2hvd1RpcExpbmUoZSwgciksXG4gICAgICAgICAgb25CbHVyOiAoKSA9PiBzZXRUaXAobnVsbCksXG4gICAgICAgIH0pKSxcbiAgICAgIC8vIHZpc2libGUgZG90cyBvbiBzcGFyc2UgcG9pbnRzXG4gICAgICByb3dzLm1hcCgociwgaSkgPT5cbiAgICAgICAgaSAlIGxhYmVsRXZlcnkgPT09IDAgfHwgaSA9PT0gbiAtIDFcbiAgICAgICAgICA/IGgoJ2NpcmNsZScsIHtcbiAgICAgICAgICAgICAga2V5OiAnZCcgKyBpLFxuICAgICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtbGluZS1kb3QnLFxuICAgICAgICAgICAgICBjeDogeChpKSxcbiAgICAgICAgICAgICAgY3k6IHkodG90T2YocikpLFxuICAgICAgICAgICAgICByOiAyLjUsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIDogbnVsbCkpLFxuICAgIHRpcFxuICAgICAgPyBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwJywgc3R5bGU6IHsgbGVmdDogdGlwLnggKyAncHgnIH0gfSxcbiAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRhdGUnIH0sIHRpcC5yb3cua2V5ICsgKHN0ZXBEYXlzID4gMSA/ICcgJyArIHQoJ3N0YXJ0TkRheXMnLCB7IG46IHN0ZXBEYXlzIH0pIDogJycpICsgJyAnICsgd2Vla2RheU5hbWUodGlwLnJvdy5rZXksIHQpKSxcbiAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXJvdycgfSxcbiAgICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRvdCB0c2QtbGVnZW5kLWluJyB9KSxcbiAgICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCB0KCdsZWdlbmRJbnB1dCcpKSxcbiAgICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0SW50KGluT2YodGlwLnJvdykpKSksXG4gICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1yb3cnIH0sXG4gICAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1kb3QgdHNkLWxlZ2VuZC1vdXQnIH0pLFxuICAgICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ2xlZ2VuZE91dHB1dCcpKSxcbiAgICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0SW50KG91dE9mKHRpcC5yb3cpKSkpLFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtdG90YWwnIH0sXG4gICAgICAgICAgICBoKCdzcGFuJywgbnVsbCwgdCgndG9vbHRpcFRvdGFsJykpLFxuICAgICAgICAgICAgaCgnc3BhbicsIG51bGwsIGZvcm1hdEludCh0b3RPZih0aXAucm93KSkpKSlcbiAgICAgIDogbnVsbClcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDlubTluqbnlKjph4/ng63lipvlm77vvIhHaXRIdWIg6aOO5qC877yJXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBIZWF0bWFwQ2FyZChwcm9wcykge1xuICBjb25zdCB7IGRheXMgfSA9IHByb3BzXG4gIGNvbnN0IHQgPSB1c2VUKClcbiAgY29uc3QgW2h0aXAsIHNldEh0aXBdID0gUmVhY3QudXNlU3RhdGUobnVsbCkgLy8geyBjZWxsLCBsZWZ0LCB0b3AgfSBpbiB2aWV3cG9ydCBjb29yZHNcbiAgY29uc3QgZ3JpZCA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IGxpc3QgPSBkYXlzIHx8IFtdXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbFxuICAgIGNvbnN0IG1heCA9IE1hdGgubWF4KDEsIC4uLmxpc3QubWFwKChkKSA9PiBkLnRvdGFsVG9rZW5zIHx8IDApKVxuICAgIGNvbnN0IGZpcnN0ID0gbmV3IERhdGUobGlzdFswXS5rZXkgKyAnVDAwOjAwOjAwJylcbiAgICBjb25zdCBvZmZzZXQgPSBmaXJzdC5nZXREYXkoKSAvLyAwID0gU3VuZGF5XG4gICAgY29uc3Qgd2Vla3MgPSBbXVxuICAgIGxldCBjdXIgPSBbXVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb2Zmc2V0OyBpKyspIGN1ci5wdXNoKG51bGwpXG4gICAgZm9yIChjb25zdCBkIG9mIGxpc3QpIHtcbiAgICAgIGN1ci5wdXNoKGQpXG4gICAgICBpZiAoY3VyLmxlbmd0aCA9PT0gNykge1xuICAgICAgICB3ZWVrcy5wdXNoKGN1cilcbiAgICAgICAgY3VyID0gW11cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGN1ci5sZW5ndGggPiAwKSB7XG4gICAgICB3aGlsZSAoY3VyLmxlbmd0aCA8IDcpIGN1ci5wdXNoKG51bGwpXG4gICAgICB3ZWVrcy5wdXNoKGN1cilcbiAgICB9XG4gICAgLy8g5pyI5Lu95qCH6K6w77ya5p+Q5pyIIDEg5pel5omA5Zyo55qE5YiXXG4gICAgY29uc3QgbW9udGhNYXJrcyA9IFtdXG4gICAgd2Vla3MuZm9yRWFjaCgod2ssIGNvbCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBjIG9mIHdrKSB7XG4gICAgICAgIGlmIChjICYmIGMua2V5LmVuZHNXaXRoKCctMDEnKSkge1xuICAgICAgICAgIG1vbnRoTWFya3MucHVzaCh7IGNvbCwgbmFtZTogdCgnbW9udGhMYWJlbCcsIHsgbjogTnVtYmVyKGMua2V5LnNsaWNlKDUsIDcpKSB9KSB9KVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiB7IHdlZWtzLCBtYXgsIG1vbnRoTWFya3MgfVxuICB9LCBbZGF5c10pXG5cbiAgaWYgKGdyaWQgPT09IG51bGwpIHJldHVybiBudWxsXG5cbiAgZnVuY3Rpb24gc2hvd0NlbGxUaXAoZSwgYykge1xuICAgIGNvbnN0IGVsUmVjdCA9IGUuY3VycmVudFRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIHNldEh0aXAoeyBjZWxsOiBjLCBsZWZ0OiBlbFJlY3QubGVmdCArIGVsUmVjdC53aWR0aCAvIDIsIHRvcDogZWxSZWN0LnRvcCB9KVxuICB9XG5cbiAgY29uc3QgaGVhdFRpcCA9IGh0aXBcbiAgICA/IGgoJ2RpdicsIHtcbiAgICAgICAgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAgdHNkLWhlYXQtdGlwJyxcbiAgICAgICAgc3R5bGU6IHsgcG9zaXRpb246ICdmaXhlZCcsIGxlZnQ6IGh0aXAubGVmdCArICdweCcsIHRvcDogaHRpcC50b3AgKyAncHgnLCB0cmFuc2Zvcm06ICd0cmFuc2xhdGUoLTUwJSwgLTExMCUpJyB9LFxuICAgICAgfSxcbiAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1kYXRlJyB9LCBodGlwLmNlbGwua2V5ICsgJyAnICsgd2Vla2RheU5hbWUoaHRpcC5jZWxsLmtleSwgdCkpLFxuICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXJvdycgfSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1kb3QnLCBzdHlsZTogeyBiYWNrZ3JvdW5kOiAndmFyKC0tZHN3LXN0YXRpYy1kZWVwc2Vlay01MDApJyB9IH0pLFxuICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCB0KCd0b3RhbFRva2VucycpKSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC12YWwnIH0sIGZvcm1hdEludChodGlwLmNlbGwudG90YWxUb2tlbnMgfHwgMCkpKSxcbiAgICAgICAgaHRpcC5jZWxsLmNhbGxzID4gMFxuICAgICAgICAgID8gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1yb3cnIH0sXG4gICAgICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRvdCcsIHN0eWxlOiB7IGJhY2tncm91bmQ6ICd2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpJyB9IH0pLFxuICAgICAgICAgICAgICBoKCdzcGFuJywgbnVsbCwgdCgnY2FsbHMnKSksXG4gICAgICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0SW50KGh0aXAuY2VsbC5jYWxscykpKVxuICAgICAgICAgIDogbnVsbClcbiAgICA6IG51bGxcblxuICBjb25zdCBkYXlOYW1lcyA9IFsnJywgdCgnd2Vla2RheU1vbicpLCAnJywgdCgnd2Vla2RheVdlZCcpLCAnJywgdCgnd2Vla2RheUZyaScpLCAnJ11cbiAgY29uc3QgbGVnZW5kU3RlcHMgPSBbMCwgMC4yNSwgMC41LCAwLjc1LCAxXVxuXG4gIHJldHVybiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkIHRzZC1oZWF0bWFwLWNhcmQnIH0sXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC1oZWFkZXInIH0sXG4gICAgICBoKCdoMycsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtdGl0bGUnIH0sIHQoJ3llYXJseUhlYXRtYXAnKSksXG4gICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC10YWcnIH0sIHQoJ3llYXJEYWlseScsIHsgeWVhcjogbmV3IERhdGUoKS5nZXRGdWxsWWVhcigpIH0pKSksXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtaGVhdG1hcCcgfSxcbiAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAtaW5uZXInIH0sXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAtbW9udGhzJyB9LFxuICAgICAgICAgIGdyaWQubW9udGhNYXJrcy5tYXAoKG0pID0+XG4gICAgICAgICAgICBoKCdzcGFuJywge1xuICAgICAgICAgICAgICBrZXk6IG0uY29sLFxuICAgICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtaGVhdG1hcC1tb250aCcsXG4gICAgICAgICAgICAgIHN0eWxlOiB7IGxlZnQ6IChtLmNvbCAqIDEyKSArICdweCcgfSxcbiAgICAgICAgICAgIH0sIG0ubmFtZSkpKSxcbiAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtaGVhdG1hcC1ib2R5JyB9LFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAtZGF5cycgfSxcbiAgICAgICAgICAgIGRheU5hbWVzLm1hcCgobiwgaSkgPT5cbiAgICAgICAgICAgICAgaCgnc3BhbicsIHsga2V5OiBpLCBjbGFzc05hbWU6ICd0c2QtaGVhdG1hcC1kYXknIH0sIG4pKSksXG4gICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtaGVhdG1hcC1ncmlkJyB9LFxuICAgICAgICAgICAgZ3JpZC53ZWVrcy5tYXAoKHdrLCBjb2wpID0+XG4gICAgICAgICAgICAgIGgoJ2RpdicsIHsga2V5OiBjb2wsIGNsYXNzTmFtZTogJ3RzZC1oZWF0bWFwLWNvbCcgfSxcbiAgICAgICAgICAgICAgICB3ay5tYXAoKGMsIHJvdykgPT5cbiAgICAgICAgICAgICAgICAgIGNcbiAgICAgICAgICAgICAgICAgICAgPyBoKCdzcGFuJywge1xuICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBjLmtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1oZWF0bWFwLWNlbGwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgYmFja2dyb3VuZDogaGVhdENvbG9yKGMudG90YWxUb2tlbnMgfHwgMCwgZ3JpZC5tYXgpIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogdCgnaG1UaXRsZScsIHsga2V5OiBjLmtleSwgdG9rZW5zOiBmb3JtYXRJbnQoYy50b3RhbFRva2VucyB8fCAwKSwgY2FsbHM6IGMuY2FsbHMgPyB0KCdobUNhbGxzJywgeyBjb3VudDogZm9ybWF0SW50KGMuY2FsbHMpIH0pIDogJycgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICBvbk1vdXNlRW50ZXI6IChlKSA9PiBzaG93Q2VsbFRpcChlLCBjKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uTW91c2VMZWF2ZTogKCkgPT4gc2V0SHRpcChudWxsKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uRm9jdXM6IChlKSA9PiBzaG93Q2VsbFRpcChlLCBjKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQmx1cjogKCkgPT4gc2V0SHRpcChudWxsKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhYkluZGV4OiAwLFxuICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIDogaCgnc3BhbicsIHsga2V5OiAnZScgKyBjb2wgKyAnLScgKyByb3csIGNsYXNzTmFtZTogJ3RzZC1oZWF0bWFwLWNlbGwnLCBzdHlsZTogeyB2aXNpYmlsaXR5OiAnaGlkZGVuJyB9IH0pKSkpKSkpLFxuICAgIGhlYXRUaXAsXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtaGVhdG1hcC1sZWdlbmQnIH0sXG4gICAgICBoKCdzcGFuJywgbnVsbCwgdCgnbGVzcycpKSxcbiAgICAgIGxlZ2VuZFN0ZXBzLm1hcCgocykgPT5cbiAgICAgICAgaCgnc3BhbicsIHtcbiAgICAgICAgICBrZXk6IHMsXG4gICAgICAgICAgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAtY2VsbCcsXG4gICAgICAgICAgc3R5bGU6IHsgYmFja2dyb3VuZDogcyA9PT0gMCA/ICd2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpJyA6IGhlYXRDb2xvcihNYXRoLm1heCgxLCBzICogMTAwKSwgMTAwKSB9LFxuICAgICAgICB9KSksXG4gICAgICBoKCdzcGFuJywgbnVsbCwgdCgnbW9yZScpKSkpKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOaMieaooeWei+aYjue7huihqFxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gTW9kZWxUYWJsZShwcm9wcykge1xuICBjb25zdCB7IHJvd3MsIGN1cnJlbmN5IH0gPSBwcm9wc1xuICBjb25zdCB0ID0gdXNlVCgpXG4gIGNvbnN0IGFsbCA9IHJvd3MgfHwgW11cbiAgY29uc3QgW3NvcnRLZXksIHNldFNvcnRLZXldID0gUmVhY3QudXNlU3RhdGUoJ3RvdGFsJylcbiAgY29uc3QgW3NvcnREaXIsIHNldFNvcnREaXJdID0gUmVhY3QudXNlU3RhdGUoJ2Rlc2MnKVxuXG4gIGNvbnN0IHZpZXcgPSBSZWFjdC51c2VNZW1vKCgpID0+IGFsbC5tYXAoKHIpID0+ICh7XG4gICAga2V5OiByLmtleSxcbiAgICBjYWxsczogci5jYWxscyB8fCAwLFxuICAgIGlucHV0OiAoci5pbnB1dFRva2VucyB8fCAwKSArIChyLmNhY2hlUmVhZFRva2VucyB8fCAwKSArIChyLmNhY2hlV3JpdGVUb2tlbnMgfHwgMCksXG4gICAgb3V0cHV0OiByLm91dHB1dFRva2VucyB8fCAwLFxuICAgIHRvdGFsOiByLnRvdGFsVG9rZW5zIHx8IDAsXG4gICAgY29zdDogci5jb3N0IHx8IDAsXG4gICAgdW5wcmljZWQ6IChyLnRvdGFsVG9rZW5zIHx8IDApID4gMCAmJiAhKHIuY29zdCA+IDApLFxuICB9KSksIFthbGxdKVxuXG4gIGNvbnN0IHN1bVRvdGFsID0gUmVhY3QudXNlTWVtbygoKSA9PiB2aWV3LnJlZHVjZSgocywgcikgPT4gcyArIHIudG90YWwsIDApLCBbdmlld10pXG5cbiAgY29uc3Qgc29ydGVkID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3QgbGlzdCA9IHZpZXcuc2xpY2UoKVxuICAgIGNvbnN0IGRpciA9IHNvcnREaXIgPT09ICdhc2MnID8gMSA6IC0xXG4gICAgbGlzdC5zb3J0KChhLCBiKSA9PiB7XG4gICAgICBjb25zdCBhdiA9IGFbc29ydEtleV1cbiAgICAgIGNvbnN0IGJ2ID0gYltzb3J0S2V5XVxuICAgICAgaWYgKGF2ID09PSBidikgcmV0dXJuIDBcbiAgICAgIHJldHVybiAoYXYgPiBidiA/IDEgOiAtMSkgKiBkaXJcbiAgICB9KVxuICAgIHJldHVybiBsaXN0XG4gIH0sIFt2aWV3LCBzb3J0S2V5LCBzb3J0RGlyXSlcblxuICBmdW5jdGlvbiB0b2dnbGVTb3J0KGtleSkge1xuICAgIGlmIChzb3J0S2V5ID09PSBrZXkpIHNldFNvcnREaXIoKGQpID0+IChkID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnKSlcbiAgICBlbHNlIHsgc2V0U29ydEtleShrZXkpOyBzZXRTb3J0RGlyKCdkZXNjJykgfVxuICB9XG5cbiAgY29uc3QgY29scyA9IFtcbiAgICB7IGtleTogJ21vZGVsJywgbGFiZWw6IHQoJ2NvbE1vZGVsJyksIHNvcnRhYmxlOiBmYWxzZSB9LFxuICAgIHsga2V5OiAnY2FsbHMnLCBsYWJlbDogdCgnY29sQ2FsbHMnKSwgc29ydGFibGU6IHRydWUgfSxcbiAgICB7IGtleTogJ2lucHV0JywgbGFiZWw6IHQoJ2NvbElucHV0JyksIHNvcnRhYmxlOiB0cnVlIH0sXG4gICAgeyBrZXk6ICdvdXRwdXQnLCBsYWJlbDogdCgnY29sT3V0cHV0JyksIHNvcnRhYmxlOiB0cnVlIH0sXG4gICAgeyBrZXk6ICd0b3RhbCcsIGxhYmVsOiB0KCdjb2xUb3RhbCcpLCBzb3J0YWJsZTogdHJ1ZSB9LFxuICAgIHsga2V5OiAnY29zdCcsIGxhYmVsOiB0KCdjb2xDb3N0JyksIHNvcnRhYmxlOiB0cnVlIH0sXG4gICAgeyBrZXk6ICdyYXRpbycsIGxhYmVsOiB0KCdjb2xTaGFyZScpLCBzb3J0YWJsZTogZmFsc2UgfSxcbiAgXVxuXG4gIHJldHVybiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkIHRzZC10YWJsZS1jYXJkJyB9LFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtaGVhZGVyJyB9LFxuICAgICAgaCgnaDMnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXRpdGxlJyB9LCB0KCdieU1vZGVsVGl0bGUnKSksXG4gICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC10YWcnIH0sXG4gICAgICAgIHQoJ21vZGVsQ291bnQnLCB7IG46IHZpZXcubGVuZ3RoIH0pICsgJyDCtyAnICsgdCgnY29sVG90YWwnKSArICcgJyArIGZvcm1hdEludChzdW1Ub3RhbCkpKSxcbiAgICB2aWV3Lmxlbmd0aCA9PT0gMFxuICAgICAgPyBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1lbXB0eS1ibG9jaycgfSwgdCgnbm9EYXRhJykpXG4gICAgICA6IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRhYmxlLXdyYXAnIH0sXG4gICAgICAgICAgaCgndGFibGUnLCB7IGNsYXNzTmFtZTogJ3RzZC10YWJsZScgfSxcbiAgICAgICAgICAgIGgoJ2NhcHRpb24nLCB7IGNsYXNzTmFtZTogJ3RzZC12aXN1YWxseS1oaWRkZW4nIH0sIHQoJ21vZGVsVGFibGVDYXB0aW9uJykpLFxuICAgICAgICAgICAgaCgndGhlYWQnLCBudWxsLFxuICAgICAgICAgICAgICBoKCd0cicsIG51bGwsIGNvbHMubWFwKChjKSA9PlxuICAgICAgICAgICAgICAgIGgoJ3RoJywge1xuICAgICAgICAgICAgICAgICAga2V5OiBjLmtleSxcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC10aCcgKyAoYy5rZXkgPT09ICdtb2RlbCcgPyAnJyA6ICcgdHNkLXRoLW51bScpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBjLnNvcnRhYmxlXG4gICAgICAgICAgICAgICAgICAgID8gaCgnYnV0dG9uJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICd0c2Qtc29ydC1idG4nICsgKHNvcnRLZXkgPT09IGMua2V5ID8gJyB0c2Qtc29ydC1hY3RpdmUnIDogJycpLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljazogKCkgPT4gdG9nZ2xlU29ydChjLmtleSksXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGMubGFiZWwsXG4gICAgICAgICAgICAgICAgICAgICAgICBzb3J0S2V5ID09PSBjLmtleVxuICAgICAgICAgICAgICAgICAgICAgICAgICA/IGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1zb3J0LWFycm93JyB9LCBzb3J0RGlyID09PSAnYXNjJyA/ICfihpEnIDogJ+KGkycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbClcbiAgICAgICAgICAgICAgICAgICAgOiBjLmxhYmVsKSkpKSxcbiAgICAgICAgICAgIGgoJ3Rib2R5JywgbnVsbCwgc29ydGVkLm1hcCgocikgPT4ge1xuICAgICAgICAgICAgICBjb25zdCByYXRpbyA9IHN1bVRvdGFsID4gMCA/IHIudG90YWwgLyBzdW1Ub3RhbCA6IDBcbiAgICAgICAgICAgICAgcmV0dXJuIGgoJ3RyJywgeyBrZXk6IHIua2V5LCBjbGFzc05hbWU6ICd0c2QtdHInIH0sXG4gICAgICAgICAgICAgICAgaCgndGQnLCB7IGNsYXNzTmFtZTogJ3RzZC10ZCB0c2QtdGQtbW9kZWwnIH0sXG4gICAgICAgICAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtbW9kZWwtbW9ubycsIHRpdGxlOiByLmtleSB9LCByLmtleSkpLFxuICAgICAgICAgICAgICAgIGgoJ3RkJywgeyBjbGFzc05hbWU6ICd0c2QtdGQgdHNkLW51bScgfSwgZm9ybWF0SW50KHIuY2FsbHMpKSxcbiAgICAgICAgICAgICAgICBoKCd0ZCcsIHsgY2xhc3NOYW1lOiAndHNkLXRkIHRzZC1udW0nIH0sIGZvcm1hdEludChyLmlucHV0KSksXG4gICAgICAgICAgICAgICAgaCgndGQnLCB7IGNsYXNzTmFtZTogJ3RzZC10ZCB0c2QtbnVtJyB9LCBmb3JtYXRJbnQoci5vdXRwdXQpKSxcbiAgICAgICAgICAgICAgICBoKCd0ZCcsIHsgY2xhc3NOYW1lOiAndHNkLXRkIHRzZC1udW0gdHNkLXRvdGFsJyB9LCBmb3JtYXRJbnQoci50b3RhbCkpLFxuICAgICAgICAgICAgICAgIGgoJ3RkJywgeyBjbGFzc05hbWU6ICd0c2QtdGQgdHNkLW51bScgfSxcbiAgICAgICAgICAgICAgICAgIHIudW5wcmljZWRcbiAgICAgICAgICAgICAgICAgICAgPyBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdW5wcmljZWQnLCB0aXRsZTogdCgndW5wcmljZWRSb3dIaW50JykgfSwgdCgndW5wcmljZWQnKSlcbiAgICAgICAgICAgICAgICAgICAgOiBmb3JtYXRDb3N0KHIuY29zdCwgY3VycmVuY3kpKSxcbiAgICAgICAgICAgICAgICBoKCd0ZCcsIHsgY2xhc3NOYW1lOiAndHNkLXRkIHRzZC10ZC1yYXRpbycgfSxcbiAgICAgICAgICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXJhdGlvJyB9LFxuICAgICAgICAgICAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1yYXRpby1iYXInIH0sXG4gICAgICAgICAgICAgICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcmF0aW8tZmlsbCcsIHN0eWxlOiB7IHdpZHRoOiByYXRpbyAqIDEwMCArICclJyB9IH0pKSxcbiAgICAgICAgICAgICAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXJhdGlvLXBjdCcgfSwgZm10UGN0KHJhdGlvKSkpKSlcbiAgICAgICAgICAgIH0pKSkpKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOS4ieaAge+8muWKoOi9vSAvIOmUmeivryAvIOepulxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gTG9hZGluZ1N0YXRlKCkge1xuICBjb25zdCB0ID0gdXNlVCgpXG4gIHJldHVybiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1sb2FkaW5nJyB9LFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmRzJyB9LFxuICAgICAgWzAsIDEsIDIsIDMsIDRdLm1hcCgoaSkgPT5cbiAgICAgICAgaCgnZGl2JywgeyBrZXk6IGksIGNsYXNzTmFtZTogJ3RzZC1jYXJkIHRzZC1jYXJkLXNrZWxldG9uJyB9LFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXNrZWxldG9uJywgc3R5bGU6IHsgd2lkdGg6ICc0MCUnLCBoZWlnaHQ6IDEyIH0gfSksXG4gICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2Qtc2tlbGV0b24nLCBzdHlsZTogeyB3aWR0aDogJzcwJScsIGhlaWdodDogMjIsIG1hcmdpblRvcDogMTAgfSB9KSkpKSxcbiAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkJyB9LFxuICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2Qtc2tlbGV0b24nLCBzdHlsZTogeyB3aWR0aDogJzEwMCUnLCBoZWlnaHQ6IDMwMCB9IH0pKSxcbiAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkJyB9LFxuICAgICAgWzAsIDEsIDIsIDMsIDQsIDVdLm1hcCgoaSkgPT5cbiAgICAgICAgaCgnZGl2JywgeyBrZXk6IGksIGNsYXNzTmFtZTogJ3RzZC1za2VsZXRvbi1yb3cnLCBzdHlsZTogeyB3aWR0aDogOTYgLSBpICogOCArICclJyB9IH0pKSkpXG59XG5cbmZ1bmN0aW9uIEVycm9yU3RhdGUocHJvcHMpIHtcbiAgY29uc3QgeyBlcnJvciwgb25SZXRyeSB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZCB0c2QtZXJyb3InLCByb2xlOiAnYWxlcnQnIH0sXG4gICAgaChTdmdJY29uLCB7IG5hbWU6ICdhbGVydCcsIHNpemU6IDIyLCBjbGFzc05hbWU6ICd0c2QtZXJyb3ItaWNvbicgfSksXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtZXJyb3ItdGV4dCcgfSxcbiAgICAgIGgoJ3AnLCB7IGNsYXNzTmFtZTogJ3RzZC1lcnJvci10aXRsZScgfSwgdCgnbG9hZEZhaWxlZFRpdGxlJykpLFxuICAgICAgaCgncCcsIHsgY2xhc3NOYW1lOiAndHNkLWVycm9yLWRldGFpbCcgfSwgU3RyaW5nKChlcnJvciAmJiBlcnJvci5tZXNzYWdlKSB8fCBlcnJvcikpKSxcbiAgICBoKCdidXR0b24nLCB7IHR5cGU6ICdidXR0b24nLCBjbGFzc05hbWU6ICd0c2QtYnRuIHRzZC1idG4tcHJpbWFyeScsIG9uQ2xpY2s6IG9uUmV0cnkgfSwgdCgncmV0cnknKSkpXG59XG5cbmZ1bmN0aW9uIEVtcHR5U3RhdGUocHJvcHMpIHtcbiAgY29uc3QgeyBmaWx0ZXJlZCwgb25SZXNldCB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZCB0c2QtZW1wdHknIH0sXG4gICAgaChTdmdJY29uLCB7IG5hbWU6ICdpbmJveCcsIHNpemU6IDI4LCBjbGFzc05hbWU6ICd0c2QtZW1wdHktaWNvbicgfSksXG4gICAgaCgncCcsIHsgY2xhc3NOYW1lOiAndHNkLWVtcHR5LXRpdGxlJyB9LCB0KCdub0RhdGEnKSksXG4gICAgaCgncCcsIHsgY2xhc3NOYW1lOiAndHNkLWVtcHR5LWRlc2MnIH0sXG4gICAgICBmaWx0ZXJlZCA/IHQoJ2VtcHR5RmlsdGVyZWQnKSA6IHQoJ2VtcHR5RGVzYycpKSxcbiAgICBoKCdidXR0b24nLCB7IHR5cGU6ICdidXR0b24nLCBjbGFzc05hbWU6ICd0c2QtYnRuIHRzZC1idG4tZ2hvc3QnLCBvbkNsaWNrOiBvblJlc2V0IH0sIHQoJ3Jlc2V0RmlsdGVycycpKSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDpobXpnaLnuqfnirbmgIHmnLogKyDluIPlsYBcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmZ1bmN0aW9uIFN0YXRzRGFzaGJvYXJkKHByb3BzKSB7XG4gIGNvbnN0IHQgPSBwcm9wcy50IHx8IGZhbGxiYWNrVFxuICBjb25zdCBbcmFuZ2UsIHNldFJhbmdlXSA9IFJlYWN0LnVzZVN0YXRlKCd0b2RheScpIC8vIHRvZGF5IHwgN2QgfCAzMGQgfCBjdXN0b21cbiAgY29uc3QgW2N1c3RvbSwgc2V0Q3VzdG9tXSA9IFJlYWN0LnVzZVN0YXRlKGRlZmF1bHRDdXN0b20pXG4gIGNvbnN0IFttb2RlbHMsIHNldE1vZGVsc10gPSBSZWFjdC51c2VTdGF0ZShbXSkgLy8gW10gPSDlhajpg6jmqKHlnotcbiAgY29uc3QgW2N1c3RvbU9wZW4sIHNldEN1c3RvbU9wZW5dID0gUmVhY3QudXNlU3RhdGUoZmFsc2UpXG4gIGNvbnN0IFtyZXRyeSwgc2V0UmV0cnldID0gUmVhY3QudXNlU3RhdGUoMClcbiAgY29uc3QgW3N0YXR1cywgc2V0U3RhdHVzXSA9IFJlYWN0LnVzZVN0YXRlKCdsb2FkaW5nJykgLy8gbG9hZGluZyB8IHJlZnJlc2hpbmcgfCByZWFkeSB8IGVycm9yXG4gIGNvbnN0IFtkYXRhLCBzZXREYXRhXSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpXG4gIGNvbnN0IFtlcnJvciwgc2V0RXJyb3JdID0gUmVhY3QudXNlU3RhdGUobnVsbClcbiAgY29uc3QgW3ByaWNlcywgc2V0UHJpY2VzXSA9IFJlYWN0LnVzZVN0YXRlKHsgcHJpY2VzOiB7fSwgY3VycmVuY3k6ICfCpScgfSlcbiAgLy8g5bGV56S65biB56eN77ya5a6/5Li75oyJ5a6D5o2i566X5oiQ5pys77yM5omA5Lul5o2i5biB56eN5b+F6aG76YeN5p+l77yb6YCJ5oup6K6w5Zyo5pys5Zyw77yI5bGV56S65YGP5aW977yMXG4gIC8vIOS4jeWGmeaPkuS7tuiuvue9ru+8jOWFjeW+l+avj+asoeWPluaVsOmDveWcqOaUueWGmeeUqOaIt+mFjee9ru+8ieOAglxuICBjb25zdCBbZGlzcGxheUN1cnJlbmN5LCBzZXREaXNwbGF5Q3VycmVuY3ldID0gUmVhY3QudXNlU3RhdGUocmVhZFN0b3JlZEN1cnJlbmN5KVxuICAvLyBQMS02IGJhY2tmaWxsIOi9ruivoueKtuaAge+8mnF1ZXJ5S2V5IOWPmOWMluaXtumHjee9ru+8jOS7heWvueWQjOS4gOafpeivouS4sui9ruivolxuICBjb25zdCBxdWVyeUtleVJlZiA9IFJlYWN0LnVzZVJlZihudWxsKVxuICBjb25zdCBiYWNrZmlsbFNlZW5SZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpXG4gIGNvbnN0IGZpbmFsUmVmcmVzaFJlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSlcblxuICBjb25zdCBlZmYgPSBSZWFjdC51c2VNZW1vKCgpID0+IHJhbmdlRm9yKHJhbmdlLCBjdXN0b20pLCBbcmFuZ2UsIGN1c3RvbV0pXG4gIC8vIEZpeGVkIHN0ZXAgcG9saWN5OiB0b2RheSA9IGhvdXJseTsgN2QvMzBkL2N1c3RvbSA9IGRhaWx5LCBjdXN0b20gdXNlcyBhXG4gIC8vIHN0YWJsZSBzdGVwICgxLzMvNS83IGRheXMpIGNob3NlbiBieSB0aGUgcmFuZ2UgbGVuZ3RoLlxuICBjb25zdCBlZmZHcmFuID0gZWZmR3JhbnVsYXJpdHkocmFuZ2UpXG4gIGNvbnN0IHN0ZXBEYXlzID0gcmFuZ2UgPT09ICdjdXN0b20nID8gcGlja1N0ZXBEYXlzKChlZmYudG8gfHwgMCkgLSAoZWZmLmZyb20gfHwgMCkpIDogMVxuICBjb25zdCBncmFuTGFiZWwgPSBzdGVwTGFiZWwodCwgcmFuZ2UsIHN0ZXBEYXlzKVxuXG4gIC8vIOafpeivoue7n+iuoe+8iOmmlui9vemqqOaetu+8m+WIt+aWsOS/neeVmeaXp+aVsOaNrui9rCByZWZyZXNoaW5n77ybZmlsbCAwIOWhq+WFhSArIOW5tOW6pueDreWKm+Wbvu+8iVxuICAvLyBQMS0277yaYmFja2ZpbGwgcnVubmluZyDml7bmr48gM3Mg6Ieq5Yqo6YeN5p+l77ybZG9uZSDlkI7ooaXkuIDmrKHmlLblsL7mn6Xor6LljbPlgZzjgIJcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBsZXQgY3VycmVudCA9IHRydWVcbiAgICBsZXQgYmFja2ZpbGxUaW1lciA9IG51bGxcbiAgICBjb25zdCBxdWVyeUtleSA9IGVmZi5mcm9tICsgJ3wnICsgZWZmLnRvICsgJ3wnICsgbW9kZWxzLmpvaW4oJywnKSArICd8JyArIGVmZkdyYW4gKyAnfCcgKyBzdGVwRGF5cyArICd8JyArIGRpc3BsYXlDdXJyZW5jeVxuICAgIGlmIChxdWVyeUtleVJlZi5jdXJyZW50ICE9PSBxdWVyeUtleSkge1xuICAgICAgcXVlcnlLZXlSZWYuY3VycmVudCA9IHF1ZXJ5S2V5XG4gICAgICBiYWNrZmlsbFNlZW5SZWYuY3VycmVudCA9IGZhbHNlXG4gICAgICBmaW5hbFJlZnJlc2hSZWYuY3VycmVudCA9IGZhbHNlXG4gICAgfVxuICAgIGNvbnN0IGlzRmluYWxSdW4gPSBmaW5hbFJlZnJlc2hSZWYuY3VycmVudFxuICAgIGZpbmFsUmVmcmVzaFJlZi5jdXJyZW50ID0gZmFsc2VcbiAgICBzZXRTdGF0dXMoKHMpID0+IChzID09PSAncmVhZHknICYmIGRhdGEgIT09IG51bGwgPyAncmVmcmVzaGluZycgOiAnbG9hZGluZycpKVxuICAgIGhvc3RDYWxsKCd1c2FnZS9xdWVyeScsIHtcbiAgICAgIGZyb206IGVmZi5mcm9tLFxuICAgICAgdG86IGVmZi50byxcbiAgICAgIG1vZGVsczogbW9kZWxzLnNsaWNlKCksXG4gICAgICAvLyDjgIzlhajpg6jjgI3kuI3lgZrpm7bloavlhYXvvJrnnJ/lrp7ovrnnlYzmmK/ovpPlh7rmobbmlbDvvIjlrr/kuLsgTUFYX0JVQ0tFVFPvvInvvIzkuI3mmK/lpKnmlbDjgIJcbiAgICAgIGZpbGw6IHJhbmdlICE9PSAnYWxsJyxcbiAgICAgIGdyYW51bGFyaXR5OiBlZmZHcmFuLFxuICAgICAgc3RlcERheXMsXG4gICAgICBoZWF0bWFwOiB0cnVlLFxuICAgICAgY3VycmVuY3k6IGRpc3BsYXlDdXJyZW5jeSxcbiAgICB9KVxuICAgICAgLnRoZW4oKHIpID0+IHtcbiAgICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm5cbiAgICAgICAgc2V0RGF0YShyKVxuICAgICAgICBzZXRTdGF0dXMoJ3JlYWR5JylcbiAgICAgICAgc2V0RXJyb3IobnVsbClcbiAgICAgICAgY29uc3QgYnMgPSByICYmIHIuYmFja2ZpbGwgPyByLmJhY2tmaWxsLnN0YXR1cyA6IG51bGxcbiAgICAgICAgaWYgKGJzID09PSAncnVubmluZycpIHtcbiAgICAgICAgICBiYWNrZmlsbFNlZW5SZWYuY3VycmVudCA9IHRydWVcbiAgICAgICAgICAvLyDlkIzkuIAgZWZmZWN0IOiHs+WkmuaMguS4gOS4quWumuaXtuWZqO+8m+mHjeafpeWkjeeUqCByZXRyeSDorqHmlbDlmajop6blj5EgZWZmZWN0IOmHjei3kVxuICAgICAgICAgIGJhY2tmaWxsVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50KSBzZXRSZXRyeSgodikgPT4gdiArIDEpXG4gICAgICAgICAgfSwgMzAwMClcbiAgICAgICAgfSBlbHNlIGlmIChicyA9PT0gJ2RvbmUnICYmIGJhY2tmaWxsU2VlblJlZi5jdXJyZW50ICYmICFpc0ZpbmFsUnVuKSB7XG4gICAgICAgICAgLy8g5Zue5aGr5pS25bC+77ya5oGw5aW95YaN5p+l5LiA5qyh5ou/5Yiw5a6M5pW05pWw5o2u5ZCO5YGc5q2iXG4gICAgICAgICAgZmluYWxSZWZyZXNoUmVmLmN1cnJlbnQgPSB0cnVlXG4gICAgICAgICAgc2V0UmV0cnkoKHYpID0+IHYgKyAxKVxuICAgICAgICB9XG4gICAgICB9LCAoZSkgPT4ge1xuICAgICAgICBpZiAoIWN1cnJlbnQpIHJldHVyblxuICAgICAgICBzZXRFcnJvcihlKVxuICAgICAgICBzZXRTdGF0dXMoJ2Vycm9yJylcbiAgICAgIH0pXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGN1cnJlbnQgPSBmYWxzZVxuICAgICAgaWYgKGJhY2tmaWxsVGltZXIgIT09IG51bGwpIGNsZWFyVGltZW91dChiYWNrZmlsbFRpbWVyKVxuICAgIH1cbiAgfSwgW2VmZi5mcm9tLCBlZmYudG8sIG1vZGVscywgZWZmR3Jhbiwgc3RlcERheXMsIGRpc3BsYXlDdXJyZW5jeSwgcmV0cnldKVxuXG4gIC8vIOS7t+agvOihqO+8mui/m+WFpemhtemdouaLieS4gOasoSArIOavj+asoeWIt+aWsOWQjOatpeOAglxuICAvLyBQMC0x77ya5LyY5YWI5a6Y5pa5IHNldHRpbmdzIHNjb3Bl77yIdXNhZ2UucHJpY2VzIOWRveWQjeepuumXtO+8ie+8jOS4jeWPr+eUqOaXtuWbnumAgCBSUEPjgIJcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBsZXQgY3VycmVudCA9IHRydWVcbiAgICBsZXQgc2NvcGVEaXNwb3NlID0gbnVsbFxuICAgIGNvbnN0IGxvYWRScGMgPSAoKSA9PiB7XG4gICAgICBob3N0Q2FsbCgndXNhZ2UvcHJpY2VzJykudGhlbigocCkgPT4ge1xuICAgICAgICBpZiAoY3VycmVudCAmJiBwICYmIHAucHJpY2VzKSBzZXRQcmljZXMocClcbiAgICAgIH0sICgpID0+IHt9KVxuICAgIH1cbiAgICB0cnkge1xuICAgICAgY29uc3Qgc2NvcGUgPSBnZXRVc2FnZVByaWNlc1Njb3BlKClcbiAgICAgIGlmIChzY29wZSAmJiB0eXBlb2Ygc2NvcGUuZ2V0U25hcHNob3QgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHNjb3BlLnN1YnNjcmliZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBsZXQgYWRvcHRlZCA9IGZhbHNlXG4gICAgICAgIGNvbnN0IGFkb3B0ID0gKCkgPT4ge1xuICAgICAgICAgIGlmICghY3VycmVudCkgcmV0dXJuXG4gICAgICAgICAgY29uc3Qgc25hcCA9IHNjb3BlLmdldFNuYXBzaG90KClcbiAgICAgICAgICBjb25zdCB2ID0gc25hcCAmJiBzbmFwLnZhbHVlXG4gICAgICAgICAgaWYgKHNuYXAgJiYgc25hcC5zdGF0dXMgPT09ICd1bmF2YWlsYWJsZScpIHJldHVyblxuICAgICAgICAgIGlmICh2ICYmICh2LnByaWNlcyB8fCB2LmN1cnJlbmN5KSkge1xuICAgICAgICAgICAgYWRvcHRlZCA9IHRydWVcbiAgICAgICAgICAgIHNldFByaWNlcyh7IHByaWNlczogdi5wcmljZXMgfHwge30sIGN1cnJlbmN5OiB2LmN1cnJlbmN5IHx8ICfCpScgfSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYWRvcHQoKVxuICAgICAgICBzY29wZURpc3Bvc2UgPSBzY29wZS5zdWJzY3JpYmUoYWRvcHQpXG4gICAgICAgIGlmICghYWRvcHRlZCkgbG9hZFJwYygpIC8vIHNjb3BlIOacquWwsee7qi/ml6DlgLzvvJrlhYjotbAgUlBD77yM6K6i6ZiF5bCx57uq5ZCOIHNjb3BlIOS8mOWFiOimhuebllxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9hZFJwYygpXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9hZFJwYygpIC8vIOaOoua1iy/nu5HlrprlvILluLjvvJrlrozmlbTlm57pgIAgUlBD77yM57ud5LiN5oqb5Ye6XG4gICAgfVxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjdXJyZW50ID0gZmFsc2VcbiAgICAgIGlmIChzY29wZURpc3Bvc2UpIHtcbiAgICAgICAgdHJ5IHsgc2NvcGVEaXNwb3NlKCkgfSBjYXRjaCAoZSkge31cbiAgICAgIH1cbiAgICB9XG4gIH0sIFtyZXRyeV0pXG5cbiAgY29uc3QgcmVsb2FkID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4gc2V0UmV0cnkoKHYpID0+IHYgKyAxKSwgW10pXG5cbiAgY29uc3QgcmVzZXRGaWx0ZXJzID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHNldE1vZGVscyhbXSlcbiAgICBzZXRDdXN0b20oZGVmYXVsdEN1c3RvbSgpKVxuICAgIHNldFJhbmdlKCd0b2RheScpXG4gIH0sIFtdKVxuXG4gIGNvbnN0IGNoYW5nZUN1cnJlbmN5ID0gUmVhY3QudXNlQ2FsbGJhY2soKGNvZGUpID0+IHtcbiAgICBzdG9yZUN1cnJlbmN5KGNvZGUpXG4gICAgc2V0RGlzcGxheUN1cnJlbmN5KGNvZGUpXG4gIH0sIFtdKVxuICAvLyDnrKblj7fku6Xlrr/kuLvlm57kvKDnmoTlrp7pmYXluIHnp43kuLrlh4bvvIjliIfmjaLlkI7nq4vliLvph43mn6XvvIzkuI3kvJrlh7rnjrDjgIzmjaLkuobmoIflv5fmsqHmjaLmlbDlrZfjgI3vvInvvJtcbiAgLy8g6ICB5a6/5Li75rKh5pyJ6K+l5a2X5q615pe25oyJ5pys5Zyw6YCJ5oup5YWc5bqV44CCXG4gIGNvbnN0IGN1cnJlbmN5U3ltYm9sID0gKGRhdGEgJiYgZGF0YS5jdXJyZW5jeSAmJiBkYXRhLmN1cnJlbmN5LnN5bWJvbClcbiAgICB8fCBDVVJSRU5DWV9TWU1CT0xTW2Rpc3BsYXlDdXJyZW5jeV0gfHwgcHJpY2VzLmN1cnJlbmN5IHx8ICfCpSdcblxuICBjb25zdCBidXN5ID0gc3RhdHVzID09PSAnbG9hZGluZycgfHwgc3RhdHVzID09PSAncmVmcmVzaGluZydcbiAgY29uc3QgcmVhZHkgPSBkYXRhICE9PSBudWxsXG4gIGNvbnN0IGlzRXJyb3IgPSBzdGF0dXMgPT09ICdlcnJvcidcbiAgY29uc3QgaXNFbXB0eSA9IHJlYWR5ICYmIGRhdGEuZGFpbHkubGVuZ3RoID09PSAwICYmIGRhdGEuYnlNb2RlbC5sZW5ndGggPT09IDBcblxuICByZXR1cm4gaChULlByb3ZpZGVyLCB7IHZhbHVlOiB0IH0sXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2Qtc2VjdGlvbicsICdhcmlhLWJ1c3knOiBidXN5IHx8IHVuZGVmaW5lZCB9LFxuICAgIGgoU3RhdHNIZWFkZXIsIHsgYnVzeSwgb25SZWZyZXNoOiByZWxvYWQgfSksXG4gICAgaChGaWx0ZXJCYXIsIHtcbiAgICAgIHJhbmdlLFxuICAgICAgY3VzdG9tLFxuICAgICAgbW9kZWxzLFxuICAgICAgY3VzdG9tT3BlbixcbiAgICAgIG1vZGVsT3B0aW9uczogZGF0YSA/IGRhdGEubW9kZWxzIDogW10sXG4gICAgICBvblByZXNldDogKHApID0+IHsgc2V0UmFuZ2UocCk7IHNldEN1c3RvbU9wZW4oZmFsc2UpIH0sXG4gICAgICBvbkN1c3RvbU9wZW46IChvcGVuKSA9PiB7IHNldFJhbmdlKCdjdXN0b20nKTsgc2V0Q3VzdG9tT3BlbihvcGVuKSB9LFxuICAgICAgb25DdXN0b21BcHBseTogKGMpID0+IHsgc2V0Q3VzdG9tKGMpOyBzZXRDdXN0b21PcGVuKGZhbHNlKSB9LFxuICAgICAgb25DdXN0b21DbG9zZTogKCkgPT4gc2V0Q3VzdG9tT3BlbihmYWxzZSksXG4gICAgICBvbk1vZGVsc0NoYW5nZTogc2V0TW9kZWxzLFxuICAgIH0pLFxuICAgIGlzRXJyb3IgJiYgIXJlYWR5XG4gICAgICA/IGgoRXJyb3JTdGF0ZSwgeyBlcnJvciwgb25SZXRyeTogcmVsb2FkIH0pXG4gICAgICA6IG51bGwsXG4gICAgIXJlYWR5ICYmICFpc0Vycm9yXG4gICAgICA/IGgoTG9hZGluZ1N0YXRlLCBudWxsKVxuICAgICAgOiBudWxsLFxuICAgIHJlYWR5ICYmIGlzRXJyb3JcbiAgICAgID8gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtYWxlcnQtYmFubmVyJywgcm9sZTogJ2FsZXJ0JyB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCB0KCdsb2FkRmFpbGVkJywgeyBtZXNzYWdlOiBTdHJpbmcoKGVycm9yICYmIGVycm9yLm1lc3NhZ2UpIHx8IGVycm9yKSB9KSksXG4gICAgICAgICAgaCgnYnV0dG9uJywgeyB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiAndHNkLWJ0biB0c2QtYnRuLWdob3N0Jywgb25DbGljazogcmVsb2FkIH0sIHQoJ3JldHJ5JykpKVxuICAgICAgOiBudWxsLFxuICAgIHJlYWR5ICYmICFpc0Vycm9yICYmIGlzRW1wdHlcbiAgICAgID8gaChFbXB0eVN0YXRlLCB7IGZpbHRlcmVkOiBtb2RlbHMubGVuZ3RoID4gMCwgb25SZXNldDogcmVzZXRGaWx0ZXJzIH0pXG4gICAgICA6IG51bGwsXG4gICAgcmVhZHkgJiYgIWlzRXJyb3IgJiYgIWlzRW1wdHlcbiAgICAgID8gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY29udGVudCcsICdkYXRhLWJ1c3knOiBidXN5ID8gJ3RydWUnIDogdW5kZWZpbmVkIH0sXG4gICAgICAgICAgaChTdW1tYXJ5Q2FyZHMsIHtcbiAgICAgICAgICAgIHRvdGFsOiBkYXRhLnRvdGFsLFxuICAgICAgICAgICAgY3VycmVuY3k6IGN1cnJlbmN5U3ltYm9sLFxuICAgICAgICAgICAgdW5wcmljZWRDYWxsczogZGF0YS51bnByaWNlZENhbGxzIHx8IDAsXG4gICAgICAgICAgICBjdXJyZW5jeUNvZGU6IGRpc3BsYXlDdXJyZW5jeSxcbiAgICAgICAgICAgIG9uQ3VycmVuY3lDaGFuZ2U6IGNoYW5nZUN1cnJlbmN5LFxuICAgICAgICAgICAgYnlNb2RlbDogZGF0YS5ieU1vZGVsLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGgoRGFpbHlDaGFydCwge1xuICAgICAgICAgICAgZGFpbHk6IGRhdGEuZGFpbHksXG4gICAgICAgICAgICBncmFuOiBlZmZHcmFuLFxuICAgICAgICAgICAgc3RlcERheXMsXG4gICAgICAgICAgICBncmFuTGFiZWwsXG4gICAgICAgICAgfSksXG4gICAgICAgICAgaChIZWF0bWFwQ2FyZCwgeyBkYXlzOiBkYXRhLmhlYXRtYXAgfHwgW10gfSksXG4gICAgICAgICAgaChNb2RlbFRhYmxlLCB7IHJvd3M6IGRhdGEuYnlNb2RlbCwgY3VycmVuY3k6IGN1cnJlbmN5U3ltYm9sIH0pKVxuICAgICAgOiBudWxsKSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDorr7nva7pobXlr7zoiKrlm77moIdcbiAqXG4gKiBgc2V0dGluZ3Muc2VjdGlvbmAg5Y+q5oqV5b2xIGlkL29yZGVyL2xhYmVs77yM5a+86Iiq5Zu+5qCH55Sx6K6+572u6aG15oyJIGlkIOeZveWQjeWNleiHquW3sVxuICog5Yaz5a6a77yIZHNoLWNsaWVudC11aS1zZXR0aW5ncy1nZW5lcmFsIOeahCBuYXZJY29u77yJ77yM56ys5LiJ5pa55rKh5pyJ5o+S5Y+j44CC5omA5Lul6L+Z6YeMXG4gKiDnu5njgIzoh6rlt7HpgqPkuIDooYzjgI3miZPkuIDkuKrlsZ7mgKfmoIforrDvvIzlho3nlKggQ1NTIG1hc2sg5oqK5YWc5bqV55qE6b2/6L2u5o2i5oiQ55So6YeP5Zu+5qCH77yaXG4gKiDkuI3mm7/mjaLoioLngrnjgIHkuI3norAgUmVhY3Qg566h55qEIHN2Z++8iOabv+aNouS8muiuqSBSZWFjdCDljbjovb3ml7bmipsgTm90Rm91bmRFcnJvcu+8ie+8jFxuICog5Y+q5Yqg5bGe5oCn44CB5Y+q55SoIDo6YmVmb3JlIOeUu+Wtl+W9ouOAglxuICpcbiAqIOiupOihjOWPquiDveaMieWPr+ingeaWh+acrO+8muexu+WQjeaYryBDU1MgTW9kdWxlcyDlk4jluIzvvIzotKblj7fooYzov5jkvJrmnaHku7blh7rnjrDjgIJcbiAqIOWumOaWueS4gOaXpue7mSBzZXR0aW5ncy5zZWN0aW9uIOWKoOS4iiBpY29uIOWtl+aute+8jOi/meS4quaooeWdl+W6lOaVtOS9k+WIoOmZpOOAglxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuY29uc3QgTkFWX0lDT05fTUFTSyA9ICdkYXRhOmltYWdlL3N2Zyt4bWw7Y2hhcnNldD11dGYtOCwnICsgZW5jb2RlVVJJQ29tcG9uZW50KFxuICAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAxNiAxNlwiPidcbiAgKyAnPHJlY3QgeD1cIjIuNVwiIHk9XCI5XCIgd2lkdGg9XCIyLjVcIiBoZWlnaHQ9XCI1XCIgcng9XCIxXCIvPidcbiAgKyAnPHJlY3QgeD1cIjYuNzVcIiB5PVwiNS41XCIgd2lkdGg9XCIyLjVcIiBoZWlnaHQ9XCI4LjVcIiByeD1cIjFcIi8+J1xuICArICc8cmVjdCB4PVwiMTFcIiB5PVwiMi41XCIgd2lkdGg9XCIyLjVcIiBoZWlnaHQ9XCIxMS41XCIgcng9XCIxXCIvPjwvc3ZnPicsXG4pXG4vLyBtYXNrIOWPquivuyBhbHBoYSDpgJrpgZPvvIzmiYDku6XlrZflvaLlv4XpobvmmK/nuq/oibLlrp7lv4PvvIhpY29uLnN2ZyDnmoTmuJDlj5jkuI7ljYrpgI/mmI7lnKjov5nph4zkvJrkuKLvvIlcbmNvbnN0IE5BVl9JQ09OX0NTUyA9IFtcbiAgJ1tkYXRhLXRzZC1uYXZdID4gc3ZnIHsgZGlzcGxheTogbm9uZTsgfScsXG4gICdbZGF0YS10c2QtbmF2XTo6YmVmb3JlIHsnLFxuICBcIiAgY29udGVudDogJyc7XCIsXG4gICcgIGZsZXg6IG5vbmU7JyxcbiAgJyAgd2lkdGg6IDE2cHg7JyxcbiAgJyAgaGVpZ2h0OiAxNnB4OycsXG4gICcgIGJhY2tncm91bmQ6IGN1cnJlbnRDb2xvcjsnLFxuICAnICAtd2Via2l0LW1hc2staW1hZ2U6IHVybChcIicgKyBOQVZfSUNPTl9NQVNLICsgJ1wiKTsnLFxuICAnICBtYXNrLWltYWdlOiB1cmwoXCInICsgTkFWX0lDT05fTUFTSyArICdcIik7JyxcbiAgJyAgLXdlYmtpdC1tYXNrLXNpemU6IDE2cHggMTZweDsnLFxuICAnICBtYXNrLXNpemU6IDE2cHggMTZweDsnLFxuICAnICAtd2Via2l0LW1hc2stcmVwZWF0OiBuby1yZXBlYXQ7JyxcbiAgJyAgbWFzay1yZXBlYXQ6IG5vLXJlcGVhdDsnLFxuICAnfScsXG5dLmpvaW4oJ1xcbicpXG5cbi8qKiDorqTkuI3lh7rooYzjgIHmi7/kuI3liLAgRE9N77yM6YO95Y+q5piv6YCA5YyW5oiQ6b2/6L2u77yM57ud5LiN5oqb5Ye644CC6L+U5ZueIGRpc3Bvc2Vy44CCICovXG5mdW5jdGlvbiBpbnN0YWxsU2V0dGluZ3NOYXZJY29uKGxhYmVsKSB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiBNdXRhdGlvbk9ic2VydmVyICE9PSAnZnVuY3Rpb24nKSByZXR1cm4gbnVsbFxuICBsZXQgc3R5bGVFbCA9IG51bGxcbiAgdHJ5IHtcbiAgICBzdHlsZUVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKVxuICAgIHN0eWxlRWwuc2V0QXR0cmlidXRlKCdkYXRhLXBsdWdpbicsICdkc2gtcGx1Z2luLXVzYWdlJylcbiAgICBzdHlsZUVsLnRleHRDb250ZW50ID0gTkFWX0lDT05fQ1NTXG4gICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZUVsKVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS53YXJuKCdbdXNhZ2VdIHNldHRpbmdzIG5hdiBpY29uOiBzdHlsZXMgdW5hdmFpbGFibGUnKVxuICAgIHJldHVybiBudWxsXG4gIH1cbiAgY29uc3QgbWFyayA9ICgpID0+IHtcbiAgICBjb25zdCByb3dzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW3JvbGU9XCJkaWFsb2dcIl0gYnV0dG9uJylcbiAgICBjb25zdCB3YW50ID0gbGFiZWwoKVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgcm93ID0gcm93c1tpXVxuICAgICAgaWYgKHJvdy5nZXRBdHRyaWJ1dGUoJ2RhdGEtdHNkLW5hdicpICE9PSBudWxsKSBjb250aW51ZVxuICAgICAgaWYgKCFyb3cucXVlcnlTZWxlY3Rvcignc3ZnJykpIGNvbnRpbnVlIC8vIOWPquagh+W4puWbvuagh+eahOWvvOiIquihjO+8jOWIq+ivr+agh+aZrumAmuaMiemSrlxuICAgICAgaWYgKChyb3cudGV4dENvbnRlbnQgfHwgJycpLnRyaW0oKSAhPT0gd2FudCkgY29udGludWVcbiAgICAgIHJvdy5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHNkLW5hdicsICcnKVxuICAgIH1cbiAgfVxuICBsZXQgb2JzZXJ2ZXIgPSBudWxsXG4gIHRyeSB7XG4gICAgbWFyaygpXG4gICAgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoKSA9PiB7IHRyeSB7IG1hcmsoKSB9IGNhdGNoIChlKSB7fSB9KVxuICAgIG9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQuYm9keSwgeyBjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWUgfSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUud2FybignW3VzYWdlXSBzZXR0aW5ncyBuYXYgaWNvbjogb2JzZXJ2ZXIgdW5hdmFpbGFibGUnLCBlKVxuICB9XG4gIHJldHVybiAoKSA9PiB7XG4gICAgaWYgKG9ic2VydmVyKSBvYnNlcnZlci5kaXNjb25uZWN0KClcbiAgICBpZiAoc3R5bGVFbCkgc3R5bGVFbC5yZW1vdmUoKVxuICAgIGNvbnN0IG1hcmtlZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLXRzZC1uYXZdJylcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hcmtlZC5sZW5ndGg7IGkrKykgbWFya2VkW2ldLnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS10c2QtbmF2JylcbiAgfVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOi+k+WFpeWMuuaIkOacrCBwaWxs77yIY29tcG9zZXIgZG9ja++8iVxuICpcbiAqIERTSCAwLjIuMS1yYy4xIOaKiui+k+WFpeWMuue7n+iuoeaLhuaIkCBgYWN0aXZpdHlgIC8gYHVzYWdlYCDkuKTkuKogY29tcG9zZXIgZG9jayDmnaHnm67vvIxcbiAqIOWuv+S4u+iHquW3seeahCBgdXNhZ2VgIHBpbGwg5pi+56S6IHRva2VuIOaVsO+8iOivu+WumOaWuSBgdG9rZW5Vc2FnZWAg5oqV5b2x77yJ44CC5a6Y5pa55oqV5b2x5Y+q5pyJXG4gKiDkvJror53lhoXlkIjorqHjgIEqKuS4jeW4puaooeWei+W9kuWboCoq77yM6ICM5oiQ5pys5b+F6aG75oyJ5qih5Z6L5Y2V5Lu3566X77yI5pys5o+S5Lu26IeqIHYwLjMg6LW35Z2a5oyBXG4gKiDkuI3mt7fku7fvvInvvIzmiYDku6Xov5nph4zkuI3otbDmipXlvbHvvIzmlLnotbDmnKzmj5Lku7boh6rlt7HnmoQgYHF1ZXJ5YO+8muiusOW9lemHjOW4piBwcm92aWRlci9tb2RlbO+8jFxuICog5a6/5Li75L6n5oyJ5qih5Z6L57K+56Gu6K6h5Lu344CCXG4gKlxuICog5Y+j5b6E5Y+W44CM5LuK5pel44CN6ICM5LiN5piv44CM5pys5Lya6K+d44CN77yaZG9jayDmnaHnm67mi7/kuI3liLDkvJror53moIfor4bvvIjlrr/kuLvmuLLmn5Pov5nkuKogc2xvdCDml7ZcbiAqIOaYryBgcmVuZGVyU2xvdChcImNvbnZlcnNhdGlvbi5jb21wb3Nlci5kb2NrXCIsIHt9KWDvvIzkuI3kvKAgcHJvcHPvvInvvIzogIzku4rml6XmiJDmnKzkuI5cbiAqIOWuv+S4u+eahCB0b2tlbiBwaWxsIOato+WlveS6kuihpeOAglxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuY29uc3QgRE9DS19SRUZSRVNIX01TID0gMzAwMDBcbi8qKiDlm57loavvvIhiYWNrZmlsbO+8iei/m+ihjOS4reeahOW/q+mHjeivlemXtOmalO+8jOS4juiuvue9rumhteS4gOiHtOOAgiAqL1xuY29uc3QgRE9DS19CQUNLRklMTF9SRVRSWV9NUyA9IDMwMDBcblxuZnVuY3Rpb24gQ29zdFBpbGwocHJvcHMpIHtcbiAgY29uc3QgdHIgPSBwcm9wcyAmJiB0eXBlb2YgcHJvcHMudCA9PT0gJ2Z1bmN0aW9uJyA/IHByb3BzLnQgOiBmYWxsYmFja1RcbiAgY29uc3QgW3N0YXRlLCBzZXRTdGF0ZV0gPSBSZWFjdC51c2VTdGF0ZSh7IHN0YXR1czogJ2xvYWRpbmcnIH0pXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgbGV0IGFsaXZlID0gdHJ1ZVxuICAgIGxldCB0aW1lciA9IG51bGxcbiAgICBjb25zdCBzY2hlZHVsZSA9IChtcykgPT4ge1xuICAgICAgaWYgKHRpbWVyICE9PSBudWxsKSBjbGVhclRpbWVvdXQodGltZXIpXG4gICAgICB0aW1lciA9IHNldFRpbWVvdXQobG9hZCwgbXMpXG4gICAgfVxuICAgIGNvbnN0IGxvYWQgPSAoKSA9PiB7XG4gICAgICBpZiAoIWFsaXZlKSByZXR1cm5cbiAgICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKClcbiAgICAgIGhvc3RDYWxsKCd1c2FnZS9xdWVyeScsIHtcbiAgICAgICAgZnJvbTogc3RhcnRPZkRheShub3cpLmdldFRpbWUoKSxcbiAgICAgICAgdG86IG5vdy5nZXRUaW1lKCksXG4gICAgICAgIC8vIOOAjOS7iuaXpeOAjeaYr+aciemZkOWMuumXtO+8jOS9huS4jemcgOmbtuWhq+WFhe+8muepuuahtuWvueaIkOacrOayoeaEj+S5ieOAglxuICAgICAgICBmaWxsOiBmYWxzZSxcbiAgICAgICAgZ3JhbnVsYXJpdHk6ICdkYXknLFxuICAgICAgICBjdXJyZW5jeTogcmVhZFN0b3JlZEN1cnJlbmN5KCksXG4gICAgICB9KVxuICAgICAgICAudGhlbigocikgPT4ge1xuICAgICAgICAgIGlmICghYWxpdmUpIHJldHVyblxuICAgICAgICAgIGNvbnN0IHRvdGFsID0gKHIgJiYgci50b3RhbCkgfHwgbnVsbFxuICAgICAgICAgIHNldFN0YXRlKHtcbiAgICAgICAgICAgIHN0YXR1czogJ3JlYWR5JyxcbiAgICAgICAgICAgIGNhbGxzOiB0b3RhbCA/IHRvdGFsLmNhbGxzIDogMCxcbiAgICAgICAgICAgIHRva2VuczogdG90YWwgPyB0b3RhbC50b3RhbFRva2VucyA6IDAsXG4gICAgICAgICAgICBjb3N0OiB0b3RhbCA/IHRvdGFsLmNvc3QgOiAwLFxuICAgICAgICAgICAgc3ltYm9sOiAociAmJiByLmN1cnJlbmN5ICYmIHIuY3VycmVuY3kuc3ltYm9sKVxuICAgICAgICAgICAgICB8fCBDVVJSRU5DWV9TWU1CT0xTW3JlYWRTdG9yZWRDdXJyZW5jeSgpXVxuICAgICAgICAgICAgICB8fCAnwqUnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgY29uc3QgYmFja2ZpbGxpbmcgPSBCb29sZWFuKHIgJiYgci5iYWNrZmlsbCAmJiByLmJhY2tmaWxsLnN0YXR1cyA9PT0gJ3J1bm5pbmcnKVxuICAgICAgICAgIHNjaGVkdWxlKGJhY2tmaWxsaW5nID8gRE9DS19CQUNLRklMTF9SRVRSWV9NUyA6IERPQ0tfUkVGUkVTSF9NUylcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyDot6/nlLHkuI3lj6/nlKggLyDlrr/kuLvmnKrlsLHnu6rvvJrkuI3njJzmlbDlrZfvvIzkuZ/kuI3miqXplJnlvLnnqpfvvIhkb2NrIOW4uOmpu++8jOS4jeiDveWIt+Wxj++8ieOAglxuICAgICAgICAgIGlmIChhbGl2ZSkge1xuICAgICAgICAgICAgc2V0U3RhdGUoeyBzdGF0dXM6ICdlcnJvcicgfSlcbiAgICAgICAgICAgIHNjaGVkdWxlKERPQ0tfUkVGUkVTSF9NUylcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuICAgIGxvYWQoKVxuICAgIGNvbnN0IG9uVmlzaWJsZSA9ICgpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZSA9PT0gJ3Zpc2libGUnKSBsb2FkKClcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcpIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Zpc2liaWxpdHljaGFuZ2UnLCBvblZpc2libGUpXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGFsaXZlID0gZmFsc2VcbiAgICAgIGlmICh0aW1lciAhPT0gbnVsbCkgY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcpIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Zpc2liaWxpdHljaGFuZ2UnLCBvblZpc2libGUpXG4gICAgfVxuICB9LCBbXSlcbiAgLy8g5LuK5pel5peg6LCD55So77yI5oiW6L+Y5rKh5p+l5Yiw77yJ5bCx5LiN5Y2g5L2N77yaZG9jayDmmK/luLjpqbvljLrvvIznqbogcGlsbCDmr5TmsqHmnInmm7TlkLXjgIJcbiAgaWYgKHN0YXRlLnN0YXR1cyAhPT0gJ3JlYWR5JyB8fCAhc3RhdGUuY2FsbHMpIHJldHVybiBudWxsXG4gIGNvbnN0IHByaWNlZCA9IHN0YXRlLmNvc3QgPiAwXG4gIGNvbnN0IHZhbHVlID0gcHJpY2VkID8gc3RhdGUuc3ltYm9sICsgY29zdERpZ2l0cyhzdGF0ZS5jb3N0KSA6IHRyKCdkb2NrVW5wcmljZWQnKVxuICBjb25zdCBoaW50ID0gdHIoJ2RvY2tIaW50Jywge1xuICAgIGNvc3Q6IHZhbHVlLFxuICAgIGNhbGxzOiBmb3JtYXRJbnQoc3RhdGUuY2FsbHMpLFxuICAgIHRva2VuczogZm9ybWF0SW50KHN0YXRlLnRva2VucyksXG4gIH0pXG4gIHJldHVybiBoKCdzcGFuJywge1xuICAgIGNsYXNzTmFtZTogJ3RzZC1kb2NrJyxcbiAgICB0aXRsZTogaGludCxcbiAgICAnYXJpYS1sYWJlbCc6IGhpbnQsXG4gICAgJ2RhdGEtdXNhZ2UtY29zdCc6IHRydWUsXG4gIH0sXG4gICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWRvY2stbGFiZWwnIH0sIHRyKCd0b2RheScpKSxcbiAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtZG9jay12YWx1ZScgfSwgdmFsdWUpKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOazqOWGjO+8mnNldHRpbmdzLnNlY3Rpb24g6aG16Z2iXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBhcHBseShjdHgpIHtcbiAgdXNhZ2VDdHggPSBjdHhcbiAgX3VzYWdlUHJpY2VzU2NvcGUgPSBudWxsIC8vIOavj+asoea/gOa0u+mHjee7ke+8jOmBv+WFjeWkjeeUqOW3sumHiuaUvueahCBzY29wZVxuICBjdHguZWZmZWN0KCgpID0+IHtcbiAgICBpZiAodHlwZW9mIHN0eWxlcyAhPT0gJ3VuZGVmaW5lZCcgJiYgc3R5bGVzICYmIHR5cGVvZiBzdHlsZXMuaW5zZXJ0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gc3R5bGVzLmluc2VydChDU1MpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJylcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgnZGF0YS1wbHVnaW4nLCAnZHNoLXBsdWdpbi11c2FnZScpXG4gICAgICBlbC50ZXh0Q29udGVudCA9IENTU1xuICAgICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChlbClcbiAgICAgIHJldHVybiAoKSA9PiB7IGVsLnJlbW92ZSgpIH1cbiAgICB9XG4gIH0sICd1c2FnZTogc3R5bGVzJylcbiAgY3R4LmVmZmVjdCgoKSA9PiBjdHgubG9jYWxlLnJlZ2lzdGVyKE5TLCB7IHpoOiBaSCwgZW46IEVOIH0pLCAndXNhZ2U6IGRpY3Rpb25hcmllcycpXG4gIGNvbnN0IHQwID0gY3R4LmxvY2FsZSA/IGN0eC5sb2NhbGUuYmluZChOUykgOiBmYWxsYmFja1RcbiAgY3R4LmVmZmVjdCgoKSA9PiBpbnN0YWxsU2V0dGluZ3NOYXZJY29uKCgpID0+IHQwKCduYXYnKSksICd1c2FnZTogbmF2LWljb24nKVxuICAvLyBjb3JkaXMgY3R4IGlzIGEgc3RyaWN0IHByb3h5OiBESVJFQ1QgcHJvcGVydHkgYWNjZXNzIG9uIGFuIHVuLWluamVjdGVkXG4gIC8vIHNlcnZpY2UgdGhyb3dzIChcImNhbm5vdCBnZXQgcHJvcGVydHkgWCB3aXRob3V0IGluamVjdFwiKSwgc28gYSBiYXJlXG4gIC8vIGBjdHguc2xvdHMgPz8gLi4uYCB3b3VsZCB0aHJvdyBhbmQgc2tpcCB0aGUgZmFsbGJhY2suIFByb2JlIHZpYSB0aGUgc2FmZVxuICAvLyBjdHguZ2V0KCkgZmlyc3Q7IGZhbGwgYmFjayB0byB0aGUgaW5qZWN0ZWQgcHJvcGVydHkgKGF2YWlsYWJsZSBvbmNlXG4gIC8vICdzbG90cycgaXMgZGVjbGFyZWQgaW4gdGhlIGluamVjdCBsaXN0IGJlbG93KS5cbiAgbGV0IHNsb3RzID0gbnVsbFxuICB0cnkge1xuICAgIHNsb3RzID0gdHlwZW9mIGN0eC5nZXQgPT09ICdmdW5jdGlvbicgPyBjdHguZ2V0KCdzbG90cycpIDogbnVsbFxuICB9IGNhdGNoIChlKSB7XG4gICAgc2xvdHMgPSBudWxsXG4gIH1cbiAgaWYgKCFzbG90cyB8fCB0eXBlb2Ygc2xvdHMuaW5qZWN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChjdHguc2xvdHMgJiYgdHlwZW9mIGN0eC5zbG90cy5pbmplY3QgPT09ICdmdW5jdGlvbicpIHNsb3RzID0gY3R4LnNsb3RzXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2xvdHMgPSBudWxsXG4gICAgfVxuICB9XG4gIGlmICghc2xvdHMgfHwgdHlwZW9mIHNsb3RzLmluamVjdCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2Ygc2xvdHMucmVnaXN0ZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zb2xlLndhcm4oJ1t1c2FnZV0gc2V0dGluZ3Muc2VjdGlvbiBzbG90IHVuYXZhaWxhYmxlJylcbiAgICByZXR1cm5cbiAgfVxuICBzbG90cy5pbmplY3QoJ3NldHRpbmdzLnNlY3Rpb24nLCAoKSA9PiBzbG90cy5yZWdpc3RlcihcbiAgICB7IG5hbWU6ICdzZXR0aW5ncy5zZWN0aW9uJywgaWQ6ICd0b2tlbi1zdGF0cycsIG9yZGVyOiAyMCwgbGFiZWw6ICgpID0+IHQwKCduYXYnKSwgbG9jYWxlOiBOUyB9LFxuICAgIChwcm9wcykgPT4gaChTdGF0c0Rhc2hib2FyZCwgcHJvcHMpLFxuICApKVxuXG4gIC8vIOi+k+WFpeWMuuaIkOacrCBwaWxs44CCMC4yLjEg55qEIGNvbXBvc2VyIGRvY2sg5pivIGxpc3Qgc2xvdO+8jOWuv+S4u+iHquW3seWNoOS6hiBhY3Rpdml0eSgwKVxuICAvLyDkuI4gdXNhZ2UoMSnvvIzmj5Lku7bmjpLlnKjlroPku6zkuYvlkI7vvJswLjIuMCDmsqHmnInov5nkuKogc2xvdO+8jOazqOWFpeWksei0peS4jeiDveaLluWeruiuvue9rumhteOAglxuICB0cnkge1xuICAgIHNsb3RzLmluamVjdCgnY29udmVyc2F0aW9uLmNvbXBvc2VyLmRvY2snLCAoKSA9PiBzbG90cy5yZWdpc3RlcihcbiAgICAgIHsgbmFtZTogJ2NvbnZlcnNhdGlvbi5jb21wb3Nlci5kb2NrJywgaWQ6ICd1c2FnZS1jb3N0Jywgb3JkZXI6IDIsIGxvY2FsZTogTlMgfSxcbiAgICAgIChwcm9wcykgPT4gaChDb3N0UGlsbCwgcHJvcHMpLFxuICAgICkpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLndhcm4oJ1t1c2FnZV0gY29tcG9zZXIgZG9jayBzbG90IHVuYXZhaWxhYmxlJywgZSlcbiAgfVxufVxuXG5yZXR1cm4geyBpbmplY3Q6IFsnbG9jYWxlJywgJ3Nsb3RzJ10sIGFwcGx5IH1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
|
|
4676
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbIi9wcml2YXRlL3RtcC9ucG1yZWwvZHNoLXBsdWdpbi11c2FnZS9zcmMvY2xpZW50L2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRva2VuIOeUqOmHj+e7n+iuoSDigJQgc2V0dGluZ3Muc2VjdGlvbiBDbGllbnQgVUnvvIjnuq8gSlPvvIzliqjmgIHmj5Lku7bmspnnrrHvvIlcbi8vIOWPr+eUqOWFqOWxgO+8mlJlYWN0IC8gY3R4IC8gc3R5bGVzIC8gaG9zdCAvIGNvbnNvbGXvvJvmtY/op4jlmajlhajlsYAgRGF0ZSAvIEludGwg562J44CCXG4vLyBDU1Mg5bi46YeP5YaF6IGU6IeqIHN0eWxlcy5qc++8iOWKqOaAgeaPkuS7tuaymeeuseaXoCBpbXBvcnTvvIzmoLflvI/pmo/mnKzmlofku7bliqDovb3vvInjgIJcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmNvbnN0IENTUyA9IGBcbi8qID09PT09PT09PT09PSDluIPlsYAgPT09PT09PT09PT09ICovXG4udHNkLXNlY3Rpb24ge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIHdpZHRoOiAxMDAlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBnYXA6IDE2cHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGFuaW1hdGlvbjogdHNkLWZhZGUtaW4gMC40cyB2YXIoLS1kcy1lYXNlLWluLW91dCk7XG59XG4vKiDliLfmlrDkuK3nmoTpgqPmnaHnu4bov5vluqbmnaHvvJrotLTlnKjmnKzoioLpobbpg6jvvIznu53lr7nlrprkvY3miYDku6XkuI3mjqjliqjniYjpnaLjgIHkuI3norDku7vkvZXmlbDlrZfjgIJcbiAgIOeUqOWug+iAjOS4jeaYr+aKiuaVtOWdl+WGheWuueWOi+aalyDigJTigJQg5bey5pyJ5pWw5a2X5pys5p2l5bCx5piv5a+555qE77yM5Y6L5pqX5Y+q6K6p5Lq65Lul5Li65Zyo6YeN566X44CCICovXG4udHNkLXByb2dyZXNzIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBpbnNldDogLTZweCAwIGF1dG8gMDtcbiAgaGVpZ2h0OiAycHg7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KSAxOCUsIHRyYW5zcGFyZW50KTtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG4udHNkLXByb2dyZXNzOjphZnRlciB7XG4gIGNvbnRlbnQ6ICcnO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGluc2V0OiAwIGF1dG8gMCAwO1xuICB3aWR0aDogMzUlO1xuICBib3JkZXItcmFkaXVzOiBpbmhlcml0O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7XG4gIGFuaW1hdGlvbjogdHNkLWluZGV0ZXJtaW5hdGUgMS4ycyB2YXIoLS1kcy1lYXNlLWluLW91dCkgaW5maW5pdGU7XG59XG4vKiDnn6XpgZPliIbmr43ml7bmlLnmiJDnoa7lrprov5vluqbvvJrlrr3luqblsLHmmK8gZG9uZS90b3RhbO+8jOS4jeWGjeadpeWbnuaJqyDigJTigJQg55So5oi355yL5Yiw55qEXG4gICBcIueul+WIsOWTquS6hlwi5piv55yf55qE77yM6ICM5LiN5piv5LiA5Liq6KOF5b+Z55qE5Yqo55S744CCICovXG4udHNkLXByb2dyZXNzW2RhdGEtZGV0ZXJtaW5hdGU9dHJ1ZV06OmFmdGVyIHtcbiAgd2lkdGg6IHZhcigtLXRzZC1wcm9ncmVzcywgMCUpO1xuICBhbmltYXRpb246IG5vbmU7XG4gIHRyYW5zZm9ybTogbm9uZTtcbiAgdHJhbnNpdGlvbjogd2lkdGggMjQwbXMgdmFyKC0tZHMtZWFzZS1pbi1vdXQpO1xufVxuQGtleWZyYW1lcyB0c2QtaW5kZXRlcm1pbmF0ZSB7XG4gIGZyb20geyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTQwJSk7IH1cbiAgdG8geyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMzAwJSk7IH1cbn1cbkBrZXlmcmFtZXMgdHNkLWZhZGUtaW4ge1xuICBmcm9tIHsgb3BhY2l0eTogMDsgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDhweCk7IH1cbiAgdG8geyBvcGFjaXR5OiAxOyB0cmFuc2Zvcm06IG5vbmU7IH1cbn1cblxuLyogPT09PT09PT09PT09IEhlYWRlciA9PT09PT09PT09PT0gKi9cbi50c2QtaGVhZGVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIGdhcDogMTJweDtcbiAgZmxleC13cmFwOiB3cmFwO1xufVxuLnRzZC10aXRsZSB7XG4gIG1hcmdpbjogMDtcbiAgZm9udC1zaXplOiAyNHB4O1xuICBmb250LXdlaWdodDogNzAwO1xuICBsZXR0ZXItc3BhY2luZzogLTAuMDJlbTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbn1cbi50c2Qtc3VidGl0bGUge1xuICBtYXJnaW46IDRweCAwIDA7XG4gIGZvbnQtc2l6ZTogMTRweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xufVxuLnRzZC1pY29uLWJ0biB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgd2lkdGg6IDI4cHg7XG4gIGhlaWdodDogMjhweDtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyOiAxcHggc29saWQgdHJhbnNwYXJlbnQ7XG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBmb250OiBpbmhlcml0O1xufVxuLnRzZC1pY29uLWJ0bjpob3ZlciB7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7XG59XG4udHNkLWljb24tYnRuOmRpc2FibGVkIHtcbiAgY3Vyc29yOiBkZWZhdWx0O1xuICBvcGFjaXR5OiAwLjY7XG59XG4udHNkLWljb24tYnRuOmRpc2FibGVkOmhvdmVyIHtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbn1cbi50c2Qtc3Bpbm5pbmcgc3ZnIHtcbiAgYW5pbWF0aW9uOiB0c2Qtc3BpbiAwLjlzIGxpbmVhciBpbmZpbml0ZTtcbn1cbkBrZXlmcmFtZXMgdHNkLXNwaW4ge1xuICB0byB7IHRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7IH1cbn1cblxuLyogPT09PT09PT09PT09IOetm+mAieagjyA9PT09PT09PT09PT0gKi9cbi50c2QtZmlsdGVyYmFyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA4cHg7XG4gIGZsZXgtd3JhcDogd3JhcDtcbn1cbi50c2Qtc2VnLXdyYXAge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xufVxuLnRzZC1zZWcge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgZ2FwOiAycHg7XG4gIHBhZGRpbmc6IDRweDtcbiAgYm9yZGVyLXJhZGl1czogMTBweDtcbiAgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSkgMTIlLCB0cmFuc3BhcmVudCk7XG59XG4udHNkLXNlZy1idG4ge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgaGVpZ2h0OiAyOHB4O1xuICBwYWRkaW5nOiAwIDEycHg7XG4gIGJvcmRlcjogbm9uZTtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgYm9yZGVyLXJhZGl1czogOHB4O1xuICBmb250OiBpbmhlcml0O1xuICBmb250LXNpemU6IDEzcHg7XG4gIGxpbmUtaGVpZ2h0OiAxO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG4udHNkLXNlZy1idG46aG92ZXIge1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpO1xufVxuLnRzZC1zZWctYWN0aXZlIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWJhc2UpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWJyYW5kLXByaW1hcnkpO1xuICBmb250LXdlaWdodDogNjAwO1xuICBib3gtc2hhZG93OiB2YXIoLS1kc3ctc2hhZG93LWx2MSk7XG59XG4udHNkLXNlZy1jdXN0b20ge1xuICBtYXgtd2lkdGg6IDIyMHB4O1xufVxuLnRzZC1zZWctY3VzdG9tIC50c2Qtc2VnLWxhYmVsIHtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG4udHNkLXNlZy1jdXN0b20udHNkLXNlZy1hY3RpdmUge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeS1pbnZlcnRlZCwgI2ZmZik7XG59XG4udHNkLXNlZy1jdXN0b20udHNkLXNlZy1hY3RpdmU6aG92ZXIge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYnV0dG9uLXByaW1hcnktaG92ZXIpO1xufVxuXG4vKiA9PT09PT09PT09PT0g6YCa55So5oyJ6ZKuID09PT09PT09PT09PSAqL1xuLnRzZC1idG4ge1xuICBoZWlnaHQ6IDMwcHg7XG4gIHBhZGRpbmc6IDAgMTRweDtcbiAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0xKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbiAgYm9yZGVyLXJhZGl1czogOHB4O1xuICBmb250OiBpbmhlcml0O1xuICBmb250LXNpemU6IDEzcHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi50c2QtYnRuOmhvdmVyIHsgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTsgfVxuLnRzZC1idG46ZGlzYWJsZWQgeyBvcGFjaXR5OiAwLjU7IGN1cnNvcjogbm90LWFsbG93ZWQ7IH1cbi50c2QtYnRuLXByaW1hcnkge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYnV0dG9uLXByaW1hcnktZmlsbCk7XG4gIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeS1pbnZlcnRlZCwgI2ZmZik7XG59XG4udHNkLWJ0bi1wcmltYXJ5OmhvdmVyIHsgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJ1dHRvbi1wcmltYXJ5LWhvdmVyKTsgfVxuLnRzZC1idG4tZ2hvc3QgeyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgfVxuLnRzZC1idG4tZ2hvc3Q6aG92ZXIgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpOyB9XG5cbi8qID09PT09PT09PT09PSDmta7lsYIgUG9wb3ZlciA9PT09PT09PT09PT0gKi9cbi50c2QtcG9wb3Zlci1hbmNob3Ige1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xufVxuLnRzZC1wb3BvdmVyIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IGNhbGMoMTAwJSArIDZweCk7XG4gIGxlZnQ6IDA7XG4gIHotaW5kZXg6IDQwO1xuICBwYWRkaW5nOiAxMnB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLW92ZXJsYXkpO1xuICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICBib3gtc2hhZG93OiB2YXIoLS1kc3ctc2hhZG93LWx2Myk7XG59XG4udHNkLW1vZGVsLXBvcG92ZXIge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICB3aWR0aDogMzIwcHg7XG4gIG1heC13aWR0aDogY2FsYygxMDB2dyAtIDI0cHgpO1xufVxuLyog5rWu5bGC6auY5bqm55SxIHVzZUZpeGVkUGFuZWwg55qEIG1heEhlaWdodCDlhrPlrprvvJrlj6rmnInliJfooajlj6/kvLjnvKnvvIzlhbbkvZnpg6jliIbkuI3ljovnvKkgKi9cbi50c2QtbW9kZWwtcG9wb3ZlciA+IC50c2QtcG9wb3Zlci10b29scyxcbi50c2QtbW9kZWwtcG9wb3ZlciA+IC50c2Qtc2VhcmNoLFxuLnRzZC1tb2RlbC1wb3BvdmVyID4gLnRzZC1wb3BvdmVyLW5vdGUsXG4udHNkLW1vZGVsLXBvcG92ZXIgPiAudHNkLXBvcG92ZXItZW1wdHkgeyBmbGV4OiBub25lOyB9XG4udHNkLXJhbmdlLXBvcG92ZXIge1xuICB3aWR0aDogMzAwcHg7XG4gIG1heC13aWR0aDogY2FsYygxMDB2dyAtIDI0cHgpO1xufVxuLnRzZC1wb3BvdmVyLXRpdGxlIHtcbiAgZm9udC1zaXplOiAxNHB4O1xuICBmb250LXdlaWdodDogNjAwO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBtYXJnaW46IDAgMCAxMHB4O1xufVxuLnRzZC1wb3BvdmVyLXRvb2xzIHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICBtYXJnaW4tYm90dG9tOiA4cHg7XG59XG4udHNkLWxpbmstYnRuIHtcbiAgYm9yZGVyOiBub25lO1xuICBiYWNrZ3JvdW5kOiBub25lO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLXN0YXRlLWJ1c2luZXNzLXByaW1hcnkpO1xuICBmb250OiBpbmhlcml0O1xuICBmb250LXNpemU6IDEycHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgcGFkZGluZzogMnB4IDRweDtcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xufVxuLnRzZC1saW5rLWJ0bjpob3ZlciB7IGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7IH1cbi50c2QtcG9wb3Zlci1hY3Rpb25zIHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBmbGV4LWVuZDtcbiAgZ2FwOiA4cHg7XG4gIG1hcmdpbi10b3A6IDEycHg7XG59XG4udHNkLXBvcG92ZXItbm90ZSB7XG4gIG1hcmdpbjogOHB4IDAgMDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbn1cbi50c2QtcG9wb3Zlci1lbXB0eSB7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZzogMTBweCAwO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG59XG5cbi8qID09PT09PT09PT09PSDmqKHlnovkuIvmi4nmkJzntKIgPT09PT09PT09PT09ICovXG4udHNkLXNlbGVjdC1idG4ge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA2cHg7XG4gIG1pbi13aWR0aDogMTIwcHg7XG4gIG1heC13aWR0aDogMjYwcHg7XG4gIGhlaWdodDogMzZweDtcbiAgcGFkZGluZzogMCAxMHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTEpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuLnRzZC1zZWxlY3QtYnRuOmhvdmVyIHsgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwzKTsgfVxuLnRzZC1zZWxlY3QtaGFzIHsgYm9yZGVyLWNvbG9yOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZHN3LWFsaWFzLWJyYW5kLXByaW1hcnkpIDQ1JSwgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMikpOyB9XG4udHNkLXNlbGVjdC1sYWJlbCB7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICBtaW4td2lkdGg6IDA7XG59XG4udHNkLWNoZXZyb24ge1xuICBmbGV4OiBub25lO1xuICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gdmFyKC0tZHMtdHJhbnNpdGlvbi1kdXJhdGlvbi1mYXN0KSB2YXIoLS1kcy1lYXNlLWluLW91dCk7XG59XG4udHNkLWNoZXZyb24tb3BlbiB7IHRyYW5zZm9ybTogcm90YXRlKDE4MGRlZyk7IH1cbi50c2Qtc2VhcmNoIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBtYXJnaW4tYm90dG9tOiA4cHg7XG59XG4udHNkLXNlYXJjaC1pY29uIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBsZWZ0OiA4cHg7XG4gIHRvcDogNTAlO1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTUwJSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cbi50c2Qtc2VhcmNoIGlucHV0IHtcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMzJweDtcbiAgcGFkZGluZzogMCA4cHggMCAyOHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTEpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgb3V0bGluZTogbm9uZTtcbn1cbi50c2Qtc2VhcmNoIGlucHV0OmZvY3VzIHtcbiAgYm9yZGVyLWNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtYnVzaW5lc3MtcHJpbWFyeSk7XG4gIGJveC1zaGFkb3c6IDAgMCAwIDJweCBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZHN3LWFsaWFzLXN0YXRlLWJ1c2luZXNzLXByaW1hcnkpIDE4JSwgdHJhbnNwYXJlbnQpO1xufVxuLnRzZC1tb2RlbC1saXN0IHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZmxleDogMSAxIGF1dG87XG4gIG1pbi1oZWlnaHQ6IDA7XG4gIGdhcDogMnB4O1xuICBtYXgtaGVpZ2h0OiAyNDBweDtcbiAgb3ZlcmZsb3cteTogYXV0bztcbiAgLS1kc2gtc2Nyb2xsYmFyLXRodW1iOiB2YXIoLS1kc3ctYWxpYXMtc2Nyb2xsYmFyLWJnLWwyKTtcbiAgLS1kc2gtc2Nyb2xsYmFyLXRodW1iLWhvdmVyOiB2YXIoLS1kc3ctYWxpYXMtc2Nyb2xsYmFyLWhvdmVyLWwyKTtcbn1cbi50c2QtbW9kZWwtaXRlbSB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogOHB4O1xuICBwYWRkaW5nOiA1cHggNnB4O1xuICBib3JkZXItcmFkaXVzOiA2cHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgZm9udC1zaXplOiAxM3B4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBtaW4td2lkdGg6IDA7XG59XG4udHNkLW1vZGVsLWl0ZW06aG92ZXIgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpOyB9XG4udHNkLW1vZGVsLWl0ZW0gaW5wdXQgeyBtYXJnaW46IDA7IGFjY2VudC1jb2xvcjogdmFyKC0tZHN3LWFsaWFzLWJyYW5kLXByaW1hcnkpOyB9XG4udHNkLW1vZGVsLW5hbWUge1xuICBmb250LWZhbWlseTogdmFyKC0tZHMtZm9udC1mYW1pbHktY29kZSk7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIG1pbi13aWR0aDogMDtcbn1cblxuLyogPT09PT09PT09PT09IOW4geenjeWIh+aNou+8iOWPguiAg+aIkOacrOWNoeaVsOWAvOihjOWGhe+8iSA9PT09PT09PT09PT0gKi9cbi8qIOaVsOWAvOihjOacgOWJjeWPquaUvuS4gOS4quOAjOespuWPtyArIOWwj+eureWktOOAjeeahOWbvuagh+W8j+inpuWPkeWZqO+8muespuWPt+acrOi6q+WwseaYr+ivu+aVsOeahOS4gOmDqOWIhu+8jFxuICAg5bC65a+4L+Wtl+mHjS/ln7rnur/nu6fmib/mlbDlgLzooYzvvIzor7votbfmnaXlg4/mlbDlrZfliY3nvIDogIzkuI3mmK/kuIDkuKrmjqfku7bjgIJcbiAgIOespuWPt+WPquWcqOi/memHjOeUu+S4gOasoe+8jGZvcm1hdENvc3Qg5LiN5YaN6YeN5aSN5bim56ym5Y+344CCICovXG4udHNkLWN1ci1hbmNob3Ige1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xufVxuLnRzZC1jdXItYnRuIHtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGFsaWduLWl0ZW1zOiBiYXNlbGluZTtcbiAgZ2FwOiAzcHg7XG4gIG1hcmdpbjogMCAycHggMCAwO1xuICBwYWRkaW5nOiAwIDJweDtcbiAgYm9yZGVyOiBub25lO1xuICBib3JkZXItcmFkaXVzOiA2cHg7XG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICBjb2xvcjogaW5oZXJpdDtcbiAgZm9udDogaW5oZXJpdDtcbiAgbGluZS1oZWlnaHQ6IGluaGVyaXQ7XG4gIHZlcnRpY2FsLWFsaWduOiBiYXNlbGluZTtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICB0cmFuc2l0aW9uOiBjb2xvciAwLjE1cyBlYXNlLCBiYWNrZ3JvdW5kIDAuMTVzIGVhc2U7XG59XG4udHNkLWN1ci1idG46aG92ZXIsXG4udHNkLWN1ci1idG4tb3BlbiB7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7XG59XG4udHNkLWN1ci1idG46Zm9jdXMtdmlzaWJsZSB7XG4gIG91dGxpbmU6IDJweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7XG4gIG91dGxpbmUtb2Zmc2V0OiAxcHg7XG59XG4udHNkLWN1ci1jaGV2cm9uIHtcbiAgZmxleDogbm9uZTtcbiAgYWxpZ24tc2VsZjogY2VudGVyO1xuICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4xNXMgZWFzZTtcbn1cbi50c2QtY3VyLWJ0bi1vcGVuIC50c2QtY3VyLWNoZXZyb24geyB0cmFuc2Zvcm06IHJvdGF0ZSgxODBkZWcpOyB9XG4udHNkLWN1ci1wb3BvdmVyIHtcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgd2lkdGg6IDE4MHB4O1xuICBtYXgtd2lkdGg6IGNhbGMoMTAwdncgLSAyNHB4KTtcbiAgcGFkZGluZzogNnB4O1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBnYXA6IDJweDtcbiAgLyog5rWu5bGC5oyC5ZyoIC50c2QtY2FyZC12YWx1ZSDph4zvvIzpgqPovrnkuLrkuobmlbDlgLzooYzlhpnkuoYgbm93cmFw77ybXG4gICAgIOa1ruWxgumHjOeahOiPnOWNlemhueS4juivtOaYjuW/hemhu+aBouWkjeaNouihjO+8jOWQpuWImemVv+aWh+ahiOS8muaoquedgOa6ouWHuua1ruWxguOAgiAqL1xuICB3aGl0ZS1zcGFjZTogbm9ybWFsO1xufVxuLnRzZC1jdXItb3B0aW9uIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA4cHg7XG4gIHBhZGRpbmc6IDdweCA5cHg7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLXJhZGl1czogOHB4O1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbiAgZm9udDogaW5oZXJpdDtcbiAgZm9udC1zaXplOiAxM3B4O1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG4udHNkLWN1ci1vcHRpb246aG92ZXIgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpOyB9XG4udHNkLWN1ci1vcHRpb246Zm9jdXMtdmlzaWJsZSB7XG4gIG91dGxpbmU6IDJweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7XG4gIG91dGxpbmUtb2Zmc2V0OiAxcHg7XG59XG4udHNkLWN1ci1zeW1ib2wge1xuICBmbGV4OiBub25lO1xuICB3aWR0aDogMjBweDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBmb250LXdlaWdodDogNjAwO1xufVxuLnRzZC1jdXItbmFtZSB7XG4gIG1pbi13aWR0aDogMDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgZm9udC1zaXplOiAxMnB4O1xufVxuLnRzZC1jdXItb3B0aW9uLWFjdGl2ZSB7IGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7IH1cbi50c2QtY3VyLWNoZWNrIHtcbiAgbWFyZ2luLWxlZnQ6IGF1dG87XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSk7XG59XG5cbi8qID09PT09PT09PT09PSDmqKHlnovljaDmr5TvvIhLUEkg5Y2h56ysIDYg5qC877yJID09PT09PT09PT09PSAqL1xuLyog5Li75L2T5piv5Y2g5q+U5p2h77yM5LiL5pa55qih5Z6L5ZCN5LiO55m+5YiG5q+U5Y6L5oiQ6ISa5rOo77yIMTFweCB0ZXJ0aWFyee+8ie+8jFxuICAg5LiO5YW25a6D5Y2h55qE5aSn5pWw5a2X5b2i5oiQ5bGC57qn5beu77yM5LiN5oqiIEtQSSDnmoTor7vmlbDkvY3nva7jgIIgKi9cbi50c2QtY2FyZC1zaGFyZS1ib2R5IHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiA4cHg7XG4gIG1pbi13aWR0aDogMDtcbiAgLyog5a+56b2QIC50c2QtY2FyZC12YWx1ZSDnmoTkuIrovrnot53vvIzlha3lvKDljaHkv53mjIHlkIzkuIDln7rnur8gKi9cbiAgbWFyZ2luLXRvcDogOHB4O1xufVxuLnRzZC1zaGFyZS10cmFjayB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBzdHJldGNoO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMHB4O1xuICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTtcbn1cbi50c2Qtc2hhcmUtc2VnIHtcbiAgaGVpZ2h0OiAxMDAlO1xuICBtaW4td2lkdGg6IDJweDtcbiAgb3V0bGluZTogbm9uZTtcbiAgb3BhY2l0eTogMC45O1xuICB0cmFuc2l0aW9uOiBvcGFjaXR5IDAuMTJzIGVhc2U7XG59XG4udHNkLXNoYXJlLXNlZzpob3Zlcixcbi50c2Qtc2hhcmUtc2VnOmZvY3VzLXZpc2libGUsXG4udHNkLXNoYXJlLXNlZ1tkYXRhLWFjdGl2ZT0ndHJ1ZSddIHsgb3BhY2l0eTogMTsgfVxuLnRzZC1zaGFyZS1jYXB0aW9uIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGJhc2VsaW5lO1xuICBnYXA6IDZweDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBsaW5lLWhlaWdodDogMTZweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG59XG4udHNkLXNoYXJlLWNhcC1uYW1lIHtcbiAgbWluLXdpZHRoOiAwO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi50c2Qtc2hhcmUtY2FwLXBjdCB7XG4gIGZsZXg6IG5vbmU7XG4gIGZvbnQtdmFyaWFudC1udW1lcmljOiB0YWJ1bGFyLW51bXM7XG59XG4udHNkLXNoYXJlLWVtcHR5IHtcbiAgZm9udC1zaXplOiAxNHB4O1xuICBmb250LXdlaWdodDogNDAwO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbn1cblxuLyogPT09PT09PT09PT09IOiHquWumuS5ieaXpeacn+a1ruWxgiA9PT09PT09PT09PT0gKi9cbi50c2QtcmFuZ2UtZmllbGRzIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiAxMHB4O1xufVxuLnRzZC1maWVsZCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogNHB4O1xufVxuLnRzZC1maWVsZC1sYWJlbCB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xufVxuLnRzZC1maWVsZCBpbnB1dCB7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDMycHg7XG4gIHBhZGRpbmc6IDAgOHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTEpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgb3V0bGluZTogbm9uZTtcbn1cbi50c2QtZmllbGQgaW5wdXQ6Zm9jdXMge1xuICBib3JkZXItY29sb3I6IHZhcigtLWRzdy1hbGlhcy1zdGF0ZS1idXNpbmVzcy1wcmltYXJ5KTtcbiAgYm94LXNoYWRvdzogMCAwIDAgMnB4IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtYnVzaW5lc3MtcHJpbWFyeSkgMTglLCB0cmFuc3BhcmVudCk7XG59XG4udHNkLWZpZWxkLWVycm9yIHtcbiAgbWFyZ2luOiA2cHggMCAwO1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtZXJyb3ItcHJpbWFyeSk7XG59XG4udHNkLWZpZWxkLWhpbnQge1xuICBtYXJnaW46IDZweCAwIDA7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG59XG5cbi8qID09PT09PT09PT09PSDmsYfmgLvmjIfmoIfljaEgPT09PT09PT09PT09ICovXG4udHNkLWNhcmRzIHtcbiAgZGlzcGxheTogZ3JpZDtcbiAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiByZXBlYXQoYXV0by1maXQsIG1pbm1heCgxNTBweCwgMWZyKSk7XG4gIGdhcDogMTBweDtcbn1cbi50c2QtY2FyZCB7XG4gIG1pbi13aWR0aDogMDtcbiAgcGFkZGluZzogMTRweCAxNnB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTMpO1xuICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICBib3gtc2hhZG93OiB2YXIoLS1kc3ctc2hhZG93LWx2MSk7XG59XG4udHNkLWNhcmQtaGVhZCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogNnB4O1xufVxuLnRzZC1jYXJkLWljb24ge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbn1cbi50c2QtY2FyZC1sYWJlbCB7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi8qIOagh+mimOW4puaPkOekuuaXtue7meS4gOS4quWPr+WPkeeOsOeahOiusOWPt++8muiZmue6v+W6lei+uSArIOaEn+WPueWPt+aMiemSru+8iOingSBIaW50VGlw77yJ44CCXG4gICDmgqzmta7nlKjljp/nlJ8gdGl0bGXvvIzngrnlh7vlsZXlvIDmta7lsYLvvJvkuKTmrrXop4TliJnpg73lnKjov5nkuIDkuKrnu4Tku7bph4zvvIzliKvlpITkuI3lho3lkITnlLvkuIDku73jgIIgKi9cbi50c2QtY2FyZC1sYWJlbFt0aXRsZV0ge1xuICBjdXJzb3I6IGhlbHA7XG4gIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lIGRvdHRlZDtcbiAgdGV4dC11bmRlcmxpbmUtb2Zmc2V0OiAycHg7XG59XG4udHNkLWhpbnQge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbn1cbi50c2QtaGludC1idG4ge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIHdpZHRoOiAxNnB4O1xuICBoZWlnaHQ6IDE2cHg7XG4gIHBhZGRpbmc6IDA7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLXJhZGl1czogNTAlO1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIGN1cnNvcjogaGVscDtcbn1cbi50c2QtaGludC1idG46aG92ZXIsXG4udHNkLWhpbnQtYnRuLW9wZW4ge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xufVxuLnRzZC1oaW50LWJ0bjpmb2N1cy12aXNpYmxlIHtcbiAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTtcbiAgb3V0bGluZS1vZmZzZXQ6IDFweDtcbn1cbi8qIOa1ruWxgumHjOS4pOauteinhOWImeWIhuauteivu++8m+ihjOeahOW3puWPs+WGhei+uei3neeUsSAudHNkLXBvcG92ZXIg57uZ77yM6L+Z6YeM5Y+q6KGl5q616Ze06LedICovXG4udHNkLWhpbnQtbGluZSB7XG4gIG1hcmdpbjogMDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBsaW5lLWhlaWdodDogMS41O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG59XG4udHNkLWhpbnQtbGluZSArIC50c2QtaGludC1saW5lIHtcbiAgbWFyZ2luLXRvcDogNnB4O1xufVxuLnRzZC1jYXJkLXZhbHVlIHtcbiAgbWFyZ2luLXRvcDogOHB4O1xuICBmb250LXNpemU6IDIwcHg7XG4gIGZvbnQtd2VpZ2h0OiA3MDA7XG4gIGxldHRlci1zcGFjaW5nOiAtMC4wMWVtO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xuICBmb250LXZhcmlhbnQtbnVtZXJpYzogdGFidWxhci1udW1zO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi50c2QtY2FyZC1zdWIge1xuICBtYXJnaW4tdG9wOiA0cHg7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG59XG4udHNkLWNhcmQtbm90ZSB7XG4gIG1hcmdpbi10b3A6IDRweDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgbGluZS1oZWlnaHQ6IDEuMzU7XG59XG4vKiDmnKrlrprku7fmmK/jgIzlsJHnrpfkuobpkrHjgI3vvIzkuI3mmK/mma7pgJrmj5DnpLrvvJrlhbbkvZnohJrms6jnlKjkuInnuqfngbDvvIzov5nkuIDooYznlKjorabnpLroibIgKi9cbi50c2QtY2FyZC1ub3RlLXdhcm4ge1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLXN0YXRlLXdhcm4tcHJpbWFyeSk7XG59XG4udHNkLWNhcmQtbm90ZXMge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBnYXA6IDJweDtcbn1cbi8qIOWPguiAg+aIkOacrOWNoeeahOWFpeWPo+aMiemSru+8mui3n+edgOagh+mimOi1sO+8jOS4jeaKouaVsOWAvOihjOeahOS9jee9riAqL1xuLnRzZC1jYXJkLWFjdGlvbiB7XG4gIG1hcmdpbi1sZWZ0OiBhdXRvO1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIHdpZHRoOiAyMHB4O1xuICBoZWlnaHQ6IDIwcHg7XG4gIHBhZGRpbmc6IDA7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLXJhZGl1czogNXB4O1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cbi50c2QtY2FyZC1hY3Rpb246aG92ZXIge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xufVxuLnRzZC1jYXJkLWFjdGlvbjpmb2N1cy12aXNpYmxlIHtcbiAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTtcbiAgb3V0bGluZS1vZmZzZXQ6IDFweDtcbn1cblxuLyogPT09PT09PT09PT09IOWNoeeJh+WktOmDqO+8iOWbvuihqCAvIOihqOagvOWFseeUqO+8iSA9PT09PT09PT09PT0gKi9cbi50c2QtY2FyZC1oZWFkZXIge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gIGdhcDogOHB4O1xuICBtYXJnaW4tYm90dG9tOiAxMnB4O1xufVxuLnRzZC1jYXJkLXRpdGxlIHtcbiAgbWFyZ2luOiAwO1xuICBmb250LXNpemU6IDE1cHg7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG59XG4udHNkLWNhcmQtdGFnIHtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG59XG5cbi8qID09PT09PT09PT09PSDmr4/ml6XnlKjph4/mn7Hnirblm74gPT09PT09PT09PT09ICovXG4udHNkLWNoYXJ0LWNhcmQgeyBwYWRkaW5nOiAxNHB4IDE2cHggMTBweDsgfVxuLnRzZC1sZWdlbmQge1xuICBkaXNwbGF5OiBmbGV4O1xuICBnYXA6IDE0cHg7XG4gIG1hcmdpbi1ib3R0b206IDhweDtcbn1cbi50c2QtbGVnZW5kLWl0ZW0ge1xuICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA2cHg7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xufVxuLnRzZC1sZWdlbmQtZG90LFxuLnRzZC10b29sdGlwLWRvdCB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgd2lkdGg6IDEwcHg7XG4gIGhlaWdodDogMTBweDtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xuICBmbGV4OiBub25lO1xufVxuLnRzZC1sZWdlbmQtaW4geyBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCk7IH1cbi50c2QtbGVnZW5kLW91dCB7IGJhY2tncm91bmQ6IHZhcigtLWRzdy1zdGF0aWMtZ3JlZW4tNTAwKTsgfVxuLnRzZC1sZWdlbmQtdG90YWwgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTsgfVxuXG4udHNkLWNoYXJ0IHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogc3RyZXRjaDtcbiAgZ2FwOiAycHg7XG4gIGhlaWdodDogMjQwcHg7XG4gIHBhZGRpbmc6IDAgNHB4O1xufVxuLnRzZC1jaGFydC1jb2wge1xuICBmbGV4OiAxO1xuICBtaW4td2lkdGg6IDA7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgY3Vyc29yOiBkZWZhdWx0O1xuICB0cmFuc2l0aW9uOiBvcGFjaXR5IHZhcigtLWRzLXRyYW5zaXRpb24tZHVyYXRpb24tZmFzdCkgdmFyKC0tZHMtZWFzZS1pbi1vdXQpO1xufVxuLnRzZC1jaGFydC1jb2w6Zm9jdXMtdmlzaWJsZSB7XG4gIG91dGxpbmU6IDJweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtYnVzaW5lc3MtcHJpbWFyeSk7XG4gIG91dGxpbmUtb2Zmc2V0OiAycHg7XG59XG4udHNkLWNoYXJ0OmhvdmVyIC50c2QtY2hhcnQtY29sIHsgb3BhY2l0eTogMC40OyB9XG4udHNkLWNoYXJ0OmhvdmVyIC50c2QtY2hhcnQtY29sOmhvdmVyLFxuLnRzZC1jaGFydDpmb2N1cy13aXRoaW4gLnRzZC1jaGFydC1jb2w6Zm9jdXMgeyBvcGFjaXR5OiAxOyB9XG5cbi50c2QtY2hhcnQtcGxvdCB7XG4gIGZsZXg6IDE7XG4gIHdpZHRoOiAxMDAlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogZmxleC1lbmQ7XG4gIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIGJhY2tncm91bmQtaW1hZ2U6IGxpbmVhci1ncmFkaWVudCh0byB0b3AsIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDEpIDFweCwgdHJhbnNwYXJlbnQgMXB4KTtcbiAgYmFja2dyb3VuZC1zaXplOiAxMDAlIDI1JTtcbiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbn1cbi50c2QtY2hhcnQtc3RhY2sge1xuICB3aWR0aDogNjIlO1xuICBoZWlnaHQ6IDEwMCU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7XG59XG4udHNkLWNoYXJ0LXNlZyB7XG4gIHdpZHRoOiAxMDAlO1xufVxuLnRzZC1zZWctaW4ge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCk7XG59XG4udHNkLXNlZy1vdXQge1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctc3RhdGljLWdyZWVuLTUwMCk7XG4gIGJvcmRlci1yYWRpdXM6IDNweCAzcHggMCAwO1xufVxuLnRzZC1jaGFydC1sYWJlbCB7XG4gIGhlaWdodDogMTRweDtcbiAgbGluZS1oZWlnaHQ6IDE0cHg7XG4gIG1hcmdpbi10b3A6IDZweDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi50c2QtY2hhcnQtbGFiZWwtaGlkZGVuIHsgdmlzaWJpbGl0eTogaGlkZGVuOyB9XG5cbi8qIHRvb2x0aXAgKi9cbi50c2QtdG9vbHRpcCB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAxMHB4O1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XG4gIHotaW5kZXg6IDY7XG4gIG1pbi13aWR0aDogMTU2cHg7XG4gIHBhZGRpbmc6IDhweCAxMHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLW92ZXJsYXkpO1xuICBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoOHB4KTtcbiAgYm9yZGVyLXJhZGl1czogOHB4O1xuICBib3gtc2hhZG93OiB2YXIoLS1kc3ctc2hhZG93LWx2Myk7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuLnRzZC10b29sdGlwLWRhdGUge1xuICBtYXJnaW4tYm90dG9tOiA2cHg7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbn1cbi50c2QtdG9vbHRpcC1yb3cge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDZweDtcbiAgbWFyZ2luOiAycHggMDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIGZvbnQtdmFyaWFudC1udW1lcmljOiB0YWJ1bGFyLW51bXM7XG59XG4udHNkLXRvb2x0aXAtdmFsIHtcbiAgbWFyZ2luLWxlZnQ6IGF1dG87XG4gIHBhZGRpbmctbGVmdDogMTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbn1cbi50c2QtdG9vbHRpcC10b3RhbCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgbWFyZ2luLXRvcDogNnB4O1xuICBwYWRkaW5nLXRvcDogNnB4O1xuICBib3JkZXItdG9wOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbiAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbn1cblxuLyogPT09PT09PT09PT09IOaMieaooeWei+aYjue7huihqCA9PT09PT09PT09PT0gKi9cbi50c2QtdGFibGUtY2FyZCB7IHBhZGRpbmc6IDA7IH1cbi50c2QtdGFibGUtY2FyZCAudHNkLWNhcmQtaGVhZGVyIHsgcGFkZGluZzogMTRweCAxNnB4IDA7IH1cbi50c2QtdGFibGUtd3JhcCB7XG4gIG92ZXJmbG93LXg6IGF1dG87XG4gIC0tZHNoLXNjcm9sbGJhci10aHVtYjogdmFyKC0tZHN3LWFsaWFzLXNjcm9sbGJhci1iZy1sMik7XG4gIC0tZHNoLXNjcm9sbGJhci10aHVtYi1ob3ZlcjogdmFyKC0tZHN3LWFsaWFzLXNjcm9sbGJhci1ob3Zlci1sMik7XG59XG4udHNkLXRhYmxlIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7XG4gIGZvbnQtc2l6ZTogMTNweDtcbn1cbi50c2QtdGgge1xuICBwYWRkaW5nOiAxMHB4IDEycHg7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG4udHNkLXRoLW51bSB7IHRleHQtYWxpZ246IHJpZ2h0OyB9XG4udHNkLXNvcnQtYnRuIHtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogMnB4O1xuICBwYWRkaW5nOiAwO1xuICBib3JkZXI6IG5vbmU7XG4gIGJhY2tncm91bmQ6IG5vbmU7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgY29sb3I6IGluaGVyaXQ7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cbi50c2Qtc29ydC1idG46aG92ZXIgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpOyB9XG4udHNkLXNvcnQtYWN0aXZlIHsgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTsgfVxuLnRzZC1zb3J0LWFycm93IHtcbiAgZm9udC1zaXplOiAxMHB4O1xuICBsaW5lLWhlaWdodDogMTtcbn1cbi50c2QtdHI6aG92ZXIgeyBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpOyB9XG4udHNkLXRkIHtcbiAgcGFkZGluZzogOXB4IDEycHg7XG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwxKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuLnRzZC10ZC1tb2RlbCB7IG1heC13aWR0aDogMjQwcHg7IH1cbi50c2QtbW9kZWwtbW9ubyB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBtYXgtd2lkdGg6IDIyMHB4O1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgZm9udC1mYW1pbHk6IHZhcigtLWRzLWZvbnQtZmFtaWx5LWNvZGUpO1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG59XG4udHNkLW51bSB7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xuICBmb250LXZhcmlhbnQtbnVtZXJpYzogdGFidWxhci1udW1zO1xufVxuLnRzZC10b3RhbCB7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG59XG4udHNkLXVucHJpY2VkIHtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIGZvbnQtc3R5bGU6IGl0YWxpYztcbn1cbi50c2QtdGQtcmF0aW8geyB0ZXh0LWFsaWduOiByaWdodDsgfVxuLnRzZC1yYXRpbyB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xuICBnYXA6IDhweDtcbn1cbi50c2QtcmF0aW8tYmFyIHtcbiAgd2lkdGg6IDYwcHg7XG4gIGhlaWdodDogNnB4O1xuICBib3JkZXItcmFkaXVzOiAzcHg7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0xKTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgZmxleDogbm9uZTtcbn1cbi50c2QtcmF0aW8tZmlsbCB7XG4gIGhlaWdodDogMTAwJTtcbiAgYm9yZGVyLXJhZGl1czogM3B4O1xuICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoOTBkZWcsIHZhcigtLWRzdy1zdGF0aWMtZGVlcHNlZWstNTAwKSwgY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWRzdy1zdGF0aWMtZGVlcHNlZWstNTAwKSA1NSUsIHZhcigtLWRzdy1zdGF0aWMtZGVlcHNlZWstMzAwKSkpO1xufVxuLnRzZC1yYXRpby1wY3Qge1xuICBtaW4td2lkdGg6IDQycHg7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbn1cblxuLyogPT09PT09PT09PT09IOS4ieaAge+8muepuiAvIOmUmeivryAvIOWKoOi9vSA9PT09PT09PT09PT0gKi9cbi50c2QtZW1wdHkge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDZweDtcbiAgcGFkZGluZzogNDBweCAxNnB4O1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG59XG4udHNkLWVtcHR5LWljb24ge1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgbWFyZ2luLWJvdHRvbTogNHB4O1xufVxuLnRzZC1lbXB0eS10aXRsZSB7XG4gIG1hcmdpbjogMDtcbiAgZm9udC1zaXplOiAxNXB4O1xuICBmb250LXdlaWdodDogNjAwO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xufVxuLnRzZC1lbXB0eS1kZXNjIHtcbiAgbWFyZ2luOiAwO1xuICBmb250LXNpemU6IDEzcHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbn1cbi50c2QtZW1wdHktYmxvY2sge1xuICBwYWRkaW5nOiAyNHB4O1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtc2l6ZTogMTNweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG59XG5cbi50c2QtZXJyb3Ige1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDEycHg7XG4gIHBhZGRpbmc6IDIwcHggMTZweDtcbiAgYm9yZGVyLWNvbG9yOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZHN3LWFsaWFzLXN0YXRlLWVycm9yLXByaW1hcnkpIDQwJSwgdHJhbnNwYXJlbnQpO1xuICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gc3JnYiwgdmFyKC0tZHN3LWFsaWFzLXN0YXRlLWVycm9yLXNlY29uZGFyeSkgMzAlLCB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMykpO1xufVxuLnRzZC1lcnJvci1pY29uIHtcbiAgZmxleDogbm9uZTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1zdGF0ZS1lcnJvci1wcmltYXJ5KTtcbn1cbi50c2QtZXJyb3ItdGV4dCB7XG4gIGZsZXg6IDE7XG4gIG1pbi13aWR0aDogMDtcbn1cbi50c2QtZXJyb3ItdGl0bGUge1xuICBtYXJnaW46IDA7XG4gIGZvbnQtc2l6ZTogMTRweDtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbn1cbi50c2QtZXJyb3ItZGV0YWlsIHtcbiAgbWFyZ2luOiAycHggMCAwO1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG5cbi50c2QtYWxlcnQtYmFubmVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiAxMHB4O1xuICBwYWRkaW5nOiAxMHB4IDE0cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtZXJyb3ItcHJpbWFyeSkgNDAlLCB0cmFuc3BhcmVudCk7XG4gIGJvcmRlci1yYWRpdXM6IDEwcHg7XG4gIGJhY2tncm91bmQ6IGNvbG9yLW1peChpbiBzcmdiLCB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtZXJyb3Itc2Vjb25kYXJ5KSAzMCUsIHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0zKSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtZXJyb3ItcHJpbWFyeSk7XG4gIGZvbnQtc2l6ZTogMTNweDtcbn1cblxuLnRzZC1sb2FkaW5nIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiAxNnB4O1xufVxuLnRzZC1jYXJkLXNrZWxldG9uIHsgbWluLWhlaWdodDogODRweDsgfVxuLnRzZC1za2VsZXRvbiB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1za2VsZXRvbik7XG4gIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgYW5pbWF0aW9uOiB0c2QtcHVsc2UgMS42cyB2YXIoLS1kcy1lYXNlLWluLW91dCkgaW5maW5pdGU7XG59XG4udHNkLXNrZWxldG9uLXJvdyB7XG4gIGhlaWdodDogMTRweDtcbiAgbWFyZ2luOiAxMnB4IDA7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1za2VsZXRvbik7XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgYW5pbWF0aW9uOiB0c2QtcHVsc2UgMS42cyB2YXIoLS1kcy1lYXNlLWluLW91dCkgaW5maW5pdGU7XG59XG5Aa2V5ZnJhbWVzIHRzZC1wdWxzZSB7XG4gIDAlLCAxMDAlIHsgb3BhY2l0eTogMTsgfVxuICA1MCUgeyBvcGFjaXR5OiAwLjQ1OyB9XG59XG5cbi8qID09PT09PT09PT09PSDliLfmlrDml7bnmoTlhoXlrrnmgIEgPT09PT09PT09PT09ICovXG4vKiDkuI3lho0gb3BhY2l0eTogLjU177ya6YKj5Lya6K6p5q+P5qyh6L2u6K+i6YO96Zeq5LiA5LiL77yM5LiU5pqX56S6XCLmlbDlrZfmraPlnKjph43nrpdcIiDigJTigJRcbiAgIOS6i+WunuS4iuaVsOWtl+aYr+S4iuS4gOi9rueahOato+ehruetlOahiOOAguWIt+aWsOeahOS/oeWPt+S6pOe7memhtumDqOmCo+adoSAycHgg6L+b5bqm5p2h5LiO5oyJ6ZKu6L2s5ZyI44CCICovXG4udHNkLWNvbnRlbnQge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBnYXA6IDE2cHg7XG59XG5cbi8qID09PT09PT09PT09PSDlh4/lsJHliqjmgIHmlYjmnpwgPT09PT09PT09PT09ICovXG4vKiDlrpjmlrnlrqLmiLfnq6/lkIzmoLfov5nkuYjlhpnvvIhzcGlubmVyIC8gc2tlbGV0b25GaWxsIOmDveWcqCBwcmVmZXJzLXJlZHVjZWQtbW90aW9uIOS4i+WFs+WKqOeUu++8ie+8jFxuICAg5oiR5Lus6L+Z5Lik5Liq5peg6ZmQ5Yqo55S777yI5ZG85ZC444CB5peL6L2s77yJ5q2k5YmN5LiA5p2h6YO95rKh5YWz44CCICovXG5AbWVkaWEgKHByZWZlcnMtcmVkdWNlZC1tb3Rpb246IHJlZHVjZSkge1xuICAudHNkLXNlY3Rpb24geyBhbmltYXRpb246IG5vbmU7IH1cbiAgLnRzZC1zcGlubmluZyBzdmcgeyBhbmltYXRpb246IG5vbmU7IH1cbiAgLnRzZC1za2VsZXRvbiwgLnRzZC1za2VsZXRvbi1yb3cgeyBhbmltYXRpb246IG5vbmU7IH1cbiAgLnRzZC1wcm9ncmVzczo6YWZ0ZXIgeyBhbmltYXRpb246IG5vbmU7IHdpZHRoOiAxMDAlOyBvcGFjaXR5OiAwLjU1OyB9XG59XG5cbi8qID09PT09PT09PT09PSDml6Dpmpznoo0gPT09PT09PT09PT09ICovXG4udHNkLXZpc3VhbGx5LWhpZGRlbiB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgd2lkdGg6IDFweDtcbiAgaGVpZ2h0OiAxcHg7XG4gIHBhZGRpbmc6IDA7XG4gIG1hcmdpbjogLTFweDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgY2xpcDogcmVjdCgwIDAgMCAwKTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgYm9yZGVyOiAwO1xufVxuLnRzZC1pY29uIHtcbiAgZmxleDogbm9uZTtcbn1cbi50c2Qtc2VnLWJ0bjpmb2N1cy12aXNpYmxlLFxuLnRzZC1zZWxlY3QtYnRuOmZvY3VzLXZpc2libGUsXG4udHNkLWJ0bjpmb2N1cy12aXNpYmxlLFxuLnRzZC1pY29uLWJ0bjpmb2N1cy12aXNpYmxlLFxuLnRzZC1saW5rLWJ0bjpmb2N1cy12aXNpYmxlLFxuLnRzZC1zb3J0LWJ0bjpmb2N1cy12aXNpYmxlIHtcbiAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1zdGF0ZS1idXNpbmVzcy1wcmltYXJ5KTtcbiAgb3V0bGluZS1vZmZzZXQ6IDJweDtcbn1cbi8qID09PT09PT09PT09PSDnspLluqbliIfmjaIgPT09PT09PT09PT09ICovXG4udHNkLWNhcmQtYWN0aW9ucyB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDhweDtcbn1cbi50c2QtZ3JhbiB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBnYXA6IDJweDtcbiAgcGFkZGluZzogMnB4O1xuICBib3JkZXItcmFkaXVzOiA4cHg7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0xKTtcbn1cbi50c2QtZ3Jhbi1idG4ge1xuICBib3JkZXI6IG5vbmU7XG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgZm9udDogaW5oZXJpdDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBsaW5lLWhlaWdodDogMTZweDtcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xuICBwYWRkaW5nOiAycHggOHB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG4udHNkLWdyYW4tYnRuW2RhdGEtYWN0aXZlPVwidHJ1ZVwiXSB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0zKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbiAgYm94LXNoYWRvdzogdmFyKC0tZHN3LXNoYWRvdy1sdjEpO1xufVxuLnRzZC1ncmFuLWJ0bjpkaXNhYmxlZCB7XG4gIG9wYWNpdHk6IDAuNDtcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbn1cbi8qID09PT09PT09PT09PSDmipjnur/lm74gPT09PT09PT09PT09ICovXG4udHNkLWxpbmVjaGFydCB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgcGFkZGluZzogNnB4IDEwcHggOHB4O1xufVxuLnRzZC1saW5lY2hhcnQgc3ZnIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IGF1dG87XG59XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtZ3JpZCB7XG4gIHN0cm9rZTogdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIHN0cm9rZS13aWR0aDogMTtcbiAgc3Ryb2tlLWRhc2hhcnJheTogMyAzO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLWF4aXMge1xuICBzdHJva2U6IHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBzdHJva2Utd2lkdGg6IDE7XG59XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtaW4ge1xuICBzdHJva2U6IHZhcigtLWRzdy1zdGF0aWMtZGVlcHNlZWstNTAwKTtcbiAgc3Ryb2tlLXdpZHRoOiAyO1xuICBmaWxsOiBub25lO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLW91dCB7XG4gIHN0cm9rZTogdmFyKC0tZHN3LXN0YXRpYy1ncmVlbi01MDApO1xuICBzdHJva2Utd2lkdGg6IDI7XG4gIGZpbGw6IG5vbmU7XG59XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtdG90YWwge1xuICBzdHJva2U6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBzdHJva2Utd2lkdGg6IDEuNTtcbiAgc3Ryb2tlLWRhc2hhcnJheTogNCAzO1xuICBmaWxsOiBub25lO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLWRvdCB7XG4gIGZpbGw6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0yKTtcbiAgc3Ryb2tlOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbiAgc3Ryb2tlLXdpZHRoOiAxO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLWhvdmVyIHtcbiAgZmlsbDogdHJhbnNwYXJlbnQ7XG4gIGN1cnNvcjogY3Jvc3NoYWlyO1xufVxuLnRzZC1saW5lY2hhcnQgLnRzZC1saW5lLWN1cnNvciB7XG4gIHN0cm9rZTogdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMyk7XG4gIHN0cm9rZS13aWR0aDogMTtcbiAgc3Ryb2tlLWRhc2hhcnJheTogMyAzO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cbi50c2QtbGluZWNoYXJ0IC50c2QtbGluZS1obCB7XG4gIHN0cm9rZTogdmFyKC0tZHN3LWFsaWFzLWJnLWJhc2UpO1xuICBzdHJva2Utd2lkdGg6IDEuNTtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtaGwtaW4geyBmaWxsOiB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCk7IH1cbi50c2QtbGluZWNoYXJ0IC50c2QtbGluZS1obC1vdXQgeyBmaWxsOiB2YXIoLS1kc3ctc3RhdGljLWdyZWVuLTUwMCk7IH1cbi50c2QtbGluZWNoYXJ0IC50c2QtbGluZS1obC10b3RhbCB7IGZpbGw6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpOyB9XG4udHNkLWxpbmVjaGFydCAudHNkLWxpbmUtdGV4dCB7XG4gIGZpbGw6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIGZvbnQtc2l6ZTogMTBweDtcbn1cbi8qID09PT09PT09PT09PSDlubTluqbng63lipvlm74gPT09PT09PT09PT09ICovXG4udHNkLWhlYXRtYXAge1xuICBwYWRkaW5nOiA2cHggMTRweCAxNHB4O1xuICBvdmVyZmxvdy14OiBhdXRvO1xufVxuLnRzZC1oZWF0bWFwLWlubmVyIHtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogNHB4O1xuICBtaW4td2lkdGg6IG1pbi1jb250ZW50O1xufVxuLnRzZC1oZWF0bWFwLW1vbnRocyB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIG1hcmdpbi1sZWZ0OiAyNnB4O1xuICBoZWlnaHQ6IDE0cHg7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cbi50c2QtaGVhdG1hcC1tb250aCB7XG4gIGZvbnQtc2l6ZTogOXB4O1xuICBsaW5lLWhlaWdodDogMTRweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAwO1xufVxuLnRzZC1oZWF0bWFwLWJvZHkge1xuICBkaXNwbGF5OiBmbGV4O1xuICBnYXA6IDRweDtcbn1cbi50c2QtaGVhdG1hcC1kYXlzIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiAycHg7XG4gIHdpZHRoOiAyMnB4O1xuICBmbGV4OiBub25lO1xufVxuLnRzZC1oZWF0bWFwLWRheSB7XG4gIGhlaWdodDogMTBweDtcbiAgZm9udC1zaXplOiA5cHg7XG4gIGxpbmUtaGVpZ2h0OiAxMHB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gIHBhZGRpbmctcmlnaHQ6IDRweDtcbn1cbi50c2QtaGVhdG1hcC1ncmlkIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZ2FwOiAycHg7XG59XG4udHNkLWhlYXRtYXAtY29sIHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiAycHg7XG59XG4udHNkLWhlYXRtYXAtY2VsbCB7XG4gIHdpZHRoOiAxMHB4O1xuICBoZWlnaHQ6IDEwcHg7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTtcbiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIHZhcigtLWRzLXRyYW5zaXRpb24tZHVyYXRpb24tZmFzdCkgdmFyKC0tZHMtZWFzZS1pbi1vdXQpLCBib3gtc2hhZG93IHZhcigtLWRzLXRyYW5zaXRpb24tZHVyYXRpb24tZmFzdCkgdmFyKC0tZHMtZWFzZS1pbi1vdXQpO1xufVxuLnRzZC1oZWF0bWFwLWNlbGw6aG92ZXIge1xuICBvdXRsaW5lOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIHRyYW5zZm9ybTogc2NhbGUoMS4zNSk7XG4gIGJveC1zaGFkb3c6IHZhcigtLWRzdy1zaGFkb3ctbHYyKTtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB6LWluZGV4OiAyO1xufVxuLnRzZC1oZWF0bWFwLWxlZ2VuZCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogNHB4O1xuICBtYXJnaW46IDhweCAxNHB4IDA7XG4gIHBhZGRpbmctdG9wOiA4cHg7XG4gIGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgZm9udC1zaXplOiAxMHB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbn1cblxuLyogPT09PT09PT09PT09IOi+k+WFpeWMuuaIkOacrCBwaWxs77yIY29tcG9zZXIgZG9ja++8iT09PT09PT09PT09PSAqL1xuLnRzZC1kb2NrIHtcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogNHB4O1xuICBoZWlnaHQ6IDIycHg7XG4gIHBhZGRpbmc6IDAgOHB4O1xuICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgYm9yZGVyOiAwLjVweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwxKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWJhc2UpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgbGluZS1oZWlnaHQ6IDE7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIGN1cnNvcjogZGVmYXVsdDtcbn1cbi50c2QtZG9jay1sYWJlbCB7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xufVxuLnRzZC1kb2NrLXZhbHVlIHtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgZm9udC12YXJpYW50LW51bWVyaWM6IHRhYnVsYXItbnVtcztcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbn1cbi8qID09PT09PT09PT09PSDlrprku7fljLnphY3lvLnnqpcgPT09PT09PT09PT09ICovXG4vKiDpga7nvanpk7rmu6Hop4blj6PvvJrorr7nva7pnaLmnb/mmK8gb3ZlcmZsb3c6aGlkZGVuIOeahOijgeWJquWuueWZqO+8jOW8ueeql+S4jeiDveaMguWcqOmdouadv+WGhemDqO+8jFxuICAg5ZCm5YiZ5a695bGP5LiL5bem5Y+z5ZCE6KKr5YiH5o6J5LiA5Z2X44CC5bGC57qn5Y6L6L+HIHBvcG92ZXIoNDAp77yM5L2O5LqO5Lu75L2V57O757uf57qn5rWu56qX44CCICovXG4udHNkLXByaWNlLW92ZXJsYXkge1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIGluc2V0OiAwO1xuICB6LWluZGV4OiA2MDtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIHBhZGRpbmc6IDI0cHg7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1tYXNrLCByZ2JhKDAsIDAsIDAsIDAuNCkpO1xufVxuLnRzZC1wcmljZS1kaWFsb2cge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICB3aWR0aDogbWluKDc2MHB4LCAxMDAlKTtcbiAgbWF4LWhlaWdodDogMTAwJTtcbiAgcGFkZGluZzogMTZweCAxOHB4IDE0cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBib3JkZXItcmFkaXVzOiAxNHB4O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMSk7XG4gIGJveC1zaGFkb3c6IHZhcigtLWRzdy1zaGFkb3ctbHYzKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbiAgZm9udC1zaXplOiAxM3B4O1xufVxuLnRzZC1wcmljZS1oZWFkIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA4cHg7XG59XG4udHNkLXByaWNlLXRpdGxlIHtcbiAgbWFyZ2luOiAwO1xuICBmb250LXNpemU6IDE1cHg7XG4gIGZvbnQtd2VpZ2h0OiA2MDA7XG59XG4udHNkLXByaWNlLWNsb3NlIHtcbiAgbWFyZ2luLWxlZnQ6IGF1dG87XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgd2lkdGg6IDI0cHg7XG4gIGhlaWdodDogMjRweDtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyOiBub25lO1xuICBib3JkZXItcmFkaXVzOiA2cHg7XG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuLnRzZC1wcmljZS1jbG9zZTpob3ZlciB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG59XG4udHNkLXByaWNlLWRlc2Mge1xuICBtYXJnaW46IDZweCAwIDEwcHg7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgbGluZS1oZWlnaHQ6IDEuNTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xufVxuLyog5Y+q5pyJ5Lit5q615rua5Yqo77ya5qCH6aKY5LiO5bqV6YOo5oyJ6ZKu5b+F6aG75bi46am777yM5ZCm5YiZ6ZW/6KGo6YeM5aSf5LiN5Yiw44CM56Gu5a6a44CNICovXG4udHNkLXByaWNlLWJvZHkge1xuICBmbGV4OiAxIDEgYXV0bztcbiAgbWluLWhlaWdodDogMDtcbiAgb3ZlcmZsb3c6IGF1dG87XG59XG4udHNkLXByaWNlLW1ldGEge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LXdyYXA6IHdyYXA7XG4gIGFsaWduLWl0ZW1zOiBiYXNlbGluZTtcbiAgZ2FwOiA0cHggMTJweDtcbiAgbWFyZ2luLWJvdHRvbTogOHB4O1xuICBmb250LXNpemU6IDExcHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xufVxuLnRzZC1wcmljZS1jb3VudHMgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7IH1cbi50c2QtcHJpY2UtdGFibGUge1xuICB3aWR0aDogMTAwJTtcbiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTtcbiAgZm9udC1zaXplOiAxMnB4O1xufVxuLnRzZC1wcmljZS10YWJsZS1zdWIge1xuICBtYXJnaW4tdG9wOiAxMHB4O1xufVxuLnRzZC1wcmljZS10YWJsZSB0aCB7XG4gIHBvc2l0aW9uOiBzdGlja3k7XG4gIHRvcDogMDtcbiAgei1pbmRleDogMTtcbiAgcGFkZGluZzogNnB4IDhweDtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTEpO1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG4gIGZvbnQtd2VpZ2h0OiA1MDA7XG4gIGZvbnQtc2l6ZTogMTFweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG4udHNkLXByaWNlLXRhYmxlIHRkIHtcbiAgcGFkZGluZzogNnB4IDhweDtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xufVxuLnRzZC1wcmljZS1yb3dbZGF0YS1kaXJ0eT0ndHJ1ZSddIHRkIHtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKTtcbn1cbi50c2QtcHJpY2UtbW9kZWwge1xuICBtYXgtd2lkdGg6IDI0MHB4O1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cbi50c2QtcHJpY2UtbW9kZWwtbmFtZSB7XG4gIGZvbnQtZmFtaWx5OiB1aS1tb25vc3BhY2UsIFNGTW9uby1SZWd1bGFyLCBNZW5sbywgbW9ub3NwYWNlO1xuICBmb250LXNpemU6IDExLjVweDtcbiAgZm9udC13ZWlnaHQ6IDUwMDtcbn1cbi50c2QtcHJpY2UtbW9kZWwtcHJvdmlkZXIge1xuICBtYXJnaW4tbGVmdDogNnB4O1xuICBmb250LWZhbWlseTogdWktbW9ub3NwYWNlLCBTRk1vbm8tUmVndWxhciwgTWVubG8sIG1vbm9zcGFjZTtcbiAgZm9udC1zaXplOiAxMC41cHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xufVxuLyog5Yy56YWN55uu5qCH5qC877ya5pW05qC85piv5LiA6aKX57Sn5YeR55qE44CM6YCJ5oup44CN5oyJ6ZKu77yI5pyq5Yy56YWN5pe26Jma57q/44CB5paH5qGI5piv5o+Q56S66K+t77yJ77yMXG4gICDmr5Tmr4/ooYzmkYrkuKTpopfmloflrZfmjInpkq7lronpnZnlvpflpJrvvJvlj6/mkJzntKLnmoTkuIvmi4nmjILlnKjlroPkuIvpnaLlsZXlvIDjgIIgKi9cbi50c2QtcHJpY2UtdGFyZ2V0IHsgbWF4LXdpZHRoOiAyMzBweDsgfVxuLnRzZC1wcmljZS10YXJnZXQtYnRuIHtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogNHB4O1xuICBtYXgtd2lkdGg6IDEwMCU7XG4gIHBhZGRpbmc6IDNweCA2cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBib3JkZXItcmFkaXVzOiA2cHg7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0yKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBmb250OiBpbmhlcml0O1xuICBmb250LXNpemU6IDEycHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cbi50c2QtcHJpY2UtdGFyZ2V0LWJ0bjpob3ZlciB7XG4gIGJvcmRlci1jb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbn1cbi50c2QtcHJpY2UtdGFyZ2V0LWJ0bjpmb2N1cy12aXNpYmxlIHtcbiAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTtcbiAgb3V0bGluZS1vZmZzZXQ6IDFweDtcbn1cbi50c2QtcHJpY2UtdGFyZ2V0LWJ0bltkYXRhLWVtcHR5PSd0cnVlJ10ge1xuICBib3JkZXItc3R5bGU6IGRhc2hlZDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG59XG4udHNkLXByaWNlLXRhcmdldC1pZCB7XG4gIG1pbi13aWR0aDogMDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG4udHNkLXByaWNlLXRhcmdldC1jaGV2IHsgZmxleDogbm9uZTsgb3BhY2l0eTogMC43OyB9XG4vKiDlj4LogIPmqKHlnovnmoTmnaXmupDmoIfnrb7vvJpEZWVwU2VlayAvIFplbiAvIOiHquWumuS5ieOAgjEwcHjjgIHml6DovrnmoYbjgIHlj6rlnKjmoLzlsL7ljaDkuIDngrnngrnvvIxcbiAgIOWFjeW+l+aKiiBpZCDmjKTmjokg4oCU4oCUIGlkIOiHquW3seW3sue7j+S8miBlbGxpcHNpc+OAgiAqL1xuLnRzZC1wcmljZS1zcmMge1xuICBtYXJnaW4tbGVmdDogNHB4O1xuICBwYWRkaW5nOiAwIDNweDtcbiAgYm9yZGVyLXJhZGl1czogNHB4O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgZm9udC1zaXplOiAxMHB4O1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuLnRzZC1wcmljZS1zcmNbZGF0YS1zb3VyY2U9J2RlZXBzZWVrJ10geyBjb2xvcjogdmFyKC0tZHN3LXN0YXRpYy1ibHVlLTUwMCk7IH1cbi50c2QtcHJpY2Utc3JjW2RhdGEtc291cmNlPSdjdXN0b20nXSB7IGNvbG9yOiB2YXIoLS1kc3ctc3RhdGljLWdyZWVuLTUwMCk7IH1cbi8qIOWAmemAieWIl+ihqOmHjOeahOWIhue7hOihqOWktO+8mueymOWcqOa7muWKqOWuueWZqOmhtumDqO+8jOa7muWIsOWTqumDveefpemBk+iHquW3seWcqOeci+WTquS4gOexu+OAgiAqL1xuLnRzZC1wcmljZS1waWNrLWdyb3VwIHtcbiAgcG9zaXRpb246IHN0aWNreTtcbiAgdG9wOiAwO1xuICBwYWRkaW5nOiA0cHggNHB4IDJweDtcbiAgYmFja2dyb3VuZDogdmFyKC0tZHN3LWFsaWFzLWJnLWxheWVyLTEpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTtcbiAgZm9udC1zaXplOiAxMC41cHg7XG4gIGxldHRlci1zcGFjaW5nOiAwLjAyZW07XG59XG4vKiDnqbrnu4TvvIjnm67liY3lj6rmnInjgIzoh6rlrprkuYnjgI3vvInnu5nkuIDooYzor7TmmI7vvIzliKvorqnov5nkuIDnsbvpmpDlvaLjgIIgKi9cbi50c2QtcHJpY2UtcGljay1zZXAge1xuICBtYXJnaW46IDRweCAwO1xuICBib3JkZXItdG9wOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG59XG4vKiDjgIzoh6rlrprkuYnjgI3pgInpobnvvJrpobbpg6jlm7rlrprnmoTkuIDmnaHvvIzluKbkuIDooYzor7TmmI7jgIIgKi9cbi50c2QtcHJpY2UtcGljay1jdXN0b20ge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBhbGlnbi1pdGVtczogZmxleC1zdGFydDtcbiAgZ2FwOiAycHg7XG4gIGJvcmRlcjogMXB4IGRhc2hlZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbn1cbi50c2QtcHJpY2UtcGljay1jdXN0b20tbGFiZWwgeyBmb250LXdlaWdodDogNTAwOyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpOyB9XG4udHNkLXByaWNlLXBpY2stY3VzdG9tLWhpbnQgeyBmb250LXNpemU6IDExcHg7IGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpOyB9XG4vKiDmiYvloavljZXku7fnmoTkuInmoLzvvJrkuIDooYzkuIDkuKrlrZfmrrXvvIzovpPlhaXmoYbljaDmu6HliankvZnlrr3luqbjgIIgKi9cbi50c2QtcHJpY2UtY3VzdG9tLWJveCB7IGdhcDogOHB4OyB9XG4udHNkLXByaWNlLWN1c3RvbS10aXRsZSB7IGZvbnQtd2VpZ2h0OiA1MDA7IH1cbi50c2QtcHJpY2UtY3VzdG9tLWZpZWxkIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZ2FwOiA4cHg7XG59XG4udHNkLXByaWNlLWN1c3RvbS1maWVsZCA+IHNwYW4ge1xuICBmbGV4OiBub25lO1xuICB3aWR0aDogNTJweDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xufVxuLnRzZC1wcmljZS1jdXN0b20taW5wdXQge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICBmbGV4OiAxIDEgYXV0bztcbiAgbWluLXdpZHRoOiAwO1xuICBoZWlnaHQ6IDI2cHg7XG4gIHBhZGRpbmc6IDAgOHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTJweDtcbn1cbi50c2QtcHJpY2UtY3VzdG9tLWhpbnQgeyBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXRlcnRpYXJ5KTsgZm9udC1zaXplOiAxMXB4OyB9XG4udHNkLXByaWNlLXN0YWxlIHtcbiAgbWFyZ2luLWxlZnQ6IDZweDtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLXN0YXRlLXdhcm4tcHJpbWFyeSk7XG59XG4udHNkLXByaWNlLXJhdGUge1xuICBmb250LXZhcmlhbnQtbnVtZXJpYzogdGFidWxhci1udW1zO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXNlY29uZGFyeSk7XG59XG4vKiDmk43kvZzmoLzvvJrpu5jorqTnqbrnnYDvvIzlj6rmnInjgIzoh6rlrprkuYkgLyDmnInmlLnliqjjgI3nmoTooYzmiY3nu5nkuIDpopfov5jljp/lm77moIfjgIJcbiAgIOazqOaEj+WIq+e7mSB0ZCDorr4gZGlzcGxheTpmbGV4IOKAlOKAlCDpgqPkvJrmiorljZXlhYPmoLzlnZfnuqfljJbvvIzmlbTliJflpLHljrvlr7npvZDjgIIgKi9cbi50c2QtcHJpY2Utb3BzIHtcbiAgd2lkdGg6IDM0cHg7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuLnRzZC1wcmljZS1yZXNldCB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgd2lkdGg6IDIycHg7XG4gIGhlaWdodDogMjJweDtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyOiAxcHggc29saWQgdHJhbnNwYXJlbnQ7XG4gIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgYmFja2dyb3VuZDogbm9uZTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC10ZXJ0aWFyeSk7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cbi50c2QtcHJpY2UtcmVzZXQ6aG92ZXIge1xuICBib3JkZXItY29sb3I6IHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBjb2xvcjogdmFyKC0tZHN3LWFsaWFzLWxhYmVsLXByaW1hcnkpO1xufVxuLnRzZC1wcmljZS1yZXNldDpmb2N1cy12aXNpYmxlIHtcbiAgb3V0bGluZTogMnB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KTtcbiAgb3V0bGluZS1vZmZzZXQ6IDFweDtcbn1cbi50c2QtYnRuLXhzIHtcbiAgaGVpZ2h0OiAyNHB4O1xuICBwYWRkaW5nOiAwIDhweDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICBib3JkZXItcmFkaXVzOiA2cHg7XG59XG4vKiDluKblm77moIfnmoTmjInpkq7vvJrlm77moIfkuI7mloflrZflkIzkuIDooYzvvIzpl7Tot53nlLEgZ2FwIOe7me+8jOWIq+WcqOaWh+ahiOmHjOWhnuepuuagvCAqL1xuLnRzZC1idG4taWNvbi1sYWJlbCB7XG4gIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDZweDtcbn1cbi8qIOWPguiAg+aooeWei+WAmemAieaYr+S4gOW6p+a1ruWxgu+8iERTSCDoh6rlt7HnmoTmqKHlnovpgInmi6nlmajlsLHmmK/ov5nnp43kuqTkupLvvInvvIzkuI3lho3loZ7ov5vooajmoLzph4zvvJpcbiAgIOWGheiBlOmdouadv+S8muaKiuaJgOWcqOihjOaSkemrmOOAgeaKiuS4i+mdoueahOihjOaVtOS9k+aOqOi1sO+8jOeci+i1t+adpeWDj+ihqOagvOWdj+S6huOAgiAqL1xuLnRzZC1wcmljZS1waWNrLWJveCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogNnB4O1xuICBtaW4taGVpZ2h0OiAwO1xuICBwYWRkaW5nOiA2cHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWRzdy1hbGlhcy1ib3JkZXItbDIpO1xuICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMSk7XG4gIGJveC1zaGFkb3c6IHZhcigtLWRzdy1zaGFkb3ctbHYzKTtcbn1cbi8qIOWbm+aAgeW+veagh++8mueyvuehrijok50pIC8g5qih57OKKOeQpeePgCkgLyDmnKrljLnphY0o54GwKSAvIOiHquWumuS5iSjnu78p77yM6aKc6Imy5peP6YO955So55yf5a6eIHRva2VuICovXG4udHNkLXByaWNlLWJhZGdlIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBwYWRkaW5nOiAxcHggN3B4O1xuICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICBmb250LXNpemU6IDExcHg7XG4gIGxpbmUtaGVpZ2h0OiAxNnB4O1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctc3RhdGljLW5ldXRyYWwtMjAwLCByZ2JhKDEyOCwgMTI4LCAxMjgsIDAuMTQpKTtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xufVxuLnRzZC1wcmljZS1iYWRnZVtkYXRhLXN0YXRlPSdleGFjdCddIHtcbiAgYmFja2dyb3VuZDogY29sb3ItbWl4KGluIG9rbGFiLCB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCkgMTYlLCB0cmFuc3BhcmVudCk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCk7XG59XG4udHNkLXByaWNlLWJhZGdlW2RhdGEtc3RhdGU9J2Z1enp5J10ge1xuICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gb2tsYWIsIHZhcigtLWRzdy1zdGF0aWMtYW1iZXItNTAwKSAxOCUsIHRyYW5zcGFyZW50KTtcbiAgY29sb3I6IHZhcigtLWRzdy1zdGF0aWMtYW1iZXItNTAwKTtcbn1cbi50c2QtcHJpY2UtYmFkZ2VbZGF0YS1zdGF0ZT0nY3VzdG9tJ10ge1xuICBiYWNrZ3JvdW5kOiBjb2xvci1taXgoaW4gb2tsYWIsIHZhcigtLWRzdy1zdGF0aWMtZ3JlZW4tNTAwKSAxNiUsIHRyYW5zcGFyZW50KTtcbiAgY29sb3I6IHZhcigtLWRzdy1zdGF0aWMtZ3JlZW4tNTAwKTtcbn1cbi8qIOacquWMuemFjeaAgeayoeacieS4u+mimOiJsuWPr+eUqO+8muWuueWZqOmCo+WxgiBiYWNrZ3JvdW5kOiBub25lIOaKiuW+veagh+W6leiJsuaKueaOieS6hu+8jOWPquWJqVxuICAg55m95a2X5Y6L5Zyo55m95bqV5LiK44CC6L+Z6YeM57uZ5a6D6Ieq5bex55qE5bqV5LiO5a2X6Imy77yM5Zub5oCB5omN6YO96IO955yL6KeB44CCICovXG4udHNkLXByaWNlLXJvd1tkYXRhLXN0YXRlPSdub25lJ10gLnRzZC1wcmljZS1iYWRnZSB7XG4gIGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtc2Vjb25kYXJ5KTtcbn1cbi50c2QtcHJpY2UtcGljay1pbnB1dCB7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDI4cHg7XG4gIHBhZGRpbmc6IDAgOHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1kc3ctYWxpYXMtYmctbGF5ZXItMSk7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtcHJpbWFyeSk7XG4gIGZvbnQ6IGluaGVyaXQ7XG4gIGZvbnQtc2l6ZTogMTJweDtcbn1cbi8qIOWAmemAieWIl+ihqOiHquW3sea7mu+8jOS4lOW/hemhu+iHquW3seWwgemhtu+8mnVzZUZpeGVkUGFuZWwg5Y+q57uZ5L2N572u5ZKM5a695bqm77yM5LiN57uZ6auY5bqm77yMXG4gICA4OSDkuKogaWQg5pGK5byA5pyJ6L+RIDIwMDBweO+8jOS4jeWwgemhtuWwseaYr+S4gOS4qui2heWHuuinhuWPo+eahOa1ruWxguOAgiAqL1xuLnRzZC1wcmljZS1waWNrLWxpc3Qge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBtaW4taGVpZ2h0OiAwO1xuICBtYXgtaGVpZ2h0OiAyNjBweDtcbiAgb3ZlcmZsb3c6IGF1dG87XG59XG4udHNkLXByaWNlLXBpY2staXRlbSB7XG4gIHBhZGRpbmc6IDRweCA4cHg7XG4gIGJvcmRlcjogbm9uZTtcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1wcmltYXJ5KTtcbiAgZm9udDogaW5oZXJpdDtcbiAgZm9udC1zaXplOiAxMnB4O1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG4udHNkLXByaWNlLXBpY2staXRlbTpob3ZlciB7IGJhY2tncm91bmQ6IHZhcigtLWRzdy1hbGlhcy1pbnRlcmFjdGl2ZS1iZy1ob3Zlcik7IH1cbi50c2QtcHJpY2UtcGljay1pdGVtLWFjdGl2ZSB7IGNvbG9yOiB2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCk7IGZvbnQtd2VpZ2h0OiA2MDA7IH1cbi50c2QtcHJpY2UtaGlzdG9yeSB7XG4gIG1hcmdpbi10b3A6IDE0cHg7XG4gIHBhZGRpbmctdG9wOiAxMHB4O1xuICBib3JkZXItdG9wOiAxcHggc29saWQgdmFyKC0tZHN3LWFsaWFzLWJvcmRlci1sMik7XG59XG4udHNkLXByaWNlLWhpc3RvcnktdG9nZ2xlIHtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogNnB4O1xuICBwYWRkaW5nOiAycHggMDtcbiAgYm9yZGVyOiBub25lO1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgY29sb3I6IHZhcigtLWRzdy1hbGlhcy1sYWJlbC1zZWNvbmRhcnkpO1xuICBmb250OiBpbmhlcml0O1xuICBmb250LXNpemU6IDEycHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cbi50c2QtcHJpY2UtaGlzdG9yeS1jaGV2IHsgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMTVzIGVhc2U7IH1cbi50c2QtcHJpY2UtaGlzdG9yeS1jaGV2LW9wZW4geyB0cmFuc2Zvcm06IHJvdGF0ZSgxODBkZWcpOyB9XG4udHNkLXByaWNlLWVtcHR5LFxuLnRzZC1wcmljZS1sb2FkaW5nIHtcbiAgcGFkZGluZzogMThweCAwO1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtbGFiZWwtdGVydGlhcnkpO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG59XG4udHNkLXByaWNlLWZvb3Qge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBnYXA6IDhweDtcbiAgbWFyZ2luLXRvcDogMTJweDtcbiAgcGFkZGluZy10b3A6IDEwcHg7XG4gIGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1kc3ctYWxpYXMtYm9yZGVyLWwyKTtcbn1cbi50c2QtcHJpY2UtaGludCB7XG4gIG1hcmdpbi1sZWZ0OiBhdXRvO1xuICBmb250LXNpemU6IDExcHg7XG4gIGNvbG9yOiB2YXIoLS1kc3ctYWxpYXMtc3RhdGUtd2Fybi1wcmltYXJ5KTtcbn1cbmBcblxuLy8gMC4yKyBob3N0IHRyYW5zcG9ydDogUE9TVCAvYXBpLzxjaGFubmVsPi88ZW5kcG9pbnQ+LCBhcmdzIGFzIHRoZSBKU09OIGJvZHksXG4vLyBhbnN3ZXJpbmcgeyBvaywgdmFsdWUgfSB8IHsgb2ssIGVycm9yIH0gKHNlZSBzcmMvaG9zdC9ycGMuanMpLiBUaGUgcm91dGUgaXNcbi8vIG1vdW50ZWQgb24gQ29ubmVjdGlvbidzIHNoYXJlZCBBUEkgY2hhbm5lbCwgc28gaXQgbmV2ZXIgbmVlZHMgdGhlIHBsdWdpbidzXG4vLyBmaWJlciB0byBvd24gYHdlYlNlcnZlcmAuXG5mdW5jdGlvbiBjYWxsRmV0Y2goY2hhbm5lbCwgZW5kcG9pbnQsIGFyZ3MpIHtcbiAgY29uc3QgcGF0aCA9ICcvYXBpLycgKyBTdHJpbmcoY2hhbm5lbCkucmVwbGFjZSgvXlxcLysvLCAnJykgKyAnLycgKyBlbmRwb2ludFxuICByZXR1cm4gZmV0Y2gocGF0aCwge1xuICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nLFxuICAgIGhlYWRlcnM6IHsgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGFyZ3MgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmdzKSxcbiAgfSkudGhlbigocmVzKSA9PiB7XG4gICAgY29uc3QgdHlwZSA9IHJlcy5oZWFkZXJzLmdldCgnY29udGVudC10eXBlJykgfHwgJydcbiAgICAvLyBSb3V0ZSBtaXNzaW5nIG9uIHRoaXMgaG9zdDogNDA0LzQwNSBmcm9tIHRoZSBzaGFyZWQgZGlzcGF0Y2hlciwgb3IgdGhlXG4gICAgLy8gU1BBIEhUTUwgd2hlbiBubyB0cmFuc3BvcnQgcm91dGUgbWF0Y2hlZCB0aGUgcGF0aCBhdCBhbGwuXG4gICAgaWYgKHJlcy5zdGF0dXMgPT09IDQwNCB8fCByZXMuc3RhdHVzID09PSA0MDUgfHwgdHlwZS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgPT09IC0xKSB7XG4gICAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigndXNhZ2UgRmV0Y2ggcm91dGUgdW5hdmFpbGFibGUgKEhUVFAgJyArIHJlcy5zdGF0dXMgKyAnKScpXG4gICAgICBlcnJvci5jb2RlID0gJ3VzYWdlLXJvdXRlLW1pc3NpbmcnXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cbiAgICByZXR1cm4gcmVzLmpzb24oKS50aGVuKChib2R5KSA9PiB7XG4gICAgICBpZiAoYm9keSAmJiBib2R5Lm9rKSByZXR1cm4gYm9keS52YWx1ZVxuICAgICAgdGhyb3cgcnBjRXJyb3IoYm9keSAmJiBib2R5LmVycm9yLCAnUlBDICcgKyBlbmRwb2ludCArICcgZmFpbGVkJylcbiAgICB9KVxuICB9KVxufVxuXG4vKipcbiAqIOaKiuWuv+S4u+i/lOWbnueahCBge2NvZGUsIG1lc3NhZ2V9YCDlj5jmiJDlj6/mmL7npLrnmoTplJnor6/jgIJcbiAqXG4gKiDlrr/kuLvlr7nmnKrlpITnkIbnmoTlvILluLjlj6rlj5HnqLPlrprnmoQgYGludGVybmFsYO+8jOe7huiKguWGmeWcqOWuv+S4u+aXpeW/l+mHjO+8m+eVjOmdouS4iuaYvuekuuacrOaPkuS7tueahFxuICog5LiA5Y+l6K+d77yM6ICM5LiN5piv5Y6f5aeL5aCG5qCI77yI5Y6f5aeL6ZSZ6K+v5LiN5LiK6aG16Z2i77yJ44CCXG4gKi9cbmZ1bmN0aW9uIHJwY0Vycm9yKGVycm9yLCBmYWxsYmFjaykge1xuICBjb25zdCBjb2RlID0gZXJyb3IgJiYgZXJyb3IuY29kZVxuICBjb25zdCBtZXNzYWdlID0gY29kZSA9PT0gJ2ludGVybmFsJyA/IGZhbGxiYWNrVCgncnBjSW50ZXJuYWxFcnJvcicpIDogKChlcnJvciAmJiBlcnJvci5tZXNzYWdlKSB8fCBmYWxsYmFjaylcbiAgY29uc3Qgd3JhcHBlZCA9IG5ldyBFcnJvcihtZXNzYWdlKVxuICBpZiAoY29kZSkgd3JhcHBlZC5jb2RlID0gY29kZVxuICByZXR1cm4gd3JhcHBlZFxufVxuXG4vLyBSUEMgYnJpZGdlOiBkeW5hbWljLXBsdWdpbiBydW5zIHByb3ZpZGUgYSBgaG9zdGAgZ2xvYmFsOyBzdGF0aWMgKGJ1bmRsZSlcbi8vIGluc3RhbGxzIHByb3ZpZGUgY3R4LmdldCgnY29ubmVjdGlvbicpLiBLZWVwIG9uZSBVSSBzb3VyY2UgZm9yIGJvdGguXG4vL1xuLy8gQ2hhbm5lbCBwcmVmZXJlbmNlLCBuYXRpdmUgZmlyc3Q6IHRoZSBwbHVnaW4ncyBvd24gdHlwZXJ0IFJlbW90ZSBuYW1lc3BhY2Vcbi8vIChgcmVtb3RlWydkc2gtcGx1Z2luLXVzYWdlJ11gLCByZWdpc3RlcmVkIGJ5IHNyYy9ob3N0L3R5cGVydC5qcyksIHRoZW4gdGhlXG4vLyBGZXRjaCByb3V0ZXMgb24gQ29ubmVjdGlvbidzIHNoYXJlZCAvYXBpIGNoYW5uZWwsIHRoZW4gdGhlIGxlZ2FjeSAvdXNhZ2Vcbi8vIHByZWZpeCBjaGFubmVsLiBBIFJlbW90ZSBuYW1lc3BhY2UgdGhhdCBleGlzdHMgYnV0IGZhaWxzIChob3N0IHJlc3RhcnRlZFxuLy8gbWlkLWZsaWdodCwgcmVjZWl2ZXIgZ29uZSkgbXVzdCBmYWxsIHRocm91Z2ggaW5zdGVhZCBvZiBicmlja2luZyB0aGUgcGFnZS5cbmNvbnN0IFVTQUdFX1JFTU9URV9OQU1FU1BBQ0UgPSAnZHNoLXBsdWdpbi11c2FnZSdcblxuLyoqXG4gKiBEZXNjcmlwdG9ycyBmb3IgdGhlIGNsaWVudC1zaWRlIG1vdW50LlxuICpcbiAqIFRoZSBnYXRld2F5J3MgYnJvd3NlciBoYWxmIHdhbnRzIGEgYHNyYy1qc29uYCByZXN1bHQgKGEgZGlyZWN0IGludm9jYXRpb24gaXNcbiAqIG5vdCByZXN1bHQtZGVjb2RlZCksIHdoaWxlIHRoZSBob3N0IGNvbnRyaWJ1dGlvbiBkZWNsYXJlcyBhIHN0cmljdCBjb2RlYy5cbiAqIEV2ZXJ5dGhpbmcgZWxzZSBtdXN0IG1hdGNoIHRoZSBob3N0IGZpZWxkIGZvciBmaWVsZC5cbiAqL1xuZnVuY3Rpb24gcmVtb3RlRGVzY3JpcHRvcnMocGFja2FnZU5hbWUsIG5hbWVzKSB7XG4gIGNvbnN0IGFyZ3NDb2RlYyA9ICgpID0+ICh7XG4gICAgbW9kZTogJ3N0cmljdCcsXG4gICAgdHlwZVN5bWJvbDogcGFja2FnZU5hbWUgKyAnL3R5cGVydCNFbmRwb2ludEFyZ3MnLFxuICAgIGNyZWF0ZTogKCkgPT4gKHsgcGFyc2U6ICh2YWx1ZSkgPT4gdmFsdWUgfSksXG4gIH0pXG4gIHJldHVybiBuYW1lcy5tYXAoKG5hbWUpID0+ICh7XG4gICAgaWQ6IHBhY2thZ2VOYW1lICsgJyMnICsgcGFja2FnZU5hbWUgKyAnLycgKyBuYW1lLFxuICAgIHNlcnZpY2U6IHBhY2thZ2VOYW1lLFxuICAgIG5hbWVzcGFjZTogcGFja2FnZU5hbWUsXG4gICAgbWV0aG9kOiBuYW1lLFxuICAgIGludm9jYXRpb246IHsga2luZDogJ2RpcmVjdCcgfSxcbiAgICBwYXJhbWV0ZXJzOiBbeyBuYW1lOiAnYXJncycsIHdpcmU6ICdhcmdzJywgc291cmNlOiAnanNvbicsIGNvZGVjOiBhcmdzQ29kZWMoKSB9XSxcbiAgICByZXN1bHQ6IHsgbW9kZTogJ3NyYy1qc29uJyB9LFxuICB9KSlcbn1cblxuLyoqXG4gKiBKb2luIHRoZSBuYXRpdmUgUmVtb3RlIGNoYW5uZWwgb24gdGhlIGJyb3dzZXIgc2lkZS5cbiAqXG4gKiBBIGZhY2UgcmVnaXN0ZXJlZCBhdCBydW50aW1lIG9uIHRoZSBob3N0IGlzIGludmlzaWJsZSB0byB0aGUgY2xpZW50J3MgYHJlbW90ZWBcbiAqIHByb3h5IHVudGlsIHRoZSBjb25zdW1lciBtb3VudHMgaXQuIFVudGlsIHRoZSBtb3VudCBsYW5kcyDigJQgb3IgaWYgaXQgbmV2ZXJcbiAqIGRvZXMg4oCUIGhvc3RDYWxsIGtlZXBzIHVzaW5nIHRoZSBGZXRjaCByb3V0ZXMsIHNvIHRoaXMgaXMgYW4gb3B0aW1pemF0aW9uLFxuICogbmV2ZXIgYSBoYXJkIGRlcGVuZGVuY3kuXG4gKi9cbmZ1bmN0aW9uIG1vdW50UmVtb3RlQ2hhbm5lbChzY29wZSkge1xuICBsZXQgcmVtb3RlID0gbnVsbFxuICB0cnkge1xuICAgIHJlbW90ZSA9IHNjb3BlLmdldCgncmVtb3RlJylcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVyblxuICB9XG4gIGlmICghcmVtb3RlIHx8IHR5cGVvZiByZW1vdGUuJG1vdW50ICE9PSAnZnVuY3Rpb24nKSByZXR1cm5cbiAgZmV0Y2hDYWxsKCd1c2FnZS9jb250cmFjdCcsIHt9KS50aGVuKChjb250cmFjdCkgPT4ge1xuICAgIGNvbnN0IG5hbWVzID0gY29udHJhY3QgJiYgQXJyYXkuaXNBcnJheShjb250cmFjdC5uYW1lcykgPyBjb250cmFjdC5uYW1lcyA6IFtdXG4gICAgaWYgKG5hbWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGxcbiAgICBjb25zdCBwYWNrYWdlTmFtZSA9IGNvbnRyYWN0LnBhY2thZ2UgfHwgVVNBR0VfUkVNT1RFX05BTUVTUEFDRVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVtb3RlLiRtb3VudCh7IHBhY2thZ2U6IHBhY2thZ2VOYW1lLCBkZXNjcmlwdG9yczogcmVtb3RlRGVzY3JpcHRvcnMocGFja2FnZU5hbWUsIG5hbWVzKSB9KSlcbiAgfSkuY2F0Y2goKCkgPT4ge1xuICAgIC8vIFN0YXkgb24gdGhlIEZldGNoIHJvdXRlczsgdGhlIGhvc3QgcmVwb3J0cyB3aGljaCBjaGFubmVsIGl0IG9wZW5lZC5cbiAgfSlcbn1cblxuZnVuY3Rpb24gcmVtb3RlQ2FsbChzY29wZSwgbWV0aG9kLCBhcmdzKSB7XG4gIGNvbnN0IG5hbWUgPSBTdHJpbmcobWV0aG9kKVxuICBjb25zdCBzbGFzaCA9IG5hbWUuaW5kZXhPZignLycpXG4gIGNvbnN0IGVuZHBvaW50ID0gc2xhc2ggPT09IC0xID8gbmFtZSA6IG5hbWUuc2xpY2Uoc2xhc2ggKyAxKVxuICBjb25zdCBjYW1lbCA9IGVuZHBvaW50LnJlcGxhY2UoLy0oW2Etel0pL2csIChtLCBjKSA9PiBjLnRvVXBwZXJDYXNlKCkpXG4gIGZvciAoY29uc3Qgc2VydmljZSBvZiBbVVNBR0VfUkVNT1RFX05BTUVTUEFDRSwgJ3VzYWdlJ10pIHtcbiAgICAvLyBgY3R4LmdldCgncmVtb3RlLjxuYW1lc3BhY2U+JylgIGlzIHRoZSBzZXJ2aWNlIGtleSB0aGUgZ2F0ZXdheSBjcmVhdGVzIHBlclxuICAgIC8vIGZhY2UgKGRzaC1hcGktZ2F0ZXdheSBjbGllbnQ6IHJlbW90ZVNlcnZpY2VLZXkpLiBUaGUgYHJlbW90ZVtuYW1lc3BhY2VdYFxuICAgIC8vIHByb3BlcnR5IGlzIHRoZSBvbGRlciBzaGFwZSBhbmQgdGhyb3dzIG9uIHRoZSBzdHJpY3QgcHJveHksIHNvIGl0IGlzIGFcbiAgICAvLyBndWFyZGVkIHNlY29uZCBjaG9pY2UuXG4gICAgbGV0IG5hbWVzcGFjZSA9IG51bGxcbiAgICB0cnkge1xuICAgICAgbmFtZXNwYWNlID0gc2NvcGUuZ2V0KCdyZW1vdGUuJyArIHNlcnZpY2UpXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbmFtZXNwYWNlID0gbnVsbFxuICAgIH1cbiAgICBpZiAoIW5hbWVzcGFjZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVtb3RlID0gc2NvcGUuZ2V0KCdyZW1vdGUnKVxuICAgICAgICBuYW1lc3BhY2UgPSByZW1vdGUgPyByZW1vdGVbc2VydmljZV0gOiBudWxsXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIG5hbWVzcGFjZSA9IG51bGxcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFuYW1lc3BhY2UpIGNvbnRpbnVlXG4gICAgY29uc3QgZm4gPSAodHlwZW9mIG5hbWVzcGFjZVtjYW1lbF0gPT09ICdmdW5jdGlvbicgJiYgbmFtZXNwYWNlW2NhbWVsXSlcbiAgICAgIHx8ICh0eXBlb2YgbmFtZXNwYWNlW2VuZHBvaW50XSA9PT0gJ2Z1bmN0aW9uJyAmJiBuYW1lc3BhY2VbZW5kcG9pbnRdKVxuICAgIGlmICghZm4pIGNvbnRpbnVlXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiBmbihhcmdzKSlcbiAgICAgIC50aGVuKChyZXMpID0+IHtcbiAgICAgICAgaWYgKHJlcyAmJiByZXMub2spIHJldHVybiByZXMudmFsdWVcbiAgICAgICAgdGhyb3cgcnBjRXJyb3IocmVzICYmIHJlcy5lcnJvciwgJ1JQQyAnICsgbWV0aG9kICsgJyBmYWlsZWQnKVxuICAgICAgfSlcbiAgfVxuICByZXR1cm4gbnVsbFxufVxuXG5mdW5jdGlvbiBob3N0Q2FsbChtZXRob2QsIGFyZ3MpIHtcbiAgY29uc3QgcmVtb3RlU2NvcGUgPSAodHlwZW9mIGN0eCAhPT0gJ3VuZGVmaW5lZCcgJiYgY3R4ICYmIHR5cGVvZiBjdHguZ2V0ID09PSAnZnVuY3Rpb24nKVxuICAgID8gY3R4XG4gICAgOiAodHlwZW9mIF91c2FnZUN0eCAhPT0gJ3VuZGVmaW5lZCcgJiYgX3VzYWdlQ3R4ICYmIHR5cGVvZiBfdXNhZ2VDdHguZ2V0ID09PSAnZnVuY3Rpb24nID8gX3VzYWdlQ3R4IDogbnVsbClcbiAgaWYgKHJlbW90ZVNjb3BlICYmIHR5cGVvZiByZW1vdGVTY29wZS5nZXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBsZXQgcGVuZGluZyA9IG51bGxcbiAgICB0cnkge1xuICAgICAgcGVuZGluZyA9IHJlbW90ZUNhbGwocmVtb3RlU2NvcGUsIG1ldGhvZCwgYXJncylcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBwZW5kaW5nID0gbnVsbFxuICAgIH1cbiAgICBpZiAocGVuZGluZyAhPT0gbnVsbCkge1xuICAgICAgLy8gRmFsbCB0aHJvdWdoIHRvIHRoZSBGZXRjaCByb3V0ZXMgd2hlbiB0aGUgUmVtb3RlIG5hbWVzcGFjZSB0dXJucyBvdXQgdG9cbiAgICAgIC8vIGJlIHVucmVhY2hhYmxlIOKAlCB0aGUgdHdvIGNoYW5uZWxzIGFuc3dlciB0aGUgc2FtZSBxdWVzdGlvbi5cbiAgICAgIHJldHVybiBwZW5kaW5nLmNhdGNoKCgpID0+IGZldGNoQ2FsbChtZXRob2QsIGFyZ3MpKVxuICAgIH1cbiAgfVxuICBpZiAodHlwZW9mIGhvc3QgIT09ICd1bmRlZmluZWQnICYmIGhvc3QgJiYgdHlwZW9mIGhvc3QuY2FsbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoaG9zdC5jYWxsKG1ldGhvZCwgYXJncykpXG4gIH1cbiAgcmV0dXJuIGZldGNoQ2FsbChtZXRob2QsIGFyZ3MpXG59XG5cbmZ1bmN0aW9uIGZldGNoQ2FsbChtZXRob2QsIGFyZ3MpIHtcbiAgLy8gU3RhdGljIGJ1bmRsZSBpbnN0YWxscyBoYXZlIG5vIGN0eC9ob3N0IGdsb2JhbHM6IHRoZSBlbnRyeSBhcHBseSgpIHN0b3Jlc1xuICAvLyB0aGUgcmVhbCBjb250ZXh0IGluIF91c2FnZUN0eCAoZGVjbGFyZWQgYnkgdGhlIGJ1aWxkIHdyYXBwZXIpLlxuICBjb25zdCBzY29wZSA9ICh0eXBlb2YgY3R4ICE9PSAndW5kZWZpbmVkJyAmJiBjdHggJiYgdHlwZW9mIGN0eC5nZXQgPT09ICdmdW5jdGlvbicpXG4gICAgPyBjdHhcbiAgICA6ICh0eXBlb2YgX3VzYWdlQ3R4ICE9PSAndW5kZWZpbmVkJyA/IF91c2FnZUN0eCA6IG51bGwpXG4gIGlmIChzY29wZSA9PT0gbnVsbCB8fCB0eXBlb2Ygc2NvcGUuZ2V0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignY29udGV4dCB1bmF2YWlsYWJsZScpKVxuICB9XG4gIGNvbnN0IG5hbWUgPSBTdHJpbmcobWV0aG9kKVxuICBjb25zdCBzbGFzaCA9IG5hbWUuaW5kZXhPZignLycpXG4gIGNvbnN0IGNoYW5uZWwgPSBzbGFzaCA9PT0gLTEgPyBuYW1lIDogbmFtZS5zbGljZSgwLCBzbGFzaClcbiAgY29uc3QgZW5kcG9pbnQgPSBzbGFzaCA9PT0gLTEgPyBuYW1lIDogbmFtZS5zbGljZShzbGFzaCArIDEpXG4gIC8vIExlZ2FjeSBwcmUtMC4yIHRyYW5zcG9ydDogYSBgL3VzYWdlYCBwcmVmaXggUlBDIGNoYW5uZWwgb3duZWQgYnkgdGhlIGhvc3RcbiAgLy8gcGx1Z2luIGl0c2VsZi5cbiAgY29uc3QgY2FsbFJwYyA9ICgpID0+IHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gc2NvcGUuZ2V0KCdjb25uZWN0aW9uJylcbiAgICBpZiAoY29ubmVjdGlvbiA9PT0gdW5kZWZpbmVkIHx8IGNvbm5lY3Rpb24ucnBjID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ2Nvbm5lY3Rpb24gc2VydmljZSB1bmF2YWlsYWJsZScpKVxuICAgIH1cbiAgICByZXR1cm4gY29ubmVjdGlvbi5ycGMuY2FsbCgnLycgKyBjaGFubmVsLnJlcGxhY2UoL15cXC8rLywgJycpLCBlbmRwb2ludCwgYXJncykudGhlbigocmVzKSA9PiB7XG4gICAgICBpZiAocmVzICYmIHJlcy5vaykgcmV0dXJuIHJlcy52YWx1ZVxuICAgICAgdGhyb3cgcnBjRXJyb3IocmVzICYmIHJlcy5lcnJvciwgJ1JQQyAnICsgbWV0aG9kICsgJyBmYWlsZWQnKVxuICAgIH0pXG4gIH1cbiAgLy8gUHJlZmVyIHRoZSBzaGFyZWQtY2hhbm5lbCBGZXRjaCByb3V0ZTsgYW4gb2xkZXIgaG9zdCBhbnN3ZXJzIFwicm91dGVcbiAgLy8gbWlzc2luZ1wiIGFuZCB3ZSBmYWxsIGJhY2sgdG8gdGhlIGxlZ2FjeSBjaGFubmVsIGl0IGRvZXMgaW1wbGVtZW50LlxuICBjb25zdCBmZXRjaFVzYWJsZSA9IHR5cGVvZiBmZXRjaCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmICEodHlwZW9mIGxvY2F0aW9uICE9PSAndW5kZWZpbmVkJyAmJiBsb2NhdGlvbi5wcm90b2NvbCA9PT0gJ2ZpbGU6JylcbiAgaWYgKCFmZXRjaFVzYWJsZSkgcmV0dXJuIGNhbGxScGMoKVxuICByZXR1cm4gY2FsbEZldGNoKGNoYW5uZWwsIGVuZHBvaW50LCBhcmdzKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICBpZiAoZXJyb3IgJiYgZXJyb3IuY29kZSA9PT0gJ3VzYWdlLXJvdXRlLW1pc3NpbmcnKSByZXR1cm4gY2FsbFJwYygpXG4gICAgdGhyb3cgZXJyb3JcbiAgfSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDorr7nva7ln5/lrprku7fvvJrlrpjmlrkgYGN0eC5jb25maWdGb3Jtcy5nZXQoJ3VzYWdlJylg77yIZHNoLWNsaWVudC11aS1zZXR0aW5nc++8ieS8mOWFiO+8jFxuICog5LiN5Y+v55So5pe25Zue6YCAIHVzYWdlL3ByaWNlcyBSUEPjgILnu5Hlrprlj6rlgZrkuIDmrKHvvIzor7vlhpnlhbHnlKjlkIzkuIAgZm9ybeOAglxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuLyoqXG4gKiDljp/nlJ/ml6Xlv5fpgJrpgZPvvJrlrr/kuLvmnIkgbG9nZ2VyIOWwseWGmeWug++8iOWumOaWueaPkuS7tumDvei1sCBjdHgubG9nZ2Vy77yJ77yM5ZCm5YiZ6YCA5ZueIGNvbnNvbGXjgIJcbiAqIGN0eCDmmK/kuKXmoLzku6PnkIbvvIzmnKrms6jlhaXnmoTlsZ7mgKfog73mipvvvIzmiYDku6XmlbTmrrXljIXlnKggdHJ5IOmHjOOAglxuICovXG5mdW5jdGlvbiBsb2dXYXJuKG1lc3NhZ2UsIGRldGFpbCkge1xuICB0cnkge1xuICAgIGNvbnN0IHNjb3BlID0gKHR5cGVvZiBfdXNhZ2VDdHggIT09ICd1bmRlZmluZWQnICYmIF91c2FnZUN0eCkgPyBfdXNhZ2VDdHggOiBudWxsXG4gICAgY29uc3QgbG9nZ2VyID0gc2NvcGUgJiYgdHlwZW9mIHNjb3BlLmdldCA9PT0gJ2Z1bmN0aW9uJyA/IHNjb3BlLmdldCgnbG9nZ2VyJykgOiBudWxsXG4gICAgaWYgKGxvZ2dlciAmJiB0eXBlb2YgbG9nZ2VyLndhcm4gPT09ICdmdW5jdGlvbicpIHsgbG9nZ2VyLndhcm4obWVzc2FnZSwgZGV0YWlsKTsgcmV0dXJuIH1cbiAgICBpZiAoc2NvcGUgJiYgc2NvcGUubG9nZ2VyICYmIHR5cGVvZiBzY29wZS5sb2dnZXIud2FybiA9PT0gJ2Z1bmN0aW9uJykgeyBzY29wZS5sb2dnZXIud2FybihtZXNzYWdlLCBkZXRhaWwpOyByZXR1cm4gfVxuICB9IGNhdGNoIChlKSB7IC8qIG5vIGxvZ2dlciBvbiB0aGlzIGNvbXBvc2l0aW9uICovIH1cbiAgY29uc29sZS53YXJuKG1lc3NhZ2UsIGRldGFpbClcbn1cblxubGV0IHVzYWdlQ3R4ID0gbnVsbFxubGV0IF91c2FnZVByaWNlc1Njb3BlID0gbnVsbFxuXG5mdW5jdGlvbiByZXNvbHZlVXNhZ2VDdHgoKSB7XG4gIGlmICh1c2FnZUN0eCAmJiB0eXBlb2YgdXNhZ2VDdHguZ2V0ID09PSAnZnVuY3Rpb24nKSByZXR1cm4gdXNhZ2VDdHhcbiAgaWYgKHR5cGVvZiBfdXNhZ2VDdHggIT09ICd1bmRlZmluZWQnICYmIF91c2FnZUN0eCAmJiB0eXBlb2YgX3VzYWdlQ3R4LmdldCA9PT0gJ2Z1bmN0aW9uJykgcmV0dXJuIF91c2FnZUN0eFxuICByZXR1cm4gbnVsbFxufVxuXG5mdW5jdGlvbiBnZXRVc2FnZVByaWNlc1Njb3BlKCkge1xuICBpZiAoX3VzYWdlUHJpY2VzU2NvcGUpIHJldHVybiBfdXNhZ2VQcmljZXNTY29wZVxuICBjb25zdCBjID0gcmVzb2x2ZVVzYWdlQ3R4KClcbiAgaWYgKCFjIHx8IHR5cGVvZiBjLmdldCAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIG51bGxcbiAgdHJ5IHtcbiAgICAvLyAwLjIueDogdGhlIG9mZmljaWFsIGNvbmZpZy1mb3JtIHN1cmZhY2UgZm9yIHRoaXMgcGx1Z2luJ3MgZW50cnkgaWRcbiAgICAvLyAoYHVzYWdlYCwgdGhlIGJ1bmRsZSBwYXRjaCByb3cgaWQpLiBgc2V0dGluZ3NTY29wZWAgZnJvbSAwLjEueCBkb2VzIG5vdFxuICAgIC8vIGV4aXN0IGluIHRoZSBzaGlwcGVkIGNsaWVudCwgc28gcHJvYmluZyBpdCBvbmx5IGV2ZXIgcmV0dXJuZWQgbnVsbC5cbiAgICBjb25zdCBmb3JtcyA9IGMuZ2V0KCdjb25maWdGb3JtcycpXG4gICAgaWYgKCFmb3JtcyB8fCB0eXBlb2YgZm9ybXMuZ2V0ICE9PSAnZnVuY3Rpb24nKSByZXR1cm4gbnVsbFxuICAgIF91c2FnZVByaWNlc1Njb3BlID0gZm9ybXMuZ2V0KCd1c2FnZScpXG4gICAgcmV0dXJuIF91c2FnZVByaWNlc1Njb3BlXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbi8vIOS7t+agvOWGmeWFpeWPo++8mnNldHRpbmdzIHNjb3BlIOWPr+eUqOaXtuWGmSB1c2FnZS5wcmljZXMg5ZG95ZCN56m66Ze05a2X5q6177yMXG4vLyDlkKbliJnlm57pgIAgdXNhZ2UvcHJpY2VzIFJQQ++8iOW9k+WJjSBVSSDml6Dku7fmoLznvJbovpHlmajvvIzkv53nlZnmraTlhpnlhaUgc2VhbSDkvpvlkI7nu63kvb/nlKjvvInjgIJcbmZ1bmN0aW9uIHVzYWdlU2F2ZVByaWNlcyhuZXh0KSB7XG4gIGNvbnN0IGFyZ3MgPSB7fVxuICBpZiAobmV4dCAmJiB0eXBlb2YgbmV4dCA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAobmV4dC5wcmljZXMgIT09IHVuZGVmaW5lZCkgYXJncy5wcmljZXMgPSBuZXh0LnByaWNlc1xuICAgIGlmIChuZXh0LmN1cnJlbmN5ICE9PSB1bmRlZmluZWQpIGFyZ3MuY3VycmVuY3kgPSBuZXh0LmN1cnJlbmN5XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCBzY29wZSA9IGdldFVzYWdlUHJpY2VzU2NvcGUoKVxuICAgIGlmIChzY29wZSAmJiB0eXBlb2Ygc2NvcGUuc2V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb25zdCBqb2JzID0gW11cbiAgICAgIGlmIChhcmdzLnByaWNlcyAhPT0gdW5kZWZpbmVkKSBqb2JzLnB1c2goc2NvcGUuc2V0KCdwcmljZXMnLCBhcmdzLnByaWNlcykpXG4gICAgICBpZiAoYXJncy5jdXJyZW5jeSAhPT0gdW5kZWZpbmVkKSBqb2JzLnB1c2goc2NvcGUuc2V0KCdjdXJyZW5jeScsIGFyZ3MuY3VycmVuY3kpKVxuICAgICAgaWYgKGpvYnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoam9icykudGhlbigoKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc25hcCA9IHR5cGVvZiBzY29wZS5nZXRTbmFwc2hvdCA9PT0gJ2Z1bmN0aW9uJyA/IHNjb3BlLmdldFNuYXBzaG90KCkgOiBudWxsXG4gICAgICAgICAgcmV0dXJuIHNuYXAgJiYgc25hcC52YWx1ZSA/IHNuYXAudmFsdWUgOiBudWxsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gZmFsbCB0aHJvdWdoIHRvIHRoZSBSUEMgd3JpdGUgcGF0aFxuICB9XG4gIHJldHVybiBob3N0Q2FsbCgndXNhZ2UvcHJpY2VzJywgYXJncylcbn1cblxuO1xuY29uc3QgaCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnRcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDlm73pmYXljJbvvJp6aC9lbiDlrZflhbggKyBDb250ZXh077yIbG9jYWxlIOacjeWKoee7jyBzbG90IOazqOWGjOazqOWFpSB077yM5a2Q57uE5Lu257uPIENvbnRleHQg5Y+W55So77yJXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5jb25zdCBOUyA9ICd1c2FnZSdcbmNvbnN0IFpIID0ge1xuICBuYXY6ICfnlKjph4/nu5/orqEnLFxuICBzdWJ0aXRsZTogJ+afpeeciyBBSSDmqKHlnovnmoTkvb/nlKjmg4XlhrXlkozmiJDmnKznu5/orqEnLFxuICByZWZyZXNoOiAn5Yi35pawJyxcbiAgY3VycmVuY3lIaW50OiAn5Y+C6ICD5oiQ5pys5biB56eN77yI5Zu65a6a5rGH546HIDEgVVNEID0gNyBDTlnvvIknLFxuICBjdXJyZW5jeUNOWTogJ+S6uuawkeW4gScsXG4gIGN1cnJlbmN5VVNEOiAn576O5YWDJyxcbiAgdG9kYXk6ICfku4rml6UnLFxuICBkb2NrSGludDogJ+S7iuaXpSB7Y29zdH0gwrcge2NhbGxzfSDmrKHosIPnlKggwrcge3Rva2Vuc30gVG9rZW4nLFxuICBkb2NrVW5wcmljZWQ6ICfmnKrlrprku7cnLFxuICBsYXN0N2Q6ICfov5E35aSpJyxcbiAgbGFzdDMwZDogJ+i/kTMw5aSpJyxcbiAgY3VzdG9tOiAn6Ieq5a6a5LmJJyxcbiAgYWxsOiAn5YWo6YOoJyxcbiAgYWxsTW9kZWxzOiAn5YWo6YOo5qih5Z6LJyxcbiAgc2VsZWN0ZWRNb2RlbHM6ICflt7LpgIkge2NvdW50fSDkuKrmqKHlnosnLFxuICBzZWxlY3RBbGw6ICflhajpgIknLFxuICBjbGVhcjogJ+a4heepuicsXG4gIHNlYXJjaE1vZGVsczogJ+aQnOe0ouaooeWeiycsXG4gIG5vTWF0Y2hNb2RlbHM6ICfml6DljLnphY3mqKHlnosnLFxuICBtb2RlbEZpbHRlckhpbnQ6ICfli77pgInljbPml7bnlJ/mlYjvvIzku4XliJflh7rlvZPliY3ojIPlm7TlhoXmnInmlbDmja7nmoTmqKHlnosnLFxuICBjdXN0b21SYW5nZVRpdGxlOiAn6Ieq5a6a5LmJ5pe26Ze06IyD5Zu0JyxcbiAgY3VzdG9tUmFuZ2VBcmlhOiAn6Ieq5a6a5LmJ5pel5pyf6IyD5Zu0JyxcbiAgc3RhcnRUaW1lOiAn5byA5aeL5pe26Ze0JyxcbiAgZW5kVGltZTogJ+e7k+adn+aXtumXtCcsXG4gIHJhbmdlSW52YWxpZDogJ+W8gOWni+aXtumXtOS4jeiDveaZmuS6jue7k+adn+aXtumXtCcsXG4gIHJhbmdlSGludDogJ+aUr+aMgemAieaLqeS7u+aEj+aXpeacn+iMg+WbtO+8jOS4jemZkOi3qOW6picsXG4gIGNhbmNlbDogJ+WPlua2iCcsXG4gIGNvbmZpcm06ICfnoa7lrponLFxuICBkYXRlUmFuZ2VHcm91cDogJ+aXpeacn+iMg+WbtCcsXG4gIG1vZGVsRmlsdGVyR3JvdXA6ICfmqKHlnovnrZvpgIknLFxuICBjaGFydFR5cGVHcm91cDogJ+WbvuihqOexu+WeiycsXG4gIHRvdGFsVG9rZW5zOiAn5oC7IFRva2VuJyxcbiAgaW5wdXRUb2tlbnM6ICfovpPlhaUgVG9rZW4nLFxuICBvdXRwdXRUb2tlbnM6ICfovpPlh7ogVG9rZW4nLFxuICBjYWxsczogJ+iwg+eUqOasoeaVsCcsXG4gIGNvc3Q6ICflj4LogIPmiJDmnKwnLFxuICBhcHByb3hJTzogJ+KJiCDovpPlhaUr6L6T5Ye6JyxcbiAgdW5wcmljZWROb3RlOiAne2NvdW50fSDmrKHosIPnlKjmnKrlrprku7cnLFxuICAvLyDlj4LogIPmiJDmnKzljaHkuIrnmoTluLjpqbvohJrms6jvvJrlj6PlvoTvvIjljaHniYfmmK/kvLDnrpfogIzkuI3mmK/otKbljZXvvIkrIOmrmOWzsOinhOWIme+8iOWNleS7t+aMiVxuICAvLyDljJfkuqzml7bpl7TliIbls7DosLfvvIzkuI3or7TmuIXmpZrlsLHnrYnkuo7ol4/kuobkuIDmnaHorqHku7fmnaHku7bvvInjgIJcbiAgY29zdFNvdXJjZU5vdGU6ICfmjIkgb3BlbmNvZGUgWmVuIOWSjCBEZWVwU2VlayDmnIDmlrDlrprku7flj6PlvoTkvLDnrpcnLFxuICBwZWFrUnVsZVNob3J0OiAn5YyX5Lqs5pe26Ze05ZGo5LiA6Iez5ZGo5LqUIDk6MDAtMTI6MDDjgIExNDowMC0xODowMCDkuLrpq5jls7DvvIzms5XlrproioLlgYfml6XpmaTlpJYnLFxuICBob2xpZGF5Tm90ZTogJ+iKguWBh+aXpeaVsOaNru+8mntyYW5nZX0nLFxuICBob2xpZGF5Tm90ZVVucHVibGlzaGVkOiAn6IqC5YGH5pel5pWw5o2u77yae3Jhbmdlfe+8m3t5ZWFyc30g5bCa5pyq5YWs5biD77yM6K+l5bm05oyJ5ZGo5pyr5Yik5a6a77yI6JC95Zyo6auY5bOw56qX5Y+j55qE6IqC5YGH5pel5Y+v6IO96KKr566X6auY77yJJyxcbiAgcHJpY2luZ09wZW46ICfmi4nlj5bmnIDmlrDlrprku7fljLnphY0nLFxuICBwcmljaW5nVGl0bGU6ICflrprku7fljLnphY0nLFxuICBwcmljaW5nRGVzYzogJ+acrOS8muivneWHuueOsOi/h+eahOaooeWei+S8muaMieWQjeensOmAkOe6p+WMuemFjeWIsOWumuS7t+ihqO+8m+acquWMuemFjeeahOaMiSAwIOiuoeS7t++8jOiuoeWFpeOAjOacquWumuS7t+OAjeOAgicsXG4gIHByaWNpbmdQdWxsOiAn5pu05paw5Yy56YWN6KGoJyxcbiAgcHJpY2luZ0hpc3Rvcnk6ICfljoblj7LljLnphY3vvIh7bn3vvIknLFxuICBwcmljaW5nSGlzdG9yeUVtcHR5OiAn6L+Y5rKh5pyJ56Gu6K6k6L+H55qE5Yy56YWNJyxcbiAgcHJpY2luZ0NvbE1vZGVsOiAn5qih5Z6LJyxcbiAgcHJpY2luZ0NvbE1hdGNoOiAn5Yy56YWN5YiwJyxcbiAgcHJpY2luZ0NvbFN0YXRlOiAn54q25oCBJyxcbiAgcHJpY2luZ0NvbFByaWNlOiAn5Y2V5Lu377yIe3VuaXR9IC8gMU3vvIknLFxuICBwcmljaW5nU2F2ZTogJ+ehruWumicsXG4gIHByaWNpbmdDbGVhcjogJ+aBouWkjeiHquWKqOWMuemFjScsXG4gIHByaWNpbmdBcHBseUhpbnQ6ICfmlLnlrozngrnjgIznoa7lrprjgI3miY3nlJ/mlYgnLFxuICBwcmljaW5nSG93QWxpYXM6ICfmjInliKvlkI0nLFxuICAvLyDmqKHns4rmgIHnmoTlvr3moIfvvJrliKvlkI3jgIHlrarnlJ/jgIHlj5jkvZPlkI7nvIDvvIgtZmFzdCAvIC0xMDE3IC8gLWZyZWXvvInpg73okL3lnKjov5nkuIDmgIHvvIxcbiAgLy8g5omA5Lul5paH5qGI6K+044CM5o6o5rWL44CN6ICM5LiN5piv5p+Q5LiA56eN5o6o5pat55qE5ZCN5a2X77yb5YW35L2T5L6d5o2u55yL5b695qCH55qEIHRvb2x0aXDjgIJcbiAgcHJpY2luZ0hvd1R3aW46ICfmjInlkI3np7DmjqjmtYsnLFxuICBwcmljaW5nSG93TGl0ZXJhbDogJ+aMieWQjeensOeyvuehricsXG4gIHByaWNpbmdIb3dDdXN0b206ICfnlKjmiLfmjIflrponLFxuICAvLyDmnKrljLnphY3mgIHnmoTlvr3moIfmlofmoYjjgILljp/mnaUgTUFUQ0hfU1RBVEVfTEFCRUwg5oyH5ZCR5LiA5Liq5LiN5a2Y5Zyo55qE6ZSuXG4gIC8vICd1bm1hdGNoZWQn77yMdCgpIOe8uumUruaXtuWOn+agt+i/lOWbniBrZXnvvIzkuo7mmK/lvr3moIfkuIrljbDnnYDoi7HmlocgXCJ1bm1hdGNoZWRcIuOAglxuICBwcmljaW5nSG93Tm9uZTogJ+acquWMuemFjScsXG4gIHByaWNpbmdTdGFsZTogJ+WumuS7t+ihqOmHjOW3suayoeaciei/meS4quaooeWeiycsXG4gIHByaWNpbmdUYWJsZU1ldGE6ICfmlbDmja7mupAge3NvdXJjZX0gwrcg6K+75Y+W5LqOIHtkYXRlfScsXG4gIHByaWNpbmdDb3VudHM6ICfnsr7noa4ge2V4YWN0fSDCtyDmqKHns4oge2Z1enp5fSDCtyDmnKrljLnphY0ge25vbmV9IMK3IOiHquWumuS5iSB7Y3VzdG9tfScsXG4gIHByaWNpbmdCb3RoVGllcnM6ICfpq5jls7Age3BlYWt9IMK3IOepuumXsiB7b2ZmfScsXG4gIHByaWNpbmdTb3VyY2VEZWVwc2VlazogJ0RlZXBTZWVrJyxcbiAgcHJpY2luZ1NvdXJjZVplbjogJ1plbicsXG4gIHByaWNpbmdTb3VyY2VDdXN0b206ICfoh6rlrprkuYknLFxuICAvLyDjgIzoh6rlrprkuYnjgI3mmK/pgInmi6nlmajpobbpg6jnmoTkuIDkuKrpgInpobnvvIzkuI3mmK/kuIDnu4Tlj4LogIPmqKHlnovvvJrpgInlroPlsLHnm7TmjqXnu5nov5nkuIDooYzloavkuInkuKrljZXku7fjgIJcbiAgcHJpY2luZ0N1c3RvbU9wdGlvbjogJ+iHquWumuS5iScsXG4gIHByaWNpbmdDdXN0b21IaW50OiAn55u05o6l5aGr5q+P55m+5LiHIFRva2VuIOeahOWNleS7tycsXG4gIHByaWNpbmdDdXN0b21JbnB1dDogJ+i+k+WFpScsXG4gIHByaWNpbmdDdXN0b21PdXRwdXQ6ICfovpPlh7onLFxuICBwcmljaW5nQ3VzdG9tQ2FjaGVSZWFkOiAn57yT5a2Y6K+7JyxcbiAgcHJpY2luZ0N1c3RvbVVuaXQ6ICfljZXkvY3vvJp7dW5pdH0gLyAxTSBUb2tlbicsXG4gIHByaWNpbmdDdXN0b21QZW5kaW5nOiAn5b6F5aGr5YaZJyxcbiAgcnBjSW50ZXJuYWxFcnJvcjogJ+e7n+iuoeacjeWKoeWHuumUmeS6hu+8jOe7huiKguW3suWGmei/m+Wuv+S4u+aXpeW/lycsXG4gIGRvbmU6ICflrozmiJAnLFxuICBwcmljaW5nQ2FyZE5vdGVUaXA6ICflj4LogIPmiJDmnKznmoTnrpfms5XjgIHljLnphY3ojIPlm7TkuI7pq5jls7Dml7bmrrXop4TliJknLFxuICBhc2tFbXB0eTogJ+aaguaXoOW+heWMuemFjeeahOaooeWeiycsXG4gIGFza1BpY2s6ICfpgInmi6nlj4LogIPmqKHlnosnLFxuICBwcmljaW5nRmFpbGVkOiAn5a6a5Lu36KGo5ouJ5Y+W5aSx6LSl77yae21lc3NhZ2V9JyxcbiAgZGFpbHlUcmVuZDogJ+avj+aXpeeUqOmHj+i2i+WKvycsXG4gIGJhclZpZXc6ICfmn7Hnirblm74nLFxuICBsaW5lVmlldzogJ+aKmOe6v+WbvicsXG4gIGJ5SG91cjogJ+aMieWwj+aXticsXG4gIGJ5RGF5OiAn5oyJ5aSpJyxcbiAgZXZlcnlORGF5czogJ+avjyB7bn0g5aSpJyxcbiAgbGVnZW5kSW5wdXQ6ICfovpPlhaUnLFxuICBsZWdlbmRPdXRwdXQ6ICfovpPlh7onLFxuICBsZWdlbmRUb3RhbDogJ+aAuyBUb2tlbicsXG4gIHRvb2x0aXBUb3RhbDogJ+WQiOiuoScsXG4gIHN0YXJ0TkRheXM6ICfotbcge259IOWkqScsXG4gIGxpbmVDaGFydEFyaWE6ICdUb2tlbiDnlKjph4/otovlir/mipjnur/lm74nLFxuICB5ZWFybHlIZWF0bWFwOiAn5bm05bqm55So6YeP54Ot5Yqb5Zu+JyxcbiAgeWVhckRhaWx5OiAne3llYXJ9IOW5tOavj+aXpSBUb2tlbiDnlKjph48nLFxuICBtb250aExhYmVsOiAne2595pyIJyxcbiAgd2Vla2RheU1vbjogJ+S4gCcsXG4gIHdlZWtkYXlXZWQ6ICfkuIknLFxuICB3ZWVrZGF5RnJpOiAn5LqUJyxcbiAgbGVzczogJ+WwkScsXG4gIG1vcmU6ICflpJonLFxuICBieU1vZGVsVGl0bGU6ICfmjInmqKHlnovmmI7nu4YnLFxuICBtb2RlbENvdW50OiAn5YWxIHtufSDkuKrmqKHlnosnLFxuICBtb2RlbFRhYmxlQ2FwdGlvbjogJ+aMieaooeWei+eUqOmHj+aYjue7hicsXG4gIGNvbE1vZGVsOiAn5qih5Z6LJyxcbiAgY29sQ2FsbHM6ICfor7fmsYLmlbAnLFxuICBjb2xJbnB1dDogJ+i+k+WFpSBUb2tlbicsXG4gIGNvbE91dHB1dDogJ+i+k+WHuiBUb2tlbicsXG4gIGNvbFRvdGFsOiAn5oC7IFRva2VuJyxcbiAgY29sQ29zdDogJ+WPguiAg+aIkOacrCcsXG4gIGNvbFNoYXJlOiAn5Y2g5q+UJyxcbiAgbW9kZWxTaGFyZTogJ+aooeWei+WNoOavlCcsXG4gIHNoYXJlT3RoZXI6ICflhbblroMnLFxuICB1bnByaWNlZDogJ+acquWumuS7tycsXG4gIHVucHJpY2VkUm93SGludDogJ+ivpeaooeWei+acqumFjee9ruWumuS7t++8jOaMiSAwIOiuoeS7tycsXG4gIG5vRGF0YTogJ+aaguaXoOaVsOaNricsXG4gIGxvYWRpbmc6ICfmraPlnKjliqDovb3nlKjph4/mlbDmja7igKYnLFxuICBjb21wdXRpbmc6ICfmraPlnKjnu5/orqEge2RvbmV9L3t0b3RhbH0g5Liq5Lya6K+d4oCmJyxcbiAgZW1wdHlEZXNjOiAn6K+l5pe26Ze05q615YaF5rKh5pyJ6LCD55So6K6w5b2VJyxcbiAgZW1wdHlGaWx0ZXJlZDogJ+W9k+WJjeetm+mAieadoeS7tuS4i+ayoeacieaVsOaNru+8jOivleivleiwg+aVtOaXtumXtOiMg+WbtOaIluaooeWeiycsXG4gIHJlc2V0RmlsdGVyczogJ+mHjee9ruetm+mAiScsXG4gIGxvYWRGYWlsZWQ6ICfmlbDmja7liqDovb3lpLHotKXvvJp7bWVzc2FnZX0nLFxuICBsb2FkRmFpbGVkVGl0bGU6ICfmlbDmja7liqDovb3lpLHotKUnLFxuICByZXRyeTogJ+mHjeivlScsXG4gIGJhckFyaWE6ICd7a2V5fe+8jOi+k+WFpSB7aW59IFRva2Vu77yM6L6T5Ye6IHtvdXR9IFRva2Vu77yM5ZCI6K6hIHt0b3R9IFRva2Vu77yM5Y+C6ICD5oiQ5pysIHtjb3N0fScsXG4gIGhtVGl0bGU6ICd7a2V5fe+8mnt0b2tlbnN9IFRva2Vue2NhbGxzfe+8jOWPguiAg+aIkOacrCB7Y29zdH0nLFxuICBobUNhbGxzOiAn77yMe2NvdW50fSDmrKHosIPnlKgnLFxuICB3ZDA6ICflkajml6UnLFxuICB3ZDE6ICflkajkuIAnLFxuICB3ZDI6ICflkajkuownLFxuICB3ZDM6ICflkajkuIknLFxuICB3ZDQ6ICflkajlm5snLFxuICB3ZDU6ICflkajkupQnLFxuICB3ZDY6ICflkajlha0nLFxufVxuY29uc3QgRU4gPSB7XG4gIG5hdjogJ1VzYWdlIFN0YXRzJyxcbiAgc3VidGl0bGU6ICdWaWV3IEFJIG1vZGVsIHVzYWdlIGFuZCBjb3N0IHN0YXRpc3RpY3MnLFxuICByZWZyZXNoOiAnUmVmcmVzaCcsXG4gIGN1cnJlbmN5SGludDogJ1JlZmVyZW5jZS1jb3N0IGN1cnJlbmN5IChmaXhlZCByYXRlOiAxIFVTRCA9IDcgQ05ZKScsXG4gIGN1cnJlbmN5Q05ZOiAnQ05ZJyxcbiAgY3VycmVuY3lVU0Q6ICdVU0QnLFxuICB0b2RheTogJ1RvZGF5JyxcbiAgZG9ja0hpbnQ6ICdUb2RheSB7Y29zdH0gwrcge2NhbGxzfSBjYWxscyDCtyB7dG9rZW5zfSB0b2tlbnMnLFxuICBkb2NrVW5wcmljZWQ6ICd1bnByaWNlZCcsXG4gIGxhc3Q3ZDogJ0xhc3QgNyBkYXlzJyxcbiAgbGFzdDMwZDogJ0xhc3QgMzAgZGF5cycsXG4gIGN1c3RvbTogJ0N1c3RvbScsXG4gIGFsbDogJ0FsbCcsXG4gIGFsbE1vZGVsczogJ0FsbCBtb2RlbHMnLFxuICBzZWxlY3RlZE1vZGVsczogJ3tjb3VudH0gbW9kZWxzIHNlbGVjdGVkJyxcbiAgc2VsZWN0QWxsOiAnU2VsZWN0IGFsbCcsXG4gIGNsZWFyOiAnQ2xlYXInLFxuICBzZWFyY2hNb2RlbHM6ICdTZWFyY2ggbW9kZWxzJyxcbiAgbm9NYXRjaE1vZGVsczogJ05vIG1hdGNoaW5nIG1vZGVscycsXG4gIG1vZGVsRmlsdGVySGludDogJ0FwcGxpZXMgaW5zdGFudGx5OyBsaXN0cyBvbmx5IG1vZGVscyB3aXRoIGRhdGEgaW4gdGhlIHJhbmdlJyxcbiAgY3VzdG9tUmFuZ2VUaXRsZTogJ0N1c3RvbSB0aW1lIHJhbmdlJyxcbiAgY3VzdG9tUmFuZ2VBcmlhOiAnQ3VzdG9tIGRhdGUgcmFuZ2UnLFxuICBzdGFydFRpbWU6ICdTdGFydCcsXG4gIGVuZFRpbWU6ICdFbmQnLFxuICByYW5nZUludmFsaWQ6ICdTdGFydCBtdXN0IG5vdCBiZSBsYXRlciB0aGFuIGVuZCcsXG4gIHJhbmdlSGludDogJ0FueSBkYXRlIHJhbmdlIOKAlCBubyBsZW5ndGggbGltaXQnLFxuICBjYW5jZWw6ICdDYW5jZWwnLFxuICBjb25maXJtOiAnT0snLFxuICBkYXRlUmFuZ2VHcm91cDogJ0RhdGUgcmFuZ2UnLFxuICBtb2RlbEZpbHRlckdyb3VwOiAnTW9kZWwgZmlsdGVyJyxcbiAgY2hhcnRUeXBlR3JvdXA6ICdDaGFydCB0eXBlJyxcbiAgdG90YWxUb2tlbnM6ICdUb3RhbCBUb2tlbnMnLFxuICBpbnB1dFRva2VuczogJ0lucHV0IFRva2VucycsXG4gIG91dHB1dFRva2VuczogJ091dHB1dCBUb2tlbnMnLFxuICBjYWxsczogJ0NhbGxzJyxcbiAgY29zdDogJ0VzdC4gY29zdCcsXG4gIGFwcHJveElPOiAn4omIIGlucHV0K291dHB1dCcsXG4gIHVucHJpY2VkTm90ZTogJ3tjb3VudH0gY2FsbHMgdW5wcmljZWQnLFxuICBjb3N0U291cmNlTm90ZTogJ0VzdGltYXRlZCBmcm9tIHRoZSBjdXJyZW50IG9wZW5jb2RlIFplbiBhbmQgRGVlcFNlZWsgcHJpY2UgbGlzdHMnLFxuICBwZWFrUnVsZVNob3J0OiAnUGVhazogTW9uLUZyaSAwOTowMC0xMjowMCBhbmQgMTQ6MDAtMTg6MDAgQmVpamluZyB0aW1lLCBleGNsdWRpbmcgcHVibGljIGhvbGlkYXlzJyxcbiAgaG9saWRheU5vdGU6ICdIb2xpZGF5IGNhbGVuZGFyOiB7cmFuZ2V9JyxcbiAgaG9saWRheU5vdGVVbnB1Ymxpc2hlZDogJ0hvbGlkYXkgY2FsZW5kYXI6IHtyYW5nZX07IHt5ZWFyc30gaXMgbm90IHB1Ymxpc2hlZCB5ZXQsIHNvIHRoYXQgeWVhciBmYWxscyBiYWNrIHRvIHRoZSB3ZWVrZW5kIHJ1bGUgKGEgaG9saWRheSBpbnNpZGUgYSBwZWFrIHdpbmRvdyBtYXkgYmUgYmlsbGVkIGhpZ2gpJyxcbiAgcHJpY2luZ09wZW46ICdQdWxsIHRoZSBsYXRlc3QgcHJpY2UgbWF0Y2hpbmcnLFxuICBwcmljaW5nVGl0bGU6ICdQcmljZSBtYXRjaGluZycsXG4gIHByaWNpbmdEZXNjOiAnTW9kZWxzIHNlZW4gaW4gdGhpcyBzZXNzaW9uIGFyZSBtYXRjaGVkIHRvIHRoZSBwcmljZSBsaXN0IGJ5IG5hbWUsIG9uZSBsZXZlbCBhdCBhIHRpbWUuIEFueXRoaW5nIHVubWF0Y2hlZCBpcyBiaWxsZWQgYXQgMCBhbmQgbGlzdGVkIHVuZGVyIHVucHJpY2VkLicsXG4gIHByaWNpbmdQdWxsOiAnVXBkYXRlIG1hdGNoZXMnLFxuICBwcmljaW5nSGlzdG9yeTogJ0NvbmZpcm1lZCBtYXRjaGVzICh7bn0pJyxcbiAgcHJpY2luZ0hpc3RvcnlFbXB0eTogJ05vIG1hdGNoIGhhcyBiZWVuIGNvbmZpcm1lZCB5ZXQnLFxuICBwcmljaW5nQ29sTW9kZWw6ICdNb2RlbCcsXG4gIHByaWNpbmdDb2xNYXRjaDogJ01hdGNoZWQgdG8nLFxuICBwcmljaW5nQ29sU3RhdGU6ICdTdGF0ZScsXG4gIHByaWNpbmdDb2xQcmljZTogJ1JhdGUgKHt1bml0fSAvIDFNKScsXG4gIHByaWNpbmdTYXZlOiAnQXBwbHknLFxuICBwcmljaW5nQ2xlYXI6ICdCYWNrIHRvIGF1dG9tYXRpYycsXG4gIHByaWNpbmdBcHBseUhpbnQ6ICdOb3RoaW5nIGNoYW5nZXMgdW50aWwgeW91IHByZXNzIEFwcGx5JyxcbiAgcHJpY2luZ0hvd0FsaWFzOiAnYnkgYWxpYXMnLFxuICBwcmljaW5nSG93VHdpbjogJ2luZmVycmVkIGZyb20gdGhlIG5hbWUnLFxuICBwcmljaW5nSG93TGl0ZXJhbDogJ2J5IGV4YWN0IG5hbWUnLFxuICBwcmljaW5nSG93Q3VzdG9tOiAnc2V0IGJ5IHlvdScsXG4gIHByaWNpbmdIb3dOb25lOiAndW5tYXRjaGVkJyxcbiAgcHJpY2luZ1N0YWxlOiAnVGhpcyBtb2RlbCBpcyBubyBsb25nZXIgaW4gdGhlIHByaWNlIGxpc3QnLFxuICBwcmljaW5nVGFibGVNZXRhOiAnU291cmNlcyB7c291cmNlfSDCtyByZWFkIHtkYXRlfScsXG4gIHByaWNpbmdDb3VudHM6ICdleGFjdCB7ZXhhY3R9IMK3IGZ1enp5IHtmdXp6eX0gwrcgdW5tYXRjaGVkIHtub25lfSDCtyBjdXN0b20ge2N1c3RvbX0nLFxuICBwcmljaW5nQm90aFRpZXJzOiAnUGVhayB7cGVha30gwrcgb2ZmLXBlYWsge29mZn0nLFxuICBwcmljaW5nU291cmNlRGVlcHNlZWs6ICdEZWVwU2VlaycsXG4gIHByaWNpbmdTb3VyY2VaZW46ICdaZW4nLFxuICBwcmljaW5nU291cmNlQ3VzdG9tOiAnQ3VzdG9tJyxcbiAgcHJpY2luZ0N1c3RvbU9wdGlvbjogJ0N1c3RvbScsXG4gIHByaWNpbmdDdXN0b21IaW50OiAnVHlwZSB0aGUgcGVyLW1pbGxpb24gcmF0ZXMgYnkgaGFuZCcsXG4gIHByaWNpbmdDdXN0b21JbnB1dDogJ0lucHV0JyxcbiAgcHJpY2luZ0N1c3RvbU91dHB1dDogJ091dHB1dCcsXG4gIHByaWNpbmdDdXN0b21DYWNoZVJlYWQ6ICdDYWNoZSByZWFkJyxcbiAgcHJpY2luZ0N1c3RvbVVuaXQ6ICdVbml0OiB7dW5pdH0gcGVyIDFNIHRva2VucycsXG4gIHByaWNpbmdDdXN0b21QZW5kaW5nOiAnbm90IHNldCcsXG4gIHJwY0ludGVybmFsRXJyb3I6ICdUaGUgdXNhZ2Ugc2VydmljZSBmYWlsZWQg4oCUIGRldGFpbHMgYXJlIGluIHRoZSBob3N0IGxvZycsXG4gIGRvbmU6ICdEb25lJyxcbiAgcHJpY2luZ0NhcmROb3RlVGlwOiAnSG93IHRoZSByZWZlcmVuY2UgY29zdCBpcyBlc3RpbWF0ZWQsIHdoaWNoIG1vZGVscyBpdCBjb3ZlcnMsIGFuZCB0aGUgcGVhay1ob3VyIHJ1bGUnLFxuICBhc2tFbXB0eTogJ05vIG1vZGVsIGlzIHdhaXRpbmcgdG8gYmUgbWF0Y2hlZCcsXG4gIGFza1BpY2s6ICdDaG9vc2UgYSByZWZlcmVuY2UgbW9kZWwnLFxuICBwcmljaW5nRmFpbGVkOiAnQ291bGQgbm90IGxvYWQgdGhlIHByaWNlIGxpc3RzOiB7bWVzc2FnZX0nLFxuICBkYWlseVRyZW5kOiAnRGFpbHkgdXNhZ2UgdHJlbmQnLFxuICBiYXJWaWV3OiAnQmFycycsXG4gIGxpbmVWaWV3OiAnTGluZScsXG4gIGJ5SG91cjogJ0hvdXJseScsXG4gIGJ5RGF5OiAnRGFpbHknLFxuICBldmVyeU5EYXlzOiAnRXZlcnkge259IGRheXMnLFxuICBsZWdlbmRJbnB1dDogJ0lucHV0JyxcbiAgbGVnZW5kT3V0cHV0OiAnT3V0cHV0JyxcbiAgbGVnZW5kVG90YWw6ICdUb3RhbCcsXG4gIHRvb2x0aXBUb3RhbDogJ1RvdGFsJyxcbiAgc3RhcnRORGF5czogJ2ZvciB7bn0gZGF5cycsXG4gIGxpbmVDaGFydEFyaWE6ICdUb2tlbiB1c2FnZSB0cmVuZCBsaW5lIGNoYXJ0JyxcbiAgeWVhcmx5SGVhdG1hcDogJ1llYXJseSBoZWF0bWFwJyxcbiAgeWVhckRhaWx5OiAnRGFpbHkgdG9rZW5zIGluIHt5ZWFyfScsXG4gIG1vbnRoTGFiZWw6ICd7bn0nLFxuICB3ZWVrZGF5TW9uOiAnTW9uJyxcbiAgd2Vla2RheVdlZDogJ1dlZCcsXG4gIHdlZWtkYXlGcmk6ICdGcmknLFxuICBsZXNzOiAnTGVzcycsXG4gIG1vcmU6ICdNb3JlJyxcbiAgYnlNb2RlbFRpdGxlOiAnQnkgbW9kZWwnLFxuICBtb2RlbENvdW50OiAne259IG1vZGVscycsXG4gIG1vZGVsVGFibGVDYXB0aW9uOiAnVG9rZW4gdXNhZ2UgYnkgbW9kZWwnLFxuICBjb2xNb2RlbDogJ01vZGVsJyxcbiAgY29sQ2FsbHM6ICdDYWxscycsXG4gIGNvbElucHV0OiAnSW5wdXQgVG9rZW5zJyxcbiAgY29sT3V0cHV0OiAnT3V0cHV0IFRva2VucycsXG4gIGNvbFRvdGFsOiAnVG90YWwgVG9rZW5zJyxcbiAgY29sQ29zdDogJ0VzdC4gY29zdCcsXG4gIGNvbFNoYXJlOiAnU2hhcmUnLFxuICBtb2RlbFNoYXJlOiAnTW9kZWwgc2hhcmUnLFxuICBzaGFyZU90aGVyOiAnT3RoZXJzJyxcbiAgdW5wcmljZWQ6ICdVbnByaWNlZCcsXG4gIHVucHJpY2VkUm93SGludDogJ05vIHByaWNpbmcgY29uZmlndXJlZDsgY291bnRlZCBhcyAwJyxcbiAgbm9EYXRhOiAnTm8gZGF0YScsXG4gIGxvYWRpbmc6ICdMb2FkaW5nIHVzYWdlIGRhdGHigKYnLFxuICBjb21wdXRpbmc6ICdDb21wdXRpbmcge2RvbmV9L3t0b3RhbH0gc2Vzc2lvbnPigKYnLFxuICBlbXB0eURlc2M6ICdObyBjYWxscyBpbiB0aGlzIHBlcmlvZCcsXG4gIGVtcHR5RmlsdGVyZWQ6ICdObyBkYXRhIGZvciB0aGUgY3VycmVudCBmaWx0ZXJzLCB0cnkgYWRqdXN0aW5nIHRoZSByYW5nZSBvciBtb2RlbHMnLFxuICByZXNldEZpbHRlcnM6ICdSZXNldCBmaWx0ZXJzJyxcbiAgbG9hZEZhaWxlZDogJ0ZhaWxlZCB0byBsb2FkIGRhdGE6IHttZXNzYWdlfScsXG4gIGxvYWRGYWlsZWRUaXRsZTogJ0ZhaWxlZCB0byBsb2FkIGRhdGEnLFxuICByZXRyeTogJ1JldHJ5JyxcbiAgYmFyQXJpYTogJ3trZXl9LCBpbnB1dCB7aW59IHRva2Vucywgb3V0cHV0IHtvdXR9IHRva2VucywgdG90YWwge3RvdH0gdG9rZW5zLCB7Y29zdH0gcmVmZXJlbmNlIGNvc3QnLFxuICBobVRpdGxlOiAne2tleX06IHt0b2tlbnN9IHRva2Vuc3tjYWxsc30sIHtjb3N0fSByZWZlcmVuY2UgY29zdCcsXG4gIGhtQ2FsbHM6ICcsIHtjb3VudH0gY2FsbHMnLFxuICB3ZDA6ICdTdW4nLFxuICB3ZDE6ICdNb24nLFxuICB3ZDI6ICdUdWUnLFxuICB3ZDM6ICdXZWQnLFxuICB3ZDQ6ICdUaHUnLFxuICB3ZDU6ICdGcmknLFxuICB3ZDY6ICdTYXQnLFxufVxuY29uc3QgVCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQobnVsbClcbmZ1bmN0aW9uIHVzZVQoKSB7XG4gIHJldHVybiBSZWFjdC51c2VDb250ZXh0KFQpXG59XG5mdW5jdGlvbiBmYWxsYmFja1Qoa2V5LCBwYXJhbXMpIHtcbiAgbGV0IHMgPSBaSFtrZXldXG4gIGlmIChzID09PSB1bmRlZmluZWQpIHJldHVybiBrZXlcbiAgaWYgKHBhcmFtcykge1xuICAgIHMgPSBzLnJlcGxhY2UoL1xceyhcXHcrKVxcfS9nLCAobSwgbikgPT4gKHBhcmFtc1tuXSAhPT0gdW5kZWZpbmVkID8gU3RyaW5nKHBhcmFtc1tuXSkgOiBtKSlcbiAgfVxuICByZXR1cm4gc1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOaVsOWtl+agvOW8j+WMlu+8iOinhOagvOesrCA1IOiKgu+8iVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gZm9ybWF0VG9rZW5zU2hvcnQobikge1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZShuKSkgcmV0dXJuICctLSdcbiAgaWYgKG4gPj0gMWU2KSByZXR1cm4gTWF0aC5yb3VuZChuIC8gMWU0KSAvIDEwMCArICdNJyAvLyAxLjIzTVxuICBpZiAobiA+PSAxZTMpIHJldHVybiBNYXRoLnJvdW5kKG4gLyAxZTIpIC8gMTAgKyAnSycgLy8gMTIuM0tcbiAgcmV0dXJuIFN0cmluZyhNYXRoLnJvdW5kKG4pKVxufVxuZnVuY3Rpb24gZm9ybWF0SW50KG4pIHtcbiAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShuKSA/IE1hdGgucm91bmQobikudG9Mb2NhbGVTdHJpbmcoKSA6ICctLSdcbn1cbi8qKiDlj6ropoHmlbDlrZfpg6jliIbvvJrmiJDmnKzljaHnmoTnrKblj7fnlLHluIHnp43liIfmjaLlmajoh6rlt7HnlLvvvIzlho3luKbkuIDmrKHlsLHmiJDkuobjgIzCpSDCpTE0Ljc444CN44CCICovXG5mdW5jdGlvbiBjb3N0RGlnaXRzKG4pIHtcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobikpIHJldHVybiAnLS0nXG4gIC8vIEJlbG93IGhhbGYgYSBjZW50IHRoZXJlIGlzIG5vdGhpbmcgdG8gc2hvdyBhdCAyIGRlY2ltYWxzOyBzYXkgc28gaW5zdGVhZCBvZlxuICAvLyBwcmludGluZyBhIG1pc2xlYWRpbmcgMC4wMCAoYSAkMC4wMyBDTlkgY29zdCBiZWNvbWVzICQwLjAwNCkuXG4gIGlmIChuID4gMCAmJiBuIDwgMC4wMDUpIHJldHVybiAnPDAuMDEnXG4gIHJldHVybiBuLnRvRml4ZWQoMilcbn1cbmZ1bmN0aW9uIGZvcm1hdENvc3QobiwgY3VyKSB7XG4gIHJldHVybiAoY3VyIHx8ICfCpScpICsgY29zdERpZ2l0cyhuKVxufVxuZnVuY3Rpb24gZGF5TGFiZWwoa2V5KSB7XG4gIGNvbnN0IFssIG0sIGRdID0gU3RyaW5nKGtleSB8fCAnJykuc3BsaXQoJy0nKVxuICBpZiAobSA9PT0gdW5kZWZpbmVkIHx8IGQgPT09IHVuZGVmaW5lZCkgcmV0dXJuICctLSdcbiAgcmV0dXJuIG0gKyAnLScgKyBkXG59XG5mdW5jdGlvbiBmbXRQY3QocmF0aW8pIHtcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUocmF0aW8pKSByZXR1cm4gJzAlJ1xuICBjb25zdCBwID0gcmF0aW8gKiAxMDBcbiAgaWYgKHAgPj0gOTkuOTUpIHJldHVybiAnMTAwJSdcbiAgcmV0dXJuIHAudG9GaXhlZCgxKSArICclJ1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOaXpeacn+W3peWFt1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gc3RhcnRPZkRheShkKSB7XG4gIGNvbnN0IHggPSBuZXcgRGF0ZShkKVxuICB4LnNldEhvdXJzKDAsIDAsIDAsIDApXG4gIHJldHVybiB4XG59XG5mdW5jdGlvbiBhZGREYXlzKGQsIG4pIHtcbiAgY29uc3QgeCA9IG5ldyBEYXRlKGQpXG4gIHguc2V0RGF0ZSh4LmdldERhdGUoKSArIG4pXG4gIHJldHVybiB4XG59XG5mdW5jdGlvbiBmbXREYXRlSW5wdXQoZCkge1xuICBjb25zdCB5ID0gZC5nZXRGdWxsWWVhcigpXG4gIGNvbnN0IG0gPSBTdHJpbmcoZC5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKVxuICBjb25zdCBkYXkgPSBTdHJpbmcoZC5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsICcwJylcbiAgcmV0dXJuIHkgKyAnLScgKyBtICsgJy0nICsgZGF5XG59XG5mdW5jdGlvbiBmbXREYXRlU2xhc2gocykge1xuICBjb25zdCBtID0gU3RyaW5nKHMgfHwgJycpLm1hdGNoKC9eKFxcZHs0fSktKFxcZHsyfSktKFxcZHsyfSkkLylcbiAgaWYgKCFtKSByZXR1cm4gJy0tJ1xuICByZXR1cm4gbVsxXSArICcvJyArIG1bMl0gKyAnLycgKyBtWzNdXG59XG4vLyDpooTorr4gLyDoh6rlrprkuYkg4oaSIHsgZnJvbSwgdG8gfe+8iFVuaXgg5q+r56eS77yJXG4vLyDku4rml6UgPSDlvZPlpKkgMDA6MDAg6Iez5LuK77yb6L+RNy8zMOWkqSA9IOWQq+S7iuWkqeW+gOWJjSBOIOS4quiHqueEtuaXpSAwMDowMCDotbfvvJvlhajpg6ggPSDkuI3pmZDotbfngrnvvJtcbi8vIOiHquWumuS5iSA9IOi1t+aXpSAwMDowMCB+IOatouaXpSAyMzo1OTo1OS45OTlcbmZ1bmN0aW9uIHJhbmdlRm9yKHByZXNldCwgY3VzdG9tKSB7XG4gIGNvbnN0IG5vdyA9IG5ldyBEYXRlKClcbiAgY29uc3QgdG9kYXkgPSBzdGFydE9mRGF5KG5vdylcbiAgaWYgKHByZXNldCA9PT0gJ3RvZGF5JykgcmV0dXJuIHsgZnJvbTogdG9kYXkuZ2V0VGltZSgpLCB0bzogbm93LmdldFRpbWUoKSB9XG4gIGlmIChwcmVzZXQgPT09ICc3ZCcpIHJldHVybiB7IGZyb206IGFkZERheXModG9kYXksIC02KS5nZXRUaW1lKCksIHRvOiBub3cuZ2V0VGltZSgpIH1cbiAgaWYgKHByZXNldCA9PT0gJzMwZCcpIHJldHVybiB7IGZyb206IGFkZERheXModG9kYXksIC0yOSkuZ2V0VGltZSgpLCB0bzogbm93LmdldFRpbWUoKSB9XG4gIC8vIOWFqOmHj++8mjAg5piv5pyJ6ZmQ5YC877yM5a6/5Li755qEIGZpbGwg5Yik5a6a6K6k5a6D77yb6LCD55So5pa55b+F6aG75ZCM5pe25LygIGZpbGw6ZmFsc2XvvIxcbiAgLy8g5ZCm5YiZ5Lya5Y676Zu25aGr5YWFIDE5NzAg5bm06Iez5LuK44CB5pKe5LiKIE1BWF9CVUNLRVRTIOmAgOWMluaIkOWPqueci+acieaVsOaNrueahOahtuOAglxuICBpZiAocHJlc2V0ID09PSAnYWxsJykgcmV0dXJuIHsgZnJvbTogMCwgdG86IG5vdy5nZXRUaW1lKCkgfVxuICBjb25zdCBmcm9tID0gbmV3IERhdGUoY3VzdG9tLmZyb20gKyAnVDAwOjAwOjAwJykuZ2V0VGltZSgpXG4gIGNvbnN0IHRvID0gbmV3IERhdGUoY3VzdG9tLnRvICsgJ1QyMzo1OTo1OS45OTknKS5nZXRUaW1lKClcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUoZnJvbSkgfHwgIU51bWJlci5pc0Zpbml0ZSh0bykpIHtcbiAgICByZXR1cm4geyBmcm9tOiB0b2RheS5nZXRUaW1lKCksIHRvOiBub3cuZ2V0VGltZSgpIH1cbiAgfVxuICByZXR1cm4geyBmcm9tLCB0byB9XG59XG5mdW5jdGlvbiB3ZWVrZGF5T2Yoa2V5KSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGtleSArICdUMDA6MDA6MDAnKS50b0xvY2FsZURhdGVTdHJpbmcoJ3poLUNOJywgeyB3ZWVrZGF5OiAnc2hvcnQnIH0pXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gJydcbiAgfVxufVxuLyoqIFdlZWtkYXkgZm9yIGEgZGF5L2hvdXIvbWludXRlIGJ1Y2tldCBrZXkgKGBZWVlZLU1NLUREYCBvciBgWVlZWS1NTS1ERCBISDptbWApLiAqL1xuZnVuY3Rpb24gd2Vla2RheU5hbWUoa2V5LCB0KSB7XG4gIHRyeSB7XG4gICAgY29uc3QgZCA9IG5ldyBEYXRlKFN0cmluZyhrZXkpLnJlcGxhY2UoJyAnLCAnVCcpKVxuICAgIHJldHVybiB0KFsnd2QwJywgJ3dkMScsICd3ZDInLCAnd2QzJywgJ3dkNCcsICd3ZDUnLCAnd2Q2J11bZC5nZXREYXkoKV0gfHwgJ3dkMCcpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gJydcbiAgfVxufVxuLyoqIFgtYXhpcyBsYWJlbCBmb3IgYSBidWNrZXQga2V5IHVuZGVyIGEgZ3JhbnVsYXJpdHkuICovXG5mdW5jdGlvbiB4TGFiZWwoa2V5LCBnKSB7XG4gIGNvbnN0IHMgPSBTdHJpbmcoa2V5KVxuICBjb25zdCBzcCA9IHMuc3BsaXQoJyAnKVxuICBpZiAoZyA9PT0gJ21pbnV0ZScpIHJldHVybiBzcC5sZW5ndGggPiAxID8gc3BbMV0uc2xpY2UoMCwgNSkgOiBzLnNsaWNlKDUpXG4gIGlmIChnID09PSAnaG91cicpIHJldHVybiBzcC5sZW5ndGggPiAxID8gc3BbMV0uc2xpY2UoMCwgMikgKyAnOjAwJyA6IHMuc2xpY2UoNSlcbiAgcmV0dXJuIGRheUxhYmVsKGtleSlcbn1cbi8qKiBGaXhlZCBncmFudWxhcml0eSBwb2xpY3k6IHRvZGF5IGlzIGhvdXJseSwgZXZlcnl0aGluZyBlbHNlIGlzIGRhaWx5LiAqL1xuZnVuY3Rpb24gZWZmR3JhbnVsYXJpdHkocmFuZ2UpIHtcbiAgcmV0dXJuIHJhbmdlID09PSAndG9kYXknID8gJ2hvdXInIDogJ2RheSc7XG59XG4vKiogU3RhYmxlIHN0ZXAgc3RyYXRlZ3kgZm9yIGN1c3RvbSByYW5nZXM6IHRhcmdldCB+MTUtMjUgYnVja2V0cy4gKi9cbmZ1bmN0aW9uIHBpY2tTdGVwRGF5cyhzcGFuTXMpIHtcbiAgY29uc3QgZGF5cyA9IE1hdGgubWF4KDEsIE1hdGgucm91bmQoKHNwYW5NcyB8fCAwKSAvIDg2NDAwMDAwKSlcbiAgaWYgKGRheXMgPD0gMzEpIHJldHVybiAxXG4gIGlmIChkYXlzIDw9IDYyKSByZXR1cm4gM1xuICBpZiAoZGF5cyA8PSAxNTApIHJldHVybiA1XG4gIHJldHVybiA3XG59XG4vKiogSHVtYW4gbGFiZWwgZm9yIHRoZSBjdXJyZW50IHN0ZXAgcG9saWN5LiAqL1xuZnVuY3Rpb24gc3RlcExhYmVsKHQsIHJhbmdlLCBzdGVwRGF5cykge1xuICBpZiAocmFuZ2UgPT09ICd0b2RheScpIHJldHVybiB0KCdieUhvdXInKVxuICByZXR1cm4gc3RlcERheXMgPiAxID8gdCgnZXZlcnlORGF5cycsIHsgbjogc3RlcERheXMgfSkgOiB0KCdieURheScpXG59XG4vKiogSGVhdG1hcCBjZWxsIGNvbG9yIGJ5IHJlbGF0aXZlIHRva2VuIHZvbHVtZS4gKi9cbmZ1bmN0aW9uIGhlYXRDb2xvcih0b3RhbCwgbWF4KSB7XG4gIGlmICghdG90YWwpIHJldHVybiAndmFyKC0tZHN3LWFsaWFzLWludGVyYWN0aXZlLWJnLWhvdmVyKSdcbiAgY29uc3QgciA9IHRvdGFsIC8gbWF4XG4gIGNvbnN0IHBjdCA9IHIgPCAwLjI1ID8gMjIgOiByIDwgMC41ID8gNDUgOiByIDwgMC43NSA/IDcwIDogMTAwXG4gIHJldHVybiAnY29sb3ItbWl4KGluIHNyZ2IsIHZhcigtLWRzdy1zdGF0aWMtZGVlcHNlZWstNTAwKSAnICsgcGN0ICsgJyUsIHZhcigtLWRzdy1hbGlhcy1iZy1sYXllci0yKSknXG59XG5mdW5jdGlvbiBuaWNlQ2VpbCh2KSB7XG4gIGlmICghTnVtYmVyLmlzRmluaXRlKHYpIHx8IHYgPD0gMCkgcmV0dXJuIDFcbiAgY29uc3QgbWFnID0gTWF0aC5wb3coMTAsIE1hdGguZmxvb3IoTWF0aC5sb2cxMCh2KSkpXG4gIGNvbnN0IG5vcm0gPSB2IC8gbWFnXG4gIGNvbnN0IG5pY2UgPSBub3JtIDw9IDEgPyAxIDogbm9ybSA8PSAyID8gMiA6IG5vcm0gPD0gNSA/IDUgOiAxMFxuICByZXR1cm4gbmljZSAqIG1hZ1xufVxuZnVuY3Rpb24gZGVmYXVsdEN1c3RvbSgpIHtcbiAgY29uc3Qgbm93ID0gbmV3IERhdGUoKVxuICByZXR1cm4geyBmcm9tOiBmbXREYXRlSW5wdXQoYWRkRGF5cyhub3csIC02KSksIHRvOiBmbXREYXRlSW5wdXQobm93KSB9XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog5YaF6IGUIFNWRyDlm77moIfvvIjml6Dlm77moIflupPvvIzmiYvlhpkgZmVhdGhlciDpo47moLwgc3Ryb2tlIOWbvuagh++8iVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuY29uc3QgSUNPTl9QQVRIUyA9IHtcbiAgbGF5ZXJzOiAnTTEyIDJsOCA0LjUtOCA0LjUtOC00LjVMMTIgMnptMCA4bDggNC41LTggNC41LTgtNC41TDEyIDEwem0wIDhsOCA0LjUtOCA0LjUtOC00LjVMMTIgMTh6JyxcbiAgZG93bjogJ00xMiAzdjEybTAgMGwtNC41LTQuNU0xMiAxNWw0LjUtNC41TTQgMjFoMTYnLFxuICB1cDogJ00xMiAyMVY5bTAgMGwtNC41IDQuNU0xMiA5bDQuNSA0LjVNNCAzaDE2JyxcbiAgYWN0aXZpdHk6ICdNMiAxMmg0bDIuNS04IDUgMTYgMi41LThoNicsXG4gIGNvaW5zOiAnTTMgOWEyIDIgMCAwMTItMmgxNGEyIDIgMCAwMTIgMnY5YTIgMiAwIDAxLTIgMkg1YTIgMiAwIDAxLTItMlY5em0wIDVoMThNOCA1LjVWNGEyIDIgMCAwMTItMmg0YTIgMiAwIDAxMiAydjEuNScsXG4gIC8vIOWIt+aWsOWbvuagh+WPluiHqiBEU0gg5Y6f55Sf5Zu+5b2i77yIMTYg572R5qC844CBc3Ryb2tlIDEuNe+8ie+8jOS4juiuvue9rumhteWFtuWug+Wbvuagh+WQjOS4gOinguaEn++8m1xuICAvLyDlhbbkvZnlm77moIfku43mmK8gMjQg572R5qC877yIc3Ryb2tlIDLvvInvvIxTdmdJY29uIOS4pOenjeWumuS5iemDveWQg+OAglxuICByZWZyZXNoOiB7XG4gICAgdmlld0JveDogJzAgMCAxNiAxNicsXG4gICAgc3Ryb2tlV2lkdGg6IDEuNSxcbiAgICBwYXRoczogW1xuICAgICAgJ00xNC41MDAxIDhDMTQuNSA5LjI4NTUyIDE0LjExODggMTAuNTQyMiAxMy40MDQ1IDExLjYxMUMxMi42OTAzIDEyLjY3OTkgMTEuNjc1MiAxMy41MTI5IDEwLjQ4NzUgMTQuMDA0OUM5LjI5OTgyIDE0LjQ5NjggNy45OTI5NSAxNC42MjU1IDYuNzMyMTIgMTQuMzc0N0M1LjQ3MTMgMTQuMTI0IDQuMzEzMTQgMTMuNTA1IDMuNDA0MSAxMi41OTZDMi40OTUxNCAxMS42ODcgMS44NzYxNCAxMC41Mjg4IDEuNjI1MzcgOS4yNjc5OEMxLjM3NDU5IDguMDA3MTYgMS41MDMzMSA2LjcwMDI4IDEuOTk1MjUgNS41MTI2MUMyLjQ4NzE5IDQuMzI0OTQgMy4zMjAyNSAzLjMwOTgxIDQuMzg5MSAyLjU5NTU3QzUuNDU3OTUgMS44ODEzNCA2LjcxNDU4IDEuNTAwMDggOC4wMDAxIDEuNUM5LjkwMDEgMS41IDExLjcwMDEgMi4zIDEzLjAwMDEgMy42TDE0LjUwMDEgNS4xJyxcbiAgICAgICdNMTQuNDk5OSAxLjVWNS4xSDEwLjg5OTknLFxuICAgIF0sXG4gIH0sXG4gIGNoZXZyb246ICdNNiA5bDYgNiA2LTYnLFxuICBpbmJveDogJ00yMiAxMmgtNmwtMiAzaC00bC0yLTNIMm0zLjUtNi41TDIgMTJ2NmEyIDIgMCAwMDIgMmgxNmEyIDIgMCAwMDItMnYtNmwtMy41LTYuNUEyIDIgMCAwMDE2Ljc2IDVINy4yNGEyIDIgMCAwMC0xLjc0IDEuNXonLFxuICBhbGVydDogJ00xMiA5djRtMCA0aC4wMU0xMC4zIDMuODZMMS44MiAxOGEyIDIgMCAwMDEuNzEgM2gxNi45NGEyIDIgMCAwMDEuNzEtM0wxMy43IDMuODZhMiAyIDAgMDAtMy40IDB6JyxcbiAgc2VhcmNoOiAnTTIxIDIxbC00LjM1LTQuMzVNMTcgMTAuNWE2LjUgNi41IDAgMTEtMTMgMCA2LjUgNi41IDAgMDExMyAweicsXG4gIC8vIOmlvOWbvu+8iOWNoOavlO+8ie+8muWkluWciCArIOallOW9ou+8jOS4juWNoeeJh+agh+mimOeahOOAjOWNoOavlOOAjeivreS5ieS4gOiHtFxuICBzaGFyZTogJ00yMS4yMSAxNS44OUExMCAxMCAwIDExOCAyLjgzTTIyIDEyQTEwIDEwIDAgMDAxMiAydjEweicsXG4gIGNoZWNrOiAnTTIwIDZMOSAxN2wtNS01JyxcbiAgeDogJ002IDZsMTIgMTJNMTggNkw2IDE4JyxcbiAgLy8g5ouJ5Y+W5Yy56YWN6KGo5oyJ6ZKu55qE5Zu+5qCH77yaRFNIIOWOn+eUnyBpY29uLWNvbnRleHQtaW5qZWN0aW9uLW91dGxpbmXjgIIxNiDnvZHmoLzjgIFcbiAgLy8g57q/5a69IDEuNe+8m+WbvuW9ouaYr+OAjOWJqui0tOadvyArIOS7jumhtumDqOepv+WFpeeahOS4i+i9veeureWktCArIOS4gOadoeWGheWuuee6v+OAje+8jOaPj+i+ueayv+eUqFxuICAvLyDlpJblsYLnmoQgY3VycmVudENvbG9y77yM5omA5Lul5q+P5p2hIHBhdGgg5Y+q57uZIGTjgIJcbiAgY29udGV4dEluamVjdGlvbjoge1xuICAgIHZpZXdCb3g6ICcwIDAgMTYgMTYnLFxuICAgIHN0cm9rZVdpZHRoOiAxLjUsXG4gICAgcGF0aHM6IFtcbiAgICAgICdNNSAyLjVIMy41QzMuMjM0NzggMi41IDIuOTgwNDMgMi42MDUzNiAyLjc5Mjg5IDIuNzkyODlDMi42MDUzNiAyLjk4MDQzIDIuNSAzLjIzNDc4IDIuNSAzLjVWMTMuNUMyLjUgMTMuNzY1MiAyLjYwNTM2IDE0LjAxOTYgMi43OTI4OSAxNC4yMDcxQzIuOTgwNDMgMTQuMzk0NiAzLjIzNDc4IDE0LjUgMy41IDE0LjVIMTIuNUMxMi43NjUyIDE0LjUgMTMuMDE5NiAxNC4zOTQ2IDEzLjIwNzEgMTQuMjA3MUMxMy4zOTQ2IDE0LjAxOTYgMTMuNSAxMy43NjUyIDEzLjUgMTMuNVYzLjVDMTMuNSAzLjIzNDc4IDEzLjM5NDYgMi45ODA0MyAxMy4yMDcxIDIuNzkyODlDMTMuMDE5NiAyLjYwNTM2IDEyLjc2NTIgMi41IDEyLjUgMi41SDExJyxcbiAgICAgICdNOCAwLjVWNy41JyxcbiAgICAgICdNNS41IDVMOCA3LjVMMTAuNSA1JyxcbiAgICAgICdNNS41IDExSDEwLjUnLFxuICAgIF0sXG4gIH0sXG4gIC8vIOaPkOekuuiusOWPt++8muWchuWciCArIOaEn+WPueWPt++8iDE2IOe9keagvOOAgee6v+WuvSAxLjXvvInjgILljp/mnaXnlKjkuIDkuKogQ1NTIOS8quWFg+e0oOeUu+OAjD/jgI3vvIxcbiAgLy8g5a2X6YeN5aSq5bCP44CB57yp5YiwIDEwcHgg5ZCO5Yeg5LmO55yL5LiN6KeB77yM5Lmf5LiN6IO954K577yb5o2i5oiQ55yf5Zu+5qCH5ZCO5Y+v5Lul5b2T5oyJ6ZKu55So44CCXG4gIGhpbnQ6IHtcbiAgICB2aWV3Qm94OiAnMCAwIDE2IDE2JyxcbiAgICBzdHJva2VXaWR0aDogMS41LFxuICAgIHBhdGhzOiBbXG4gICAgICAnTTggMS43NWE2LjI1IDYuMjUgMCAxIDEgMCAxMi41YTYuMjUgNi4yNSAwIDEgMSAwLTEyLjVaJyxcbiAgICAgICdNOCA0Ljl2My41JyxcbiAgICAgICdNOCAxMS4xNWguMDEnLFxuICAgIF0sXG4gIH0sXG59XG5mdW5jdGlvbiBTdmdJY29uKHByb3BzKSB7XG4gIGNvbnN0IHsgbmFtZSwgc2l6ZSwgY2xhc3NOYW1lIH0gPSBwcm9wc1xuICAvLyDkuIDkuKrlkI3lrZflr7nlupTjgIzkuIDkuLIgcGF0aCArIOiHquW3seeahCB2aWV3Qm94L+e6v+WuveOAje+8m+Wtl+espuS4suaYryAyNCDnvZHmoLznmoTnroDlhpnvvIxcbiAgLy8g6LCD55So5pa577yIMzEg5aSE77yJ5peg6ZyA5YWz5b+D5beu5Yir44CCXG4gIGNvbnN0IHNwZWMgPSBJQ09OX1BBVEhTW25hbWVdIHx8IElDT05fUEFUSFMuYWN0aXZpdHlcbiAgY29uc3QgaWNvbiA9IHR5cGVvZiBzcGVjID09PSAnc3RyaW5nJ1xuICAgID8geyB2aWV3Qm94OiAnMCAwIDI0IDI0Jywgc3Ryb2tlV2lkdGg6IDIsIHBhdGhzOiBbc3BlY10gfVxuICAgIDogc3BlY1xuICByZXR1cm4gaCgnc3ZnJywge1xuICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lIHx8ICd0c2QtaWNvbicsXG4gICAgd2lkdGg6IHNpemUgfHwgMTYsXG4gICAgaGVpZ2h0OiBzaXplIHx8IDE2LFxuICAgIHZpZXdCb3g6IGljb24udmlld0JveCB8fCAnMCAwIDI0IDI0JyxcbiAgICBmaWxsOiAnbm9uZScsXG4gICAgc3Ryb2tlOiAnY3VycmVudENvbG9yJyxcbiAgICBzdHJva2VXaWR0aDogaWNvbi5zdHJva2VXaWR0aCB8fCAyLFxuICAgIHN0cm9rZUxpbmVjYXA6ICdyb3VuZCcsXG4gICAgc3Ryb2tlTGluZWpvaW46ICdyb3VuZCcsXG4gICAgJ2FyaWEtaGlkZGVuJzogdHJ1ZSxcbiAgfSwgaWNvbi5wYXRocy5tYXAoKGQsIGkpID0+IGgoJ3BhdGgnLCB7IGtleTogaSwgZCB9KSkpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog6YCa55SoIEhvb2vvvJrlpJbpg6jngrnlh7vlhbPpl61cbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmZ1bmN0aW9uIHVzZU91dHNpZGVDbGljayhvcGVuLCByZWYsIG9uQ2xvc2UpIHtcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIW9wZW4pIHJldHVybiB1bmRlZmluZWRcbiAgICBmdW5jdGlvbiBoYW5kbGVyKGUpIHtcbiAgICAgIGlmIChyZWYuY3VycmVudCAmJiAhcmVmLmN1cnJlbnQuY29udGFpbnMoZS50YXJnZXQpKSBvbkNsb3NlKClcbiAgICB9XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoYW5kbGVyKVxuICAgIHJldHVybiAoKSA9PiBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGhhbmRsZXIpXG4gIH0sIFtvcGVuLCBvbkNsb3NlLCByZWZdKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOmAmueUqCBIb29r77ya5rWu5bGC5a6a5L2N77yIdmlld3BvcnQg5a6a5L2NICsg56m66Ze05LiN6Laz5LiK57+7ICsg6auY5bqm5bCB6aG277yJXG4gKlxuICog6K6+572u6Z2i5p2/5pys6Lqr5pivIGBvdmVyZmxvdzogaGlkZGVuYCDnmoToo4HliarlrrnlmajvvIzotLTnnYDov4fmu6TmoI/lj7Pnq6/nmoQgYWJzb2x1dGVcbiAqIOa1ruWxguS8muiiq+aVtOadoeijgeaOie+8iOWPs+S+p+eahOOAjOa4heepuuOAjeeci+S4jeinge+8ieOAgkNTUyDml6Dms5XmhJ/nn6XnpZblhYjoo4HliarvvIzlj6rog73ph4/kuIDmrKFcbiAqIOinhuWPo+WGjeWumuS9je+8m+a7muWKqOaIlue8qeaUvuaXtumHjeeul++8jOmBv+WFjea1ruWxgueVmeWcqOWOn+WcsOOAglxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuY29uc3QgUEFORUxfTUlOX1JPT00gPSAyNDAgLy8g5LiL5pa556m66Ze05bCP5LqO5a6D5LiU5LiK5pa55pu05a696KOV5pe25LiK57+7XG5jb25zdCBQQU5FTF9NSU5fSEVJR0hUID0gMTYwXG5cbmZ1bmN0aW9uIHVzZUZpeGVkUGFuZWwoYW5jaG9yUmVmLCBvcGVuLCB3aWR0aCwgZ2FwID0gNiwgbWFyZ2luID0gMTIpIHtcbiAgY29uc3QgW3N0eWxlLCBzZXRTdHlsZV0gPSBSZWFjdC51c2VTdGF0ZShudWxsKVxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghb3Blbikge1xuICAgICAgc2V0U3R5bGUobnVsbClcbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG4gICAgZnVuY3Rpb24gbWVhc3VyZSgpIHtcbiAgICAgIGNvbnN0IGVsID0gYW5jaG9yUmVmLmN1cnJlbnRcbiAgICAgIGlmICghZWwpIHJldHVyblxuICAgICAgY29uc3QgciA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICBjb25zdCBib3hXID0gTWF0aC5taW4od2lkdGgsIHdpbmRvdy5pbm5lcldpZHRoIC0gbWFyZ2luICogMilcbiAgICAgIGNvbnN0IGxlZnQgPSBNYXRoLm1heChtYXJnaW4sIE1hdGgubWluKHIubGVmdCwgd2luZG93LmlubmVyV2lkdGggLSBtYXJnaW4gLSBib3hXKSlcbiAgICAgIGNvbnN0IGJlbG93ID0gd2luZG93LmlubmVySGVpZ2h0IC0gci5ib3R0b20gLSBnYXAgLSBtYXJnaW5cbiAgICAgIGNvbnN0IGFib3ZlID0gci50b3AgLSBnYXAgLSBtYXJnaW5cbiAgICAgIGNvbnN0IGZsaXAgPSBiZWxvdyA8IFBBTkVMX01JTl9ST09NICYmIGFib3ZlID4gYmVsb3dcbiAgICAgIHNldFN0eWxlKHtcbiAgICAgICAgcG9zaXRpb246ICdmaXhlZCcsXG4gICAgICAgIGxlZnQsXG4gICAgICAgIHdpZHRoOiBib3hXLFxuICAgICAgICBtYXhIZWlnaHQ6IE1hdGgubWF4KFBBTkVMX01JTl9IRUlHSFQsIGZsaXAgPyBhYm92ZSA6IGJlbG93KSxcbiAgICAgICAgLi4uKGZsaXBcbiAgICAgICAgICA/IHsgYm90dG9tOiB3aW5kb3cuaW5uZXJIZWlnaHQgLSByLnRvcCArIGdhcCB9XG4gICAgICAgICAgOiB7IHRvcDogci5ib3R0b20gKyBnYXAgfSksXG4gICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgICAgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsXG4gICAgICAgIHpJbmRleDogNDAsXG4gICAgICB9KVxuICAgIH1cbiAgICBtZWFzdXJlKClcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgbWVhc3VyZSlcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgbWVhc3VyZSwgdHJ1ZSlcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG1lYXN1cmUpXG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgbWVhc3VyZSwgdHJ1ZSlcbiAgICB9XG4gIH0sIFtvcGVuLCBhbmNob3JSZWYsIHdpZHRoLCBnYXAsIG1hcmdpbl0pXG4gIGlmICghb3BlbikgcmV0dXJuIG51bGxcbiAgLy8g6aaW5bin6L+Y5rKh6YeP5Yiw5bC65a+477ya5YWI6JeP6LW35p2l77yM5ZCm5YiZ5Lya6Zeq5Yiw5bem5LiK6KeSXG4gIHJldHVybiBzdHlsZSB8fCB7IHBvc2l0aW9uOiAnZml4ZWQnLCB0b3A6IDAsIGxlZnQ6IDAsIHZpc2liaWxpdHk6ICdoaWRkZW4nIH1cbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBIZWFkZXLvvJrmoIfpopggKyDlia/moIfpopggKyDliLfmlrDmjInpkq5cbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmZ1bmN0aW9uIFN0YXRzSGVhZGVyKHByb3BzKSB7XG4gIC8vIGBjb21wdXRpbmdgIOihqOekulwi57uf6K6h6L+Y5rKh566X5a6MXCLvvIjlrr/kuLsgYmFja2ZpbGwuc3RhdHVzID09PSAncnVubmluZyfvvInvvIxcbiAgLy8g5ZKMIGBidXN5YO+8iOi/meS4gOi9ruivt+axguWcqOmjnu+8ieS4jeaYr+S4gOWbnuS6i++8muivt+axguWHoOWNgeavq+enkuWwsee7k+adn++8jOiAjOWFqOmHj+e7n+iuoeimgeWHoOenkuOAglxuICAvLyDlj6rlnKjor7fmsYLlnKjpo57ml7bovazlnIjvvIznlKjmiLflsLHkvJrnnIvliLBcIumhtemdouaYjuaYjuayoeeul+WujOWNtOS7gOS5iOmDveS4jeWKqFwi44CCXG4gIGNvbnN0IHsgYnVzeSwgb25SZWZyZXNoLCBjb21wdXRpbmcsIGNvbXB1dGVEb25lLCBjb21wdXRlVG90YWwgfSA9IHByb3BzXG4gIGNvbnN0IHQgPSB1c2VUKClcbiAgY29uc3Qgc3VidGl0bGUgPSBjb21wdXRpbmdcbiAgICA/IHQoJ2NvbXB1dGluZycsIHsgZG9uZTogZm9ybWF0SW50KGNvbXB1dGVEb25lIHx8IDApLCB0b3RhbDogZm9ybWF0SW50KGNvbXB1dGVUb3RhbCB8fCAwKSB9KVxuICAgIDogdCgnc3VidGl0bGUnKVxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtaGVhZGVyJyB9LFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWhlYWRlci10ZXh0JyB9LFxuICAgICAgaCgnaDInLCB7IGNsYXNzTmFtZTogJ3RzZC10aXRsZScgfSwgdCgnbmF2JykpLFxuICAgICAgLy8g5Ymv5qCH6aKY6L+Z5LiA5Y+l55u05o6l5o2i5oiQ6L+b5bqm5Y+l77ya5ZCM5LiA5Liq5L2N572u44CB5ZCM5qC355qE6KGM6auY77yM5omA5Lul5LiN566X5a6M4oaS566X5a6M5LiN6Lez54mI44CCXG4gICAgICBoKCdwJywgeyBjbGFzc05hbWU6ICd0c2Qtc3VidGl0bGUnLCByb2xlOiBjb21wdXRpbmcgPyAnc3RhdHVzJyA6IG51bGwgfSwgc3VidGl0bGUpKSxcbiAgICBoKCdidXR0b24nLCB7XG4gICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgIGNsYXNzTmFtZTogJ3RzZC1pY29uLWJ0bicgKyAoYnVzeSB8fCBjb21wdXRpbmcgPyAnIHRzZC1zcGlubmluZycgOiAnJyksXG4gICAgICBvbkNsaWNrOiBvblJlZnJlc2gsXG4gICAgICBkaXNhYmxlZDogYnVzeSxcbiAgICAgICdhcmlhLWJ1c3knOiBidXN5IHx8IGNvbXB1dGluZyB8fCB1bmRlZmluZWQsXG4gICAgICB0aXRsZTogdCgncmVmcmVzaCcpLFxuICAgICAgJ2FyaWEtbGFiZWwnOiB0KCdyZWZyZXNoJyksXG4gICAgfSwgaChTdmdJY29uLCB7IG5hbWU6ICdyZWZyZXNoJyB9KSkpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog6Ieq5a6a5LmJ5pel5pyf6IyD5Zu05rWu5bGCXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBDdXN0b21SYW5nZVBvcG92ZXIocHJvcHMpIHtcbiAgY29uc3QgeyBjdXN0b20sIG9uQXBwbHksIG9uQ2xvc2UsIGFuY2hvclJlZiB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICBjb25zdCBwYW5lbFN0eWxlID0gdXNlRml4ZWRQYW5lbChhbmNob3JSZWYsIHRydWUsIDMwMClcbiAgY29uc3QgW2Zyb20sIHNldEZyb21dID0gUmVhY3QudXNlU3RhdGUoY3VzdG9tLmZyb20pXG4gIGNvbnN0IFt0bywgc2V0VG9dID0gUmVhY3QudXNlU3RhdGUoY3VzdG9tLnRvKVxuICBjb25zdCBpbnZhbGlkID0gIWZyb20gfHwgIXRvIHx8IGZyb20gPiB0b1xuICAvLyBQMi0xMe+8mmRpYWxvZyDku6UgRXNjYXBlIOWFs+mXrVxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGZ1bmN0aW9uIG9uS2V5KGUpIHtcbiAgICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScgfHwgZS5rZXkgPT09ICdFc2MnKSBvbkNsb3NlKClcbiAgICB9XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5KVxuICAgIHJldHVybiAoKSA9PiBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXkpXG4gIH0sIFtvbkNsb3NlXSlcbiAgcmV0dXJuIGgoJ2RpdicsIHtcbiAgICBjbGFzc05hbWU6ICd0c2QtcG9wb3ZlciB0c2QtcmFuZ2UtcG9wb3ZlcicsXG4gICAgc3R5bGU6IHBhbmVsU3R5bGUsXG4gICAgcm9sZTogJ2RpYWxvZycsXG4gICAgJ2FyaWEtbGFiZWwnOiB0KCdjdXN0b21SYW5nZUFyaWEnKSxcbiAgfSxcbiAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1wb3BvdmVyLXRpdGxlJyB9LCB0KCdjdXN0b21SYW5nZVRpdGxlJykpLFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXJhbmdlLWZpZWxkcycgfSxcbiAgICAgIGgoJ2xhYmVsJywgeyBjbGFzc05hbWU6ICd0c2QtZmllbGQnIH0sXG4gICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1maWVsZC1sYWJlbCcgfSwgdCgnc3RhcnRUaW1lJykpLFxuICAgICAgICBoKCdpbnB1dCcsIHtcbiAgICAgICAgICB0eXBlOiAnZGF0ZScsIHZhbHVlOiBmcm9tLCAnYXJpYS1sYWJlbCc6IHQoJ3N0YXJ0VGltZScpLFxuICAgICAgICAgIG9uQ2hhbmdlOiAoZSkgPT4gc2V0RnJvbShlLnRhcmdldC52YWx1ZSksXG4gICAgICAgIH0pKSxcbiAgICAgIGgoJ2xhYmVsJywgeyBjbGFzc05hbWU6ICd0c2QtZmllbGQnIH0sXG4gICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1maWVsZC1sYWJlbCcgfSwgdCgnZW5kVGltZScpKSxcbiAgICAgICAgaCgnaW5wdXQnLCB7XG4gICAgICAgICAgdHlwZTogJ2RhdGUnLCB2YWx1ZTogdG8sICdhcmlhLWxhYmVsJzogdCgnZW5kVGltZScpLFxuICAgICAgICAgIG9uQ2hhbmdlOiAoZSkgPT4gc2V0VG8oZS50YXJnZXQudmFsdWUpLFxuICAgICAgICB9KSkpLFxuICAgIGludmFsaWRcbiAgICAgID8gaCgncCcsIHsgY2xhc3NOYW1lOiAndHNkLWZpZWxkLWVycm9yJywgcm9sZTogJ2FsZXJ0JyB9LCB0KCdyYW5nZUludmFsaWQnKSlcbiAgICAgIDogbnVsbCxcbiAgICBoKCdwJywgeyBjbGFzc05hbWU6ICd0c2QtZmllbGQtaGludCcgfSwgdCgncmFuZ2VIaW50JykpLFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXBvcG92ZXItYWN0aW9ucycgfSxcbiAgICAgIGgoJ2J1dHRvbicsIHsgdHlwZTogJ2J1dHRvbicsIGNsYXNzTmFtZTogJ3RzZC1idG4gdHNkLWJ0bi1naG9zdCcsIG9uQ2xpY2s6IG9uQ2xvc2UgfSwgdCgnY2FuY2VsJykpLFxuICAgICAgaCgnYnV0dG9uJywge1xuICAgICAgICB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiAndHNkLWJ0biB0c2QtYnRuLXByaW1hcnknLFxuICAgICAgICBkaXNhYmxlZDogaW52YWxpZCxcbiAgICAgICAgb25DbGljazogKCkgPT4geyBpZiAoIWludmFsaWQpIG9uQXBwbHkoeyBmcm9tLCB0byB9KSB9LFxuICAgICAgfSwgdCgnY29uZmlybScpKSkpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog5qih5Z6L5aSa6YCJ5LiL5ouJXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBNb2RlbERyb3Bkb3duKHByb3BzKSB7XG4gIGNvbnN0IHsgb3B0aW9ucywgc2VsZWN0ZWQsIG9uQ2hhbmdlIH0gPSBwcm9wc1xuICBjb25zdCB0ID0gdXNlVCgpXG4gIGNvbnN0IFtvcGVuLCBzZXRPcGVuXSA9IFJlYWN0LnVzZVN0YXRlKGZhbHNlKVxuICBjb25zdCBbcXVlcnksIHNldFF1ZXJ5XSA9IFJlYWN0LnVzZVN0YXRlKCcnKVxuICBjb25zdCBhbmNob3JSZWYgPSBSZWFjdC51c2VSZWYobnVsbClcbiAgY29uc3QgcGFuZWxTdHlsZSA9IHVzZUZpeGVkUGFuZWwoYW5jaG9yUmVmLCBvcGVuLCAzMjApXG5cbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIW9wZW4pIHJldHVybiB1bmRlZmluZWRcbiAgICBmdW5jdGlvbiBoYW5kbGVyKGUpIHtcbiAgICAgIGlmIChhbmNob3JSZWYuY3VycmVudCAmJiAhYW5jaG9yUmVmLmN1cnJlbnQuY29udGFpbnMoZS50YXJnZXQpKSBzZXRPcGVuKGZhbHNlKVxuICAgIH1cbiAgICBmdW5jdGlvbiBvbktleShlKSB7XG4gICAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnIHx8IGUua2V5ID09PSAnRXNjJykgc2V0T3BlbihmYWxzZSlcbiAgICB9XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoYW5kbGVyKVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbktleSlcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBoYW5kbGVyKVxuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIG9uS2V5KVxuICAgIH1cbiAgfSwgW29wZW5dKVxuXG4gIC8vIOWPquWIl+WHuuW9k+WJjeiMg+WbtOacieaVsOaNrueahOaooeWei++8m+W3sumAieS9huaOieWHuuWAmemAieWIl+ihqOeahOOAjOihpeWbnuOAje+8jOS/neivgeWPr+a4suafk+OAgeWPr+a4hemZpFxuICAvLyDlgJnpgInplK7nm7TmjqXnlKjlrr/kuLvnu5nlpb3nmoQgYGtleWDvvIhjb21wb3NpdGVNb2RlbEtleSDnmoTnu5PmnpzvvInvvJrlrqLmiLfnq6/kuI3lho3oh6rlt7Hmi7xcbiAgLy8gYHByb3ZpZGVyICsgJy8nICsgbW9kZWxg77yMcHJvdmlkZXIg5Li656m65pe26YKj56eN5ou85rOV5Lya5b6X5YiwIGAvbW9kZWxgIOiAjOawuOi/nOmAieS4jeS4reOAglxuICBjb25zdCBjYW5kaWRhdGVzID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3Qgc2V0ID0gbmV3IFNldCgob3B0aW9ucyB8fCBbXSkubWFwKChtKSA9PiBtLmtleSB8fCAobS5wcm92aWRlciA/IG0ucHJvdmlkZXIgKyAnLycgKyBtLm1vZGVsIDogbS5tb2RlbCkpKVxuICAgIDsoc2VsZWN0ZWQgfHwgW10pLmZvckVhY2goKG0pID0+IHNldC5hZGQobSkpXG4gICAgY29uc3QgbGlzdCA9IEFycmF5LmZyb20oc2V0KVxuICAgIGxpc3Quc29ydCgpXG4gICAgcmV0dXJuIGxpc3RcbiAgfSwgW29wdGlvbnMsIHNlbGVjdGVkXSlcblxuICBjb25zdCBxID0gcXVlcnkudHJpbSgpLnRvTG9jYWxlTG93ZXJDYXNlKClcbiAgY29uc3QgZmlsdGVyZWQgPSBxID09PSAnJyA/IGNhbmRpZGF0ZXMgOiBjYW5kaWRhdGVzLmZpbHRlcigoYykgPT4gYy50b0xvY2FsZUxvd2VyQ2FzZSgpLmluZGV4T2YocSkgPj0gMClcbiAgY29uc3QgbGFiZWwgPSBzZWxlY3RlZC5sZW5ndGggPT09IDAgPyB0KCdhbGxNb2RlbHMnKSA6IHQoJ3NlbGVjdGVkTW9kZWxzJywgeyBjb3VudDogc2VsZWN0ZWQubGVuZ3RoIH0pXG5cbiAgcmV0dXJuIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXBvcG92ZXItYW5jaG9yJywgcmVmOiBhbmNob3JSZWYgfSxcbiAgICBoKCdidXR0b24nLCB7XG4gICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgIGNsYXNzTmFtZTogJ3RzZC1zZWxlY3QtYnRuJyArIChzZWxlY3RlZC5sZW5ndGggPiAwID8gJyB0c2Qtc2VsZWN0LWhhcycgOiAnJyksXG4gICAgICBvbkNsaWNrOiAoKSA9PiB7IHNldE9wZW4oKHYpID0+ICF2KTsgc2V0UXVlcnkoJycpIH0sXG4gICAgICAnYXJpYS1leHBhbmRlZCc6IG9wZW4sXG4gICAgICAnYXJpYS1oYXNwb3B1cCc6ICdsaXN0Ym94JyxcbiAgICAgIHRpdGxlOiBsYWJlbCxcbiAgICB9LFxuICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXNlbGVjdC1sYWJlbCcgfSwgbGFiZWwpLFxuICAgICAgaChTdmdJY29uLCB7IG5hbWU6ICdjaGV2cm9uJywgc2l6ZTogMTQsIGNsYXNzTmFtZTogJ3RzZC1jaGV2cm9uJyArIChvcGVuID8gJyB0c2QtY2hldnJvbi1vcGVuJyA6ICcnKSB9KSksXG4gICAgb3BlblxuICAgICAgPyBoKCdkaXYnLCB7XG4gICAgICAgICAgY2xhc3NOYW1lOiAndHNkLXBvcG92ZXIgdHNkLW1vZGVsLXBvcG92ZXInLFxuICAgICAgICAgIHN0eWxlOiBwYW5lbFN0eWxlLFxuICAgICAgICAgIHJvbGU6ICdsaXN0Ym94JyxcbiAgICAgICAgICAnYXJpYS1sYWJlbCc6IHQoJ21vZGVsRmlsdGVyR3JvdXAnKSxcbiAgICAgICAgICAnYXJpYS1tdWx0aXNlbGVjdGFibGUnOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXBvcG92ZXItdG9vbHMnIH0sXG4gICAgICAgICAgICBoKCdidXR0b24nLCB7IHR5cGU6ICdidXR0b24nLCBjbGFzc05hbWU6ICd0c2QtbGluay1idG4nLCBvbkNsaWNrOiAoKSA9PiBvbkNoYW5nZShjYW5kaWRhdGVzLnNsaWNlKCkpIH0sIHQoJ3NlbGVjdEFsbCcpKSxcbiAgICAgICAgICAgIGgoJ2J1dHRvbicsIHsgdHlwZTogJ2J1dHRvbicsIGNsYXNzTmFtZTogJ3RzZC1saW5rLWJ0bicsIG9uQ2xpY2s6ICgpID0+IG9uQ2hhbmdlKFtdKSB9LCB0KCdjbGVhcicpKSksXG4gICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2Qtc2VhcmNoJyB9LFxuICAgICAgICAgICAgaChTdmdJY29uLCB7IG5hbWU6ICdzZWFyY2gnLCBzaXplOiAxNCwgY2xhc3NOYW1lOiAndHNkLXNlYXJjaC1pY29uJyB9KSxcbiAgICAgICAgICAgIGgoJ2lucHV0Jywge1xuICAgICAgICAgICAgICB0eXBlOiAnc2VhcmNoJywgdmFsdWU6IHF1ZXJ5LCBwbGFjZWhvbGRlcjogdCgnc2VhcmNoTW9kZWxzJyksXG4gICAgICAgICAgICAgICdhcmlhLWxhYmVsJzogdCgnc2VhcmNoTW9kZWxzJyksXG4gICAgICAgICAgICAgIG9uQ2hhbmdlOiAoZSkgPT4gc2V0UXVlcnkoZS50YXJnZXQudmFsdWUpLFxuICAgICAgICAgICAgfSkpLFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLW1vZGVsLWxpc3QnIH0sXG4gICAgICAgICAgICBmaWx0ZXJlZC5sZW5ndGggPT09IDBcbiAgICAgICAgICAgICAgPyBoKCdwJywgeyBjbGFzc05hbWU6ICd0c2QtcG9wb3Zlci1lbXB0eScgfSwgdCgnbm9NYXRjaE1vZGVscycpKVxuICAgICAgICAgICAgICA6IG51bGwsXG4gICAgICAgICAgICBmaWx0ZXJlZC5tYXAoKGtleSkgPT5cbiAgICAgICAgICAgICAgaCgnbGFiZWwnLCB7IGtleSwgY2xhc3NOYW1lOiAndHNkLW1vZGVsLWl0ZW0nIH0sXG4gICAgICAgICAgICAgICAgaCgnaW5wdXQnLCB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnY2hlY2tib3gnLFxuICAgICAgICAgICAgICAgICAgY2hlY2tlZDogc2VsZWN0ZWQuaW5kZXhPZihrZXkpID49IDAsXG4gICAgICAgICAgICAgICAgICBvbkNoYW5nZTogKGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dCA9IHNlbGVjdGVkLnNsaWNlKClcbiAgICAgICAgICAgICAgICAgICAgaWYgKGUudGFyZ2V0LmNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dC5pbmRleE9mKGtleSkgPCAwKSBuZXh0LnB1c2goa2V5KVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGkgPSBuZXh0LmluZGV4T2Yoa2V5KVxuICAgICAgICAgICAgICAgICAgICAgIGlmIChpID49IDApIG5leHQuc3BsaWNlKGksIDEpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2UobmV4dCkgLy8g5Yu+6YCJ5Y2z5pe255Sf5pWIXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1tb2RlbC1uYW1lJywgdGl0bGU6IGtleSB9LCBrZXkpKSkpLFxuICAgICAgICAgIGgoJ3AnLCB7IGNsYXNzTmFtZTogJ3RzZC1wb3BvdmVyLW5vdGUnIH0sIHQoJ21vZGVsRmlsdGVySGludCcpKSlcbiAgICAgIDogbnVsbClcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDnrZvpgInmoI/vvJrml6XmnJ/pooTorr7vvIjliIbmrrXmjInpkq7vvIkrIOiHquWumuS5iea1ruWxgiArIOaooeWei+WkmumAiVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gRmlsdGVyQmFyKHByb3BzKSB7XG4gIGNvbnN0IHtcbiAgICByYW5nZSwgY3VzdG9tLCBtb2RlbHMsIGN1c3RvbU9wZW4sIG1vZGVsT3B0aW9ucyxcbiAgICBvblByZXNldCwgb25DdXN0b21PcGVuLCBvbkN1c3RvbUFwcGx5LCBvbkN1c3RvbUNsb3NlLCBvbk1vZGVsc0NoYW5nZSxcbiAgfSA9IHByb3BzXG4gIGNvbnN0IHQgPSB1c2VUKClcbiAgY29uc3Qgc2VnUmVmID0gUmVhY3QudXNlUmVmKG51bGwpXG4gIGNvbnN0IGN1c3RvbUJ0blJlZiA9IFJlYWN0LnVzZVJlZihudWxsKVxuICB1c2VPdXRzaWRlQ2xpY2soY3VzdG9tT3Blbiwgc2VnUmVmLCBvbkN1c3RvbUNsb3NlKVxuXG4gIGNvbnN0IGN1c3RvbUxhYmVsID0gZm10RGF0ZVNsYXNoKGN1c3RvbS5mcm9tKSArICcgLSAnICsgZm10RGF0ZVNsYXNoKGN1c3RvbS50bylcbiAgY29uc3QgcHJlc2V0cyA9IFtcbiAgICB7IGtleTogJ3RvZGF5JywgbGFiZWw6IHQoJ3RvZGF5JykgfSxcbiAgICB7IGtleTogJzdkJywgbGFiZWw6IHQoJ2xhc3Q3ZCcpIH0sXG4gICAgeyBrZXk6ICczMGQnLCBsYWJlbDogdCgnbGFzdDMwZCcpIH0sXG4gICAgeyBrZXk6ICdhbGwnLCBsYWJlbDogdCgnYWxsJykgfSxcbiAgICB7IGtleTogJ2N1c3RvbScsIGxhYmVsOiB0KCdjdXN0b20nKSB9LFxuICBdXG5cbiAgcmV0dXJuIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWZpbHRlcmJhcicgfSxcbiAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1zZWctd3JhcCcsIHJlZjogc2VnUmVmIH0sXG4gICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1zZWcnLCByb2xlOiAnZ3JvdXAnLCAnYXJpYS1sYWJlbCc6IHQoJ2RhdGVSYW5nZUdyb3VwJykgfSxcbiAgICAgICAgcHJlc2V0cy5tYXAoKHApID0+IHtcbiAgICAgICAgICBjb25zdCBhY3RpdmUgPSByYW5nZSA9PT0gcC5rZXlcbiAgICAgICAgICBjb25zdCBpc0N1c3RvbSA9IHAua2V5ID09PSAnY3VzdG9tJ1xuICAgICAgICAgIGNvbnN0IGxhYmVsID0gaXNDdXN0b20gJiYgYWN0aXZlID8gY3VzdG9tTGFiZWwgOiBwLmxhYmVsXG4gICAgICAgICAgcmV0dXJuIGgoJ2J1dHRvbicsIHtcbiAgICAgICAgICAgIGtleTogcC5rZXksXG4gICAgICAgICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgICAgICAgIHJlZjogaXNDdXN0b20gPyBjdXN0b21CdG5SZWYgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBjbGFzc05hbWU6ICd0c2Qtc2VnLWJ0bicgKyAoYWN0aXZlID8gJyB0c2Qtc2VnLWFjdGl2ZScgOiAnJykgKyAoaXNDdXN0b20gPyAnIHRzZC1zZWctY3VzdG9tJyA6ICcnKSxcbiAgICAgICAgICAgICdhcmlhLXByZXNzZWQnOiBhY3RpdmUsXG4gICAgICAgICAgICB0aXRsZTogaXNDdXN0b20gJiYgYWN0aXZlID8gY3VzdG9tTGFiZWwgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBvbkNsaWNrOiAoKSA9PiB7IGlmIChpc0N1c3RvbSkgb25DdXN0b21PcGVuKCFjdXN0b21PcGVuKTsgZWxzZSBvblByZXNldChwLmtleSkgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXNlZy1sYWJlbCcgfSwgbGFiZWwpKVxuICAgICAgICB9KSksXG4gICAgICBjdXN0b21PcGVuXG4gICAgICAgID8gaChDdXN0b21SYW5nZVBvcG92ZXIsIHsgY3VzdG9tLCBvbkFwcGx5OiBvbkN1c3RvbUFwcGx5LCBvbkNsb3NlOiBvbkN1c3RvbUNsb3NlLCBhbmNob3JSZWY6IGN1c3RvbUJ0blJlZiB9KVxuICAgICAgICA6IG51bGwpLFxuICAgIGgoTW9kZWxEcm9wZG93biwgeyBvcHRpb25zOiBtb2RlbE9wdGlvbnMsIHNlbGVjdGVkOiBtb2RlbHMsIG9uQ2hhbmdlOiBvbk1vZGVsc0NoYW5nZSB9KSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDlj4LogIPmiJDmnKzluIHnp43liIfmjaLvvIjkurrmsJHluIEgLyDnvo7lhYPvvIzlm7rlrpogMSBVU0QgPSA3IENOWe+8iVxuICpcbiAqIOaNoueul+WcqOWuv+S4u+S+p+WujOaIkO+8iOS7t+ebruihqOaYr+e+juWFg+S7t++8jOe7neS4jeWbnuWGme+8ie+8jOaJgOS7pei/memHjOWPqui0n+i0o+mAieaLqeS4juaMgeS5heWMlu+8mlxuICog5o2i5biB56eN5Y2z5o2i5p+l6K+i77yM5LiN6YeN5p+l5pWw5a2X5LiN5Lya5Y+Y44CCXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5jb25zdCBDVVJSRU5DWV9TWU1CT0xTID0geyBDTlk6ICfCpScsIFVTRDogJyQnIH1cbmNvbnN0IENVUlJFTkNZX1NUT1JFX0tFWSA9ICdkc2gtcGx1Z2luLXVzYWdlOmRpc3BsYXktY3VycmVuY3knXG5cbmZ1bmN0aW9uIHJlYWRTdG9yZWRDdXJyZW5jeSgpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKENVUlJFTkNZX1NUT1JFX0tFWSkgPT09ICdVU0QnID8gJ1VTRCcgOiAnQ05ZJ1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuICdDTlknIC8vIOaXoOeXleaooeW8jyAvIOWtmOWCqOiiq+emge+8mumAgOWbnum7mOiupFxuICB9XG59XG5mdW5jdGlvbiBzdG9yZUN1cnJlbmN5KGNvZGUpIHtcbiAgdHJ5IHtcbiAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oQ1VSUkVOQ1lfU1RPUkVfS0VZLCBjb2RlKVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8g5a2Y5LiN5LiL5bCx5Y+q5b2x5ZON5LiL5qyh5omT5byA77yM5LiN5b2x5ZON5pys5qyh5pi+56S6XG4gIH1cbn1cblxuZnVuY3Rpb24gQ3VycmVuY3lQaWNrZXIocHJvcHMpIHtcbiAgY29uc3QgeyBjb2RlLCBvbkNoYW5nZSB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICBjb25zdCBbb3Blbiwgc2V0T3Blbl0gPSBSZWFjdC51c2VTdGF0ZShmYWxzZSlcbiAgY29uc3QgcmVmID0gUmVhY3QudXNlUmVmKG51bGwpXG4gIGNvbnN0IHBhbmVsU3R5bGUgPSB1c2VGaXhlZFBhbmVsKHJlZiwgb3BlbiwgMTgwKVxuICB1c2VPdXRzaWRlQ2xpY2sob3BlbiwgcmVmLCAoKSA9PiBzZXRPcGVuKGZhbHNlKSlcbiAgY29uc3QgYWN0aXZlID0gQ1VSUkVOQ1lfU1lNQk9MU1tjb2RlXSA/IGNvZGUgOiAnQ05ZJ1xuICBjb25zdCBvcHRpb25zID0gWydDTlknLCAnVVNEJ11cbiAgLy8g5pS26LW35pe2IOKGkeKGkyDnm7TmjqXmjaLlgLzvvIjlg4/ljp/nlJ8gc2VsZWN077yJ77yM5bGV5byA5pe25Zyo5Lik6aG56Ze056e75Yqo77ybRXNjIOWFs+iPnOWNleOAglxuICBjb25zdCBtb3ZlID0gKHN0ZXApID0+IHtcbiAgICBjb25zdCBpID0gb3B0aW9ucy5pbmRleE9mKGFjdGl2ZSlcbiAgICBvbkNoYW5nZShvcHRpb25zWyhpICsgc3RlcCArIG9wdGlvbnMubGVuZ3RoKSAlIG9wdGlvbnMubGVuZ3RoXSlcbiAgfVxuICBjb25zdCBvbktleURvd24gPSAoZSkgPT4ge1xuICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpIHsgc2V0T3BlbihmYWxzZSk7IHJldHVybiB9XG4gICAgaWYgKCFvcGVuKSB7XG4gICAgICBpZiAoZS5rZXkgPT09ICdBcnJvd0Rvd24nIHx8IGUua2V5ID09PSAnQXJyb3dVcCcpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyBtb3ZlKGUua2V5ID09PSAnQXJyb3dEb3duJyA/IDEgOiAtMSk7IHJldHVybiB9XG4gICAgICBpZiAoZS5rZXkgPT09ICdFbnRlcicgfHwgZS5rZXkgPT09ICcgJykgeyBlLnByZXZlbnREZWZhdWx0KCk7IHNldE9wZW4odHJ1ZSkgfVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmIChlLmtleSA9PT0gJ0Fycm93RG93bicpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyBtb3ZlKDEpIH1cbiAgICBlbHNlIGlmIChlLmtleSA9PT0gJ0Fycm93VXAnKSB7IGUucHJldmVudERlZmF1bHQoKTsgbW92ZSgtMSkgfVxuICB9XG4gIHJldHVybiBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtY3VyLWFuY2hvcicsIHJlZiB9LFxuICAgIGgoJ2J1dHRvbicsIHtcbiAgICAgIHR5cGU6ICdidXR0b24nLFxuICAgICAgY2xhc3NOYW1lOiAndHNkLWN1ci1idG4nICsgKG9wZW4gPyAnIHRzZC1jdXItYnRuLW9wZW4nIDogJycpLFxuICAgICAgdGl0bGU6IHQoJ2N1cnJlbmN5SGludCcpLFxuICAgICAgJ2FyaWEtbGFiZWwnOiB0KCdjdXJyZW5jeUhpbnQnKSxcbiAgICAgICdhcmlhLWhhc3BvcHVwJzogJ2xpc3Rib3gnLFxuICAgICAgJ2FyaWEtZXhwYW5kZWQnOiBvcGVuLFxuICAgICAgb25DbGljazogKCkgPT4gc2V0T3BlbigodikgPT4gIXYpLFxuICAgICAgb25LZXlEb3duLFxuICAgIH0sXG4gICAgICBoKCdzcGFuJywgbnVsbCwgQ1VSUkVOQ1lfU1lNQk9MU1thY3RpdmVdKSxcbiAgICAgIGgoU3ZnSWNvbiwgeyBuYW1lOiAnY2hldnJvbicsIHNpemU6IDEwLCBjbGFzc05hbWU6ICd0c2QtY3VyLWNoZXZyb24nIH0pKSxcbiAgICBvcGVuXG4gICAgICA/IGgoJ2RpdicsIHtcbiAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtcG9wb3ZlciB0c2QtY3VyLXBvcG92ZXInLFxuICAgICAgICAgIHN0eWxlOiBwYW5lbFN0eWxlLFxuICAgICAgICAgIHJvbGU6ICdsaXN0Ym94JyxcbiAgICAgICAgICAnYXJpYS1sYWJlbCc6IHQoJ2N1cnJlbmN5SGludCcpLFxuICAgICAgICAgIG9uS2V5RG93bixcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9ucy5tYXAoKGMpID0+IGgoJ2J1dHRvbicsIHtcbiAgICAgICAgICBrZXk6IGMsXG4gICAgICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICAgICAgcm9sZTogJ29wdGlvbicsXG4gICAgICAgICAgJ2FyaWEtc2VsZWN0ZWQnOiBjID09PSBhY3RpdmUsXG4gICAgICAgICAgY2xhc3NOYW1lOiAndHNkLWN1ci1vcHRpb24nICsgKGMgPT09IGFjdGl2ZSA/ICcgdHNkLWN1ci1vcHRpb24tYWN0aXZlJyA6ICcnKSxcbiAgICAgICAgICBvbkNsaWNrOiAoKSA9PiB7IG9uQ2hhbmdlKGMpOyBzZXRPcGVuKGZhbHNlKSB9LFxuICAgICAgICB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1jdXItc3ltYm9sJyB9LCBDVVJSRU5DWV9TWU1CT0xTW2NdKSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtY3VyLW5hbWUnIH0sIHQoYyA9PT0gJ0NOWScgPyAnY3VycmVuY3lDTlknIDogJ2N1cnJlbmN5VVNEJykpLFxuICAgICAgICAgIGMgPT09IGFjdGl2ZSA/IGgoU3ZnSWNvbiwgeyBuYW1lOiAnY2hlY2snLCBzaXplOiAxMiwgY2xhc3NOYW1lOiAndHNkLWN1ci1jaGVjaycgfSkgOiBudWxsKSksXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXBvcG92ZXItbm90ZScgfSwgdCgnY3VycmVuY3lIaW50JykpKVxuICAgICAgOiBudWxsKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOaooeWei+WNoOavlO+8iEtQSSDnvZHmoLzph4znmoTnrKwgNiDmoLzvvIlcbiAqXG4gKiDmlbDmja7nm7TmjqXlkIPlrr/kuLsgYGJ5TW9kZWxgIOeahOihjO+8iOS4juOAjOaMieaooeWei+aYjue7huOAjeihqOWQjOS4gOS7ve+8ie+8jOS4jeWPpueul+S4gOmBjeOAglxuICog5piO57uG5pS+5Zyo5ZCE5q6155qE5Y6f55SfIHRpdGxlIOS4iuiAjOS4jeaYr+a1ruWxgu+8mktQSSDljaHotLTnnYDorr7nva7pnaLmnb/nmoToo4HliarovrnnlYzvvIxcbiAqIOWGjeWPoOS4gOWxgua1ruWxguWPquS8muaKiuS5i+WJjeS/ruWlveeahOijgeWJqumXrumimOW4puWbnuadpeOAglxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuY29uc3QgU0hBUkVfQ09MT1JTID0gW1xuICAvLyDlj6rnlKjkuLvpopjph4znnJ/lrp7lrZjlnKjjgIHkuJTlvbzmraTliIblvpflvIDnmoTlvanoibLml4/vvJrmt7Hok53jgIHnu7/jgIHnkKXnj4DjgIHnuqLjgIJcbiAgLy8g5LiN55SoIG5ldXRyYWwgLyDnmb0gLyDpu5Eg4oCU4oCUIOWug+S7rOWcqOa3sea1heS4pOWll+S4u+mimOmHjOS4gOi+ueS8mueziui/m+iDjOaZr++8jOS4gOi+ueS8muiiq+ivu+aIkOemgeeUqOaAgeOAglxuICAndmFyKC0tZHN3LXN0YXRpYy1kZWVwc2Vlay01MDApJyxcbiAgJ3ZhcigtLWRzdy1zdGF0aWMtZ3JlZW4tNTAwKScsXG4gICd2YXIoLS1kc3ctc3RhdGljLWFtYmVyLTUwMCknLFxuICAndmFyKC0tZHN3LXN0YXRpYy1yZWQtNDAwKScsXG5dXG5jb25zdCBTSEFSRV9UT1AgPSA0XG5jb25zdCBTSEFSRV9SRVNUX0tFWSA9ICdfX3Jlc3RfXydcblxuLyoqIGBwcm92aWRlci9tb2RlbGAg4oaSIOijuOaooeWei+WQje+8m+iJsuW4puagvOS9jeaUvuS4jeS4i+WFqOWQje+8jOWFqOWQjeeVmee7mSB0aXRsZSDkuI4gYXJpYeOAgiAqL1xuZnVuY3Rpb24gc2hvcnRNb2RlbE5hbWUoa2V5KSB7XG4gIGNvbnN0IHMgPSBTdHJpbmcoa2V5ID09IG51bGwgPyAnJyA6IGtleSlcbiAgY29uc3QgaSA9IHMubGFzdEluZGV4T2YoJy8nKVxuICByZXR1cm4gaSA9PT0gLTEgPyBzIDogcy5zbGljZShpICsgMSlcbn1cbi8qKlxuICog44CM6K+75Y+W5LqO44CN6KaB55qE5piv55yf5a6e5pe25Yi777yM5LiN5piv5pel5pyf44CCXG4gKlxuICog5Lu355uu6KGo6YeM5a2Y55qE5piv5oqT5Y+W6YKj5LiA5Yi755qEIElTTyDml7bpl7TvvIjluKbnp5LjgIFVVEPvvInvvJvov5nph4zmjaLmiJDmtY/op4jlmajmnKzlnLDml7bljLpcbiAqIOaYvuekuu+8jOeyvuehruWIsOenkuOAguaXqeacn+WPquacieaXpeacn++8iGAyMDI2LTEwLTE5YO+8ieeahOihqOS5n+iupOW+l++8jOihpSAwMDowMDowMOOAglxuICovXG5mdW5jdGlvbiBzdGFtcFRleHQodikge1xuICBpZiAoIXYpIHJldHVybiAn4oCUJ1xuICBjb25zdCBkID0gbmV3IERhdGUodilcbiAgaWYgKE51bWJlci5pc05hTihkLmdldFRpbWUoKSkpIHJldHVybiBTdHJpbmcodilcbiAgY29uc3QgcCA9IChuKSA9PiAobiA8IDEwID8gJzAnICsgbiA6IFN0cmluZyhuKSlcbiAgcmV0dXJuIGQuZ2V0RnVsbFllYXIoKSArICctJyArIHAoZC5nZXRNb250aCgpICsgMSkgKyAnLScgKyBwKGQuZ2V0RGF0ZSgpKSArXG4gICAgJyAnICsgcChkLmdldEhvdXJzKCkpICsgJzonICsgcChkLmdldE1pbnV0ZXMoKSkgKyAnOicgKyBwKGQuZ2V0U2Vjb25kcygpKVxufVxuLyoqIOWuv+S4u+ihjOaYryBgdG90YWxUb2tlbnNg77yb5YW85a655bey5pig5bCE5oiQIGB0b3RhbGAg55qE5b2i54q277yM56m66KGM5Lmf5LiN6IO95oqb44CCICovXG5mdW5jdGlvbiByb3dUb3RhbChyKSB7XG4gIHJldHVybiByID8gKHIudG90YWxUb2tlbnMgfHwgci50b3RhbCB8fCAwKSA6IDBcbn1cbi8qKiDpmY3luo/lj5bliY0gNCDmrrXvvIzlhbbkvZnlubbmiJDjgIzlhbblroPjgI3vvJvml6DmlbDmja7ml7bov5Tlm57nqbrmrrXjgIIgKi9cbmZ1bmN0aW9uIHNoYXJlU2VnbWVudHMocm93cykge1xuICBjb25zdCBsaXN0ID0gKHJvd3MgfHwgW10pLnNsaWNlKCkuc29ydCgoYSwgYikgPT4gcm93VG90YWwoYikgLSByb3dUb3RhbChhKSlcbiAgY29uc3QgdG90YWwgPSBsaXN0LnJlZHVjZSgocywgcikgPT4gcyArIHJvd1RvdGFsKHIpLCAwKVxuICBpZiAodG90YWwgPD0gMCkgcmV0dXJuIHsgdG90YWw6IDAsIHNlZ3M6IFtdIH1cbiAgY29uc3QgbnVtYmVycyA9IChyKSA9PiAoe1xuICAgIHRva2Vuczogcm93VG90YWwociksXG4gICAgY2FsbHM6IHIuY2FsbHMgfHwgMCxcbiAgICAvLyDkuI7mmI7nu4booajlkIzkuIDlj6PlvoTvvJrovpPlhaXlkKvnvJPlrZjor7vlhplcbiAgICBpbnB1dDogKHIuaW5wdXRUb2tlbnMgfHwgMCkgKyAoci5jYWNoZVJlYWRUb2tlbnMgfHwgMCkgKyAoci5jYWNoZVdyaXRlVG9rZW5zIHx8IDApLFxuICAgIG91dHB1dDogci5vdXRwdXRUb2tlbnMgfHwgMCxcbiAgICBjb3N0OiByLmNvc3QgfHwgMCxcbiAgfSlcbiAgY29uc3Qgc2VncyA9IGxpc3Quc2xpY2UoMCwgU0hBUkVfVE9QKS5tYXAoKHIsIGkpID0+IE9iamVjdC5hc3NpZ24oe1xuICAgIGtleTogU3RyaW5nKHIua2V5KSxcbiAgICBsYWJlbDogc2hvcnRNb2RlbE5hbWUoci5rZXkpLFxuICAgIHBjdDogcm93VG90YWwocikgLyB0b3RhbCxcbiAgICBjb2xvcjogU0hBUkVfQ09MT1JTW2kgJSBTSEFSRV9DT0xPUlMubGVuZ3RoXSxcbiAgfSwgbnVtYmVycyhyKSkpXG4gIGNvbnN0IHJlc3RSb3dzID0gbGlzdC5zbGljZShTSEFSRV9UT1ApXG4gIGNvbnN0IHJlc3RUb2tlbnMgPSByZXN0Um93cy5yZWR1Y2UoKHMsIHIpID0+IHMgKyByb3dUb3RhbChyKSwgMClcbiAgaWYgKHJlc3RUb2tlbnMgPiAwKSB7XG4gICAgY29uc3QgYWdnID0gcmVzdFJvd3MucmVkdWNlKChhLCByKSA9PiB7XG4gICAgICBjb25zdCBuID0gbnVtYmVycyhyKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9rZW5zOiBhLnRva2VucyArIG4udG9rZW5zLFxuICAgICAgICBjYWxsczogYS5jYWxscyArIG4uY2FsbHMsXG4gICAgICAgIGlucHV0OiBhLmlucHV0ICsgbi5pbnB1dCxcbiAgICAgICAgb3V0cHV0OiBhLm91dHB1dCArIG4ub3V0cHV0LFxuICAgICAgICBjb3N0OiBhLmNvc3QgKyBuLmNvc3QsXG4gICAgICB9XG4gICAgfSwgeyB0b2tlbnM6IDAsIGNhbGxzOiAwLCBpbnB1dDogMCwgb3V0cHV0OiAwLCBjb3N0OiAwIH0pXG4gICAgc2Vncy5wdXNoKE9iamVjdC5hc3NpZ24oe1xuICAgICAga2V5OiBTSEFSRV9SRVNUX0tFWSxcbiAgICAgIGxhYmVsOiBudWxsLCAvLyDjgIzlhbblroPjgI3nmoTmlofmoYjnlLHmuLLmn5PlsYLlj5bor43lhbhcbiAgICAgIHBjdDogcmVzdFRva2VucyAvIHRvdGFsLFxuICAgICAgLy8g44CM5YW25a6D44CN55So5ZCM6Imy57O755qE5reh6Imy77yI5rWF6JOd77yJ77yM5LiN55So54GwL+eZve+8mumCo+S4pOenjeWcqOa3seiJsuWNoeeJh+S4iuS8muiiq+ivu+aIkOemgeeUqFxuICAgICAgY29sb3I6ICd2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTMwMCknLFxuICAgIH0sIGFnZykpXG4gIH1cbiAgcmV0dXJuIHsgdG90YWwsIHNlZ3MgfVxufVxuXG5mdW5jdGlvbiBNb2RlbFNoYXJlQmFyKHByb3BzKSB7XG4gIGNvbnN0IHsgcm93cywgY3VycmVuY3kgfSA9IHByb3BzXG4gIGNvbnN0IHQgPSB1c2VUKClcbiAgY29uc3QgW3RpcCwgc2V0VGlwXSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpIC8vIHsga2V5LCBsZWZ0LCB0b3AgfSBpbiB2aWV3cG9ydCBjb29yZHNcbiAgY29uc3Qgb2NjID0gc2hhcmVTZWdtZW50cyhyb3dzKVxuICBpZiAob2NjLnRvdGFsIDw9IDApIHJldHVybiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXZhbHVlIHRzZC1zaGFyZS1lbXB0eScgfSwgdCgnbm9EYXRhJykpXG4gIGNvbnN0IGZpbmQgPSAoa2V5KSA9PiBvY2Muc2Vncy5maWx0ZXIoKHMpID0+IHMua2V5ID09PSBrZXkpWzBdIHx8IG51bGxcbiAgY29uc3Qgc2hvd24gPSAodGlwICYmIGZpbmQodGlwLmtleSkpIHx8IG9jYy5zZWdzWzBdXG4gIGNvbnN0IGxhYmVsT2YgPSAocykgPT4gKHMua2V5ID09PSBTSEFSRV9SRVNUX0tFWSA/IHQoJ3NoYXJlT3RoZXInKSA6IHMubGFiZWwpXG4gIGNvbnN0IGZ1bGxPZiA9IChzKSA9PiAocy5rZXkgPT09IFNIQVJFX1JFU1RfS0VZID8gdCgnc2hhcmVPdGhlcicpIDogcy5rZXkpXG4gIGNvbnN0IGNvc3RPZiA9IChzKSA9PiAocy51bnByaWNlZCA9PT0gdHJ1ZSA/IHQoJ3VucHJpY2VkJykgOiBmb3JtYXRDb3N0KHMuY29zdCwgY3VycmVuY3kpKVxuICAvLyDmgqzlgZwv6IGa54Sm77ya5LuO5q6155qE6KeG5Y+j55+p5b2i5o6o5byA77yMZml4ZWQg5a6a5L2N5LiN5Y+X6K6+572u6Z2i5p2/IG92ZXJmbG93IOijgeWJqlxuICBjb25zdCBzaG93VGlwID0gKGUsIHMpID0+IHtcbiAgICBjb25zdCByID0gZS5jdXJyZW50VGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgc2V0VGlwKHsga2V5OiBzLmtleSwgbGVmdDogci5sZWZ0ICsgci53aWR0aCAvIDIsIHRvcDogci50b3AgfSlcbiAgfVxuICBjb25zdCBoaWRlVGlwID0gKCkgPT4gc2V0VGlwKG51bGwpXG4gIGNvbnN0IHRpcEJveCA9IHNob3duICYmIHRpcFxuICAgID8gaCgnZGl2Jywge1xuICAgICAgICBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcCB0c2Qtc2hhcmUtdGlwJyxcbiAgICAgICAgc3R5bGU6IHsgcG9zaXRpb246ICdmaXhlZCcsIGxlZnQ6IHRpcC5sZWZ0ICsgJ3B4JywgdG9wOiB0aXAudG9wICsgJ3B4JywgdHJhbnNmb3JtOiAndHJhbnNsYXRlKC01MCUsIC0xMTAlKScgfSxcbiAgICAgIH0sXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtZGF0ZScgfSwgZnVsbE9mKHNob3duKSksXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtcm93JyB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRvdCcsIHN0eWxlOiB7IGJhY2tncm91bmQ6IHNob3duLmNvbG9yIH0gfSksXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ3RvdGFsVG9rZW5zJykpLFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0SW50KHNob3duLnRva2VucykpKSxcbiAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1yb3cnIH0sXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ2xlZ2VuZElucHV0JykpLFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0SW50KHNob3duLmlucHV0KSkpLFxuICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXJvdycgfSxcbiAgICAgICAgICBoKCdzcGFuJywgbnVsbCwgdCgnbGVnZW5kT3V0cHV0JykpLFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0SW50KHNob3duLm91dHB1dCkpKSxcbiAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1yb3cnIH0sXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ2Nvc3QnKSksXG4gICAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtdmFsJyB9LCBjb3N0T2Yoc2hvd24pKSkpXG4gICAgOiBudWxsXG4gIHJldHVybiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXNoYXJlLWJvZHknIH0sXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2Qtc2hhcmUtdHJhY2snLCBvbk1vdXNlTGVhdmU6IGhpZGVUaXAgfSxcbiAgICAgIG9jYy5zZWdzLm1hcCgocykgPT4gaCgnZGl2Jywge1xuICAgICAgICBrZXk6IHMua2V5LFxuICAgICAgICBjbGFzc05hbWU6ICd0c2Qtc2hhcmUtc2VnJyxcbiAgICAgICAgJ2RhdGEtc2hhcmUta2V5Jzogcy5rZXksXG4gICAgICAgICdkYXRhLWFjdGl2ZSc6IHNob3duICYmIHNob3duLmtleSA9PT0gcy5rZXkgPyAndHJ1ZScgOiB1bmRlZmluZWQsXG4gICAgICAgIHN0eWxlOiB7IHdpZHRoOiBzLnBjdCAqIDEwMCArICclJywgYmFja2dyb3VuZDogcy5jb2xvciB9LFxuICAgICAgICByb2xlOiAnaW1nJyxcbiAgICAgICAgdGFiSW5kZXg6IDAsXG4gICAgICAgICdhcmlhLWxhYmVsJzogZnVsbE9mKHMpICsgJyDCtyAnICsgZm10UGN0KHMucGN0KSArICcgwrcgJyArIGZvcm1hdEludChzLnRva2VucykgKyAnICcgKyB0KCd0b3RhbFRva2VucycpLFxuICAgICAgICBvbk1vdXNlRW50ZXI6IChlKSA9PiBzaG93VGlwKGUsIHMpLFxuICAgICAgICBvbkZvY3VzOiAoZSkgPT4gc2hvd1RpcChlLCBzKSxcbiAgICAgICAgb25CbHVyOiBoaWRlVGlwLFxuICAgICAgfSkpKSxcbiAgICAvLyDmnaHkuIvlj6rnlZnkuIDooYzkvY7osIPohJrms6jvvIjlvZPliY3mgqzmta7nmoTpgqPmrrXvvIzlkKbliJnmnIDlpKfnmoTpgqPmrrXvvInvvJtcbiAgICAvLyDlhajlkI3kuI7mmI7nu4bpg73lnKjmgqzmta7ljaHniYfph4zvvIzmiYDku6Xov5nph4zkuI3mjIIgdGl0bGXjgIJcbiAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1zaGFyZS1jYXB0aW9uJyB9LFxuICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXNoYXJlLWNhcC1uYW1lJyB9LCBsYWJlbE9mKHNob3duKSksXG4gICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2Qtc2hhcmUtY2FwLXBjdCcgfSwgZm10UGN0KHNob3duLnBjdCkpKSxcbiAgICB0aXBCb3gpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog5qCH6aKY5peB55qE5o+Q56S66K6w5Y+3XG4gKlxuICog44CM54K55Ye7IC8g5oKs5rWu5Y+M5pi+56S644CN5piv56Gs6KaB5rGC77yaXG4gKiAgLSDmgqzmta7otbDljp/nlJ8gdGl0bGXvvIjmtY/op4jlmajoh6rlt7HlvLnvvIzkuI3kvp3otZbohJrmnKzvvIzkuZ/kuI3kvJrooqvorr7nva7pnaLmnb/nmoQgb3ZlcmZsb3cg6KOB5o6J77yJ77ybXG4gKiAgLSDngrnlh7vlsZXlvIDlkIzkuIDkuKrmta7lsYIg4oCU4oCUIOinpuWxj+ayoeaciSBob3Zlcu+8jOmUruebmOS5n+imgeiDveivu+WIsO+8jOS4lOa1ruWxgumHjOS4pOauteinhOWImeaNouihjFxuICogICAg6K+76LW35p2l5q+U5LiA5pW06KGMIHRvb2x0aXAg5riF5qWa5b6X5aSa44CCXG4gKiDljp/nlJ8gdGl0bGUg5LiO5rWu5bGC5YWx55So5ZCM5LiA5Lu95paH5pys77yI5a6/5Li7L+iwg+eUqOaWueWPquS8oOS4gOasoe+8ie+8jOS4jee7tOaKpOesrOS6jOS7veaWh+ahiOOAglxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gSGludFRpcChwcm9wcykge1xuICBjb25zdCB7IHRleHQsIGxhYmVsIH0gPSBwcm9wc1xuICBjb25zdCBbb3Blbiwgc2V0T3Blbl0gPSBSZWFjdC51c2VTdGF0ZShmYWxzZSlcbiAgY29uc3QgcmVmID0gUmVhY3QudXNlUmVmKG51bGwpXG4gIGNvbnN0IHBhbmVsU3R5bGUgPSB1c2VGaXhlZFBhbmVsKHJlZiwgb3BlbiwgMjYwKVxuICB1c2VPdXRzaWRlQ2xpY2sob3BlbiwgcmVmLCAoKSA9PiBzZXRPcGVuKGZhbHNlKSlcbiAgY29uc3QgbGluZXMgPSBTdHJpbmcodGV4dCA9PSBudWxsID8gJycgOiB0ZXh0KS5zcGxpdCgnXFxuJykuZmlsdGVyKChzKSA9PiBzLnRyaW0oKS5sZW5ndGggPiAwKVxuICByZXR1cm4gaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWhpbnQnLCByZWYgfSxcbiAgICBoKCdidXR0b24nLCB7XG4gICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgIGNsYXNzTmFtZTogJ3RzZC1oaW50LWJ0bicgKyAob3BlbiA/ICcgdHNkLWhpbnQtYnRuLW9wZW4nIDogJycpLFxuICAgICAgdGl0bGU6IHRleHQgfHwgbnVsbCxcbiAgICAgICdhcmlhLWxhYmVsJzogbGFiZWwgfHwgdGV4dCB8fCAnJyxcbiAgICAgICdhcmlhLWV4cGFuZGVkJzogb3BlbixcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHNldE9wZW4oKHYpID0+ICF2KSxcbiAgICAgIG9uS2V5RG93bjogKGUpID0+IHtcbiAgICAgICAgaWYgKGUua2V5ID09PSAnRXNjYXBlJyAmJiBvcGVuKSB7IGUuc3RvcFByb3BhZ2F0aW9uKCk7IHNldE9wZW4oZmFsc2UpIH1cbiAgICAgIH0sXG4gICAgfSwgaChTdmdJY29uLCB7IG5hbWU6ICdoaW50Jywgc2l6ZTogMTIgfSkpLFxuICAgIG9wZW5cbiAgICAgID8gaCgnZGl2Jywge1xuICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1wb3BvdmVyIHRzZC1oaW50LXBvcG92ZXInLFxuICAgICAgICAgIHN0eWxlOiBwYW5lbFN0eWxlLFxuICAgICAgICAgIHJvbGU6ICdub3RlJyxcbiAgICAgICAgfSwgbGluZXMubWFwKChzLCBpKSA9PiBoKCdwJywgeyBrZXk6IGksIGNsYXNzTmFtZTogJ3RzZC1oaW50LWxpbmUnIH0sIHMpKSlcbiAgICAgIDogbnVsbClcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDmsYfmgLvmjIfmoIfljaEgw5c2XG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKlxuICog6IqC5YGH5pel6KaG55uW6K+05piO77ya5ZOq5Lqb5bm05Lu95Zyo5omL44CB5ZOq5LiA5bm06L+Y5rKh5YWs5biD44CCXG4gKlxuICog5bOw6LC35Lu35L6d6LWW5Lit5Zu95rOV5a6a6IqC5YGH5pel6KGo77yb5pyq5YWs5biD55qE5bm05Lu95Y+q6IO95oyJ44CM5ZGo5pyrICsg5pe25q6144CN5Yik5a6a77yM6IqC5YGH5pelXG4gKiDokL3lnKjpq5jls7Dnqpflj6PlhoXnmoTosIPnlKjkvJrooqvnrpfpq5jjgILkuI7lhbborqnov5nkuKror6/lt67pmpDouqvvvIzkuI3lpoLlnKjjgIzlj4LogIPmiJDmnKzjgI3nmoTmj5DnpLpcbiAqIOmHjOaKiuimhuebluiMg+WbtOWGmea4healmuOAglxuICovXG5mdW5jdGlvbiBob2xpZGF5Tm90ZShwcmljaW5nLCB0KSB7XG4gIGNvbnN0IHllYXJzID0gcHJpY2luZyAmJiBwcmljaW5nLmhvbGlkYXlzICYmIHR5cGVvZiBwcmljaW5nLmhvbGlkYXlzID09PSAnb2JqZWN0J1xuICAgID8gT2JqZWN0LmtleXMocHJpY2luZy5ob2xpZGF5cykubWFwKE51bWJlcikuZmlsdGVyKChuKSA9PiBOdW1iZXIuaXNGaW5pdGUobikpLnNvcnQoKGEsIGIpID0+IGEgLSBiKVxuICAgIDogW11cbiAgaWYgKHllYXJzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGxcbiAgY29uc3QgcmFuZ2UgPSB5ZWFycy5sZW5ndGggPT09IDEgPyBTdHJpbmcoeWVhcnNbMF0pIDogeWVhcnNbMF0gKyAn4oCTJyArIHllYXJzW3llYXJzLmxlbmd0aCAtIDFdXG4gIGNvbnN0IG1pc3NpbmcgPSB5ZWFycy5maWx0ZXIoKHllYXIpID0+IHByaWNpbmcuaG9saWRheXNbeWVhcl0gJiYgcHJpY2luZy5ob2xpZGF5c1t5ZWFyXS51bnB1Ymxpc2hlZCA9PT0gdHJ1ZSlcbiAgaWYgKG1pc3NpbmcubGVuZ3RoID09PSAwKSByZXR1cm4gdCgnaG9saWRheU5vdGUnLCB7IHJhbmdlIH0pXG4gIHJldHVybiB0KCdob2xpZGF5Tm90ZVVucHVibGlzaGVkJywgeyByYW5nZSwgeWVhcnM6IG1pc3Npbmcuam9pbign44CBJykgfSlcbn1cblxuLyog57uf6K6h5Y2h55qE5qe95L2N6KGo77ya6aqo5p625bGP5oyJ5a6D55S75Y2g5L2N5Z2X44CCXG4gKlxuICog6L+Z5byg6KGo5a2Y5Zyo55qE5ZSv5LiA55CG55Sx5pivKirliKvlho3mvIIqKu+8mumqqOaetuWxj+abvue7j+WGmeatuyA1IOS4quWNoOS9jeWdl++8jOiAjOecn+WunuWNoeeJh+W3sue7j1xuICogNiDlvKDvvIjooaXkuobjgIzmqKHlnovljaDmr5TjgI3vvInvvIznu5PmnpzliqDovb3mgIHlsJHkuIDmoLzjgIHmlbDmja7liLDovr7ml7bmlbTooYzph43mjpLjgIJcbiAqIOanveS9jemhuuW6j+W/hemhu+S4jiBgU3VtbWFyeUNhcmRzYCDph4znmoQgYGNhcmRzYCDmlbDnu4TkuIDoh7Qg4oCU4oCUIGB0ZXN0cy9jbGllbnQtc2xvdHMudGVzdC5qc2BcbiAqIOS8mumAkOWtl+avlOWvueS4pOi+ueeahCBrZXkg5YiX6KGo77yM5pS55LiA5aSE5ryP5Y+m5LiA5aSE55u05o6l5Y+Y57qi44CCXG4gKi9cbmNvbnN0IFNVTU1BUllfQ0FSRF9TTE9UUyA9IFsndG90YWwnLCAnaW5wdXQnLCAnb3V0cHV0JywgJ2NhbGxzJywgJ2Nvc3QnLCAnc2hhcmUnXVxuXG5mdW5jdGlvbiBTdW1tYXJ5Q2FyZHMocHJvcHMpIHtcbiAgY29uc3QgeyB0b3RhbCwgY3VycmVuY3ksIHVucHJpY2VkQ2FsbHMsIGN1cnJlbmN5Q29kZSwgb25DdXJyZW5jeUNoYW5nZSwgYnlNb2RlbCwgcHJpY2luZywgb25PcGVuUHJpY2luZyB9ID0gcHJvcHNcbiAgY29uc3QgdHQgPSB1c2VUKClcbiAgY29uc3QgZCA9IHRvdGFsIHx8IHt9XG4gIGNvbnN0IGlucHV0VG90YWwgPSAoZC5pbnB1dFRva2VucyB8fCAwKSArIChkLmNhY2hlUmVhZFRva2VucyB8fCAwKSArIChkLmNhY2hlV3JpdGVUb2tlbnMgfHwgMClcbiAgY29uc3QgY2FyZHMgPSBbXG4gICAge1xuICAgICAga2V5OiAndG90YWwnLCBpY29uOiAnbGF5ZXJzJywgbGFiZWw6IHR0KCd0b3RhbFRva2VucycpLFxuICAgICAgdmFsdWU6IGZvcm1hdFRva2Vuc1Nob3J0KGQudG90YWxUb2tlbnMpLCB0aXRsZTogZm9ybWF0SW50KGQudG90YWxUb2tlbnMpLFxuICAgICAgc3ViOiB0dCgnYXBwcm94SU8nKSwgY29sb3I6ICd2YXIoLS1kc3ctYWxpYXMtYnJhbmQtcHJpbWFyeSknLFxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnaW5wdXQnLCBpY29uOiAnZG93bicsIGxhYmVsOiB0dCgnaW5wdXRUb2tlbnMnKSxcbiAgICAgIHZhbHVlOiBmb3JtYXRUb2tlbnNTaG9ydChpbnB1dFRvdGFsKSwgdGl0bGU6IGZvcm1hdEludChpbnB1dFRvdGFsKSxcbiAgICAgIGNvbG9yOiAndmFyKC0tZHN3LXN0YXRpYy1kZWVwc2Vlay01MDApJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ291dHB1dCcsIGljb246ICd1cCcsIGxhYmVsOiB0dCgnb3V0cHV0VG9rZW5zJyksXG4gICAgICB2YWx1ZTogZm9ybWF0VG9rZW5zU2hvcnQoZC5vdXRwdXRUb2tlbnMpLCB0aXRsZTogZm9ybWF0SW50KGQub3V0cHV0VG9rZW5zKSxcbiAgICAgIGNvbG9yOiAndmFyKC0tZHN3LXN0YXRpYy1ncmVlbi01MDApJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ2NhbGxzJywgaWNvbjogJ2FjdGl2aXR5JywgbGFiZWw6IHR0KCdjYWxscycpLFxuICAgICAgdmFsdWU6IGZvcm1hdEludChkLmNhbGxzKSwgdGl0bGU6IGZvcm1hdEludChkLmNhbGxzKSxcbiAgICAgIGNvbG9yOiAndmFyKC0tZHN3LXN0YXRpYy1kZWVwc2Vlay01MDApJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ2Nvc3QnLCBpY29uOiAnY29pbnMnLCBsYWJlbDogdHQoJ2Nvc3QnKSwgYWN0aW9uOiB0cnVlLFxuICAgICAgLy8g56ym5Y+355SxIHByZWZpeCDnmoTluIHnp43liIfmjaLlmajnlLvvvIjlroPmmL7npLrlvZPliY3luIHnp43nrKblj7fvvInvvIzov5nph4zlj6rnu5nmlbDlrZdcbiAgICAgIHZhbHVlOiBjb3N0RGlnaXRzKGQuY29zdCksIHRpdGxlOiBmb3JtYXRDb3N0KGQuY29zdCwgY3VycmVuY3kpLFxuICAgICAgY29sb3I6ICd2YXIoLS1kc3ctc3RhdGljLWdyZWVuLTUwMCknLFxuICAgICAgcHJlZml4OiBoKEN1cnJlbmN5UGlja2VyLCB7IGNvZGU6IGN1cnJlbmN5Q29kZSwgb25DaGFuZ2U6IG9uQ3VycmVuY3lDaGFuZ2UgfSksXG4gICAgICAvLyDjgIzov5nkuKrmlbDmgI7kuYjmnaXnmoTjgI3vvJrlj6PlvoTlj6XkuI7pq5jls7Dop4TliJnljp/mnKzmmK/kuKTooYzluLjpqbvlsI/lrZfvvIzmiorlsI/ljaHmjKTmu6HkuobvvIxcbiAgICAgIC8vIOaUueaIkOagh+mimOeahOaCrOa1ruaPkOekuiDigJTigJQg5LiN5Zyo6KeG6YeO6YeM5Y2g5L2N77yM5oyH5LiA5LiL5bCx6IO96K+75Yiw5YWo5paH44CCXG4gICAgICAvLyDmnKrlrprku7fmnaHmlbDku43nhLbnlZnlnKjljaHpnaLkuIrvvJrlroPmmK/kuIDmnaHlvoXlip7vvIzkuI3mmK/op6Pph4rjgIJcbiAgICAgIHRpcDogW3R0KCdjb3N0U291cmNlTm90ZScpLCB0dCgncGVha1J1bGVTaG9ydCcpLCBob2xpZGF5Tm90ZShwcmljaW5nLCB0dCldLmZpbHRlcihCb29sZWFuKS5qb2luKCdcXG4nKSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ3NoYXJlJywgaWNvbjogJ3NoYXJlJywgbGFiZWw6IHR0KCdtb2RlbFNoYXJlJyksXG4gICAgICBjb2xvcjogJ3ZhcigtLWRzdy1hbGlhcy1icmFuZC1wcmltYXJ5KScsXG4gICAgICBjb250ZW50OiBoKE1vZGVsU2hhcmVCYXIsIHsgcm93czogYnlNb2RlbCwgY3VycmVuY3kgfSksXG4gICAgfSxcbiAgXVxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZHMnIH0sXG4gICAgY2FyZHMubWFwKChjKSA9PlxuICAgICAgaCgnZGl2JywgeyBrZXk6IGMua2V5LCBjbGFzc05hbWU6ICd0c2QtY2FyZCcgfSxcbiAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC1oZWFkJyB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLWljb24nLCBzdHlsZTogeyBjb2xvcjogYy5jb2xvciB9IH0sXG4gICAgICAgICAgICBoKFN2Z0ljb24sIHsgbmFtZTogYy5pY29uLCBzaXplOiAxNCB9KSksXG4gICAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtbGFiZWwnLCB0aXRsZTogYy50aXAgfHwgbnVsbCB9LCBjLmxhYmVsKSxcbiAgICAgICAgICAvLyDmj5DnpLrorrDlj7fmmK/ni6znq4vmjInpkq7vvJrmgqzmta7mnInljp/nlJ8gdGl0bGXvvIzngrnlh7vlsZXlvIDmta7lsYLjgIJcbiAgICAgICAgICBjLnRpcCA/IGgoSGludFRpcCwgeyB0ZXh0OiBjLnRpcCwgbGFiZWw6IHR0KCdwcmljaW5nQ2FyZE5vdGVUaXAnKSB9KSA6IG51bGwsXG4gICAgICAgICAgLy8g5Y+C6ICD5oiQ5pys5Y2h55qE44CM5oCO5LmI566X5Ye65p2l55qE44CN5YWl5Y+j77ya5omT5byA5Yy56YWN5by556qX44CC5Zu+5qCH5LiO5by556qX6YeM55qEXG4gICAgICAgICAgLy8g44CM5pu05paw5Yy56YWN6KGo44CN5ZCM5qy+77yI5Ymq6LS05p2/77yJ77yM5LiA55y855yL5Ye65Lik6ICF5piv5ZCM5LiA5Lu25LqL44CCXG4gICAgICAgICAgYy5hY3Rpb25cbiAgICAgICAgICAgID8gaCgnYnV0dG9uJywge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdidXR0b24nLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1jYXJkLWFjdGlvbicsXG4gICAgICAgICAgICAgICAgdGl0bGU6IHR0KCdwcmljaW5nT3BlbicpLFxuICAgICAgICAgICAgICAgICdhcmlhLWxhYmVsJzogdHQoJ3ByaWNpbmdPcGVuJyksXG4gICAgICAgICAgICAgICAgb25DbGljazogb25PcGVuUHJpY2luZyxcbiAgICAgICAgICAgICAgfSwgaChTdmdJY29uLCB7IG5hbWU6ICdjb250ZXh0SW5qZWN0aW9uJywgc2l6ZTogMTIgfSkpXG4gICAgICAgICAgICA6IG51bGwpLFxuICAgICAgICBjLmNvbnRlbnRcbiAgICAgICAgICA/IGMuY29udGVudFxuICAgICAgICAgIDogaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC12YWx1ZScsIHRpdGxlOiBjLnRpdGxlIH0sIGMucHJlZml4IHx8IG51bGwsIGMudmFsdWUpLFxuICAgICAgICAvLyDlj4LogIPmiJDmnKzljaHnmoTohJrms6jvvJrlj6PlvoTkuI7pq5jls7Dop4TliJnlt7Lnp7vliLDmoIfpopjnmoTmgqzmta7mj5DnpLrvvIzov5nph4zlj6rlialcbiAgICAgICAgLy8g44CM6L+Y5pyJ5Yeg5qyh6LCD55So5rKh5a6a5Lu344CN6L+Z5p2h5b6F5Yqe77yI5pyJ5LqL5omN5Ye6546w77yJ44CCXG4gICAgICAgIGMua2V5ID09PSAnY29zdCcgJiYgdW5wcmljZWRDYWxscyA+IDBcbiAgICAgICAgICA/IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtbm90ZXMnIH0sXG4gICAgICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtbm90ZSB0c2QtY2FyZC1ub3RlLXdhcm4nIH0sIHR0KCd1bnByaWNlZE5vdGUnLCB7IGNvdW50OiBmb3JtYXRJbnQodW5wcmljZWRDYWxscykgfSkpKVxuICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgYy5zdWIgPyBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXN1YicgfSwgYy5zdWIpIDogbnVsbCkpKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOWumuS7t+WMuemFjeW8ueeql1xuICpcbiAqIOino+WGs+eahOaYr+OAjOWPguiAg+aIkOacrOS4uuS7gOS5iOaYr+i/meS4quaVsOOAje+8muavj+S4quaooeWei+aMieWQjeensOmAkOe6p+WMuemFjeWIsOWumuS7t+ihqO+8jOWMuemFjVxuICog57uT5p6c5YiG5Zub5oCB77yI57K+56GuIC8g5qih57OKIC8g5pyq5Yy56YWNIC8g6Ieq5a6a5LmJ77yJ77yM5Zub5oCB6YO96IO95pS544CB6YO96IO95pS25Zue44CCXG4gKlxuICog5Lik5p2h56Gs6KeE5YiZ5YaZ5Zyo6L+Z6YeM77yM5Yir5aSE5LiN6KaB5ZCE5YaZ5LiA5Lu977yaXG4gKiAgMS4g5omT5byA5by556qX44CB5ouJ5Y+W5Yy56YWN6KGo6YO9KirkuI3okL3nm5gqKuOAguWPquacieOAjOehruWumuOAjeaJjeWGme+8jOWGmeWFpeeahOaYr+iEj+ihjOWSjOiiq1xuICogICAgIOaUtuWbnueahCBrZXkg4oCU4oCUIOayoeWKqOi/h+eahOihjOS4jeWGme+8jOWFjeW+l+aKiuWIq+S6uuWImuehruiupOeahOWMuemFjeimhuebluaOieOAglxuICogIDIuIOWAmemAieadpeiHquW9k+WJjeWumuS7t+ihqOeahCBpZO+8iOWuv+S4uyBwcm9wb3NlIOS4gOW5tuW4puWbnu+8ie+8jOS4jeWcqOWJjeerr+WPpuWtmOS4gOS7veWQjeWNleOAglxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuY29uc3QgTUFUQ0hfU1RBVEVfTEFCRUwgPSB7IGV4YWN0OiAncHJpY2luZ0hvd0xpdGVyYWwnLCBmdXp6eTogJ3ByaWNpbmdIb3dUd2luJywgbm9uZTogJ3ByaWNpbmdIb3dOb25lJywgY3VzdG9tOiAncHJpY2luZ0hvd0N1c3RvbScgfVxuXG4vKlxuICog5Zub5oCB55Sx5a6/5Li757uZ77yIcHJpY2VSb3cuc3RhdGXvvInvvIzliY3nq6/kuI3lho3op6Pph4ogaG9344CCXG4gKiDov5nph4zmm77nu4/mnInkuIDku70gbWF0Y2hTdGF0ZU9mKHJvdynvvIzmioogaG93IOaYoOWwhOaIkOWbm+aAge+8m+Wug+WGmeatu+S6huS4gOS4qumYtuair+mHjOS4jeWtmOWcqFxuICog55qE5YC877yIJ2xpdGVyYWwn77yJ77yM5LqO5piv5omA5pyJ57K+56Gu5ZG95Lit6YO95pi+56S65oiQ44CM5pyq5Yy56YWN44CN4oCU4oCU5Lik5Liq6K+N6KGo77yM5Lik5aSE57u05oqk77yMXG4gKiDkuIDlpITplJnlsLHlhajplJnjgILnjrDlnKjlj6rmnInkuIDlpITvvJpwcmljaW5nLmpzIOeahCByZXNvbHZlUHJpY2XjgIJcbiAqL1xuXG4vKiog5by556qX6YeM5pS55Yqo55qE6I2J56i/77yaa2V5IOKGkiB7IHRhcmdldCwgY2xlYXJlZCwgZGlydHkgfeOAgiAqL1xuZnVuY3Rpb24gbWVyZ2VEcmFmdChwcmV2LCBrZXksIHBhdGNoKSB7XG4gIGNvbnN0IG5leHQgPSB7IC4uLnByZXYgfVxuICBjb25zdCBjdXIgPSBuZXh0W2tleV0gfHwgeyB0YXJnZXQ6IG51bGwsIGNsZWFyZWQ6IGZhbHNlLCBkaXJ0eTogZmFsc2UgfVxuICBuZXh0W2tleV0gPSB7IC4uLmN1ciwgLi4ucGF0Y2gsIGRpcnR5OiB0cnVlIH1cbiAgcmV0dXJuIG5leHRcbn1cblxuLyoqIOS4gOihjOaPkOS6pOaXtuS8muW4puS7gOS5iO+8mmB1bmRlZmluZWRgID0g5rKh5Yqo6L+H77yM5LiN5o+Q5Lqk44CCICovXG5mdW5jdGlvbiBkZWNpc2lvbk9mKGRyYWZ0KSB7XG4gIGlmICghZHJhZnQgfHwgIWRyYWZ0LmRpcnR5KSByZXR1cm4gdW5kZWZpbmVkXG4gIGlmIChkcmFmdC5jbGVhcmVkKSByZXR1cm4geyBrZXk6IGRyYWZ0LmtleSwgY2xlYXI6IHRydWUgfVxuICBpZiAodHlwZW9mIGRyYWZ0LnRhcmdldCA9PT0gJ3N0cmluZycgJiYgZHJhZnQudGFyZ2V0ICE9PSAnJykgcmV0dXJuIHsga2V5OiBkcmFmdC5rZXksIHRhcmdldDogZHJhZnQudGFyZ2V0IH1cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBQcmljaW5nRGlhbG9nKHByb3BzKSB7XG4gIGNvbnN0IHsgb25DbG9zZSwgb25BcHBsaWVkLCBjdXJyZW5jeSB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICBjb25zdCBbcm93cywgc2V0Um93c10gPSBSZWFjdC51c2VTdGF0ZShbXSlcbiAgY29uc3QgW3RhYmxlLCBzZXRUYWJsZV0gPSBSZWFjdC51c2VTdGF0ZShudWxsKVxuICBjb25zdCBbc2F2ZWQsIHNldFNhdmVkXSA9IFJlYWN0LnVzZVN0YXRlKHt9KVxuICBjb25zdCBbZHJhZnQsIHNldERyYWZ0XSA9IFJlYWN0LnVzZVN0YXRlKHt9KVxuICBjb25zdCBbc3RhdHVzLCBzZXRTdGF0dXNdID0gUmVhY3QudXNlU3RhdGUoJ2xvYWRpbmcnKSAvLyBsb2FkaW5nIHwgcmVhZHkgfCBlcnJvclxuICBjb25zdCBbZXJyb3IsIHNldEVycm9yXSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpXG4gIGNvbnN0IFtzYXZpbmcsIHNldFNhdmluZ10gPSBSZWFjdC51c2VTdGF0ZShmYWxzZSlcbiAgY29uc3QgW3BpY2tGb3IsIHNldFBpY2tGb3JdID0gUmVhY3QudXNlU3RhdGUobnVsbCkgLy8g5q2j5Zyo6YCJ5Y+C6ICD5qih5Z6L55qEIGtleVxuICBjb25zdCBbcGlja1RleHQsIHNldFBpY2tUZXh0XSA9IFJlYWN0LnVzZVN0YXRlKCcnKVxuICBjb25zdCBbZWRpdEZvciwgc2V0RWRpdEZvcl0gPSBSZWFjdC51c2VTdGF0ZShudWxsKSAvLyDmraPlnKjmiYvloavljZXku7fnmoQga2V577yI6Ieq5a6a5LmJ6YCJ6aG577yJXG4gIGNvbnN0IFtoaXN0b3J5T3Blbiwgc2V0SGlzdG9yeU9wZW5dID0gUmVhY3QudXNlU3RhdGUoZmFsc2UpXG4gIC8vIOWAmemAieWIl+ihqOaMguWcqOihjOWGheOAjOWMuemFjeWIsOOAjemCo+S4gOagvOS4iu+8mua1ruWxguaYryBwb3NpdGlvbjogZml4ZWTvvIzmkpHkuI3lvIDooajmoLzvvJtcbiAgLy8g5L2GIERPTSDkuIrku43nlZnlnKjpgqPkuIDmoLzph4wg4oCU4oCUIHVzZU91dHNpZGVDbGljayDnlKggY29udGFpbnMg5Yik5YaF5aSW77yM5b+F6aG76L+Z5qC35oyC44CCXG4gIGNvbnN0IHBpY2tBbmNob3IgPSBSZWFjdC51c2VSZWYobnVsbClcbiAgY29uc3QgY2xvc2VQaWNrID0gUmVhY3QudXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHNldFBpY2tGb3IobnVsbClcbiAgICBzZXRQaWNrVGV4dCgnJylcbiAgfSwgW10pXG4gIGNvbnN0IHBpY2tTdHlsZSA9IHVzZUZpeGVkUGFuZWwocGlja0FuY2hvciwgcGlja0ZvciAhPT0gbnVsbCwgMzAwLCA0LCAxMilcbiAgY29uc3QgY3VzdG9tU3R5bGUgPSB1c2VGaXhlZFBhbmVsKHBpY2tBbmNob3IsIGVkaXRGb3IgIT09IG51bGwsIDI4MCwgNCwgMTIpXG4gIHVzZU91dHNpZGVDbGljayhwaWNrRm9yICE9PSBudWxsLCBwaWNrQW5jaG9yLCBjbG9zZVBpY2spXG5cbiAgY29uc3QgcHVsbCA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzZXRTdGF0dXMoJ2xvYWRpbmcnKVxuICAgIHNldEVycm9yKG51bGwpXG4gICAgaG9zdENhbGwoJ3VzYWdlL3F1ZXJ5JywgeyBmaWxsOiBmYWxzZSwgbW9kZWxzOiBbXSwgaGVhdG1hcDogZmFsc2UsIGJhY2tmaWxsOiBmYWxzZSB9KVxuICAgICAgLnRoZW4oKHIpID0+IHtcbiAgICAgICAgY29uc3Qgc2VlbiA9IEFycmF5LmlzQXJyYXkociAmJiByLm1vZGVscykgPyByLm1vZGVscyA6IFtdXG4gICAgICAgIHJldHVybiBob3N0Q2FsbCgndXNhZ2UvcHJpY2luZycsIHsgYWN0aW9uOiAncHJvcG9zZScsIG1vZGVsczogc2VlbiB9KVxuICAgICAgfSlcbiAgICAgIC50aGVuKCh2KSA9PiB7XG4gICAgICAgIHNldFJvd3MoQXJyYXkuaXNBcnJheSh2ICYmIHYucm93cykgPyB2LnJvd3MgOiBbXSlcbiAgICAgICAgc2V0VGFibGUodiAmJiB2LnRhYmxlID8gdi50YWJsZSA6IG51bGwpXG4gICAgICAgIHNldFNhdmVkKHYgJiYgdi5tYXRjaE1hcCA/IHYubWF0Y2hNYXAgOiB7fSlcbiAgICAgICAgc2V0RHJhZnQoe30pXG4gICAgICAgIHNldFN0YXR1cygncmVhZHknKVxuICAgICAgfSwgKGUpID0+IHtcbiAgICAgICAgc2V0RXJyb3IoZSlcbiAgICAgICAgc2V0U3RhdHVzKCdlcnJvcicpXG4gICAgICB9KVxuICB9LCBbXSlcblxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4geyBwdWxsKCkgfSwgW3B1bGxdKVxuXG4gIGNvbnN0IGNvdW50cyA9IFJlYWN0LnVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IG4gPSB7IGV4YWN0OiAwLCBmdXp6eTogMCwgbm9uZTogMCwgY3VzdG9tOiAwIH1cbiAgICAvLyDmr4/kuIDooYzpg73oh6rluKYgc3RhdGXvvIjlrr/kuLsgcHJpY2VSb3cg57uZ55qE77yJ77yM5YmN56uv5LiN5YaN5LuOIGhvdyDlj43mjqgg4oCU4oCUIOWPjeaOqOi/h1xuICAgIC8vIOS4gOasoe+8jOWGmeatu+eahCAnbGl0ZXJhbCcg6Zi25qKv6YeM5qC55pys5LiN5a2Y5Zyo77yM5omA5pyJ57K+56Gu5ZG95Lit6YO95pi+56S65oiQ44CM5pyq5Yy56YWN44CN44CCXG4gICAgZm9yIChjb25zdCByIG9mIHJvd3MpIG5bci5zdGF0ZV0gKz0gMVxuICAgIHJldHVybiBuXG4gIH0sIFtyb3dzXSlcblxuICAvLyDljZXku7fmnKzouqvmmK/nvo7lhYPku7fvvIjku7fnm67ooajlsLHmmK/nvo7lhYPvvInvvIzmmL7npLrml7blpZfnlKjlvZPliY3lsZXnpLrluIHnp43vvIzlkozljaHniYflkIzkuIDkuKrmlbDjgIJcbiAgY29uc3QgbW9uZXlQZXJVc2QgPSBSZWFjdC51c2VDYWxsYmFjaygoKSA9PiAoY3VycmVuY3kgJiYgY3VycmVuY3kuY29kZSA9PT0gJ1VTRCcgPyAxIDogNyksIFtjdXJyZW5jeV0pXG4gIGNvbnN0IG1vbmV5T2YgPSBSZWFjdC51c2VDYWxsYmFjaygodXNkKSA9PiB7XG4gICAgY29uc3QgY29kZSA9IGN1cnJlbmN5ICYmIGN1cnJlbmN5LmNvZGUgPT09ICdVU0QnID8gJ1VTRCcgOiAnQ05ZJ1xuICAgIGNvbnN0IHN5bWJvbCA9IGN1cnJlbmN5ICYmIGN1cnJlbmN5LnN5bWJvbCA/IGN1cnJlbmN5LnN5bWJvbCA6IChDVVJSRU5DWV9TWU1CT0xTW2NvZGVdIHx8ICfCpScpXG4gICAgcmV0dXJuIHR5cGVvZiB1c2QgPT09ICdudW1iZXInID8gZm9ybWF0Q29zdCh1c2QgKiAoY29kZSA9PT0gJ1VTRCcgPyAxIDogNyksIHN5bWJvbCkgOiAn4oCUJ1xuICB9LCBbY3VycmVuY3ldKVxuICAvLyDooajlpLTljZXkvY3lv4XpobvlkozljZXlhYPmoLznlKjnmoTmmK/lkIzkuIDkuKrnrKblj7fvvIzlkKbliJnkvJrlh7rnjrDjgIzljZXku7fvvIgkIC8gMU3vvInjgI3phY3jgIzCpTIuMTDjgI3jgIJcbiAgY29uc3QgcHJpY2VVbml0ID0gKGN1cnJlbmN5ICYmIGN1cnJlbmN5LnN5bWJvbCkgfHwgJ8KlJ1xuXG4gIC8vIOW+hemAiSA9IOmYtuair+ayoeaJvuWIsOS7t+eahOihjOOAguWIpOaNrueUqCBzdGF0ZSDogIzkuI3mmK8gdW5wcmljZWTvvJpgdW5wcmljZWRgIOaYr+afpeivoumCo+i+uVxuICAvLyDjgIzmn5DmnaHorrDlvZXmsqHku7fjgI3nmoTlrZfmrrXvvIxwcm9wb3NlIOeahOihjOS7juadpeayoeacieWugyDigJTigJQg5ou/5a6D5b2T6L+H5ruk5p2h5Lu255qE5ZCO5p6c5piv5b6F6YCJXG4gIC8vIOihqOawuOi/nOaYr+epuueahO+8jOacquWMuemFjeeahOaooeWei+S4gOihjOmDvemcsuS4jeWHuuadpeOAglxuICBjb25zdCBwZW5kaW5nID0gcm93cy5maWx0ZXIoKHIpID0+IHIuc3RhdGUgPT09ICdub25lJylcbiAgLy8g5Y6G5Y+y6KGoID0g5bey57uP5YaZ6L+bIG1hdGNoTWFwIOeahCBjb25maXJtZWQg6K6w5b2V44CC5Yik5o2u5Y+q55yLIG1hdGNoTWFw77ya55uu5qCH6Iul5bey5LuOXG4gIC8vIOS7t+ebruihqOS4i+e6v++8jOi/meS4gOihjOS7jeeEtueVmeWcqOi/memHjO+8iOi/mOiDveaUtuWbnu+8ie+8jOS4u+ihqOmHjOWImeaMieOAjOacquWMuemFjeOAjeaYvuekuuW5tuaghyBzdGFsZeOAglxuICBjb25zdCBoaXN0b3J5Um93cyA9IHJvd3MuZmlsdGVyKChyKSA9PiBzYXZlZFtyLmtleV0gIT09IHVuZGVmaW5lZClcbiAgY29uc3QgcGVuZGluZ1Jvd3MgPSBwZW5kaW5nLmZpbHRlcigocikgPT4gIWhpc3RvcnlSb3dzLmluY2x1ZGVzKHIpKVxuICBjb25zdCBtYXRjaGVkUm93cyA9IHJvd3MuZmlsdGVyKChyKSA9PiByLnN0YXRlICE9PSAnbm9uZScgJiYgIWhpc3RvcnlSb3dzLmluY2x1ZGVzKHIpKVxuICAvLyDnqbrnirbmgIHliKTnmoTmmK/kuLvooajmnInmsqHmnInooYzjgILmraTliY3liKTnmoTmmK8gYHBlbmRpbmcubGVuZ3RoYCDigJTigJQg5Y+q6KaB5pyJ5qih5Z6L5oyJ6Zi25qKvXG4gIC8vIOWRveS4reS6huS7t++8jOesrOS4gOW8oOihqOWwseaVtOWdl+a2iOWkse+8jOS6juaYr+OAjOeyvuehriAvIOaooeeziuOAjeS4pOenjeeKtuaAgeawuOi/nOayoeacuuS8mumcsumdouOAglxuICBjb25zdCBoYXNNYWluUm93cyA9IHBlbmRpbmdSb3dzLmxlbmd0aCA+IDAgfHwgbWF0Y2hlZFJvd3MubGVuZ3RoID4gMFxuXG4gIC8vIOazqOaEj++8mue7hOS7tumHjOeahCBgc2V0RHJhZnRgIOaYryB1c2VTdGF0ZSDnmoQgc2V0dGVy77yM5LiN5piv5LiK6Z2i6YKj5Liq57qv5Ye95pWw44CCXG4gIC8vIOWGmeaIkCBzZXREcmFmdCgocHJldikgPT4gc2V0RHJhZnQocHJldiwgLi4uKSkg5Lya6YCS5b2S6LCD6Ieq5bex77yI5Yid5YC8IHVuZGVmaW5lZO+8ie+8jFxuICAvLyDmiYDku6Xov5nph4znlKjnuq/lh73mlbDnmoTlkI3lrZcgYG1lcmdlRHJhZnRgIOWMuuWIhuW8gOOAglxuICBjb25zdCBjaG9vc2UgPSAoa2V5LCB0YXJnZXQpID0+IHtcbiAgICBzZXREcmFmdCgocHJldikgPT4gbWVyZ2VEcmFmdChwcmV2LCBrZXksIHsgdGFyZ2V0LCBjbGVhcmVkOiBmYWxzZSwgY3VzdG9tOiBudWxsLCBrZXkgfSkpXG4gICAgc2V0RWRpdEZvcihudWxsKVxuICAgIGNsb3NlUGljaygpXG4gIH1cbiAgY29uc3QgY2xlYXJSb3cgPSAoa2V5KSA9PiB7XG4gICAgc2V0RHJhZnQoKHByZXYpID0+IG1lcmdlRHJhZnQocHJldiwga2V5LCB7IHRhcmdldDogbnVsbCwgY2xlYXJlZDogdHJ1ZSwgY3VzdG9tOiBudWxsLCBrZXkgfSkpXG4gICAgc2V0RWRpdEZvcigoaykgPT4gKGsgPT09IGtleSA/IG51bGwgOiBrKSlcbiAgfVxuXG4gIC8qKiDmiYvloavljZXku7fvvJrkuInmoLzvvIzpg73mmK/jgIzmr4/nmb7kuIcgVG9rZW7jgI3nmoTlsZXnpLrluIHnp43ph5Hpop3jgIIgKi9cbiAgY29uc3QgQ1VTVE9NX0ZJRUxEUyA9IFtbJ2lucHV0JywgJ3ByaWNpbmdDdXN0b21JbnB1dCddLCBbJ291dHB1dCcsICdwcmljaW5nQ3VzdG9tT3V0cHV0J10sIFsnY2FjaGVSZWFkJywgJ3ByaWNpbmdDdXN0b21DYWNoZVJlYWQnXV1cbiAgLyoqIOafkOS4qiBrZXkg5b2T5YmN55qE5omL5aGr5YC877yI6I2J56i/5LyY5YWI77yM5YW25qyh5a6/5Li75bey5pyJ55qE6Ieq5a6a5LmJ5Lu377yJ44CCICovXG4gIGNvbnN0IGN1c3RvbU9mID0gKHIpID0+IHtcbiAgICBjb25zdCBkID0gZHJhZnRbci5rZXldXG4gICAgaWYgKGQgJiYgZC5jdXN0b20pIHJldHVybiBkLmN1c3RvbVxuICAgIC8vIOWuv+S4u+W3suaMieiHquWumuS5ieS7t+iuoei/h+i0pu+8mueUqOWug+W9k+WJjeeahOi0ueeOh+WbnuWhq++8jOaWueS+v+aUueOAglxuICAgIGlmIChyLmhvdyA9PT0gJ2N1c3RvbScgJiYgci5yYXRlcykge1xuICAgICAgY29uc3QgcGVyID0gbW9uZXlQZXJVc2QoKVxuICAgICAgY29uc3QgYXQgPSByLnJhdGVzLnBlYWsgfHwgci5yYXRlcy5vZmZQZWFrXG4gICAgICByZXR1cm4ge1xuICAgICAgICBpbnB1dDogU3RyaW5nKE51bWJlcigoYXQuaW5wdXQgKiBwZXIpLnRvRml4ZWQoNCkpKSxcbiAgICAgICAgb3V0cHV0OiBTdHJpbmcoTnVtYmVyKChhdC5vdXRwdXQgKiBwZXIpLnRvRml4ZWQoNCkpKSxcbiAgICAgICAgY2FjaGVSZWFkOiBTdHJpbmcoTnVtYmVyKChhdC5jYWNoZVJlYWQgKiBwZXIpLnRvRml4ZWQoNCkpKSxcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgaW5wdXQ6ICcnLCBvdXRwdXQ6ICcnLCBjYWNoZVJlYWQ6ICcnIH1cbiAgfVxuICAvKiog5byA5aeL5omL5aGr77ya5oqK6L+Z5LiA6KGM5YiH5oiQ57yW6L6R5oCB77yM6I2J56i/6YeM5YWI5pS+5LiA5Lu95Y+v57yW6L6R55qE5YC844CCICovXG4gIGNvbnN0IHN0YXJ0Q3VzdG9tID0gKGtleSkgPT4ge1xuICAgIGNvbnN0IHJvdyA9IHJvd3MuZmluZCgoeCkgPT4geC5rZXkgPT09IGtleSlcbiAgICBjb25zdCBzZWVkID0gcm93ID8gY3VzdG9tT2Yocm93KSA6IHsgaW5wdXQ6ICcnLCBvdXRwdXQ6ICcnLCBjYWNoZVJlYWQ6ICcnIH1cbiAgICBzZXREcmFmdCgocHJldikgPT4gbWVyZ2VEcmFmdChwcmV2LCBrZXksIHsgdGFyZ2V0OiBudWxsLCBjbGVhcmVkOiBmYWxzZSwgY3VzdG9tOiBzZWVkLCBrZXkgfSkpXG4gICAgc2V0RWRpdEZvcihrZXkpXG4gICAgY2xvc2VQaWNrKClcbiAgfVxuICBjb25zdCBzZXRDdXN0b21GaWVsZCA9IChrZXksIGZpZWxkLCB2YWx1ZSkgPT4ge1xuICAgIHNldERyYWZ0KChwcmV2KSA9PiB7XG4gICAgICBjb25zdCBjdXIgPSAocHJldltrZXldICYmIHByZXZba2V5XS5jdXN0b20pIHx8IHsgaW5wdXQ6ICcnLCBvdXRwdXQ6ICcnLCBjYWNoZVJlYWQ6ICcnIH1cbiAgICAgIHJldHVybiBtZXJnZURyYWZ0KHByZXYsIGtleSwgeyB0YXJnZXQ6IG51bGwsIGNsZWFyZWQ6IGZhbHNlLCBjdXN0b206IHsgLi4uY3VyLCBbZmllbGRdOiB2YWx1ZSB9LCBrZXkgfSlcbiAgICB9KVxuICB9XG5cbiAgY29uc3QgZGlydHlLZXlzID0gT2JqZWN0LmtleXMoZHJhZnQpLmZpbHRlcigoaykgPT4gZHJhZnRba10uZGlydHkpXG4gIC8qKiDkuInmoLzpg73og73or7vmiJDpnZ7otJ/mlbDlrZfmiY3nrpfkuIDmnaHmiYvloavku7fvvIzlkKbliJnkuI3lj5Hlh7rljrvvvIjpgb/lhY3miornqbrkuLLlhpnmiJAgMO+8ieOAgiAqL1xuICBjb25zdCBjdXN0b21PZkRyYWZ0ID0gKGQpID0+IHtcbiAgICBpZiAoIWQgfHwgIWQuY3VzdG9tKSByZXR1cm4gbnVsbFxuICAgIGNvbnN0IG91dCA9IHt9XG4gICAgZm9yIChjb25zdCBbZmllbGRdIG9mIENVU1RPTV9GSUVMRFMpIHtcbiAgICAgIGNvbnN0IHJhdyA9IFN0cmluZyhkLmN1c3RvbVtmaWVsZF0gPT0gbnVsbCA/ICcnIDogZC5jdXN0b21bZmllbGRdKS50cmltKClcbiAgICAgIGlmIChyYXcgPT09ICcnKSByZXR1cm4gbnVsbFxuICAgICAgY29uc3QgdiA9IE51bWJlcihyYXcpXG4gICAgICBpZiAoIU51bWJlci5pc0Zpbml0ZSh2KSB8fCB2IDwgMCkgcmV0dXJuIG51bGxcbiAgICAgIG91dFtmaWVsZF0gPSB2XG4gICAgfVxuICAgIHJldHVybiBvdXRcbiAgfVxuICBjb25zdCBzdWJtaXQgPSAoKSA9PiB7XG4gICAgaWYgKGRpcnR5S2V5cy5sZW5ndGggPT09IDAgfHwgc2F2aW5nKSB7IGlmIChkaXJ0eUtleXMubGVuZ3RoID09PSAwKSBvbkNsb3NlKCk7IHJldHVybiB9XG4gICAgY29uc3QgZGVjaXNpb25zID0gW11cbiAgICBjb25zdCBjbGVhcmVkID0gW11cbiAgICBjb25zdCBjdXN0b21zID0gW11cbiAgICBmb3IgKGNvbnN0IGsgb2YgZGlydHlLZXlzKSB7XG4gICAgICBjb25zdCBkID0gZHJhZnRba11cbiAgICAgIGlmIChkLmNsZWFyZWQpIGNsZWFyZWQucHVzaChrKVxuICAgICAgZWxzZSBpZiAoZC5jdXN0b20pIHtcbiAgICAgICAgY29uc3QgcmF0ZSA9IGN1c3RvbU9mRHJhZnQoZClcbiAgICAgICAgaWYgKHJhdGUgIT09IG51bGwpIGN1c3RvbXMucHVzaCh7IGtleTogaywgLi4ucmF0ZSB9KVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZC50YXJnZXQgPT09ICdzdHJpbmcnICYmIGQudGFyZ2V0ICE9PSAnJykgZGVjaXNpb25zLnB1c2goeyBrZXk6IGssIHRhcmdldDogZC50YXJnZXQgfSlcbiAgICB9XG4gICAgc2V0U2F2aW5nKHRydWUpXG4gICAgaG9zdENhbGwoJ3VzYWdlL3ByaWNpbmcnLCB7IGFjdGlvbjogJ2NvbW1pdCcsIGRlY2lzaW9ucywgY2xlYXJlZCwgY3VzdG9tcywgY3VycmVuY3k6IGN1cnJlbmN5ICYmIGN1cnJlbmN5LmNvZGUgPyBjdXJyZW5jeS5jb2RlIDogJ0NOWScgfSlcbiAgICAgIC50aGVuKCh2KSA9PiB7XG4gICAgICAgIHNldFNhdmluZyhmYWxzZSlcbiAgICAgICAgc2V0RHJhZnQoe30pXG4gICAgICAgIHNldEVkaXRGb3IobnVsbClcbiAgICAgICAgaWYgKG9uQXBwbGllZCkgb25BcHBsaWVkKHYpXG4gICAgICAgIG9uQ2xvc2UoKVxuICAgICAgfSwgKGUpID0+IHtcbiAgICAgICAgc2V0U2F2aW5nKGZhbHNlKVxuICAgICAgICBzZXRFcnJvcihlKVxuICAgICAgICBzZXRTdGF0dXMoJ2Vycm9yJylcbiAgICAgIH0pXG4gIH1cblxuICBjb25zdCBvbktleURvd24gPSAoZSkgPT4ge1xuICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpIHtcbiAgICAgIC8vIOS4gOi3r+mAgOWHuu+8muWFiOaUtuWAmemAieWIl+ihqO+8jOWGjeWFs+W8ueeql1xuICAgICAgaWYgKHBpY2tGb3IgIT09IG51bGwpIHsgY2xvc2VQaWNrKCk7IHJldHVybiB9XG4gICAgICBvbkNsb3NlKClcbiAgICB9XG4gIH1cblxuICAvLyDljZXku7fvvJrlrr/kuLvnu5nnmoTmmK/kuKTmoaPotLnnjofvvIhyYXRlc++8ie+8jHRpZXIg5piv5a6D6Ieq5bex566X55qE44CM546w5Zyo5oyJ5ZOq5qGj5pi+56S644CN44CCXG4gIC8vIOWJjeerr+WPquafpeihqOOAgeS4jeeMnOahoyDigJTigJQg5LmL5YmN5a6/5Li75oqK5qGj5oqY5oiQ5LiA6KGM5YaN5Y+R6L+H5p2l77yM5Y+m5LiA5qGj5bCx5Yet56m65raI5aSx5LqG44CCXG4gIGNvbnN0IHJhdGVMaW5lID0gKHJhdGVzKSA9PiBbcmF0ZXMuaW5wdXQsIHJhdGVzLm91dHB1dCwgcmF0ZXMuY2FjaGVSZWFkXS5tYXAobW9uZXlPZikuam9pbignIC8gJylcbiAgY29uc3QgcHJpY2VMaW5lID0gKHIpID0+IHtcbiAgICAvLyDmiYvloavku7fvvJrkuInmoLzpg73loavlpb3lsLHnhafloavnmoTljbDvvIjlroPku6zmnKzmnaXlsLHmmK/lsZXnpLrluIHnp43vvInvvIzlkKbliJnmj5DnpLrov5jmsqHloavlrozjgIJcbiAgICBjb25zdCBkID0gciA/IGRyYWZ0W3Iua2V5XSA6IG51bGxcbiAgICBpZiAoZCAmJiBkLmN1c3RvbSkge1xuICAgICAgY29uc3QgdmFscyA9IENVU1RPTV9GSUVMRFMubWFwKChbZmllbGRdKSA9PiBTdHJpbmcoZC5jdXN0b21bZmllbGRdID09IG51bGwgPyAnJyA6IGQuY3VzdG9tW2ZpZWxkXSkudHJpbSgpKVxuICAgICAgaWYgKHZhbHMuZXZlcnkoKHYpID0+IHYgIT09ICcnICYmIE51bWJlci5pc0Zpbml0ZShOdW1iZXIodikpKSkge1xuICAgICAgICByZXR1cm4gdmFscy5tYXAoKHYpID0+IHByaWNlVW5pdCArIE51bWJlcih2KS50b0ZpeGVkKDIpKS5qb2luKCcgLyAnKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHQoJ3ByaWNpbmdDdXN0b21QZW5kaW5nJylcbiAgICB9XG4gICAgcmV0dXJuIHIgJiYgci5yYXRlcyA/IHJhdGVMaW5lKHIucmF0ZXNbci50aWVyXSB8fCByLnJhdGVzLnBlYWspIDogdCgndW5wcmljZWQnKVxuICB9XG4gIC8qKiDmgqzlgZzml7bmiorkuKTmoaPpg73liJflh7rmnaXvvJrlkIzkuIDmoLzlj6rljbDkuIDmoaPvvIzkvYbkuI3og73orqnlj6bkuIDljYrku7fmoLznnIvkuI3op4HjgIIgKi9cbiAgY29uc3QgcHJpY2VUaXRsZSA9IChyKSA9PiB7XG4gICAgaWYgKCFyIHx8ICFyLnJhdGVzKSByZXR1cm4gbnVsbFxuICAgIHJldHVybiB0KCdwcmljaW5nQm90aFRpZXJzJywgeyBwZWFrOiByYXRlTGluZShyLnJhdGVzLnBlYWspLCBvZmY6IHJhdGVMaW5lKHIucmF0ZXMub2ZmUGVhaykgfSlcbiAgfVxuXG4gIC8vIOWPguiAg+aooeWei+WAmemAieaMieadpea6kOWIhue7hO+8mkRlZXBTZWVrIOWumOaWueOAgW9wZW5jb2RlIFplbuOAguOAjOiHquWumuS5ieOAjeS4jeaYr+S4gOS4que7hO+8jFxuICAvLyDogIzmmK/liJfooajpobbpg6jnmoTkuIDkuKrljZXni6zpgInpobkg4oCU4oCUIOmAieWug+S4jeaYr+aMkeS4gOS4quWPguiAg+aooeWei++8jOiAjOaYr+ebtOaOpee7mei/meS4gOihjOWhq1xuICAvLyDkuInkuKrljZXku7fvvIjovpPlhaUgLyDovpPlh7ogLyDnvJPlrZjor7vvvInvvIzlrZjov5sgYHByaWNlc2DjgIJcbiAgY29uc3QgU09VUkNFX0xBQkVMID0geyBkZWVwc2VlazogJ3ByaWNpbmdTb3VyY2VEZWVwc2VlaycsIHplbjogJ3ByaWNpbmdTb3VyY2VaZW4nLCBjdXN0b206ICdwcmljaW5nU291cmNlQ3VzdG9tJyB9XG4gIGNvbnN0IGNhbmRpZGF0ZUdyb3VwcyA9ICgpID0+IHtcbiAgICBpZiAoIXRhYmxlIHx8ICFBcnJheS5pc0FycmF5KHRhYmxlLmdyb3VwcykpIHJldHVybiBbXVxuICAgIGNvbnN0IHEgPSBwaWNrVGV4dC50cmltKCkudG9Mb3dlckNhc2UoKVxuICAgIGxldCBidWRnZXQgPSA4MFxuICAgIGNvbnN0IG91dCA9IFtdXG4gICAgZm9yIChjb25zdCBncm91cCBvZiB0YWJsZS5ncm91cHMpIHtcbiAgICAgIGNvbnN0IGFsbCA9IEFycmF5LmlzQXJyYXkoZ3JvdXAuaWRzKSA/IGdyb3VwLmlkcyA6IFtdXG4gICAgICBjb25zdCBpZHMgPSBhbGwuZmlsdGVyKChpZCkgPT4gKHEgPT09ICcnID8gdHJ1ZSA6IGlkLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocSkpKVxuICAgICAgaWYgKGlkcy5sZW5ndGggPT09IDApIGNvbnRpbnVlXG4gICAgICBjb25zdCBrZXB0ID0gaWRzLnNsaWNlKDAsIE1hdGgubWF4KDAsIGJ1ZGdldCkpXG4gICAgICBidWRnZXQgLT0ga2VwdC5sZW5ndGhcbiAgICAgIG91dC5wdXNoKHsgc291cmNlOiBncm91cC5zb3VyY2UsIGlkczoga2VwdCB9KVxuICAgICAgaWYgKGJ1ZGdldCA8PSAwKSBicmVha1xuICAgIH1cbiAgICByZXR1cm4gb3V0XG4gIH1cblxuICAvKiog5p+Q57uE6YeM55qEIGlkIOWxnuS6juWTquS4quadpea6kO+8iOiNieeov+WImumAieeahOebruagh+S5n+afpeW+l+WIsO+8ieOAgiAqL1xuICBjb25zdCBzb3VyY2VPZiA9IChpZCkgPT4ge1xuICAgIGlmICghaWQgfHwgIXRhYmxlIHx8ICFBcnJheS5pc0FycmF5KHRhYmxlLmdyb3VwcykpIHJldHVybiBudWxsXG4gICAgZm9yIChjb25zdCBncm91cCBvZiB0YWJsZS5ncm91cHMpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGdyb3VwLmlkcykgJiYgZ3JvdXAuaWRzLmluY2x1ZGVzKGlkKSkgcmV0dXJuIGdyb3VwLnNvdXJjZVxuICAgIH1cbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIOW9k+WJjeihjOimgeaYvuekuueahOWMuemFjeebruagh++8muiNieeov+S8mOWFiOS6juWuv+S4u+eahOetlOahiOOAglxuICAgKlxuICAgKiDnlKjmiLfliJrpgInlroznm67moIflsLHopoHnq4vliLvnnIvop4HvvIzlkKbliJnor7votbfmnaXlg4/jgIzngrnkuobmsqHlj43lupTjgI3vvJvlt7LmlLblm57nmoTmmL7npLrkuLrnqbrjgIJcbiAgICovXG4gIGNvbnN0IHNob3duT2YgPSAocikgPT4ge1xuICAgIGNvbnN0IGQgPSBkcmFmdFtyLmtleV1cbiAgICBpZiAoIWQpIHJldHVybiByLnRhcmdldFxuICAgIGlmIChkLmNsZWFyZWQpIHJldHVybiBudWxsXG4gICAgaWYgKGQuY3VzdG9tKSByZXR1cm4gbnVsbCAvLyDmiYvloavku7fmsqHmnInlj4LogIPmqKHlnosgaWTvvIzmoLzlrZDmmL7npLrjgIzoh6rlrprkuYnjgI1cbiAgICByZXR1cm4gZC50YXJnZXRcbiAgfVxuXG4gIC8qKiDkuIDooYznmoTlm5vmgIHvvJrmlLblm57ljbPmnKrljLnphY3vvIzpgInkuobnm67moIfmiJbmiYvloavku7fljbPoh6rlrprkuYnvvIzlhbbkvZnnlKjlrr/kuLvnu5nnmoQgc3RhdGXjgIIgKi9cbiAgY29uc3Qgc3RhdGVPZiA9IChyKSA9PiB7XG4gICAgY29uc3QgZCA9IGRyYWZ0W3Iua2V5XVxuICAgIGlmIChkICYmIGQuY2xlYXJlZCkgcmV0dXJuICdub25lJ1xuICAgIGlmIChkICYmIChkLnRhcmdldCB8fCBkLmN1c3RvbSkpIHJldHVybiAnY3VzdG9tJ1xuICAgIHJldHVybiByLnN0YXRlXG4gIH1cblxuICAvKipcbiAgICog6YCJ5oup5Zmo5pys5L2T44CCXG4gICAqXG4gICAqIOacquWMuemFjeeahOihjOS4jeWGjeimgeaxguWFiOeCueS4gOasoeOAjOmAieaLqeWPguiAg+aooeWei+OAje+8muWxleW8gOeahOmCo+S4gOWIu+i+k+WFpeahhuWwseW4pueEpueCue+8jFxuICAgKiDpgInlroznm7TmjqXokL3ov5vojYnnqL/vvIjku43nhLbopoHmjInjgIznoa7lrprjgI3miY3lhpnnm5jvvInjgIJcbiAgICovXG4gIGNvbnN0IHBpY2tlckZvciA9IChrZXkpID0+IHtcbiAgICBjb25zdCByb3cgPSByb3dzLmZpbmQoKHgpID0+IHgua2V5ID09PSBrZXkpXG4gICAgY29uc3QgY3VyID0gcm93ID8gc2hvd25PZihyb3cpIDogbnVsbFxuICAgIHJldHVybiBbXG4gICAgICBoKCdpbnB1dCcsIHtcbiAgICAgICAga2V5OiAncScsXG4gICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgY2xhc3NOYW1lOiAndHNkLXByaWNlLXBpY2staW5wdXQnLFxuICAgICAgICB2YWx1ZTogcGlja1RleHQsXG4gICAgICAgIHBsYWNlaG9sZGVyOiB0KCdhc2tQaWNrJyksXG4gICAgICAgIGF1dG9Gb2N1czogdHJ1ZSxcbiAgICAgICAgb25DaGFuZ2U6IChlKSA9PiBzZXRQaWNrVGV4dChlLnRhcmdldC52YWx1ZSksXG4gICAgICB9KSxcbiAgICAgIGgoJ2RpdicsIHsga2V5OiAnbCcsIGNsYXNzTmFtZTogJ3RzZC1wcmljZS1waWNrLWxpc3QnLCByb2xlOiAnbGlzdGJveCcgfSxcbiAgICAgICAgLy8g6aG26YOo5Zu65a6a5LiA5p2h44CM6Ieq5a6a5LmJ44CN77ya6YCJ5a6D5LiN5piv5oyR5Y+C6ICD5qih5Z6L77yM6ICM5piv57uZ6L+Z5LiA6KGM5omL5aGr5LiJ5Liq5Y2V5Lu344CCXG4gICAgICAgIGgoJ2J1dHRvbicsIHtcbiAgICAgICAgICBrZXk6ICdjdXN0b20nLFxuICAgICAgICAgIHR5cGU6ICdidXR0b24nLFxuICAgICAgICAgIHJvbGU6ICdvcHRpb24nLFxuICAgICAgICAgICdhcmlhLXNlbGVjdGVkJzogJ2ZhbHNlJyxcbiAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtcHJpY2UtcGljay1pdGVtIHRzZC1wcmljZS1waWNrLWN1c3RvbScsXG4gICAgICAgICAgb25DbGljazogKCkgPT4gc3RhcnRDdXN0b20oa2V5KSxcbiAgICAgICAgfSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtcHJpY2UtcGljay1jdXN0b20tbGFiZWwnIH0sIHQoJ3ByaWNpbmdDdXN0b21PcHRpb24nKSksXG4gICAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLXBpY2stY3VzdG9tLWhpbnQnIH0sIHQoJ3ByaWNpbmdDdXN0b21IaW50JykpKSxcbiAgICAgICAgaCgnZGl2JywgeyBrZXk6ICdzZXAnLCBjbGFzc05hbWU6ICd0c2QtcHJpY2UtcGljay1zZXAnLCByb2xlOiAncHJlc2VudGF0aW9uJyB9KSxcbiAgICAgICAgLy8g5LiA57uE5LiA5Liq6KGo5aS0ICsg6Iul5bmy6YCJ6aG544CCcm9sZSDkv53mjIEgbGlzdGJveC9vcHRpb27vvIzooajlpLTlj6rmmK/liIbnu4TmoIfnrb7jgIJcbiAgICAgICAgY2FuZGlkYXRlR3JvdXBzKCkubWFwKChncm91cCkgPT4gW1xuICAgICAgICAgIGgoJ2RpdicsIHtcbiAgICAgICAgICAgIGtleTogJ2c6JyArIGdyb3VwLnNvdXJjZSxcbiAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1wcmljZS1waWNrLWdyb3VwJyxcbiAgICAgICAgICAgIHJvbGU6ICdwcmVzZW50YXRpb24nLFxuICAgICAgICAgIH0sIHQoU09VUkNFX0xBQkVMW2dyb3VwLnNvdXJjZV0gfHwgZ3JvdXAuc291cmNlKSksXG4gICAgICAgICAgLi4uZ3JvdXAuaWRzLm1hcCgoaWQpID0+IGgoJ2J1dHRvbicsIHtcbiAgICAgICAgICAgIGtleTogaWQsXG4gICAgICAgICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgICAgICAgIHJvbGU6ICdvcHRpb24nLFxuICAgICAgICAgICAgJ2FyaWEtc2VsZWN0ZWQnOiBpZCA9PT0gKGN1ciB8fCAnJyksXG4gICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtcHJpY2UtcGljay1pdGVtJyArIChpZCA9PT0gY3VyID8gJyB0c2QtcHJpY2UtcGljay1pdGVtLWFjdGl2ZScgOiAnJyksXG4gICAgICAgICAgICBvbkNsaWNrOiAoKSA9PiBjaG9vc2Uoa2V5LCBpZCksXG4gICAgICAgICAgfSwgaWQpKSxcbiAgICAgICAgXSkpLFxuICAgIF1cbiAgfVxuXG4gIGNvbnN0IGJpbmRQaWNrQW5jaG9yID0gKGVsKSA9PiB7IGlmIChlbCkgcGlja0FuY2hvci5jdXJyZW50ID0gZWwgfVxuXG4gIGNvbnN0IHJlbmRlclJvdyA9IChyKSA9PiB7XG4gICAgY29uc3QgZCA9IGRyYWZ0W3Iua2V5XVxuICAgIGNvbnN0IHN0YXRlID0gc3RhdGVPZihyKVxuICAgIGNvbnN0IHNob3duID0gc2hvd25PZihyKVxuICAgIGNvbnN0IHBpY2tpbmcgPSBwaWNrRm9yID09PSByLmtleVxuICAgIGNvbnN0IGVkaXRpbmcgPSBlZGl0Rm9yID09PSByLmtleVxuICAgIGNvbnN0IG9wZW5QaWNrID0gKCkgPT4geyBpZiAocGlja2luZykgeyBjbG9zZVBpY2soKTsgcmV0dXJuIH0gc2V0RWRpdEZvcihudWxsKTsgc2V0UGlja0ZvcihyLmtleSk7IHNldFBpY2tUZXh0KCcnKSB9XG4gICAgLy8g6L+Y5Y6f5Y+q5Zyo55yf55qE5pS56L+H77yI5oiW5Y6G5Y+y56Gu6K6k6L+H77yJ55qE6KGM5LiK5Ye6546w77ya57K+56GuL+aooeeziuWRveS4reeahOihjOacrOadpeWwseayoeaciVxuICAgIC8vIOWPr+i/mOWOn+eahOS4nOilv++8jOavj+ihjOmDveaMguS4gOmil+aMiemSruWPquS8muaKiuihqOagvOaMpOaIkOihqOWNleOAglxuICAgIGNvbnN0IGNhblJlc2V0ID0gc3RhdGUgPT09ICdjdXN0b20nIHx8IChkICYmIGQuZGlydHkpXG4gICAgLy8g5by556qX6YGu572p5pivIHotaW5kZXggNjDvvIzmta7lsYLlv4XpobvljovlnKjlroPkuIrpnaLvvJvlhbbkvZnlrprkvY3vvIjkuIrnv7vjgIHlsIHpq5jvvInkuqTnu5kgaG9va+OAglxuICAgIGNvbnN0IHBpY2tQYW5lbCA9IHBpY2tpbmdcbiAgICAgID8gaCgnZGl2Jywge1xuICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1wcmljZS1waWNrLWJveCcsXG4gICAgICAgICAgc3R5bGU6IE9iamVjdC5hc3NpZ24oe30sIHBpY2tTdHlsZSwgeyB6SW5kZXg6IDcwIH0pLFxuICAgICAgICAgIG9uS2V5RG93bjogKGUpID0+IHsgaWYgKGUua2V5ID09PSAnRXNjYXBlJykgeyBlLnN0b3BQcm9wYWdhdGlvbigpOyBjbG9zZVBpY2soKSB9IH0sXG4gICAgICAgIH0sIHBpY2tlckZvcihyLmtleSkpXG4gICAgICA6IG51bGxcbiAgICAvLyDmiYvloavljZXku7fnmoTmta7lsYLvvJrkuInmoLzvvIjovpPlhaUgLyDovpPlh7ogLyDnvJPlrZjor7vvvInvvIzljZXkvY3lsLHmmK/ooajmoLznmoTlsZXnpLrluIHnp43jgIJcbiAgICBjb25zdCBjdXIgPSBlZGl0aW5nID8gY3VzdG9tT2YocikgOiBudWxsXG4gICAgY29uc3QgY3VzdG9tUGFuZWwgPSBlZGl0aW5nXG4gICAgICA/IGgoJ2RpdicsIHtcbiAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtcHJpY2UtcGljay1ib3ggdHNkLXByaWNlLWN1c3RvbS1ib3gnLFxuICAgICAgICAgIHN0eWxlOiBPYmplY3QuYXNzaWduKHt9LCBjdXN0b21TdHlsZSwgeyB6SW5kZXg6IDcwIH0pLFxuICAgICAgICAgIG9uS2V5RG93bjogKGUpID0+IHsgaWYgKGUua2V5ID09PSAnRXNjYXBlJykgeyBlLnN0b3BQcm9wYWdhdGlvbigpOyBzZXRFZGl0Rm9yKG51bGwpIH0gfSxcbiAgICAgICAgfSxcbiAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1wcmljZS1jdXN0b20tdGl0bGUnIH0sIHQoJ3ByaWNpbmdDdXN0b21PcHRpb24nKSksXG4gICAgICAgICAgLi4uQ1VTVE9NX0ZJRUxEUy5tYXAoKFtmaWVsZCwgbGFiZWxdKSA9PiBoKCdsYWJlbCcsIHsga2V5OiBmaWVsZCwgY2xhc3NOYW1lOiAndHNkLXByaWNlLWN1c3RvbS1maWVsZCcgfSxcbiAgICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCB0KGxhYmVsKSksXG4gICAgICAgICAgICBoKCdpbnB1dCcsIHtcbiAgICAgICAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgICAgICAgIG1pbjogJzAnLFxuICAgICAgICAgICAgICBzdGVwOiAnMC4wMDEnLFxuICAgICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtcHJpY2UtY3VzdG9tLWlucHV0JyxcbiAgICAgICAgICAgICAgJ2RhdGEtZmllbGQnOiBmaWVsZCxcbiAgICAgICAgICAgICAgdmFsdWU6IGN1cltmaWVsZF0sXG4gICAgICAgICAgICAgIGF1dG9Gb2N1czogZmllbGQgPT09ICdpbnB1dCcsXG4gICAgICAgICAgICAgIG9uQ2hhbmdlOiAoZSkgPT4gc2V0Q3VzdG9tRmllbGQoci5rZXksIGZpZWxkLCBlLnRhcmdldC52YWx1ZSksXG4gICAgICAgICAgICB9KSkpLFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLWN1c3RvbS1oaW50JyB9LCB0KCdwcmljaW5nQ3VzdG9tVW5pdCcsIHsgdW5pdDogcHJpY2VVbml0IH0pKSxcbiAgICAgICAgICBoKCdidXR0b24nLCB7XG4gICAgICAgICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1idG4gdHNkLWJ0bi1naG9zdCB0c2QtYnRuLXhzJyxcbiAgICAgICAgICAgIG9uQ2xpY2s6ICgpID0+IHNldEVkaXRGb3IobnVsbCksXG4gICAgICAgICAgfSwgdCgnZG9uZScpKSlcbiAgICAgIDogbnVsbFxuICAgIC8vIOi/meS4gOihjOWMuemFjeWIsOeahOWPguiAg+aooeWei+WxnuS6juWTquS4gOexu++8iERlZXBTZWVrIC8gWmVuIC8g6Ieq5a6a5LmJ77yJ44CC6I2J56i/6YeM5Yia6YCJ55qEXG4gICAgLy8g55uu5qCH5Lmf5p+l5b6X5Yiw77ya5YCZ6YCJ5ZCN5Y2V5pys5p2l5bCx5oyJ5p2l5rqQ5YiG5aW95LqG57uE77yM5LiN55So5YaN6Zeu5a6/5Li75LiA5qyh44CCXG4gICAgLy8g44CM6Ieq5a6a5LmJ44CN5LiN5LuF5oyH6I2J56i/77ya5LuOIGBwcmljZXNgIOiuoeS7t+eahOihjOS5n+ayoeacieWPguiAg+aooeWeiyBpZO+8iHRhcmdldCDkuLrnqbrvvInvvIxcbiAgICAvLyDlroPnmoTnm67moIfmoLzopoHlhpnjgIzoh6rlrprkuYnjgI3vvIzkuI3nhLbkvJrmmL7npLrmiJDlvoXpgInjgIJcbiAgICBjb25zdCBpc0N1c3RvbSA9IEJvb2xlYW4oZCAmJiBkLmN1c3RvbSkgfHwgKHIuaG93ID09PSAnY3VzdG9tJyAmJiAhci50YXJnZXQpXG4gICAgY29uc3Qgc3JjID0gc2hvd24gPyAoc291cmNlT2Yoc2hvd24pIHx8IHIuc291cmNlKSA6IChpc0N1c3RvbSA/ICdjdXN0b20nIDogbnVsbClcbiAgICByZXR1cm4gaCgndHInLCB7IGtleTogci5rZXksIGNsYXNzTmFtZTogJ3RzZC1wcmljZS1yb3cnLCAnZGF0YS1zdGF0ZSc6IHN0YXRlLCAnZGF0YS1tb2RlbCc6IHIua2V5LCAnZGF0YS1kaXJ0eSc6IGQgJiYgZC5kaXJ0eSA/ICd0cnVlJyA6IHVuZGVmaW5lZCB9LFxuICAgICAgaCgndGQnLCB7IGNsYXNzTmFtZTogJ3RzZC1wcmljZS1tb2RlbCcsIHRpdGxlOiByLmtleSB9LFxuICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtcHJpY2UtbW9kZWwtbmFtZScgfSwgc2hvcnRNb2RlbE5hbWUoci5rZXkpKSxcbiAgICAgICAgci5wcm92aWRlciA/IGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1wcmljZS1tb2RlbC1wcm92aWRlcicgfSwgci5wcm92aWRlcikgOiBudWxsKSxcbiAgICAgIC8vIOWMuemFjeebruagh+agvOacrOi6q+WwseaYr+mAieaLqeWZqOWFpeWPo++8muS4gOmil+e0p+WHkeaMiemSru+8jOacquWMuemFjeaXtuiZmue6vyArIOaPkOekuuivreOAglxuICAgICAgaCgndGQnLCB7IGNsYXNzTmFtZTogJ3RzZC1wcmljZS10YXJnZXQnLCByZWY6IHBpY2tpbmcgfHwgZWRpdGluZyA/IGJpbmRQaWNrQW5jaG9yIDogdW5kZWZpbmVkIH0sXG4gICAgICAgIGgoJ2J1dHRvbicsIHtcbiAgICAgICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtcHJpY2UtdGFyZ2V0LWJ0bicsXG4gICAgICAgICAgJ2RhdGEtZW1wdHknOiBzaG93biB8fCBpc0N1c3RvbSA/IHVuZGVmaW5lZCA6ICd0cnVlJyxcbiAgICAgICAgICAnYXJpYS1leHBhbmRlZCc6IHBpY2tpbmcgfHwgZWRpdGluZyA/ICd0cnVlJyA6ICdmYWxzZScsXG4gICAgICAgICAgJ2FyaWEtaGFzcG9wdXAnOiAnbGlzdGJveCcsXG4gICAgICAgICAgdGl0bGU6IHNob3duID8gc2hvd24gKyAoc3JjID8gJyDCtyAnICsgdChTT1VSQ0VfTEFCRUxbc3JjXSB8fCBzcmMpIDogJycpIDogbnVsbCxcbiAgICAgICAgICBvbkNsaWNrOiBvcGVuUGljayxcbiAgICAgICAgfSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtcHJpY2UtdGFyZ2V0LWlkJyB9LCBzaG93biB8fCAoaXNDdXN0b20gPyB0KCdwcmljaW5nQ3VzdG9tT3B0aW9uJykgOiB0KCdhc2tQaWNrJykpKSxcbiAgICAgICAgICBoKFN2Z0ljb24sIHsgbmFtZTogJ2NoZXZyb24nLCBzaXplOiAxMiwgY2xhc3NOYW1lOiAndHNkLXByaWNlLXRhcmdldC1jaGV2JyB9KSksXG4gICAgICAgIHNyY1xuICAgICAgICAgID8gaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLXNyYycsICdkYXRhLXNvdXJjZSc6IHNyYyB9LCB0KFNPVVJDRV9MQUJFTFtzcmNdIHx8IHNyYykpXG4gICAgICAgICAgOiBudWxsLFxuICAgICAgICBzdGF0ZSAhPT0gJ25vbmUnICYmICFyLnJhdGVzICYmICFpc0N1c3RvbVxuICAgICAgICAgID8gaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLXN0YWxlJyB9LCB0KCdwcmljaW5nU3RhbGUnKSlcbiAgICAgICAgICA6IG51bGwsXG4gICAgICAgIHBpY2tQYW5lbCxcbiAgICAgICAgY3VzdG9tUGFuZWwpLFxuICAgICAgaCgndGQnLCBudWxsLCBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtcHJpY2UtYmFkZ2UnLCAnZGF0YS1zdGF0ZSc6IHN0YXRlLCB0aXRsZTogci53aHkgfHwgbnVsbCB9LCB0KE1BVENIX1NUQVRFX0xBQkVMW3N0YXRlXSkpKSxcbiAgICAgIGgoJ3RkJywgeyBjbGFzc05hbWU6ICd0c2QtcHJpY2UtcmF0ZScsIHRpdGxlOiBwcmljZVRpdGxlKHIpIH0sIHByaWNlTGluZShyKSksXG4gICAgICBoKCd0ZCcsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLW9wcycgfSxcbiAgICAgICAgY2FuUmVzZXRcbiAgICAgICAgICA/IGgoJ2J1dHRvbicsIHtcbiAgICAgICAgICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1wcmljZS1yZXNldCcsXG4gICAgICAgICAgICAgIHRpdGxlOiB0KCdwcmljaW5nQ2xlYXInKSxcbiAgICAgICAgICAgICAgJ2FyaWEtbGFiZWwnOiB0KCdwcmljaW5nQ2xlYXInKSxcbiAgICAgICAgICAgICAgb25DbGljazogKCkgPT4gY2xlYXJSb3coci5rZXkpLFxuICAgICAgICAgICAgfSwgaChTdmdJY29uLCB7IG5hbWU6ICdyZWZyZXNoJywgc2l6ZTogMTIgfSkpXG4gICAgICAgICAgOiBudWxsKSlcbiAgfVxuXG4gIGNvbnN0IGJvZHkgPSBzdGF0dXMgPT09ICdsb2FkaW5nJ1xuICAgID8gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcHJpY2UtbG9hZGluZycgfSwgdCgnbG9hZGluZycpKVxuICAgIDogc3RhdHVzID09PSAnZXJyb3InXG4gICAgICA/IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWFsZXJ0LWJhbm5lcicsIHJvbGU6ICdhbGVydCcgfSxcbiAgICAgICAgICBoKCdzcGFuJywgbnVsbCwgdCgncHJpY2luZ0ZhaWxlZCcsIHsgbWVzc2FnZTogU3RyaW5nKChlcnJvciAmJiBlcnJvci5tZXNzYWdlKSB8fCBlcnJvcikgfSkpLFxuICAgICAgICAgIGgoJ2J1dHRvbicsIHsgdHlwZTogJ2J1dHRvbicsIGNsYXNzTmFtZTogJ3RzZC1idG4gdHNkLWJ0bi1naG9zdCcsIG9uQ2xpY2s6IHB1bGwgfSwgdCgncmV0cnknKSkpXG4gICAgICA6IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLWJvZHknIH0sXG4gICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcHJpY2UtbWV0YScgfSxcbiAgICAgICAgICAgIHRhYmxlICYmIHRhYmxlLnNvdXJjZVxuICAgICAgICAgICAgICA/IHQoJ3ByaWNpbmdUYWJsZU1ldGEnLCB7IHNvdXJjZTogdGFibGUuc291cmNlLCBkYXRlOiBzdGFtcFRleHQodGFibGUuY2FwdHVyZWRBdCkgfSlcbiAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLWNvdW50cycgfSwgdCgncHJpY2luZ0NvdW50cycsIHtcbiAgICAgICAgICAgICAgZXhhY3Q6IGNvdW50cy5leGFjdCwgZnV6enk6IGNvdW50cy5mdXp6eSwgbm9uZTogY291bnRzLm5vbmUsIGN1c3RvbTogY291bnRzLmN1c3RvbSxcbiAgICAgICAgICAgIH0pKSksXG4gICAgICAgICAgLy8g5LiA5byg6KGo6KOF5Lik5q616KGM77ya5b6F6YCJ55qE5pyq5a6a5Lu36KGM5Zyo5YmN77yM5bey5oyJ6Zi25qKv5ZG95Lit55qE6KGM5Zyo5ZCO44CCXG4gICAgICAgICAgLy8g5YiG5oiQ5Lik5byg6KGo5Lya5Ye6546w5Lik6KGM6KGo5aS077yM55yL6LW35p2l5YOP5Lik5Lu95pWw5o2u44CCXG4gICAgICAgICAgIWhhc01haW5Sb3dzXG4gICAgICAgICAgICA/IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLWVtcHR5JyB9LCB0KCdhc2tFbXB0eScpKVxuICAgICAgICAgICAgOiBoKCd0YWJsZScsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLXRhYmxlJyB9LFxuICAgICAgICAgICAgICAgIGgoJ3RoZWFkJywgbnVsbCwgaCgndHInLCBudWxsLFxuICAgICAgICAgICAgICAgICAgaCgndGgnLCBudWxsLCB0KCdwcmljaW5nQ29sTW9kZWwnKSksXG4gICAgICAgICAgICAgICAgICBoKCd0aCcsIG51bGwsIHQoJ3ByaWNpbmdDb2xNYXRjaCcpKSxcbiAgICAgICAgICAgICAgICAgIGgoJ3RoJywgbnVsbCwgdCgncHJpY2luZ0NvbFN0YXRlJykpLFxuICAgICAgICAgICAgICAgICAgaCgndGgnLCBudWxsLCB0KCdwcmljaW5nQ29sUHJpY2UnLCB7IHVuaXQ6IHByaWNlVW5pdCB9KSksXG4gICAgICAgICAgICAgICAgICBoKCd0aCcsIG51bGwsICcnKSkpLFxuICAgICAgICAgICAgICAgIGgoJ3Rib2R5JywgbnVsbCxcbiAgICAgICAgICAgICAgICAgIHBlbmRpbmdSb3dzLm1hcCgocikgPT4gcmVuZGVyUm93KHIpKSxcbiAgICAgICAgICAgICAgICAgIG1hdGNoZWRSb3dzLm1hcCgocikgPT4gcmVuZGVyUm93KHIpKSkpLFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLWhpc3RvcnknIH0sXG4gICAgICAgICAgICBoKCdidXR0b24nLCB7XG4gICAgICAgICAgICAgIHR5cGU6ICdidXR0b24nLFxuICAgICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtcHJpY2UtaGlzdG9yeS10b2dnbGUnLFxuICAgICAgICAgICAgICAnYXJpYS1leHBhbmRlZCc6IGhpc3RvcnlPcGVuLFxuICAgICAgICAgICAgICBvbkNsaWNrOiAoKSA9PiBzZXRIaXN0b3J5T3BlbigodikgPT4gIXYpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgaChTdmdJY29uLCB7IG5hbWU6ICdjaGV2cm9uJywgc2l6ZTogMTIsIGNsYXNzTmFtZTogJ3RzZC1wcmljZS1oaXN0b3J5LWNoZXYnICsgKGhpc3RvcnlPcGVuID8gJyB0c2QtcHJpY2UtaGlzdG9yeS1jaGV2LW9wZW4nIDogJycpIH0pLFxuICAgICAgICAgICAgICBoKCdzcGFuJywgbnVsbCwgdCgncHJpY2luZ0hpc3RvcnknLCB7IG46IGhpc3RvcnlSb3dzLmxlbmd0aCB9KSkpLFxuICAgICAgICAgICAgaGlzdG9yeU9wZW5cbiAgICAgICAgICAgICAgPyBoaXN0b3J5Um93cy5sZW5ndGggPT09IDBcbiAgICAgICAgICAgICAgICA/IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLWVtcHR5JyB9LCB0KCdwcmljaW5nSGlzdG9yeUVtcHR5JykpXG4gICAgICAgICAgICAgICAgOiBoKCdkaXYnLCBudWxsLFxuICAgICAgICAgICAgICAgICAgICBoKCd0YWJsZScsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLXRhYmxlIHRzZC1wcmljZS10YWJsZS1zdWInIH0sXG4gICAgICAgICAgICAgICAgICAgICAgaCgndGhlYWQnLCBudWxsLCBoKCd0cicsIG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBoKCd0aCcsIG51bGwsIHQoJ3ByaWNpbmdDb2xNb2RlbCcpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGgoJ3RoJywgbnVsbCwgdCgncHJpY2luZ0NvbE1hdGNoJykpLFxuICAgICAgICAgICAgICAgICAgICAgICAgaCgndGgnLCBudWxsLCB0KCdwcmljaW5nQ29sU3RhdGUnKSksXG4gICAgICAgICAgICAgICAgICAgICAgICBoKCd0aCcsIG51bGwsIHQoJ3ByaWNpbmdDb2xQcmljZScsIHsgdW5pdDogcHJpY2VVbml0IH0pKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGgoJ3RoJywgbnVsbCwgJycpKSksXG4gICAgICAgICAgICAgICAgICAgICAgaCgndGJvZHknLCBudWxsLCBoaXN0b3J5Um93cy5tYXAoKHIpID0+IHJlbmRlclJvdyhyKSkpKSlcbiAgICAgICAgICAgICAgOiBudWxsKSlcblxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcHJpY2Utb3ZlcmxheScsIHJvbGU6ICdwcmVzZW50YXRpb24nLCBvbk1vdXNlRG93bjogKGUpID0+IHsgaWYgKGUudGFyZ2V0ID09PSBlLmN1cnJlbnRUYXJnZXQpIG9uQ2xvc2UoKSB9IH0sXG4gICAgaCgnZGl2Jywge1xuICAgICAgY2xhc3NOYW1lOiAndHNkLXByaWNlLWRpYWxvZycsXG4gICAgICByb2xlOiAnZGlhbG9nJyxcbiAgICAgICdhcmlhLW1vZGFsJzogJ3RydWUnLFxuICAgICAgJ2FyaWEtbGFiZWwnOiB0KCdwcmljaW5nVGl0bGUnKSxcbiAgICAgIG9uS2V5RG93bixcbiAgICB9LFxuICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcHJpY2UtaGVhZCcgfSxcbiAgICAgICAgaCgnaDMnLCB7IGNsYXNzTmFtZTogJ3RzZC1wcmljZS10aXRsZScgfSwgdCgncHJpY2luZ1RpdGxlJykpLFxuICAgICAgICBoKCdidXR0b24nLCB7XG4gICAgICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICAgICAgY2xhc3NOYW1lOiAndHNkLXByaWNlLWNsb3NlJyxcbiAgICAgICAgICB0aXRsZTogdCgnY2FuY2VsJyksXG4gICAgICAgICAgJ2FyaWEtbGFiZWwnOiB0KCdjYW5jZWwnKSxcbiAgICAgICAgICBvbkNsaWNrOiBvbkNsb3NlLFxuICAgICAgICB9LCBoKFN2Z0ljb24sIHsgbmFtZTogJ3gnLCBzaXplOiAxNCB9KSkpLFxuICAgICAgaCgncCcsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLWRlc2MnIH0sIHQoJ3ByaWNpbmdEZXNjJykpLFxuICAgICAgYm9keSxcbiAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLWZvb3QnIH0sXG4gICAgICAgIGgoJ2J1dHRvbicsIHtcbiAgICAgICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtYnRuIHRzZC1idG4tZ2hvc3QgdHNkLWJ0bi1pY29uLWxhYmVsJyxcbiAgICAgICAgICBvbkNsaWNrOiBwdWxsLFxuICAgICAgICAgIGRpc2FibGVkOiBzdGF0dXMgPT09ICdsb2FkaW5nJyB8fCBzYXZpbmcsXG4gICAgICAgIH0sXG4gICAgICAgICAgaChTdmdJY29uLCB7IG5hbWU6ICdjb250ZXh0SW5qZWN0aW9uJywgc2l6ZTogMTQgfSksXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ3ByaWNpbmdQdWxsJykpKSxcbiAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXByaWNlLWhpbnQnIH0sIGRpcnR5S2V5cy5sZW5ndGggPiAwID8gdCgncHJpY2luZ0FwcGx5SGludCcpIDogJycpLFxuICAgICAgICBoKCdidXR0b24nLCB7IHR5cGU6ICdidXR0b24nLCBjbGFzc05hbWU6ICd0c2QtYnRuIHRzZC1idG4tZ2hvc3QnLCBvbkNsaWNrOiBvbkNsb3NlLCBkaXNhYmxlZDogc2F2aW5nIH0sIHQoJ2NhbmNlbCcpKSxcbiAgICAgICAgaCgnYnV0dG9uJywge1xuICAgICAgICAgIHR5cGU6ICdidXR0b24nLFxuICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1idG4gdHNkLWJ0bi1wcmltYXJ5JyxcbiAgICAgICAgICBvbkNsaWNrOiBzdWJtaXQsXG4gICAgICAgICAgZGlzYWJsZWQ6IHNhdmluZyxcbiAgICAgICAgfSwgc2F2aW5nID8gdCgnbG9hZGluZycpIDogdCgncHJpY2luZ1NhdmUnKSkpKSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDmr4/ml6XnlKjph4/mn7Hnirblm77vvIjmiYvlhpkgZGl2IOWghuWPoOafse+8muS4i+autei+k+WFpeiTnSAvIOS4iuautei+k+WHuue7v++8iVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuLyoqXG4gKiBPbmUgaG92ZXItdGlwIGNvbnRlbnQgYmxvY2ssIHNoYXJlZCBieSB0aGUgdHJlbmQgY2hhcnQgKGJhciArIGxpbmUpIGFuZCB0aGVcbiAqIHllYXJseSBoZWF0bWFwOiBkYXRlLCBpbnB1dCwgb3V0cHV0LCB0b3RhbCwgcmVmZXJlbmNlIGNvc3QuXG4gKlxuICogQ29zdCBjb21lcyBmcm9tIHRoZSBob3N0IGJ1Y2tldCAoYGNvc3RgLCBhbHJlYWR5IGNvbnZlcnRlZCB0byB0aGUgZGlzcGxheVxuICogY3VycmVuY3kpLCBzbyBhbGwgdGhyZWUgdGlwcyBzaG93IHRoZSBzYW1lIG51bWJlciBhcyB0aGUgc3VtbWFyeSBjYXJkIGFuZCB0aGVcbiAqIG1vZGVsIHRhYmxlLiBBIHplcm8gaXMgcHJpbnRlZCBhcyDCpTAuMDAg4oCUIFwiMFwiIGlzIGEgcHJpY2UsIFwidW5wcmljZWRcIiBpcyBhXG4gKiBkaWZmZXJlbnQgdmVyZGljdCwgYW5kIGl0IGlzIHRoZSBob3N0J3MgdG8gZ2l2ZS5cbiAqL1xuZnVuY3Rpb24gVGlwUm93cyhwcm9wcykge1xuICBjb25zdCB7IHJvdywgdCwgY3VycmVuY3ksIHdpdGhTcGxpdCB9ID0gcHJvcHNcbiAgY29uc3QgaW5UID0gcm93LmlucHV0VG9rZW5zIHx8IDBcbiAgY29uc3Qgb3V0VCA9IHJvdy5vdXRwdXRUb2tlbnMgfHwgMFxuICBjb25zdCB0b3RUID0gcm93LnRvdGFsVG9rZW5zIHx8IDBcbiAgcmV0dXJuIFtcbiAgICB3aXRoU3BsaXRcbiAgICAgID8gaCgnZGl2JywgeyBrZXk6ICdpbicsIGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXJvdycgfSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1kb3QgdHNkLWxlZ2VuZC1pbicgfSksXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ2xlZ2VuZElucHV0JykpLFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0SW50KGluVCkpKVxuICAgICAgOiBoKCdkaXYnLCB7IGtleTogJ2luJywgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtcm93JyB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRvdCcsIHN0eWxlOiB7IGJhY2tncm91bmQ6ICd2YXIoLS1kc3ctc3RhdGljLWRlZXBzZWVrLTUwMCknIH0gfSksXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ3RvdGFsVG9rZW5zJykpLFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0SW50KHRvdFQpKSksXG4gICAgd2l0aFNwbGl0XG4gICAgICA/IGgoJ2RpdicsIHsga2V5OiAnb3V0JywgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtcm93JyB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRvdCB0c2QtbGVnZW5kLW91dCcgfSksXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIHQoJ2xlZ2VuZE91dHB1dCcpKSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC12YWwnIH0sIGZvcm1hdEludChvdXRUKSkpXG4gICAgICA6IG51bGwsXG4gICAgLy8g5oiQ5pys5LiO6LCD55So5qyh5pWw5rKh5pyJ5a+55bqU5Zu+5L6L77yM5omA5Lul5Y+q55WZIDEwcHgg55qE56m655m95Y2g5L2N77yILnRzZC10b29sdGlwLWRvdCDmnKzouqvml6DlupXoibLvvInvvIxcbiAgICAvLyDkuI3nlLvoibLlnZfvvJroibLlnZfnmoTlkKvkuYnmmK/jgIzov5nkuIDooYzlr7nlupTlm77kvovph4znmoTlk6rkuKrpopzoibLjgI3jgIJcbiAgICBoKCdkaXYnLCB7IGtleTogJ2Nvc3QnLCBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1yb3cnIH0sXG4gICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1kb3QnLCAnYXJpYS1oaWRkZW4nOiAndHJ1ZScgfSksXG4gICAgICBoKCdzcGFuJywgbnVsbCwgdCgnY29zdCcpKSxcbiAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXZhbCcgfSwgZm9ybWF0Q29zdChyb3cuY29zdCB8fCAwLCBjdXJyZW5jeSkpKSxcbiAgICByb3cuY2FsbHMgPiAwXG4gICAgICA/IGgoJ2RpdicsIHsga2V5OiAnY2FsbHMnLCBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC1yb3cnIH0sXG4gICAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtZG90JywgJ2FyaWEtaGlkZGVuJzogJ3RydWUnIH0pLFxuICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCB0KCdjYWxscycpKSxcbiAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcC12YWwnIH0sIGZvcm1hdEludChyb3cuY2FsbHMpKSlcbiAgICAgIDogbnVsbCxcbiAgICB3aXRoU3BsaXRcbiAgICAgID8gaCgnZGl2JywgeyBrZXk6ICd0b3RhbCcsIGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLXRvdGFsJyB9LFxuICAgICAgICAgIGgoJ3NwYW4nLCBudWxsLCB0KCd0b29sdGlwVG90YWwnKSksXG4gICAgICAgICAgaCgnc3BhbicsIG51bGwsIGZvcm1hdEludCh0b3RUKSkpXG4gICAgICA6IG51bGwsXG4gIF1cbn1cblxuZnVuY3Rpb24gRGFpbHlDaGFydChwcm9wcykge1xuICBjb25zdCB7IGRhaWx5LCBncmFuLCBzdGVwRGF5cywgZ3JhbkxhYmVsLCBjdXJyZW5jeSB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICBjb25zdCBjaGFydFJlZiA9IFJlYWN0LnVzZVJlZihudWxsKVxuICBjb25zdCBbdGlwLCBzZXRUaXBdID0gUmVhY3QudXNlU3RhdGUobnVsbCkgLy8geyByb3csIHggfVxuICBjb25zdCBbdmlldywgc2V0Vmlld10gPSBSZWFjdC51c2VTdGF0ZSgnYmFyJykgLy8gYmFyIHwgbGluZVxuICBjb25zdCByb3dzID0gZGFpbHkgfHwgW11cblxuICBjb25zdCBpbk9mID0gKHIpID0+IChyLmlucHV0VG9rZW5zIHx8IDApICsgKHIuY2FjaGVSZWFkVG9rZW5zIHx8IDApICsgKHIuY2FjaGVXcml0ZVRva2VucyB8fCAwKVxuICBjb25zdCBvdXRPZiA9IChyKSA9PiByLm91dHB1dFRva2VucyB8fCAwXG4gIGNvbnN0IHRvdE9mID0gKHIpID0+IHIudG90YWxUb2tlbnMgfHwgMFxuXG4gIGlmIChyb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkIHRzZC1jaGFydC1jYXJkJyB9LFxuICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC1oZWFkZXInIH0sXG4gICAgICAgIGgoJ2gzJywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC10aXRsZScgfSwgdCgnZGFpbHlUcmVuZCcpKSxcbiAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtdGFnJyB9LCB0KCdub0RhdGEnKSkpLFxuICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtZW1wdHktYmxvY2snIH0sIHQoJ25vRGF0YScpKSlcbiAgfVxuXG4gIGNvbnN0IG1heCA9IE1hdGgubWF4KDEsIC4uLnJvd3MubWFwKChkKSA9PiBkLnRvdGFsVG9rZW5zIHx8IDApKVxuICBjb25zdCBsYWJlbEV2ZXJ5ID0gcm93cy5sZW5ndGggPiAyOCA/IDQgOiByb3dzLmxlbmd0aCA+IDE0ID8gMiA6IDFcbiAgY29uc3QgZmlyc3RMYWJlbCA9IHhMYWJlbChyb3dzWzBdLmtleSwgZ3JhbilcbiAgY29uc3QgbGFzdExhYmVsID0geExhYmVsKHJvd3Nbcm93cy5sZW5ndGggLSAxXS5rZXksIGdyYW4pXG4gIGNvbnN0IHJhbmdlTGFiZWwgPSBmaXJzdExhYmVsICsgJyAtICcgKyBsYXN0TGFiZWxcblxuICBmdW5jdGlvbiBzaG93VGlwKGUsIHJvdykge1xuICAgIGNvbnN0IGNoYXJ0UmVjdCA9IGNoYXJ0UmVmLmN1cnJlbnQgPyBjaGFydFJlZi5jdXJyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIDogbnVsbFxuICAgIGlmICghY2hhcnRSZWN0KSByZXR1cm5cbiAgICBjb25zdCBlbFJlY3QgPSBlLmN1cnJlbnRUYXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICBjb25zdCB4ID0gTWF0aC5taW4oTWF0aC5tYXgoZWxSZWN0LmxlZnQgKyBlbFJlY3Qud2lkdGggLyAyIC0gY2hhcnRSZWN0LmxlZnQsIDcyKSwgY2hhcnRSZWN0LndpZHRoIC0gNzIpXG4gICAgc2V0VGlwKHsgcm93LCB4IH0pXG4gIH1cblxuICBjb25zdCB2aWV3U3dpdGNoZXIgPSBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1ncmFuJywgcm9sZTogJ2dyb3VwJywgJ2FyaWEtbGFiZWwnOiB0KCdjaGFydFR5cGVHcm91cCcpIH0sXG4gICAgaCgnYnV0dG9uJywge1xuICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICBjbGFzc05hbWU6ICd0c2QtZ3Jhbi1idG4nLFxuICAgICAgJ2RhdGEtYWN0aXZlJzogdmlldyA9PT0gJ2JhcicgPyAndHJ1ZScgOiB1bmRlZmluZWQsXG4gICAgICBvbkNsaWNrOiAoKSA9PiB7IHNldFRpcChudWxsKTsgc2V0VmlldygnYmFyJykgfSxcbiAgICB9LCB0KCdiYXJWaWV3JykpLFxuICAgIGgoJ2J1dHRvbicsIHtcbiAgICAgIHR5cGU6ICdidXR0b24nLFxuICAgICAgY2xhc3NOYW1lOiAndHNkLWdyYW4tYnRuJyxcbiAgICAgICdkYXRhLWFjdGl2ZSc6IHZpZXcgPT09ICdsaW5lJyA/ICd0cnVlJyA6IHVuZGVmaW5lZCxcbiAgICAgIG9uQ2xpY2s6ICgpID0+IHsgc2V0VGlwKG51bGwpOyBzZXRWaWV3KCdsaW5lJykgfSxcbiAgICB9LCB0KCdsaW5lVmlldycpKSlcblxuICBjb25zdCBiYXJUaXAgPSB0aXBcbiAgICA/IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAnLCBzdHlsZTogeyBsZWZ0OiB0aXAueCArICdweCcgfSB9LFxuICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRhdGUnIH0sIHRpcC5yb3cua2V5ICsgJyAnICsgd2Vla2RheU5hbWUodGlwLnJvdy5rZXksIHQpKSxcbiAgICAgICAgaChUaXBSb3dzLCB7IHJvdzogdGlwLnJvdywgdCwgY3VycmVuY3ksIHdpdGhTcGxpdDogdHJ1ZSB9KSlcbiAgICA6IG51bGxcblxuICBjb25zdCBib2R5ID0gdmlldyA9PT0gJ2xpbmUnXG4gICAgPyBoKExpbmVDaGFydCwgeyByb3dzLCBncmFuLCBzdGVwRGF5cywgc2hvd1RpcCwgdGlwLCBzZXRUaXAsIGNoYXJ0UmVmLCBjdXJyZW5jeSB9KVxuICAgIDogaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2hhcnQnLCByZWY6IGNoYXJ0UmVmIH0sXG4gICAgICAgIHJvd3MubWFwKChyb3csIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBpblQgPSBpbk9mKHJvdylcbiAgICAgICAgICBjb25zdCBvdXRUID0gb3V0T2Yocm93KVxuICAgICAgICAgIGNvbnN0IHRvdFQgPSB0b3RPZihyb3cpXG4gICAgICAgICAgY29uc3QgcGN0SW4gPSAoaW5UIC8gbWF4KSAqIDEwMFxuICAgICAgICAgIGNvbnN0IHBjdE91dCA9IChvdXRUIC8gbWF4KSAqIDEwMFxuICAgICAgICAgIGNvbnN0IHNob3dMYWJlbCA9IGkgJSBsYWJlbEV2ZXJ5ID09PSAwIHx8IGkgPT09IHJvd3MubGVuZ3RoIC0gMVxuICAgICAgICAgIHJldHVybiBoKCdkaXYnLCB7XG4gICAgICAgICAgICBrZXk6IHJvdy5rZXksXG4gICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtY2hhcnQtY29sJyxcbiAgICAgICAgICAgIHRhYkluZGV4OiAwLFxuICAgICAgICAgICAgb25Nb3VzZUVudGVyOiAoZSkgPT4gc2hvd1RpcChlLCByb3cpLFxuICAgICAgICAgICAgb25Nb3VzZUxlYXZlOiAoKSA9PiBzZXRUaXAobnVsbCksXG4gICAgICAgICAgICBvbkZvY3VzOiAoZSkgPT4gc2hvd1RpcChlLCByb3cpLFxuICAgICAgICAgICAgb25CbHVyOiAoKSA9PiBzZXRUaXAobnVsbCksXG4gICAgICAgICAgICAnYXJpYS1sYWJlbCc6IHQoJ2JhckFyaWEnLCB7IGtleTogcm93LmtleSwgaW46IGZvcm1hdEludChpblQpLCBvdXQ6IGZvcm1hdEludChvdXRUKSwgdG90OiBmb3JtYXRJbnQodG90VCksIGNvc3Q6IGZvcm1hdENvc3Qocm93LmNvc3QgfHwgMCwgY3VycmVuY3kpIH0pLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jaGFydC1wbG90JyB9LFxuICAgICAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jaGFydC1zdGFjaycgfSxcbiAgICAgICAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jaGFydC1zZWcgdHNkLXNlZy1vdXQnLCBzdHlsZTogeyBoZWlnaHQ6IHBjdE91dCArICclJyB9IH0pLFxuICAgICAgICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNoYXJ0LXNlZyB0c2Qtc2VnLWluJywgc3R5bGU6IHsgaGVpZ2h0OiBwY3RJbiArICclJyB9IH0pKSksXG4gICAgICAgICAgICBoKCdzcGFuJywge1xuICAgICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtY2hhcnQtbGFiZWwnICsgKHNob3dMYWJlbCA/ICcnIDogJyB0c2QtY2hhcnQtbGFiZWwtaGlkZGVuJyksXG4gICAgICAgICAgICB9LCB4TGFiZWwocm93LmtleSwgZ3JhbikpKVxuICAgICAgICB9KSxcbiAgICAgICAgYmFyVGlwKVxuXG4gIHJldHVybiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkIHRzZC1jaGFydC1jYXJkJyB9LFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtaGVhZGVyJyB9LFxuICAgICAgaCgnaDMnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXRpdGxlJyB9LCB0KCdkYWlseVRyZW5kJykpLFxuICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtYWN0aW9ucycgfSxcbiAgICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtdGFnJyB9LCBncmFuTGFiZWwgKyAnIMK3ICcgKyByYW5nZUxhYmVsKSxcbiAgICAgICAgdmlld1N3aXRjaGVyKSksXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtbGVnZW5kJyB9LFxuICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWxlZ2VuZC1pdGVtJyB9LFxuICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtbGVnZW5kLWRvdCB0c2QtbGVnZW5kLWluJyB9KSwgdCgnbGVnZW5kSW5wdXQnKSksXG4gICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtbGVnZW5kLWl0ZW0nIH0sXG4gICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1sZWdlbmQtZG90IHRzZC1sZWdlbmQtb3V0JyB9KSwgdCgnbGVnZW5kT3V0cHV0JykpLFxuICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWxlZ2VuZC1pdGVtJyB9LFxuICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtbGVnZW5kLWRvdCB0c2QtbGVnZW5kLXRvdGFsJyB9KSwgdCgnbGVnZW5kVG90YWwnKSkpLFxuICAgIGJvZHkpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog5oqY57q/5Zu+77yIU1ZH77ya6L6T5YWlIC8g6L6T5Ye6IC8g5oC7IFRva2Vu77yJXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG4vKiogQ2F0bXVsbC1Sb20gLT4gY3ViaWMgYmV6aWVyIHNtb290aCBwYXRoIHRocm91Z2ggdGhlIGdpdmVuIHBvaW50cy4gKi9cbmZ1bmN0aW9uIHNtb290aFBhdGgocHRzKSB7XG4gIGlmICghcHRzIHx8IHB0cy5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgY29uc3QgZiA9ICh2KSA9PiBNYXRoLnJvdW5kKHYgKiAxMDApIC8gMTAwXG4gIGxldCBkID0gJ00gJyArIGYocHRzWzBdLngpICsgJyAnICsgZihwdHNbMF0ueSlcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwdHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgY29uc3QgcDAgPSBwdHNbaSAtIDFdIHx8IHB0c1tpXVxuICAgIGNvbnN0IHAxID0gcHRzW2ldXG4gICAgY29uc3QgcDIgPSBwdHNbaSArIDFdXG4gICAgY29uc3QgcDMgPSBwdHNbaSArIDJdIHx8IHAyXG4gICAgY29uc3QgYzF4ID0gcDEueCArIChwMi54IC0gcDAueCkgLyA2XG4gICAgY29uc3QgYzF5ID0gcDEueSArIChwMi55IC0gcDAueSkgLyA2XG4gICAgY29uc3QgYzJ4ID0gcDIueCAtIChwMy54IC0gcDEueCkgLyA2XG4gICAgY29uc3QgYzJ5ID0gcDIueSAtIChwMy55IC0gcDEueSkgLyA2XG4gICAgZCArPSAnIEMgJyArIGYoYzF4KSArICcgJyArIGYoYzF5KSArICcsICcgKyBmKGMyeCkgKyAnICcgKyBmKGMyeSkgKyAnLCAnICsgZihwMi54KSArICcgJyArIGYocDIueSlcbiAgfVxuICByZXR1cm4gZFxufVxuXG5mdW5jdGlvbiBMaW5lQ2hhcnQocHJvcHMpIHtcbiAgY29uc3QgeyByb3dzLCBncmFuLCBzdGVwRGF5cywgc2hvd1RpcCwgdGlwLCBzZXRUaXAsIGNoYXJ0UmVmLCBjdXJyZW5jeSB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICBjb25zdCBXID0gNjIwXG4gIGNvbnN0IEggPSAyNDBcbiAgY29uc3QgUEFEID0geyB0OiAxNCwgcjogMTQsIGI6IDI2LCBsOiA0OCB9XG4gIGNvbnN0IGlubmVyVyA9IFcgLSBQQUQubCAtIFBBRC5yXG4gIGNvbnN0IGlubmVySCA9IEggLSBQQUQudCAtIFBBRC5iXG4gIGNvbnN0IG4gPSByb3dzLmxlbmd0aFxuXG4gIGNvbnN0IGluT2YgPSAocikgPT4gKHIuaW5wdXRUb2tlbnMgfHwgMCkgKyAoci5jYWNoZVJlYWRUb2tlbnMgfHwgMCkgKyAoci5jYWNoZVdyaXRlVG9rZW5zIHx8IDApXG4gIGNvbnN0IG91dE9mID0gKHIpID0+IHIub3V0cHV0VG9rZW5zIHx8IDBcbiAgY29uc3QgdG90T2YgPSAocikgPT4gci50b3RhbFRva2VucyB8fCAwXG4gIGNvbnN0IG1heCA9IE1hdGgubWF4KDEsIC4uLnJvd3MubWFwKChkKSA9PiBkLnRvdGFsVG9rZW5zIHx8IDApKVxuICBjb25zdCBuaWNlTWF4ID0gbmljZUNlaWwobWF4KVxuXG4gIGNvbnN0IHggPSAoaSkgPT4gUEFELmwgKyAobiA9PT0gMSA/IGlubmVyVyAvIDIgOiAoaSAvIChuIC0gMSkpICogaW5uZXJXKVxuICBjb25zdCB5ID0gKHYpID0+IFBBRC50ICsgaW5uZXJIIC0gKHYgLyBuaWNlTWF4KSAqIGlubmVySFxuICBjb25zdCBjb2xXID0gaW5uZXJXIC8gblxuXG4gIC8vIEhvdmVyIHN0YXRlOiBwaXhlbCB4IGZvciB0aGUgdG9vbHRpcCwgdmlld0JveCB4IGZvciB0aGUgY3Vyc29yICsgZG90cy5cbiAgZnVuY3Rpb24gc2hvd1RpcExpbmUoZSwgcm93KSB7XG4gICAgY29uc3QgcmVjdCA9IGNoYXJ0UmVmLmN1cnJlbnQgPyBjaGFydFJlZi5jdXJyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIDogbnVsbFxuICAgIGlmICghcmVjdCB8fCByZWN0LndpZHRoID09PSAwKSByZXR1cm5cbiAgICBjb25zdCBlbFJlY3QgPSBlLmN1cnJlbnRUYXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICBjb25zdCB4UHggPSBlbFJlY3QubGVmdCArIGVsUmVjdC53aWR0aCAvIDIgLSByZWN0LmxlZnRcbiAgICBjb25zdCBzdmdYID0gKHhQeCAvIHJlY3Qud2lkdGgpICogV1xuICAgIGNvbnN0IHggPSBNYXRoLm1pbihNYXRoLm1heCh4UHgsIDcyKSwgcmVjdC53aWR0aCAtIDcyKVxuICAgIHNldFRpcCh7IHJvdywgeCwgc3ZnWCB9KVxuICB9XG4gIGNvbnN0IHRyb3cgPSB0aXAgPyB0aXAucm93IDogbnVsbFxuICBjb25zdCBjdXJzb3IgPSB0aXBcbiAgICA/IGgoJ2xpbmUnLCB7XG4gICAgICAgIGtleTogJ2N1cnNvcicsXG4gICAgICAgIGNsYXNzTmFtZTogJ3RzZC1saW5lLWN1cnNvcicsXG4gICAgICAgIHgxOiB0aXAuc3ZnWCwgeTE6IFBBRC50LCB4MjogdGlwLnN2Z1gsIHkyOiBIIC0gUEFELmIsXG4gICAgICB9KVxuICAgIDogbnVsbFxuICBjb25zdCBkb3RzID0gdGlwXG4gICAgPyBbXG4gICAgICAgIGgoJ2NpcmNsZScsIHsga2V5OiAnaGwtaW4nLCBjbGFzc05hbWU6ICd0c2QtbGluZS1obCB0c2QtbGluZS1obC1pbicsIGN4OiB0aXAuc3ZnWCwgY3k6IHkoaW5PZih0cm93KSksIHI6IDMuNSB9KSxcbiAgICAgICAgaCgnY2lyY2xlJywgeyBrZXk6ICdobC1vdXQnLCBjbGFzc05hbWU6ICd0c2QtbGluZS1obCB0c2QtbGluZS1obC1vdXQnLCBjeDogdGlwLnN2Z1gsIGN5OiB5KG91dE9mKHRyb3cpKSwgcjogMy41IH0pLFxuICAgICAgICBoKCdjaXJjbGUnLCB7IGtleTogJ2hsLXRvdCcsIGNsYXNzTmFtZTogJ3RzZC1saW5lLWhsIHRzZC1saW5lLWhsLXRvdGFsJywgY3g6IHRpcC5zdmdYLCBjeTogeSh0b3RPZih0cm93KSksIHI6IDMuNSB9KSxcbiAgICAgIF1cbiAgICA6IG51bGxcblxuICBjb25zdCBpblB0cyA9IHNtb290aFBhdGgocm93cy5tYXAoKHIsIGkpID0+ICh7IHg6IHgoaSksIHk6IHkoaW5PZihyKSkgfSkpKVxuICBjb25zdCBvdXRQdHMgPSBzbW9vdGhQYXRoKHJvd3MubWFwKChyLCBpKSA9PiAoeyB4OiB4KGkpLCB5OiB5KG91dE9mKHIpKSB9KSkpXG4gIGNvbnN0IHRvdFB0cyA9IHNtb290aFBhdGgocm93cy5tYXAoKHIsIGkpID0+ICh7IHg6IHgoaSksIHk6IHkodG90T2YocikpIH0pKSlcbiAgY29uc3QgZ3JpZEYgPSBbMCwgMC4yNSwgMC41LCAwLjc1LCAxXVxuICBjb25zdCBsYWJlbEV2ZXJ5ID0gcm93cy5sZW5ndGggPiAyOCA/IDQgOiByb3dzLmxlbmd0aCA+IDE0ID8gMiA6IDFcbiAgY29uc3Qgc2hvd0xhYmVsID0gKGkpID0+IGkgJSBsYWJlbEV2ZXJ5ID09PSAwIHx8IGkgPT09IHJvd3MubGVuZ3RoIC0gMVxuXG4gIHJldHVybiBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1saW5lY2hhcnQnLCByZWY6IGNoYXJ0UmVmIH0sXG4gICAgaCgnc3ZnJywgeyB2aWV3Qm94OiAnMCAwICcgKyBXICsgJyAnICsgSCwgcm9sZTogJ2ltZycsICdhcmlhLWxhYmVsJzogdCgnbGluZUNoYXJ0QXJpYScpIH0sXG4gICAgICAvLyBncmlkICsgYXhpc1xuICAgICAgZ3JpZEYubWFwKChmKSA9PlxuICAgICAgICBoKCdsaW5lJywge1xuICAgICAgICAgIGtleTogJ2cnICsgZixcbiAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtbGluZS1ncmlkJyxcbiAgICAgICAgICB4MTogUEFELmwsIHkxOiB5KGYgKiBuaWNlTWF4KSwgeDI6IFcgLSBQQUQuciwgeTI6IHkoZiAqIG5pY2VNYXgpLFxuICAgICAgICB9KSksXG4gICAgICBoKCdsaW5lJywgeyBjbGFzc05hbWU6ICd0c2QtbGluZS1heGlzJywgeDE6IFBBRC5sLCB5MTogUEFELnQsIHgyOiBQQUQubCwgeTI6IEggLSBQQUQuYiB9KSxcbiAgICAgIGgoJ2xpbmUnLCB7IGNsYXNzTmFtZTogJ3RzZC1saW5lLWF4aXMnLCB4MTogUEFELmwsIHkxOiBIIC0gUEFELmIsIHgyOiBXIC0gUEFELnIsIHkyOiBIIC0gUEFELmIgfSksXG4gICAgICAvLyB5IGxhYmVsc1xuICAgICAgZ3JpZEYubWFwKChmKSA9PlxuICAgICAgICBoKCd0ZXh0Jywge1xuICAgICAgICAgIGtleTogJ3l0JyArIGYsXG4gICAgICAgICAgY2xhc3NOYW1lOiAndHNkLWxpbmUtdGV4dCcsXG4gICAgICAgICAgeDogUEFELmwgLSA2LFxuICAgICAgICAgIHk6IHkoZiAqIG5pY2VNYXgpICsgMyxcbiAgICAgICAgICB0ZXh0QW5jaG9yOiAnZW5kJyxcbiAgICAgICAgfSwgZm9ybWF0VG9rZW5zU2hvcnQoZiAqIG5pY2VNYXgpKSksXG4gICAgICAvLyBzZXJpZXMgKHNtb290aCBjdXJ2ZXMpXG4gICAgICBoKCdwYXRoJywgeyBjbGFzc05hbWU6ICd0c2QtbGluZS10b3RhbCcsIGQ6IHRvdFB0cyB9KSxcbiAgICAgIGgoJ3BhdGgnLCB7IGNsYXNzTmFtZTogJ3RzZC1saW5lLWluJywgZDogaW5QdHMgfSksXG4gICAgICBoKCdwYXRoJywgeyBjbGFzc05hbWU6ICd0c2QtbGluZS1vdXQnLCBkOiBvdXRQdHMgfSksXG4gICAgICBjdXJzb3IsXG4gICAgICBkb3RzLFxuICAgICAgLy8geCBsYWJlbHNcbiAgICAgIHJvd3MubWFwKChyLCBpKSA9PlxuICAgICAgICBzaG93TGFiZWwoaSlcbiAgICAgICAgICA/IGgoJ3RleHQnLCB7XG4gICAgICAgICAgICAgIGtleTogJ3hsJyArIGksXG4gICAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1saW5lLXRleHQnLFxuICAgICAgICAgICAgICB4OiB4KGkpLFxuICAgICAgICAgICAgICB5OiBIIC0gOCxcbiAgICAgICAgICAgICAgdGV4dEFuY2hvcjogaSA9PT0gMCA/ICdzdGFydCcgOiBpID09PSBuIC0gMSA/ICdlbmQnIDogJ21pZGRsZScsXG4gICAgICAgICAgICB9LCB4TGFiZWwoci5rZXksIGdyYW4pKVxuICAgICAgICAgIDogbnVsbCksXG4gICAgICAvLyBob3ZlciB0YXJnZXRzOiBhIGZ1bGwtaGVpZ2h0IGNvbHVtbiBwZXIgYnVja2V0LCBtYXRjaGluZyB0aGUgYmFyIGNoYXJ0IGZlZWxcbiAgICAgIHJvd3MubWFwKChyLCBpKSA9PlxuICAgICAgICBoKCdyZWN0Jywge1xuICAgICAgICAgIGtleTogJ2gnICsgaSxcbiAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtbGluZS1ob3ZlcicsXG4gICAgICAgICAgeDogeChpKSAtIGNvbFcgLyAyLFxuICAgICAgICAgIHk6IFBBRC50LFxuICAgICAgICAgIHdpZHRoOiBjb2xXLFxuICAgICAgICAgIGhlaWdodDogaW5uZXJILFxuICAgICAgICAgIHRhYkluZGV4OiAwLFxuICAgICAgICAgIG9uTW91c2VFbnRlcjogKGUpID0+IHNob3dUaXBMaW5lKGUsIHIpLFxuICAgICAgICAgIG9uTW91c2VMZWF2ZTogKCkgPT4gc2V0VGlwKG51bGwpLFxuICAgICAgICAgIG9uRm9jdXM6IChlKSA9PiBzaG93VGlwTGluZShlLCByKSxcbiAgICAgICAgICBvbkJsdXI6ICgpID0+IHNldFRpcChudWxsKSxcbiAgICAgICAgfSkpLFxuICAgICAgLy8gdmlzaWJsZSBkb3RzIG9uIHNwYXJzZSBwb2ludHNcbiAgICAgIHJvd3MubWFwKChyLCBpKSA9PlxuICAgICAgICBpICUgbGFiZWxFdmVyeSA9PT0gMCB8fCBpID09PSBuIC0gMVxuICAgICAgICAgID8gaCgnY2lyY2xlJywge1xuICAgICAgICAgICAgICBrZXk6ICdkJyArIGksXG4gICAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1saW5lLWRvdCcsXG4gICAgICAgICAgICAgIGN4OiB4KGkpLFxuICAgICAgICAgICAgICBjeTogeSh0b3RPZihyKSksXG4gICAgICAgICAgICAgIHI6IDIuNSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgOiBudWxsKSksXG4gICAgdGlwXG4gICAgICA/IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAnLCBzdHlsZTogeyBsZWZ0OiB0aXAueCArICdweCcgfSB9LFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXRvb2x0aXAtZGF0ZScgfSwgdGlwLnJvdy5rZXkgKyAoc3RlcERheXMgPiAxID8gJyAnICsgdCgnc3RhcnRORGF5cycsIHsgbjogc3RlcERheXMgfSkgOiAnJykgKyAnICcgKyB3ZWVrZGF5TmFtZSh0aXAucm93LmtleSwgdCkpLFxuICAgICAgICAgIGgoVGlwUm93cywgeyByb3c6IHRpcC5yb3csIHQsIGN1cnJlbmN5LCB3aXRoU3BsaXQ6IHRydWUgfSkpXG4gICAgICA6IG51bGwpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog5bm05bqm55So6YeP54Ot5Yqb5Zu+77yIR2l0SHViIOmjjuagvO+8iVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gSGVhdG1hcENhcmQocHJvcHMpIHtcbiAgY29uc3QgeyBkYXlzLCBjdXJyZW5jeSB9ID0gcHJvcHNcbiAgY29uc3QgdCA9IHVzZVQoKVxuICBjb25zdCBbaHRpcCwgc2V0SHRpcF0gPSBSZWFjdC51c2VTdGF0ZShudWxsKSAvLyB7IGNlbGwsIGxlZnQsIHRvcCB9IGluIHZpZXdwb3J0IGNvb3Jkc1xuICBjb25zdCBncmlkID0gUmVhY3QudXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3QgbGlzdCA9IGRheXMgfHwgW11cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDApIHJldHVybiBudWxsXG4gICAgY29uc3QgbWF4ID0gTWF0aC5tYXgoMSwgLi4ubGlzdC5tYXAoKGQpID0+IGQudG90YWxUb2tlbnMgfHwgMCkpXG4gICAgY29uc3QgZmlyc3QgPSBuZXcgRGF0ZShsaXN0WzBdLmtleSArICdUMDA6MDA6MDAnKVxuICAgIGNvbnN0IG9mZnNldCA9IGZpcnN0LmdldERheSgpIC8vIDAgPSBTdW5kYXlcbiAgICBjb25zdCB3ZWVrcyA9IFtdXG4gICAgbGV0IGN1ciA9IFtdXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvZmZzZXQ7IGkrKykgY3VyLnB1c2gobnVsbClcbiAgICBmb3IgKGNvbnN0IGQgb2YgbGlzdCkge1xuICAgICAgY3VyLnB1c2goZClcbiAgICAgIGlmIChjdXIubGVuZ3RoID09PSA3KSB7XG4gICAgICAgIHdlZWtzLnB1c2goY3VyKVxuICAgICAgICBjdXIgPSBbXVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoY3VyLmxlbmd0aCA+IDApIHtcbiAgICAgIHdoaWxlIChjdXIubGVuZ3RoIDwgNykgY3VyLnB1c2gobnVsbClcbiAgICAgIHdlZWtzLnB1c2goY3VyKVxuICAgIH1cbiAgICAvLyDmnIjku73moIforrDvvJrmn5DmnIggMSDml6XmiYDlnKjnmoTliJdcbiAgICBjb25zdCBtb250aE1hcmtzID0gW11cbiAgICB3ZWVrcy5mb3JFYWNoKCh3aywgY29sKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGMgb2Ygd2spIHtcbiAgICAgICAgaWYgKGMgJiYgYy5rZXkuZW5kc1dpdGgoJy0wMScpKSB7XG4gICAgICAgICAgbW9udGhNYXJrcy5wdXNoKHsgY29sLCBuYW1lOiB0KCdtb250aExhYmVsJywgeyBuOiBOdW1iZXIoYy5rZXkuc2xpY2UoNSwgNykpIH0pIH0pXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIHsgd2Vla3MsIG1heCwgbW9udGhNYXJrcyB9XG4gIH0sIFtkYXlzXSlcblxuICBpZiAoZ3JpZCA9PT0gbnVsbCkgcmV0dXJuIG51bGxcblxuICBmdW5jdGlvbiBzaG93Q2VsbFRpcChlLCBjKSB7XG4gICAgY29uc3QgZWxSZWN0ID0gZS5jdXJyZW50VGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgc2V0SHRpcCh7IGNlbGw6IGMsIGxlZnQ6IGVsUmVjdC5sZWZ0ICsgZWxSZWN0LndpZHRoIC8gMiwgdG9wOiBlbFJlY3QudG9wIH0pXG4gIH1cblxuICBjb25zdCBoZWF0VGlwID0gaHRpcFxuICAgID8gaCgnZGl2Jywge1xuICAgICAgICBjbGFzc05hbWU6ICd0c2QtdG9vbHRpcCB0c2QtaGVhdC10aXAnLFxuICAgICAgICBzdHlsZTogeyBwb3NpdGlvbjogJ2ZpeGVkJywgbGVmdDogaHRpcC5sZWZ0ICsgJ3B4JywgdG9wOiBodGlwLnRvcCArICdweCcsIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZSgtNTAlLCAtMTEwJSknIH0sXG4gICAgICB9LFxuICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC10b29sdGlwLWRhdGUnIH0sIGh0aXAuY2VsbC5rZXkgKyAnICcgKyB3ZWVrZGF5TmFtZShodGlwLmNlbGwua2V5LCB0KSksXG4gICAgICAgIGgoVGlwUm93cywgeyByb3c6IGh0aXAuY2VsbCwgdCwgY3VycmVuY3ksIHdpdGhTcGxpdDogZmFsc2UgfSkpXG4gICAgOiBudWxsXG5cbiAgY29uc3QgZGF5TmFtZXMgPSBbJycsIHQoJ3dlZWtkYXlNb24nKSwgJycsIHQoJ3dlZWtkYXlXZWQnKSwgJycsIHQoJ3dlZWtkYXlGcmknKSwgJyddXG4gIGNvbnN0IGxlZ2VuZFN0ZXBzID0gWzAsIDAuMjUsIDAuNSwgMC43NSwgMV1cblxuICByZXR1cm4gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZCB0c2QtaGVhdG1hcC1jYXJkJyB9LFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtaGVhZGVyJyB9LFxuICAgICAgaCgnaDMnLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXRpdGxlJyB9LCB0KCd5ZWFybHlIZWF0bWFwJykpLFxuICAgICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtdGFnJyB9LCB0KCd5ZWFyRGFpbHknLCB7IHllYXI6IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKSB9KSkpLFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAnIH0sXG4gICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1oZWF0bWFwLWlubmVyJyB9LFxuICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1oZWF0bWFwLW1vbnRocycgfSxcbiAgICAgICAgICBncmlkLm1vbnRoTWFya3MubWFwKChtKSA9PlxuICAgICAgICAgICAgaCgnc3BhbicsIHtcbiAgICAgICAgICAgICAga2V5OiBtLmNvbCxcbiAgICAgICAgICAgICAgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAtbW9udGgnLFxuICAgICAgICAgICAgICBzdHlsZTogeyBsZWZ0OiAobS5jb2wgKiAxMikgKyAncHgnIH0sXG4gICAgICAgICAgICB9LCBtLm5hbWUpKSksXG4gICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAtYm9keScgfSxcbiAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1oZWF0bWFwLWRheXMnIH0sXG4gICAgICAgICAgICBkYXlOYW1lcy5tYXAoKG4sIGkpID0+XG4gICAgICAgICAgICAgIGgoJ3NwYW4nLCB7IGtleTogaSwgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAtZGF5JyB9LCBuKSkpLFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAtZ3JpZCcgfSxcbiAgICAgICAgICAgIGdyaWQud2Vla3MubWFwKCh3aywgY29sKSA9PlxuICAgICAgICAgICAgICBoKCdkaXYnLCB7IGtleTogY29sLCBjbGFzc05hbWU6ICd0c2QtaGVhdG1hcC1jb2wnIH0sXG4gICAgICAgICAgICAgICAgd2subWFwKChjLCByb3cpID0+XG4gICAgICAgICAgICAgICAgICBjXG4gICAgICAgICAgICAgICAgICAgID8gaCgnc3BhbicsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleTogYy5rZXksXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICd0c2QtaGVhdG1hcC1jZWxsJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IGJhY2tncm91bmQ6IGhlYXRDb2xvcihjLnRvdGFsVG9rZW5zIHx8IDAsIGdyaWQubWF4KSB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IHQoJ2htVGl0bGUnLCB7IGtleTogYy5rZXksIHRva2VuczogZm9ybWF0SW50KGMudG90YWxUb2tlbnMgfHwgMCksIGNhbGxzOiBjLmNhbGxzID8gdCgnaG1DYWxscycsIHsgY291bnQ6IGZvcm1hdEludChjLmNhbGxzKSB9KSA6ICcnLCBjb3N0OiBmb3JtYXRDb3N0KGMuY29zdCB8fCAwLCBjdXJyZW5jeSkgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICBvbk1vdXNlRW50ZXI6IChlKSA9PiBzaG93Q2VsbFRpcChlLCBjKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uTW91c2VMZWF2ZTogKCkgPT4gc2V0SHRpcChudWxsKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uRm9jdXM6IChlKSA9PiBzaG93Q2VsbFRpcChlLCBjKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQmx1cjogKCkgPT4gc2V0SHRpcChudWxsKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhYkluZGV4OiAwLFxuICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIDogaCgnc3BhbicsIHsga2V5OiAnZScgKyBjb2wgKyAnLScgKyByb3csIGNsYXNzTmFtZTogJ3RzZC1oZWF0bWFwLWNlbGwnLCBzdHlsZTogeyB2aXNpYmlsaXR5OiAnaGlkZGVuJyB9IH0pKSkpKSkpLFxuICAgIGhlYXRUaXAsXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtaGVhdG1hcC1sZWdlbmQnIH0sXG4gICAgICBoKCdzcGFuJywgbnVsbCwgdCgnbGVzcycpKSxcbiAgICAgIGxlZ2VuZFN0ZXBzLm1hcCgocykgPT5cbiAgICAgICAgaCgnc3BhbicsIHtcbiAgICAgICAgICBrZXk6IHMsXG4gICAgICAgICAgY2xhc3NOYW1lOiAndHNkLWhlYXRtYXAtY2VsbCcsXG4gICAgICAgICAgc3R5bGU6IHsgYmFja2dyb3VuZDogcyA9PT0gMCA/ICd2YXIoLS1kc3ctYWxpYXMtaW50ZXJhY3RpdmUtYmctaG92ZXIpJyA6IGhlYXRDb2xvcihNYXRoLm1heCgxLCBzICogMTAwKSwgMTAwKSB9LFxuICAgICAgICB9KSksXG4gICAgICBoKCdzcGFuJywgbnVsbCwgdCgnbW9yZScpKSkpKVxufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIOaMieaooeWei+aYjue7huihqFxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gTW9kZWxUYWJsZShwcm9wcykge1xuICBjb25zdCB7IHJvd3MsIGN1cnJlbmN5IH0gPSBwcm9wc1xuICBjb25zdCB0ID0gdXNlVCgpXG4gIGNvbnN0IGFsbCA9IHJvd3MgfHwgW11cbiAgY29uc3QgW3NvcnRLZXksIHNldFNvcnRLZXldID0gUmVhY3QudXNlU3RhdGUoJ3RvdGFsJylcbiAgY29uc3QgW3NvcnREaXIsIHNldFNvcnREaXJdID0gUmVhY3QudXNlU3RhdGUoJ2Rlc2MnKVxuXG4gIGNvbnN0IHZpZXcgPSBSZWFjdC51c2VNZW1vKCgpID0+IGFsbC5tYXAoKHIpID0+ICh7XG4gICAga2V5OiByLmtleSxcbiAgICBjYWxsczogci5jYWxscyB8fCAwLFxuICAgIGlucHV0OiAoci5pbnB1dFRva2VucyB8fCAwKSArIChyLmNhY2hlUmVhZFRva2VucyB8fCAwKSArIChyLmNhY2hlV3JpdGVUb2tlbnMgfHwgMCksXG4gICAgb3V0cHV0OiByLm91dHB1dFRva2VucyB8fCAwLFxuICAgIHRvdGFsOiByLnRvdGFsVG9rZW5zIHx8IDAsXG4gICAgY29zdDogci5jb3N0IHx8IDAsXG4gICAgLy8gVGhlIHZlcmRpY3QgY29tZXMgZnJvbSB0aGUgaG9zdCwgd2hpY2gga25vd3Mgd2hldGhlciBhIHByaWNlIHdhcyBmb3VuZC5cbiAgICAvLyBUaGlzIHVzZWQgdG8gYmUgcmUtZGVyaXZlZCBoZXJlIGFzIGB0b2tlbnMgPiAwICYmICEoY29zdCA+IDApYCwgd2hpY2hcbiAgICAvLyBsYWJlbHMgZXZlcnkgMC1jb3N0IHJvdyDmnKrlrprku7cg4oCUIGluY2x1ZGluZyBhIG1vZGVsIHRoZSB1c2VyIGV4cGxpY2l0bHlcbiAgICAvLyBwcmljZWQgYXQgMCAoYSByZWFsIHByaWNlLCBjb3N0IDAsIHNvIMKlMC4wMCBpcyB0aGUgaG9uZXN0IGFuc3dlcikuXG4gICAgdW5wcmljZWQ6IHIudW5wcmljZWQgPT09IHRydWUsXG4gIH0pKSwgW2FsbF0pXG5cbiAgY29uc3Qgc3VtVG90YWwgPSBSZWFjdC51c2VNZW1vKCgpID0+IHZpZXcucmVkdWNlKChzLCByKSA9PiBzICsgci50b3RhbCwgMCksIFt2aWV3XSlcblxuICBjb25zdCBzb3J0ZWQgPSBSZWFjdC51c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBsaXN0ID0gdmlldy5zbGljZSgpXG4gICAgY29uc3QgZGlyID0gc29ydERpciA9PT0gJ2FzYycgPyAxIDogLTFcbiAgICBsaXN0LnNvcnQoKGEsIGIpID0+IHtcbiAgICAgIGNvbnN0IGF2ID0gYVtzb3J0S2V5XVxuICAgICAgY29uc3QgYnYgPSBiW3NvcnRLZXldXG4gICAgICBpZiAoYXYgPT09IGJ2KSByZXR1cm4gMFxuICAgICAgcmV0dXJuIChhdiA+IGJ2ID8gMSA6IC0xKSAqIGRpclxuICAgIH0pXG4gICAgcmV0dXJuIGxpc3RcbiAgfSwgW3ZpZXcsIHNvcnRLZXksIHNvcnREaXJdKVxuXG4gIGZ1bmN0aW9uIHRvZ2dsZVNvcnQoa2V5KSB7XG4gICAgaWYgKHNvcnRLZXkgPT09IGtleSkgc2V0U29ydERpcigoZCkgPT4gKGQgPT09ICdhc2MnID8gJ2Rlc2MnIDogJ2FzYycpKVxuICAgIGVsc2UgeyBzZXRTb3J0S2V5KGtleSk7IHNldFNvcnREaXIoJ2Rlc2MnKSB9XG4gIH1cblxuICBjb25zdCBjb2xzID0gW1xuICAgIHsga2V5OiAnbW9kZWwnLCBsYWJlbDogdCgnY29sTW9kZWwnKSwgc29ydGFibGU6IGZhbHNlIH0sXG4gICAgeyBrZXk6ICdjYWxscycsIGxhYmVsOiB0KCdjb2xDYWxscycpLCBzb3J0YWJsZTogdHJ1ZSB9LFxuICAgIHsga2V5OiAnaW5wdXQnLCBsYWJlbDogdCgnY29sSW5wdXQnKSwgc29ydGFibGU6IHRydWUgfSxcbiAgICB7IGtleTogJ291dHB1dCcsIGxhYmVsOiB0KCdjb2xPdXRwdXQnKSwgc29ydGFibGU6IHRydWUgfSxcbiAgICB7IGtleTogJ3RvdGFsJywgbGFiZWw6IHQoJ2NvbFRvdGFsJyksIHNvcnRhYmxlOiB0cnVlIH0sXG4gICAgeyBrZXk6ICdjb3N0JywgbGFiZWw6IHQoJ2NvbENvc3QnKSwgc29ydGFibGU6IHRydWUgfSxcbiAgICB7IGtleTogJ3JhdGlvJywgbGFiZWw6IHQoJ2NvbFNoYXJlJyksIHNvcnRhYmxlOiBmYWxzZSB9LFxuICBdXG5cbiAgcmV0dXJuIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQgdHNkLXRhYmxlLWNhcmQnIH0sXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZC1oZWFkZXInIH0sXG4gICAgICBoKCdoMycsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQtdGl0bGUnIH0sIHQoJ2J5TW9kZWxUaXRsZScpKSxcbiAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1jYXJkLXRhZycgfSxcbiAgICAgICAgdCgnbW9kZWxDb3VudCcsIHsgbjogdmlldy5sZW5ndGggfSkgKyAnIMK3ICcgKyB0KCdjb2xUb3RhbCcpICsgJyAnICsgZm9ybWF0SW50KHN1bVRvdGFsKSkpLFxuICAgIHZpZXcubGVuZ3RoID09PSAwXG4gICAgICA/IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWVtcHR5LWJsb2NrJyB9LCB0KCdub0RhdGEnKSlcbiAgICAgIDogaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtdGFibGUtd3JhcCcgfSxcbiAgICAgICAgICBoKCd0YWJsZScsIHsgY2xhc3NOYW1lOiAndHNkLXRhYmxlJyB9LFxuICAgICAgICAgICAgaCgnY2FwdGlvbicsIHsgY2xhc3NOYW1lOiAndHNkLXZpc3VhbGx5LWhpZGRlbicgfSwgdCgnbW9kZWxUYWJsZUNhcHRpb24nKSksXG4gICAgICAgICAgICBoKCd0aGVhZCcsIG51bGwsXG4gICAgICAgICAgICAgIGgoJ3RyJywgbnVsbCwgY29scy5tYXAoKGMpID0+XG4gICAgICAgICAgICAgICAgaCgndGgnLCB7XG4gICAgICAgICAgICAgICAgICBrZXk6IGMua2V5LFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAndHNkLXRoJyArIChjLmtleSA9PT0gJ21vZGVsJyA/ICcnIDogJyB0c2QtdGgtbnVtJyksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGMuc29ydGFibGVcbiAgICAgICAgICAgICAgICAgICAgPyBoKCdidXR0b24nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnYnV0dG9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1zb3J0LWJ0bicgKyAoc29ydEtleSA9PT0gYy5rZXkgPyAnIHRzZC1zb3J0LWFjdGl2ZScgOiAnJyksXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiAoKSA9PiB0b2dnbGVTb3J0KGMua2V5KSxcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgYy5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvcnRLZXkgPT09IGMua2V5XG4gICAgICAgICAgICAgICAgICAgICAgICAgID8gaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLXNvcnQtYXJyb3cnIH0sIHNvcnREaXIgPT09ICdhc2MnID8gJ+KGkScgOiAn4oaTJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsKVxuICAgICAgICAgICAgICAgICAgICA6IGMubGFiZWwpKSkpLFxuICAgICAgICAgICAgaCgndGJvZHknLCBudWxsLCBzb3J0ZWQubWFwKChyKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHJhdGlvID0gc3VtVG90YWwgPiAwID8gci50b3RhbCAvIHN1bVRvdGFsIDogMFxuICAgICAgICAgICAgICByZXR1cm4gaCgndHInLCB7IGtleTogci5rZXksIGNsYXNzTmFtZTogJ3RzZC10cicgfSxcbiAgICAgICAgICAgICAgICBoKCd0ZCcsIHsgY2xhc3NOYW1lOiAndHNkLXRkIHRzZC10ZC1tb2RlbCcgfSxcbiAgICAgICAgICAgICAgICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1tb2RlbC1tb25vJywgdGl0bGU6IHIua2V5IH0sIHIua2V5KSksXG4gICAgICAgICAgICAgICAgaCgndGQnLCB7IGNsYXNzTmFtZTogJ3RzZC10ZCB0c2QtbnVtJyB9LCBmb3JtYXRJbnQoci5jYWxscykpLFxuICAgICAgICAgICAgICAgIGgoJ3RkJywgeyBjbGFzc05hbWU6ICd0c2QtdGQgdHNkLW51bScgfSwgZm9ybWF0SW50KHIuaW5wdXQpKSxcbiAgICAgICAgICAgICAgICBoKCd0ZCcsIHsgY2xhc3NOYW1lOiAndHNkLXRkIHRzZC1udW0nIH0sIGZvcm1hdEludChyLm91dHB1dCkpLFxuICAgICAgICAgICAgICAgIGgoJ3RkJywgeyBjbGFzc05hbWU6ICd0c2QtdGQgdHNkLW51bSB0c2QtdG90YWwnIH0sIGZvcm1hdEludChyLnRvdGFsKSksXG4gICAgICAgICAgICAgICAgaCgndGQnLCB7IGNsYXNzTmFtZTogJ3RzZC10ZCB0c2QtbnVtJyB9LFxuICAgICAgICAgICAgICAgICAgci51bnByaWNlZFxuICAgICAgICAgICAgICAgICAgICA/IGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC11bnByaWNlZCcsIHRpdGxlOiB0KCd1bnByaWNlZFJvd0hpbnQnKSB9LCB0KCd1bnByaWNlZCcpKVxuICAgICAgICAgICAgICAgICAgICA6IGZvcm1hdENvc3Qoci5jb3N0LCBjdXJyZW5jeSkpLFxuICAgICAgICAgICAgICAgIGgoJ3RkJywgeyBjbGFzc05hbWU6ICd0c2QtdGQgdHNkLXRkLXJhdGlvJyB9LFxuICAgICAgICAgICAgICAgICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtcmF0aW8nIH0sXG4gICAgICAgICAgICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXJhdGlvLWJhcicgfSxcbiAgICAgICAgICAgICAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1yYXRpby1maWxsJywgc3R5bGU6IHsgd2lkdGg6IHJhdGlvICogMTAwICsgJyUnIH0gfSkpLFxuICAgICAgICAgICAgICAgICAgICBoKCdzcGFuJywgeyBjbGFzc05hbWU6ICd0c2QtcmF0aW8tcGN0JyB9LCBmbXRQY3QocmF0aW8pKSkpKVxuICAgICAgICAgICAgfSkpKSkpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog5LiJ5oCB77ya5Yqg6L29IC8g6ZSZ6K+vIC8g56m6XG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBMb2FkaW5nU3RhdGUocHJvcHMpIHtcbiAgY29uc3QgdCA9IHVzZVQoKVxuICAvLyDnu5/orqHkuK3vvIhjb21wdXRpbmfvvInml7blpLTpg6jlia/moIfpopjlt7Lnu4/lnKjmkq3miqXov5vluqbvvIzov5nph4zlsLHkuI3lho3lgZrnrKzkuozkuKogbGl2ZSDljLrln5/vvIxcbiAgLy8g5ZCm5YiZ5bGP5bmV6ZiF6K+75Zmo5Lya5oqK44CM5q2j5Zyo5Yqg6L2944CN5ZKM44CM5q2j5Zyo57uf6K6hIDEyLzI1OOOAjeWQhOW/teS4gOmBjeOAglxuICBjb25zdCBhbm5vdW5jZSA9ICFwcm9wcyB8fCBwcm9wcy5hbm5vdW5jZSAhPT0gZmFsc2VcbiAgcmV0dXJuIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWxvYWRpbmcnLCByb2xlOiAnc3RhdHVzJywgJ2FyaWEtbGl2ZSc6IGFubm91bmNlID8gJ3BvbGl0ZScgOiAnb2ZmJyB9LFxuICAgIC8vIOmqqOaetuWxj+WvueecvOedm+aYr1wi5q2j5Zyo5p2lXCLvvIzlr7nlsY/luZXpmIXor7vlmajku4DkuYjpg73kuI3mmK/vvJrnu5nlroPkuIDlj6Xlj6/or7vnmoTnirbmgIHjgIJcbiAgICBhbm5vdW5jZSA/IGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC12aXN1YWxseS1oaWRkZW4nIH0sIHQoJ2xvYWRpbmcnKSkgOiBudWxsLFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmRzJyB9LFxuICAgICAgLy8g5LiA5byg5Y2h5LiA5Liq5Y2g5L2N5Z2X77yM5byg5pWw5Y+W6IeqIFNVTU1BUllfQ0FSRF9TTE9UUyDigJTigJQg5LiO55yf5a6e5Y2h54mH5ZCM5LiA5Lu96aG65bqP6KGo77yMXG4gICAgICAvLyDmiYDku6XooaXljaHniYfml7bpqqjmnrboh6rliqjot5/kuIrvvIjov5nph4zmm77nu4/lhpnmrbsgNSDkuKrvvIznnJ/lrp7mmK8gNiDkuKrvvInjgIJcbiAgICAgIFNVTU1BUllfQ0FSRF9TTE9UUy5tYXAoKHNsb3QpID0+XG4gICAgICAgIGgoJ2RpdicsIHsga2V5OiBzbG90LCBjbGFzc05hbWU6ICd0c2QtY2FyZCB0c2QtY2FyZC1za2VsZXRvbicgfSxcbiAgICAgICAgICBoKCdkaXYnLCB7IGNsYXNzTmFtZTogJ3RzZC1za2VsZXRvbicsIHN0eWxlOiB7IHdpZHRoOiAnNDAlJywgaGVpZ2h0OiAxMiB9IH0pLFxuICAgICAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXNrZWxldG9uJywgc3R5bGU6IHsgd2lkdGg6ICc3MCUnLCBoZWlnaHQ6IDIyLCBtYXJnaW5Ub3A6IDEwIH0gfSkpKSksXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZCcgfSxcbiAgICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLXNrZWxldG9uJywgc3R5bGU6IHsgd2lkdGg6ICcxMDAlJywgaGVpZ2h0OiAzMDAgfSB9KSksXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY2FyZCcgfSxcbiAgICAgIFswLCAxLCAyLCAzLCA0LCA1XS5tYXAoKGkpID0+XG4gICAgICAgIGgoJ2RpdicsIHsga2V5OiBpLCBjbGFzc05hbWU6ICd0c2Qtc2tlbGV0b24tcm93Jywgc3R5bGU6IHsgd2lkdGg6IDk2IC0gaSAqIDggKyAnJScgfSB9KSkpKVxufVxuXG5mdW5jdGlvbiBFcnJvclN0YXRlKHByb3BzKSB7XG4gIGNvbnN0IHsgZXJyb3IsIG9uUmV0cnkgfSA9IHByb3BzXG4gIGNvbnN0IHQgPSB1c2VUKClcbiAgcmV0dXJuIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQgdHNkLWVycm9yJywgcm9sZTogJ2FsZXJ0JyB9LFxuICAgIGgoU3ZnSWNvbiwgeyBuYW1lOiAnYWxlcnQnLCBzaXplOiAyMiwgY2xhc3NOYW1lOiAndHNkLWVycm9yLWljb24nIH0pLFxuICAgIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWVycm9yLXRleHQnIH0sXG4gICAgICBoKCdwJywgeyBjbGFzc05hbWU6ICd0c2QtZXJyb3ItdGl0bGUnIH0sIHQoJ2xvYWRGYWlsZWRUaXRsZScpKSxcbiAgICAgIGgoJ3AnLCB7IGNsYXNzTmFtZTogJ3RzZC1lcnJvci1kZXRhaWwnIH0sIFN0cmluZygoZXJyb3IgJiYgZXJyb3IubWVzc2FnZSkgfHwgZXJyb3IpKSksXG4gICAgaCgnYnV0dG9uJywgeyB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiAndHNkLWJ0biB0c2QtYnRuLXByaW1hcnknLCBvbkNsaWNrOiBvblJldHJ5IH0sIHQoJ3JldHJ5JykpKVxufVxuXG5mdW5jdGlvbiBFbXB0eVN0YXRlKHByb3BzKSB7XG4gIGNvbnN0IHsgZmlsdGVyZWQsIG9uUmVzZXQgfSA9IHByb3BzXG4gIGNvbnN0IHQgPSB1c2VUKClcbiAgcmV0dXJuIGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWNhcmQgdHNkLWVtcHR5JyB9LFxuICAgIGgoU3ZnSWNvbiwgeyBuYW1lOiAnaW5ib3gnLCBzaXplOiAyOCwgY2xhc3NOYW1lOiAndHNkLWVtcHR5LWljb24nIH0pLFxuICAgIGgoJ3AnLCB7IGNsYXNzTmFtZTogJ3RzZC1lbXB0eS10aXRsZScgfSwgdCgnbm9EYXRhJykpLFxuICAgIGgoJ3AnLCB7IGNsYXNzTmFtZTogJ3RzZC1lbXB0eS1kZXNjJyB9LFxuICAgICAgZmlsdGVyZWQgPyB0KCdlbXB0eUZpbHRlcmVkJykgOiB0KCdlbXB0eURlc2MnKSksXG4gICAgaCgnYnV0dG9uJywgeyB0eXBlOiAnYnV0dG9uJywgY2xhc3NOYW1lOiAndHNkLWJ0biB0c2QtYnRuLWdob3N0Jywgb25DbGljazogb25SZXNldCB9LCB0KCdyZXNldEZpbHRlcnMnKSkpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog6aG16Z2i57qn54q25oCB5py6ICsg5biD5bGAXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5mdW5jdGlvbiBTdGF0c0Rhc2hib2FyZChwcm9wcykge1xuICBjb25zdCB0ID0gcHJvcHMudCB8fCBmYWxsYmFja1RcbiAgY29uc3QgW3JhbmdlLCBzZXRSYW5nZV0gPSBSZWFjdC51c2VTdGF0ZSgndG9kYXknKSAvLyB0b2RheSB8IDdkIHwgMzBkIHwgY3VzdG9tXG4gIGNvbnN0IFtjdXN0b20sIHNldEN1c3RvbV0gPSBSZWFjdC51c2VTdGF0ZShkZWZhdWx0Q3VzdG9tKVxuICBjb25zdCBbbW9kZWxzLCBzZXRNb2RlbHNdID0gUmVhY3QudXNlU3RhdGUoW10pIC8vIFtdID0g5YWo6YOo5qih5Z6LXG4gIGNvbnN0IFtjdXN0b21PcGVuLCBzZXRDdXN0b21PcGVuXSA9IFJlYWN0LnVzZVN0YXRlKGZhbHNlKVxuICBjb25zdCBbcmV0cnksIHNldFJldHJ5XSA9IFJlYWN0LnVzZVN0YXRlKDApXG4gIGNvbnN0IFtzdGF0dXMsIHNldFN0YXR1c10gPSBSZWFjdC51c2VTdGF0ZSgnbG9hZGluZycpIC8vIGxvYWRpbmcgfCByZWZyZXNoaW5nIHwgcmVhZHkgfCBlcnJvclxuICBjb25zdCBbZGF0YSwgc2V0RGF0YV0gPSBSZWFjdC51c2VTdGF0ZShudWxsKVxuICBjb25zdCBbZXJyb3IsIHNldEVycm9yXSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpXG4gIGNvbnN0IFtwcmljZXMsIHNldFByaWNlc10gPSBSZWFjdC51c2VTdGF0ZSh7IHByaWNlczoge30sIGN1cnJlbmN5OiAnwqUnIH0pXG4gIC8vIOWxleekuuW4geenje+8muWuv+S4u+aMieWug+aNoueul+aIkOacrO+8jOaJgOS7peaNouW4geenjeW/hemhu+mHjeafpe+8m+mAieaLqeiusOWcqOacrOWcsO+8iOWxleekuuWBj+Wlve+8jFxuICAvLyDkuI3lhpnmj5Lku7borr7nva7vvIzlhY3lvpfmr4/mrKHlj5bmlbDpg73lnKjmlLnlhpnnlKjmiLfphY3nva7vvInjgIJcbiAgY29uc3QgW2Rpc3BsYXlDdXJyZW5jeSwgc2V0RGlzcGxheUN1cnJlbmN5XSA9IFJlYWN0LnVzZVN0YXRlKHJlYWRTdG9yZWRDdXJyZW5jeSlcbiAgLy8g5a6a5Lu35Yy56YWN5by556qX77ya5Y+q5Zyo6L+Z6YeM5byA552A77yM5YWz5o6J5Y2z5Y246L2977yI5a6D55qE5YaF6YOo54q25oCB6ZqP5LmL5Lii5byD77yMXG4gIC8vIOaJgOS7peOAjOS4jeehruWumuWwseS4jeeUn+aViOOAjeS4jemcgOimgemineWklua4heeQhumAu+i+ke+8ieOAglxuICBjb25zdCBbcHJpY2luZ09wZW4sIHNldFByaWNpbmdPcGVuXSA9IFJlYWN0LnVzZVN0YXRlKGZhbHNlKVxuICAvLyBQMS02IGJhY2tmaWxsIOi9ruivoueKtuaAge+8mnF1ZXJ5S2V5IOWPmOWMluaXtumHjee9ru+8jOS7heWvueWQjOS4gOafpeivouS4sui9ruivolxuICBjb25zdCBxdWVyeUtleVJlZiA9IFJlYWN0LnVzZVJlZihudWxsKVxuICBjb25zdCBiYWNrZmlsbFNlZW5SZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpXG4gIGNvbnN0IGZpbmFsUmVmcmVzaFJlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSlcbiAgLy8g6L2u6K+i6IqC5aWP77ya57uf6K6h56qX5Y+j55+t5YiZ5b+r6Zeu44CB6ZW/5YiZ5oWi6Zeu44CC5Zu65a6aIDMgcyDml7bvvIzmmpbnvJPlrZggfjAuOCBzIOWwsei3keWujO+8jFxuICAvLyDlrqLmiLfnq6/opoHnrYkgMyBzIOaJjeabtOaWsCDigJTigJQg6L+b5bqm5p2h5YWI6Lq6552A5YaN6Lez5LiA5qC877yM5q+U5rKh5pyJ5pu057Of44CCXG4gIGNvbnN0IHBvbGxTdGVwUmVmID0gUmVhY3QudXNlUmVmKDApXG4gIGNvbnN0IFBPTExfREVMQVlTID0gWzYwMCwgMTUwMCwgMzAwMF1cblxuICBjb25zdCBlZmYgPSBSZWFjdC51c2VNZW1vKCgpID0+IHJhbmdlRm9yKHJhbmdlLCBjdXN0b20pLCBbcmFuZ2UsIGN1c3RvbV0pXG4gIC8vIEZpeGVkIHN0ZXAgcG9saWN5OiB0b2RheSA9IGhvdXJseTsgN2QvMzBkL2N1c3RvbSA9IGRhaWx5LCBjdXN0b20gdXNlcyBhXG4gIC8vIHN0YWJsZSBzdGVwICgxLzMvNS83IGRheXMpIGNob3NlbiBieSB0aGUgcmFuZ2UgbGVuZ3RoLlxuICBjb25zdCBlZmZHcmFuID0gZWZmR3JhbnVsYXJpdHkocmFuZ2UpXG4gIGNvbnN0IHN0ZXBEYXlzID0gcmFuZ2UgPT09ICdjdXN0b20nID8gcGlja1N0ZXBEYXlzKChlZmYudG8gfHwgMCkgLSAoZWZmLmZyb20gfHwgMCkpIDogMVxuICBjb25zdCBncmFuTGFiZWwgPSBzdGVwTGFiZWwodCwgcmFuZ2UsIHN0ZXBEYXlzKVxuXG4gIC8vIOafpeivoue7n+iuoe+8iOmmlui9vemqqOaetu+8m+WIt+aWsOS/neeVmeaXp+aVsOaNrui9rCByZWZyZXNoaW5n77ybZmlsbCAwIOWhq+WFhSArIOW5tOW6pueDreWKm+Wbvu+8iVxuICAvLyBQMS0277yaYmFja2ZpbGwgcnVubmluZyDml7bmr48gM3Mg6Ieq5Yqo6YeN5p+l77ybZG9uZSDlkI7ooaXkuIDmrKHmlLblsL7mn6Xor6LljbPlgZzjgIJcbiAgUmVhY3QudXNlRWZmZWN0KCgpID0+IHtcbiAgICBsZXQgY3VycmVudCA9IHRydWVcbiAgICBsZXQgYmFja2ZpbGxUaW1lciA9IG51bGxcbiAgICBjb25zdCBxdWVyeUtleSA9IGVmZi5mcm9tICsgJ3wnICsgZWZmLnRvICsgJ3wnICsgbW9kZWxzLmpvaW4oJywnKSArICd8JyArIGVmZkdyYW4gKyAnfCcgKyBzdGVwRGF5cyArICd8JyArIGRpc3BsYXlDdXJyZW5jeVxuICAgIGlmIChxdWVyeUtleVJlZi5jdXJyZW50ICE9PSBxdWVyeUtleSkge1xuICAgICAgcXVlcnlLZXlSZWYuY3VycmVudCA9IHF1ZXJ5S2V5XG4gICAgICBiYWNrZmlsbFNlZW5SZWYuY3VycmVudCA9IGZhbHNlXG4gICAgICBmaW5hbFJlZnJlc2hSZWYuY3VycmVudCA9IGZhbHNlXG4gICAgICBwb2xsU3RlcFJlZi5jdXJyZW50ID0gMFxuICAgIH1cbiAgICBjb25zdCBpc0ZpbmFsUnVuID0gZmluYWxSZWZyZXNoUmVmLmN1cnJlbnRcbiAgICBmaW5hbFJlZnJlc2hSZWYuY3VycmVudCA9IGZhbHNlXG4gICAgc2V0U3RhdHVzKChzKSA9PiAocyA9PT0gJ3JlYWR5JyAmJiBkYXRhICE9PSBudWxsID8gJ3JlZnJlc2hpbmcnIDogJ2xvYWRpbmcnKSlcbiAgICBob3N0Q2FsbCgndXNhZ2UvcXVlcnknLCB7XG4gICAgICBmcm9tOiBlZmYuZnJvbSxcbiAgICAgIHRvOiBlZmYudG8sXG4gICAgICBtb2RlbHM6IG1vZGVscy5zbGljZSgpLFxuICAgICAgLy8g44CM5YWo6YOo44CN5LiN5YGa6Zu25aGr5YWF77ya55yf5a6e6L6555WM5piv6L6T5Ye65qG25pWw77yI5a6/5Li7IE1BWF9CVUNLRVRT77yJ77yM5LiN5piv5aSp5pWw44CCXG4gICAgICBmaWxsOiByYW5nZSAhPT0gJ2FsbCcsXG4gICAgICBncmFudWxhcml0eTogZWZmR3JhbixcbiAgICAgIHN0ZXBEYXlzLFxuICAgICAgaGVhdG1hcDogdHJ1ZSxcbiAgICAgIGN1cnJlbmN5OiBkaXNwbGF5Q3VycmVuY3ksXG4gICAgfSlcbiAgICAgIC50aGVuKChyKSA9PiB7XG4gICAgICAgIGlmICghY3VycmVudCkgcmV0dXJuXG4gICAgICAgIHNldERhdGEocilcbiAgICAgICAgc2V0U3RhdHVzKCdyZWFkeScpXG4gICAgICAgIHNldEVycm9yKG51bGwpXG4gICAgICAgIGNvbnN0IGJzID0gciAmJiByLmJhY2tmaWxsID8gci5iYWNrZmlsbC5zdGF0dXMgOiBudWxsXG4gICAgICAgIGlmIChicyA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgYmFja2ZpbGxTZWVuUmVmLmN1cnJlbnQgPSB0cnVlXG4gICAgICAgICAgLy8g5ZCM5LiAIGVmZmVjdCDoh7PlpJrmjILkuIDkuKrlrprml7blmajvvJvph43mn6XlpI3nlKggcmV0cnkg6K6h5pWw5Zmo6Kem5Y+RIGVmZmVjdCDph43ot5HjgIJcbiAgICAgICAgICAvLyDlhYjlv6vlkI7mhaLvvJo2MDAgbXMg6LW35q2l6IO96Lef5LiKIDAuOCBzIOeahOaalue8k+WtmOeql+WPo++8jOmVv+S7u+WKoeWGjemAgOWIsCAzIHPvvIxcbiAgICAgICAgICAvLyDkuI3oh7Pkuo7miorlrr/kuLvpl67miJDljovlipvmtYvor5XjgIJcbiAgICAgICAgICBjb25zdCBkZWxheSA9IFBPTExfREVMQVlTW01hdGgubWluKHBvbGxTdGVwUmVmLmN1cnJlbnQsIFBPTExfREVMQVlTLmxlbmd0aCAtIDEpXVxuICAgICAgICAgIHBvbGxTdGVwUmVmLmN1cnJlbnQgKz0gMVxuICAgICAgICAgIGJhY2tmaWxsVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50KSBzZXRSZXRyeSgodikgPT4gdiArIDEpXG4gICAgICAgICAgfSwgZGVsYXkpXG4gICAgICAgIH0gZWxzZSBpZiAoYnMgPT09ICdkb25lJyAmJiBiYWNrZmlsbFNlZW5SZWYuY3VycmVudCAmJiAhaXNGaW5hbFJ1bikge1xuICAgICAgICAgIC8vIOWbnuWhq+aUtuWwvu+8muaBsOWlveWGjeafpeS4gOasoeaLv+WIsOWujOaVtOaVsOaNruWQjuWBnOatolxuICAgICAgICAgIGZpbmFsUmVmcmVzaFJlZi5jdXJyZW50ID0gdHJ1ZVxuICAgICAgICAgIHNldFJldHJ5KCh2KSA9PiB2ICsgMSlcbiAgICAgICAgfVxuICAgICAgfSwgKGUpID0+IHtcbiAgICAgICAgaWYgKCFjdXJyZW50KSByZXR1cm5cbiAgICAgICAgc2V0RXJyb3IoZSlcbiAgICAgICAgc2V0U3RhdHVzKCdlcnJvcicpXG4gICAgICB9KVxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjdXJyZW50ID0gZmFsc2VcbiAgICAgIGlmIChiYWNrZmlsbFRpbWVyICE9PSBudWxsKSBjbGVhclRpbWVvdXQoYmFja2ZpbGxUaW1lcilcbiAgICB9XG4gIH0sIFtlZmYuZnJvbSwgZWZmLnRvLCBtb2RlbHMsIGVmZkdyYW4sIHN0ZXBEYXlzLCBkaXNwbGF5Q3VycmVuY3ksIHJldHJ5XSlcblxuICAvLyDku7fmoLzooajvvJrov5vlhaXpobXpnaLmi4nkuIDmrKEgKyDmr4/mrKHliLfmlrDlkIzmraXjgIJcbiAgLy8gUDAtMe+8muS8mOWFiOWumOaWuSBzZXR0aW5ncyBzY29wZe+8iHVzYWdlLnByaWNlcyDlkb3lkI3nqbrpl7TvvInvvIzkuI3lj6/nlKjml7blm57pgIAgUlBD44CCXG4gIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgbGV0IGN1cnJlbnQgPSB0cnVlXG4gICAgbGV0IHNjb3BlRGlzcG9zZSA9IG51bGxcbiAgICBjb25zdCBsb2FkUnBjID0gKCkgPT4ge1xuICAgICAgaG9zdENhbGwoJ3VzYWdlL3ByaWNlcycpLnRoZW4oKHApID0+IHtcbiAgICAgICAgaWYgKGN1cnJlbnQgJiYgcCAmJiBwLnByaWNlcykgc2V0UHJpY2VzKHApXG4gICAgICB9LCAoKSA9PiB7fSlcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHNjb3BlID0gZ2V0VXNhZ2VQcmljZXNTY29wZSgpXG4gICAgICBpZiAoc2NvcGUgJiYgdHlwZW9mIHNjb3BlLmdldFNuYXBzaG90ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBzY29wZS5zdWJzY3JpYmUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgbGV0IGFkb3B0ZWQgPSBmYWxzZVxuICAgICAgICBjb25zdCBhZG9wdCA9ICgpID0+IHtcbiAgICAgICAgICBpZiAoIWN1cnJlbnQpIHJldHVyblxuICAgICAgICAgIGNvbnN0IHNuYXAgPSBzY29wZS5nZXRTbmFwc2hvdCgpXG4gICAgICAgICAgY29uc3QgdiA9IHNuYXAgJiYgc25hcC52YWx1ZVxuICAgICAgICAgIGlmIChzbmFwICYmIHNuYXAuc3RhdHVzID09PSAndW5hdmFpbGFibGUnKSByZXR1cm5cbiAgICAgICAgICBpZiAodiAmJiAodi5wcmljZXMgfHwgdi5jdXJyZW5jeSkpIHtcbiAgICAgICAgICAgIGFkb3B0ZWQgPSB0cnVlXG4gICAgICAgICAgICBzZXRQcmljZXMoeyBwcmljZXM6IHYucHJpY2VzIHx8IHt9LCBjdXJyZW5jeTogdi5jdXJyZW5jeSB8fCAnwqUnIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGFkb3B0KClcbiAgICAgICAgc2NvcGVEaXNwb3NlID0gc2NvcGUuc3Vic2NyaWJlKGFkb3B0KVxuICAgICAgICBpZiAoIWFkb3B0ZWQpIGxvYWRScGMoKSAvLyBzY29wZSDmnKrlsLHnu6ov5peg5YC877ya5YWI6LWwIFJQQ++8jOiuoumYheWwsee7quWQjiBzY29wZSDkvJjlhYjopobnm5ZcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvYWRScGMoKVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvYWRScGMoKSAvLyDmjqLmtYsv57uR5a6a5byC5bi477ya5a6M5pW05Zue6YCAIFJQQ++8jOe7neS4jeaKm+WHulxuICAgIH1cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgY3VycmVudCA9IGZhbHNlXG4gICAgICBpZiAoc2NvcGVEaXNwb3NlKSB7XG4gICAgICAgIHRyeSB7IHNjb3BlRGlzcG9zZSgpIH0gY2F0Y2ggKGUpIHt9XG4gICAgICB9XG4gICAgfVxuICB9LCBbcmV0cnldKVxuXG4gIGNvbnN0IHJlbG9hZCA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHNldFJldHJ5KCh2KSA9PiB2ICsgMSksIFtdKVxuXG4gIGNvbnN0IHJlc2V0RmlsdGVycyA9IFJlYWN0LnVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzZXRNb2RlbHMoW10pXG4gICAgc2V0Q3VzdG9tKGRlZmF1bHRDdXN0b20oKSlcbiAgICBzZXRSYW5nZSgndG9kYXknKVxuICB9LCBbXSlcblxuICBjb25zdCBjaGFuZ2VDdXJyZW5jeSA9IFJlYWN0LnVzZUNhbGxiYWNrKChjb2RlKSA9PiB7XG4gICAgc3RvcmVDdXJyZW5jeShjb2RlKVxuICAgIHNldERpc3BsYXlDdXJyZW5jeShjb2RlKVxuICB9LCBbXSlcbiAgLy8g56ym5Y+35Lul5a6/5Li75Zue5Lyg55qE5a6e6ZmF5biB56eN5Li65YeG77yI5YiH5o2i5ZCO56uL5Yi76YeN5p+l77yM5LiN5Lya5Ye6546w44CM5o2i5LqG5qCH5b+X5rKh5o2i5pWw5a2X44CN77yJ77ybXG4gIC8vIOiAgeWuv+S4u+ayoeacieivpeWtl+auteaXtuaMieacrOWcsOmAieaLqeWFnOW6leOAglxuICBjb25zdCBjdXJyZW5jeVN5bWJvbCA9IChkYXRhICYmIGRhdGEuY3VycmVuY3kgJiYgZGF0YS5jdXJyZW5jeS5zeW1ib2wpXG4gICAgfHwgQ1VSUkVOQ1lfU1lNQk9MU1tkaXNwbGF5Q3VycmVuY3ldIHx8IHByaWNlcy5jdXJyZW5jeSB8fCAnwqUnXG5cbiAgY29uc3QgYnVzeSA9IHN0YXR1cyA9PT0gJ2xvYWRpbmcnIHx8IHN0YXR1cyA9PT0gJ3JlZnJlc2hpbmcnXG4gIGNvbnN0IHJlYWR5ID0gZGF0YSAhPT0gbnVsbFxuICBjb25zdCBpc0Vycm9yID0gc3RhdHVzID09PSAnZXJyb3InXG4gIGNvbnN0IGlzRW1wdHkgPSByZWFkeSAmJiBkYXRhLmRhaWx5Lmxlbmd0aCA9PT0gMCAmJiBkYXRhLmJ5TW9kZWwubGVuZ3RoID09PSAwXG4gIC8vIFwi57uf6K6h5rKh566X5a6MXCLvvJrlrr/kuLvov5jlnKjlm57loavljoblj7LvvIhiYWNrZmlsbC5zdGF0dXMgPT09ICdydW5uaW5nJ++8ieOAglxuICAvLyDlroPmr5QgYnVzeSDplb/lvpflpJrvvIjlhajph48gMjU4IOS4quS8muivneimgeWHoOenku+8ie+8jOaJgOS7pei/m+W6puadoeS4juaWh+ahiOmDveS7peWug+S4uuWHhu+8m1xuICAvLyDor7fmsYLlnKjpo57vvIhidXN577yJ5Y+q5piv5Yi35paw77yM5LiN6K+l6KKr5b2T5oiQXCLlnKjnrpdcIuOAglxuICBjb25zdCBiYWNrZmlsbCA9IChkYXRhICYmIGRhdGEuYmFja2ZpbGwpIHx8IG51bGxcbiAgY29uc3QgY29tcHV0aW5nID0gQm9vbGVhbihiYWNrZmlsbCAmJiBiYWNrZmlsbC5zdGF0dXMgPT09ICdydW5uaW5nJylcbiAgY29uc3QgY29tcHV0ZVRvdGFsID0gKGJhY2tmaWxsICYmIGJhY2tmaWxsLnRvdGFsKSB8fCAwXG4gIGNvbnN0IGNvbXB1dGVEb25lID0gKGJhY2tmaWxsICYmIGJhY2tmaWxsLmRvbmUpIHx8IDBcbiAgY29uc3QgY29tcHV0ZVBjdCA9IGNvbXB1dGluZyAmJiBjb21wdXRlVG90YWwgPiAwXG4gICAgPyBNYXRoLm1pbigxMDAsIE1hdGgucm91bmQoKGNvbXB1dGVEb25lIC8gY29tcHV0ZVRvdGFsKSAqIDEwMCkpXG4gICAgOiBudWxsXG4gIGNvbnN0IHNob3dQcm9ncmVzcyA9IGNvbXB1dGluZyB8fCAoYnVzeSAmJiByZWFkeSAmJiAhaXNFcnJvcilcblxuICByZXR1cm4gaChULlByb3ZpZGVyLCB7IHZhbHVlOiB0IH0sXG4gICAgaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2Qtc2VjdGlvbicsICdhcmlhLWJ1c3knOiBidXN5IHx8IGNvbXB1dGluZyB8fCB1bmRlZmluZWQgfSxcbiAgICAvLyDpppblsY/otbDlkI7pqqjmnrblsY/vvIjop4EgTG9hZGluZ1N0YXRl77yJ77yb6L+Z6YeM566hXCLmnInmlbDmja7kvYbmsqHnrpflroxcIuS4jlwi5q2j5Zyo5Yi35pawXCLvvJpcbiAgICAvLyDkuIDmnaEgMnB4IOeahOe7hui/m+W6puadoe+8jOe7neWvueWumuS9je+8jOS4jeaOqOWKqOeJiOmdouS5n+S4jeeisOS7u+S9leaVsOWtl+OAglxuICAgIC8vIOeul+W+l+WujOeahOaXtuWAmeWug+aYr+ehruWumui/m+W6pu+8iOWuveW6piA9IGRvbmUvdG90YWzvvInvvIzlkKbliJnmmK/kuI3noa7lrprmiavliqjjgIJcbiAgICBzaG93UHJvZ3Jlc3NcbiAgICAgID8gaCgnZGl2Jywge1xuICAgICAgICAgIGNsYXNzTmFtZTogJ3RzZC1wcm9ncmVzcycsXG4gICAgICAgICAgJ2FyaWEtaGlkZGVuJzogJ3RydWUnLFxuICAgICAgICAgICdkYXRhLWRldGVybWluYXRlJzogY29tcHV0ZVBjdCA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6ICd0cnVlJyxcbiAgICAgICAgICBzdHlsZTogY29tcHV0ZVBjdCA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IHsgJy0tdHNkLXByb2dyZXNzJzogY29tcHV0ZVBjdCArICclJyB9LFxuICAgICAgICB9KVxuICAgICAgOiBudWxsLFxuICAgIGgoU3RhdHNIZWFkZXIsIHtcbiAgICAgIGJ1c3ksXG4gICAgICBjb21wdXRpbmcsXG4gICAgICBjb21wdXRlRG9uZSxcbiAgICAgIGNvbXB1dGVUb3RhbCxcbiAgICAgIG9uUmVmcmVzaDogcmVsb2FkLFxuICAgIH0pLFxuICAgIGgoRmlsdGVyQmFyLCB7XG4gICAgICByYW5nZSxcbiAgICAgIGN1c3RvbSxcbiAgICAgIG1vZGVscyxcbiAgICAgIGN1c3RvbU9wZW4sXG4gICAgICBtb2RlbE9wdGlvbnM6IGRhdGEgPyBkYXRhLm1vZGVscyA6IFtdLFxuICAgICAgb25QcmVzZXQ6IChwKSA9PiB7IHNldFJhbmdlKHApOyBzZXRDdXN0b21PcGVuKGZhbHNlKSB9LFxuICAgICAgb25DdXN0b21PcGVuOiAob3BlbikgPT4geyBzZXRSYW5nZSgnY3VzdG9tJyk7IHNldEN1c3RvbU9wZW4ob3BlbikgfSxcbiAgICAgIG9uQ3VzdG9tQXBwbHk6IChjKSA9PiB7IHNldEN1c3RvbShjKTsgc2V0Q3VzdG9tT3BlbihmYWxzZSkgfSxcbiAgICAgIG9uQ3VzdG9tQ2xvc2U6ICgpID0+IHNldEN1c3RvbU9wZW4oZmFsc2UpLFxuICAgICAgb25Nb2RlbHNDaGFuZ2U6IHNldE1vZGVscyxcbiAgICB9KSxcbiAgICBpc0Vycm9yICYmICFyZWFkeVxuICAgICAgPyBoKEVycm9yU3RhdGUsIHsgZXJyb3IsIG9uUmV0cnk6IHJlbG9hZCB9KVxuICAgICAgOiBudWxsLFxuICAgIC8vICoq5LuOIERTSCDlkK/liqjliLDnu5/orqHnrpflrozvvIzmlbTmrrXpg73mmK/liqDovb3mgIHjgIIqKlxuICAgIC8vIOimhuebluS4pOenjVwi6L+Y5rKh5Lic6KW/5Y+v55yLXCLvvJpcbiAgICAvLyAg4pGgIOmmluWxj+ivt+axgui/mOayoeWbnuadpe+8iCFyZWFkee+8ie+8m1xuICAgIC8vICDikaEg5a6/5Li76L+Y5Zyo5Zue5aGr5Y6G5Y+y77yIY29tcHV0aW5n77yJ4oCU4oCUIOWTquaAleaYr+esrOS6jOasoei/m+adpeOAgeaJi+mHjOW3sue7j+acieWNiuS7veaVsOaNruOAglxuICAgIC8vIOWNiuS7veaVsOWtl+avlOmqqOaetuabtOivr+WvvO+8muWug+eci+i1t+adpeWDj1wi5L2g5Y+q5pyJ6L+Z5LmI5aSa55So6YePXCLvvIzogIzkuJTkvJrkuIDmoLzkuIDmoLzlvoDkuIrniKzjgIJcbiAgICAvLyDov5nkuZ/mraPmmK/jgIzmlbDlrZfkuIDngrnngrnlvoDkuIrniKzjgI3pgqPkuKrmirHmgKjnmoTmnaXmupDvvIzmiYDku6XlroHlj6/nrYnvvIzkuZ/kuI3opoHnu5nmrovnvLrnmoTnrZTmoYjjgIJcbiAgICAoIXJlYWR5IHx8IGNvbXB1dGluZykgJiYgIWlzRXJyb3JcbiAgICAgID8gaChMb2FkaW5nU3RhdGUsIHsgYW5ub3VuY2U6ICFjb21wdXRpbmcgfSlcbiAgICAgIDogbnVsbCxcbiAgICByZWFkeSAmJiBpc0Vycm9yXG4gICAgICA/IGgoJ2RpdicsIHsgY2xhc3NOYW1lOiAndHNkLWFsZXJ0LWJhbm5lcicsIHJvbGU6ICdhbGVydCcgfSxcbiAgICAgICAgICBoKCdzcGFuJywgbnVsbCwgdCgnbG9hZEZhaWxlZCcsIHsgbWVzc2FnZTogU3RyaW5nKChlcnJvciAmJiBlcnJvci5tZXNzYWdlKSB8fCBlcnJvcikgfSkpLFxuICAgICAgICAgIGgoJ2J1dHRvbicsIHsgdHlwZTogJ2J1dHRvbicsIGNsYXNzTmFtZTogJ3RzZC1idG4gdHNkLWJ0bi1naG9zdCcsIG9uQ2xpY2s6IHJlbG9hZCB9LCB0KCdyZXRyeScpKSlcbiAgICAgIDogbnVsbCxcbiAgICAvLyDnqbrmgIHlj6rlnKhcIuehruWunueul+WujOS6hui/mOayoeacieiusOW9lVwi5pe25Ye6546w44CC57uf6K6h5Lit5LiN6JC95Yiw56m65oCB44CCXG4gICAgcmVhZHkgJiYgIWlzRXJyb3IgJiYgaXNFbXB0eSAmJiAhY29tcHV0aW5nXG4gICAgICA/IGgoRW1wdHlTdGF0ZSwgeyBmaWx0ZXJlZDogbW9kZWxzLmxlbmd0aCA+IDAsIG9uUmVzZXQ6IHJlc2V0RmlsdGVycyB9KVxuICAgICAgOiBudWxsLFxuICAgIC8vIOaVsOaNruWMuuWQjOeQhu+8mueul+WujOS5i+WJjeS4jea4suafk++8jOWFjeW+l+aui+e8uuaVsOWtl+WFiOWHuueOsOWGjei3s+WPmOOAglxuICAgIHJlYWR5ICYmICFpc0Vycm9yICYmICFpc0VtcHR5ICYmICFjb21wdXRpbmdcbiAgICAgID8gaCgnZGl2JywgeyBjbGFzc05hbWU6ICd0c2QtY29udGVudCcgfSxcbiAgICAgICAgICBoKFN1bW1hcnlDYXJkcywge1xuICAgICAgICAgICAgdG90YWw6IGRhdGEudG90YWwsXG4gICAgICAgICAgICBjdXJyZW5jeTogY3VycmVuY3lTeW1ib2wsXG4gICAgICAgICAgICB1bnByaWNlZENhbGxzOiBkYXRhLnVucHJpY2VkQ2FsbHMgfHwgMCxcbiAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogZGlzcGxheUN1cnJlbmN5LFxuICAgICAgICAgICAgb25DdXJyZW5jeUNoYW5nZTogY2hhbmdlQ3VycmVuY3ksXG4gICAgICAgICAgICBieU1vZGVsOiBkYXRhLmJ5TW9kZWwsXG4gICAgICAgICAgICBwcmljaW5nOiBkYXRhLnByaWNpbmcsXG4gICAgICAgICAgICBvbk9wZW5QcmljaW5nOiAoKSA9PiBzZXRQcmljaW5nT3Blbih0cnVlKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBoKERhaWx5Q2hhcnQsIHtcbiAgICAgICAgICAgIGRhaWx5OiBkYXRhLmRhaWx5LFxuICAgICAgICAgICAgZ3JhbjogZWZmR3JhbixcbiAgICAgICAgICAgIHN0ZXBEYXlzLFxuICAgICAgICAgICAgZ3JhbkxhYmVsLFxuICAgICAgICAgICAgY3VycmVuY3k6IGN1cnJlbmN5U3ltYm9sLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGgoSGVhdG1hcENhcmQsIHsgZGF5czogZGF0YS5oZWF0bWFwIHx8IFtdLCBjdXJyZW5jeTogY3VycmVuY3lTeW1ib2wgfSksXG4gICAgICAgICAgaChNb2RlbFRhYmxlLCB7IHJvd3M6IGRhdGEuYnlNb2RlbCwgY3VycmVuY3k6IGN1cnJlbmN5U3ltYm9sIH0pKVxuICAgICAgOiBudWxsLFxuICAgIHByaWNpbmdPcGVuXG4gICAgICA/IGgoUHJpY2luZ0RpYWxvZywge1xuICAgICAgICAgIGN1cnJlbmN5OiB7IGNvZGU6IGRpc3BsYXlDdXJyZW5jeSwgc3ltYm9sOiBjdXJyZW5jeVN5bWJvbCB9LFxuICAgICAgICAgIG9uQ2xvc2U6ICgpID0+IHNldFByaWNpbmdPcGVuKGZhbHNlKSxcbiAgICAgICAgICAvLyDnoa7lrprlkI7ph43mn6XkuIDmrKHvvJrljLnphY3mlLnkuobvvIzljaHniYfkuIrnmoTmlbDlrZflv4Xpobvot5/nnYDlj5jvvIzlkKbliJnnlKjmiLfkvJrku6XkuLrmsqHkv53lrZjmiJDlip/jgIJcbiAgICAgICAgICBvbkFwcGxpZWQ6IHJlbG9hZCxcbiAgICAgICAgfSlcbiAgICAgIDogbnVsbCkpXG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICog6K6+572u6aG15a+86Iiq5Zu+5qCHXG4gKlxuICog5Y6f55Sf56Gu5a6e5rKh5pyJ6L+Z5Liq5o+S5Y+jIOKAlOKAlCDlj5bor4Hov4fnmoTvvIzkuI3mmK9cIuaIkeinieW+l1wi77yaXG4gKiAgIMK3IOWumOaWueiuvue9rumhteaKiiBgc2V0dGluZ3Muc2VjdGlvbmAg55qE5p2h55uu5oqV5b2x5oiQIGB7aWQsIG9yZGVyLCBsYWJlbH1gIOS4ieWtl+aute+8jFxuICogICAgIOayoeaciSBpY29u77yIYEBkZWVwc2Vlay1haS9kc2gtY2xpZW50LXVpLXNldHRpbmdzLWdlbmVyYWxgIOeahCBuYXYgcm93c1xuICogICAgIGdldFNuYXBzaG9077yaYGN0eC5zbG90cy5lbnRyaWVzKFwic2V0dGluZ3Muc2VjdGlvblwiKS5tYXAoZSA9PiAoe2lkLCBvcmRlcixcbiAqICAgICBsYWJlbDogcmVzb2x2ZVNsb3RMYWJlbChlLm9wdGlvbnMubGFiZWwpfSkpYO+8ie+8m1xuICogICDCtyDlm77moIfnlLHor6XljIXoh6rlt7HnmoQgYG5hdkljb24oaWQpYCDmjIkgaWQg55m95ZCN5Y2V6YCJ77yM5pyq5YiX5Ye655qEIGlkIOWbnuiQveWIsOiuvue9rum9v+i9rlxuICogICAgIO+8iOWQjOWMhSBgZnVuY3Rpb24gbmF2SWNvbihpZClg77yM5YW25rOo6YeK5Y6f5paHIFwidW5rbm93biBpZHMgZmFsbCBiYWNrIHRvIHRoZVxuICogICAgIHNldHRpbmdzIGdlYXJcIu+8ieOAglxuICog5omA5Lul56ys5LiJ5pa55Y+q6IO957uZ6Ieq5bex55qE6YKj5LiA6KGM5omT5bGe5oCn5qCH6K6w44CB55SoIENTUyBtYXNrIOaNouWtl+W9ou+8muS4jeabv+aNouiKgueCueOAgeS4jeeisFxuICogUmVhY3Qg566h55qEIHN2Z++8iOabv+aNouS8muiuqSBSZWFjdCDljbjovb3ml7bmipsgTm90Rm91bmRFcnJvcu+8ie+8jOWPquWKoOWxnuaAp+OAgeWPqueUqCA6OmJlZm9yZVxuICog55S75a2X5b2i44CC5a6Y5pa55LiA5pem57uZIGBzZXR0aW5ncy5zZWN0aW9uYCDliqDkuIogaWNvbiDlrZfmrrXvvIzov5nkuKrmqKHlnZflupTmlbTkvZPliKDpmaQg4oCU4oCUXG4gKiDpgqPml7blroPmmK/lj6/lvJXnlKjnmoQgTDDvvIzkuI3or6Xlho3nlZkgTDIg6KGl57y644CCXG4gKlxuICog6K6k6KGM5Y+q6IO95oyJ5Y+v6KeB5paH5pys77ya57G75ZCN5pivIENTUyBNb2R1bGVzIOWTiOW4jO+8jOi0puWPt+ihjOi/mOS8muadoeS7tuWHuueOsOOAglxuICog5a6Y5pa55LiA5pem57uZIHNldHRpbmdzLnNlY3Rpb24g5Yqg5LiKIGljb24g5a2X5q6177yM6L+Z5Liq5qih5Z2X5bqU5pW05L2T5Yig6Zmk44CCXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5jb25zdCBOQVZfSUNPTl9NQVNLID0gJ2RhdGE6aW1hZ2Uvc3ZnK3htbDtjaGFyc2V0PXV0Zi04LCcgKyBlbmNvZGVVUklDb21wb25lbnQoXG4gICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCI+J1xuICArICc8cmVjdCB4PVwiMi41XCIgeT1cIjlcIiB3aWR0aD1cIjIuNVwiIGhlaWdodD1cIjVcIiByeD1cIjFcIi8+J1xuICArICc8cmVjdCB4PVwiNi43NVwiIHk9XCI1LjVcIiB3aWR0aD1cIjIuNVwiIGhlaWdodD1cIjguNVwiIHJ4PVwiMVwiLz4nXG4gICsgJzxyZWN0IHg9XCIxMVwiIHk9XCIyLjVcIiB3aWR0aD1cIjIuNVwiIGhlaWdodD1cIjExLjVcIiByeD1cIjFcIi8+PC9zdmc+Jyxcbilcbi8vIG1hc2sg5Y+q6K+7IGFscGhhIOmAmumBk++8jOaJgOS7peWtl+W9ouW/hemhu+aYr+e6r+iJsuWunuW/g++8iGljb24uc3ZnIOeahOa4kOWPmOS4juWNiumAj+aYjuWcqOi/memHjOS8muS4ou+8iVxuY29uc3QgTkFWX0lDT05fQ1NTID0gW1xuICAnW2RhdGEtdHNkLW5hdl0gPiBzdmcgeyBkaXNwbGF5OiBub25lOyB9JyxcbiAgJ1tkYXRhLXRzZC1uYXZdOjpiZWZvcmUgeycsXG4gIFwiICBjb250ZW50OiAnJztcIixcbiAgJyAgZmxleDogbm9uZTsnLFxuICAnICB3aWR0aDogMTZweDsnLFxuICAnICBoZWlnaHQ6IDE2cHg7JyxcbiAgJyAgYmFja2dyb3VuZDogY3VycmVudENvbG9yOycsXG4gICcgIC13ZWJraXQtbWFzay1pbWFnZTogdXJsKFwiJyArIE5BVl9JQ09OX01BU0sgKyAnXCIpOycsXG4gICcgIG1hc2staW1hZ2U6IHVybChcIicgKyBOQVZfSUNPTl9NQVNLICsgJ1wiKTsnLFxuICAnICAtd2Via2l0LW1hc2stc2l6ZTogMTZweCAxNnB4OycsXG4gICcgIG1hc2stc2l6ZTogMTZweCAxNnB4OycsXG4gICcgIC13ZWJraXQtbWFzay1yZXBlYXQ6IG5vLXJlcGVhdDsnLFxuICAnICBtYXNrLXJlcGVhdDogbm8tcmVwZWF0OycsXG4gICd9Jyxcbl0uam9pbignXFxuJylcblxuLyoqIOiupOS4jeWHuuihjOOAgeaLv+S4jeWIsCBET03vvIzpg73lj6rmmK/pgIDljJbmiJDpvb/ova7vvIznu53kuI3mipvlh7rjgILov5Tlm54gZGlzcG9zZXLjgIIgKi9cbmZ1bmN0aW9uIGluc3RhbGxTZXR0aW5nc05hdkljb24obGFiZWwpIHtcbiAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIE11dGF0aW9uT2JzZXJ2ZXIgIT09ICdmdW5jdGlvbicpIHJldHVybiBudWxsXG4gIGxldCBzdHlsZUVsID0gbnVsbFxuICB0cnkge1xuICAgIHN0eWxlRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpXG4gICAgc3R5bGVFbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtcGx1Z2luJywgJ2RzaC1wbHVnaW4tdXNhZ2UnKVxuICAgIHN0eWxlRWwudGV4dENvbnRlbnQgPSBOQVZfSUNPTl9DU1NcbiAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlRWwpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dXYXJuKCdbdXNhZ2VdIHNldHRpbmdzIG5hdiBpY29uOiBzdHlsZXMgdW5hdmFpbGFibGUnKVxuICAgIHJldHVybiBudWxsXG4gIH1cbiAgY29uc3QgbWFyayA9ICgpID0+IHtcbiAgICBjb25zdCByb3dzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW3JvbGU9XCJkaWFsb2dcIl0gYnV0dG9uJylcbiAgICBjb25zdCB3YW50ID0gbGFiZWwoKVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgcm93ID0gcm93c1tpXVxuICAgICAgaWYgKHJvdy5nZXRBdHRyaWJ1dGUoJ2RhdGEtdHNkLW5hdicpICE9PSBudWxsKSBjb250aW51ZVxuICAgICAgaWYgKCFyb3cucXVlcnlTZWxlY3Rvcignc3ZnJykpIGNvbnRpbnVlIC8vIOWPquagh+W4puWbvuagh+eahOWvvOiIquihjO+8jOWIq+ivr+agh+aZrumAmuaMiemSrlxuICAgICAgaWYgKChyb3cudGV4dENvbnRlbnQgfHwgJycpLnRyaW0oKSAhPT0gd2FudCkgY29udGludWVcbiAgICAgIHJvdy5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHNkLW5hdicsICcnKVxuICAgIH1cbiAgfVxuICBsZXQgb2JzZXJ2ZXIgPSBudWxsXG4gIHRyeSB7XG4gICAgbWFyaygpXG4gICAgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcigoKSA9PiB7IHRyeSB7IG1hcmsoKSB9IGNhdGNoIChlKSB7fSB9KVxuICAgIG9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQuYm9keSwgeyBjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IHRydWUgfSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZ1dhcm4oJ1t1c2FnZV0gc2V0dGluZ3MgbmF2IGljb246IG9ic2VydmVyIHVuYXZhaWxhYmxlJywgZSlcbiAgfVxuICByZXR1cm4gKCkgPT4ge1xuICAgIGlmIChvYnNlcnZlcikgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpXG4gICAgaWYgKHN0eWxlRWwpIHN0eWxlRWwucmVtb3ZlKClcbiAgICBjb25zdCBtYXJrZWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS10c2QtbmF2XScpXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXJrZWQubGVuZ3RoOyBpKyspIG1hcmtlZFtpXS5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtdHNkLW5hdicpXG4gIH1cbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDovpPlhaXljLrmiJDmnKwgcGlsbO+8iGNvbXBvc2VyIGRvY2vvvIlcbiAqXG4gKiBEU0ggMC4yLjEtcmMuMSDmiorovpPlhaXljLrnu5/orqHmi4bmiJAgYGFjdGl2aXR5YCAvIGB1c2FnZWAg5Lik5LiqIGNvbXBvc2VyIGRvY2sg5p2h55uu77yMXG4gKiDlrr/kuLvoh6rlt7HnmoQgYHVzYWdlYCBwaWxsIOaYvuekuiB0b2tlbiDmlbDvvIjor7vlrpjmlrkgYHRva2VuVXNhZ2VgIOaKleW9se+8ieOAguWumOaWueaKleW9seWPquaciVxuICog5Lya6K+d5YaF5ZCI6K6h44CBKirkuI3luKbmqKHlnovlvZLlm6AqKu+8jOiAjOaIkOacrOW/hemhu+aMieaooeWei+WNleS7t+eul++8iOacrOaPkuS7tuiHqiB2MC4zIOi1t+WdmuaMgVxuICog5LiN5re35Lu377yJ77yM5omA5Lul6L+Z6YeM5LiN6LWw5oqV5b2x77yM5pS56LWw5pys5o+S5Lu26Ieq5bex55qEIGBxdWVyeWDvvJrorrDlvZXph4zluKYgcHJvdmlkZXIvbW9kZWzvvIxcbiAqIOWuv+S4u+S+p+aMieaooeWei+eyvuehruiuoeS7t+OAglxuICpcbiAqIOWPo+W+hOWPluOAjOS7iuaXpeOAjeiAjOS4jeaYr+OAjOacrOS8muivneOAje+8mmRvY2sg5p2h55uu5ou/5LiN5Yiw5Lya6K+d5qCH6K+G77yI5a6/5Li75riy5p+T6L+Z5LiqIHNsb3Qg5pe2XG4gKiDmmK8gYHJlbmRlclNsb3QoXCJjb252ZXJzYXRpb24uY29tcG9zZXIuZG9ja1wiLCB7fSlg77yM5LiN5LygIHByb3Bz77yJ77yM6ICM5LuK5pel5oiQ5pys5LiOXG4gKiDlrr/kuLvnmoQgdG9rZW4gcGlsbCDmraPlpb3kupLooaXjgIJcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmNvbnN0IERPQ0tfUkVGUkVTSF9NUyA9IDMwMDAwXG4vKiog5Zue5aGr77yIYmFja2ZpbGzvvInov5vooYzkuK3nmoTlv6vph43or5Xpl7TpmpTvvIzkuI7orr7nva7pobXkuIDoh7TjgIIgKi9cbmNvbnN0IERPQ0tfQkFDS0ZJTExfUkVUUllfTVMgPSAzMDAwXG5cbmZ1bmN0aW9uIENvc3RQaWxsKHByb3BzKSB7XG4gIGNvbnN0IHRyID0gcHJvcHMgJiYgdHlwZW9mIHByb3BzLnQgPT09ICdmdW5jdGlvbicgPyBwcm9wcy50IDogZmFsbGJhY2tUXG4gIGNvbnN0IFtzdGF0ZSwgc2V0U3RhdGVdID0gUmVhY3QudXNlU3RhdGUoeyBzdGF0dXM6ICdsb2FkaW5nJyB9KVxuICBSZWFjdC51c2VFZmZlY3QoKCkgPT4ge1xuICAgIGxldCBhbGl2ZSA9IHRydWVcbiAgICBsZXQgdGltZXIgPSBudWxsXG4gICAgY29uc3Qgc2NoZWR1bGUgPSAobXMpID0+IHtcbiAgICAgIGlmICh0aW1lciAhPT0gbnVsbCkgY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KGxvYWQsIG1zKVxuICAgIH1cbiAgICBjb25zdCBsb2FkID0gKCkgPT4ge1xuICAgICAgaWYgKCFhbGl2ZSkgcmV0dXJuXG4gICAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpXG4gICAgICBob3N0Q2FsbCgndXNhZ2UvcXVlcnknLCB7XG4gICAgICAgIGZyb206IHN0YXJ0T2ZEYXkobm93KS5nZXRUaW1lKCksXG4gICAgICAgIHRvOiBub3cuZ2V0VGltZSgpLFxuICAgICAgICAvLyDjgIzku4rml6XjgI3mmK/mnInpmZDljLrpl7TvvIzkvYbkuI3pnIDpm7bloavlhYXvvJrnqbrmobblr7nmiJDmnKzmsqHmhI/kuYnjgIJcbiAgICAgICAgZmlsbDogZmFsc2UsXG4gICAgICAgIGdyYW51bGFyaXR5OiAnZGF5JyxcbiAgICAgICAgY3VycmVuY3k6IHJlYWRTdG9yZWRDdXJyZW5jeSgpLFxuICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHIpID0+IHtcbiAgICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm5cbiAgICAgICAgICBjb25zdCB0b3RhbCA9IChyICYmIHIudG90YWwpIHx8IG51bGxcbiAgICAgICAgICBzZXRTdGF0ZSh7XG4gICAgICAgICAgICBzdGF0dXM6ICdyZWFkeScsXG4gICAgICAgICAgICBjYWxsczogdG90YWwgPyB0b3RhbC5jYWxscyA6IDAsXG4gICAgICAgICAgICB0b2tlbnM6IHRvdGFsID8gdG90YWwudG90YWxUb2tlbnMgOiAwLFxuICAgICAgICAgICAgY29zdDogdG90YWwgPyB0b3RhbC5jb3N0IDogMCxcbiAgICAgICAgICAgIHN5bWJvbDogKHIgJiYgci5jdXJyZW5jeSAmJiByLmN1cnJlbmN5LnN5bWJvbClcbiAgICAgICAgICAgICAgfHwgQ1VSUkVOQ1lfU1lNQk9MU1tyZWFkU3RvcmVkQ3VycmVuY3koKV1cbiAgICAgICAgICAgICAgfHwgJ8KlJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIGNvbnN0IGJhY2tmaWxsaW5nID0gQm9vbGVhbihyICYmIHIuYmFja2ZpbGwgJiYgci5iYWNrZmlsbC5zdGF0dXMgPT09ICdydW5uaW5nJylcbiAgICAgICAgICBzY2hlZHVsZShiYWNrZmlsbGluZyA/IERPQ0tfQkFDS0ZJTExfUkVUUllfTVMgOiBET0NLX1JFRlJFU0hfTVMpXG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8g6Lev55Sx5LiN5Y+v55SoIC8g5a6/5Li75pyq5bCx57uq77ya5LiN54yc5pWw5a2X77yM5Lmf5LiN5oql6ZSZ5by556qX77yIZG9jayDluLjpqbvvvIzkuI3og73liLflsY/vvInjgIJcbiAgICAgICAgICBpZiAoYWxpdmUpIHtcbiAgICAgICAgICAgIHNldFN0YXRlKHsgc3RhdHVzOiAnZXJyb3InIH0pXG4gICAgICAgICAgICBzY2hlZHVsZShET0NLX1JFRlJFU0hfTVMpXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cbiAgICBsb2FkKClcbiAgICBjb25zdCBvblZpc2libGUgPSAoKSA9PiB7XG4gICAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC52aXNpYmlsaXR5U3RhdGUgPT09ICd2aXNpYmxlJykgbG9hZCgpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd2aXNpYmlsaXR5Y2hhbmdlJywgb25WaXNpYmxlKVxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBhbGl2ZSA9IGZhbHNlXG4gICAgICBpZiAodGltZXIgIT09IG51bGwpIGNsZWFyVGltZW91dCh0aW1lcilcbiAgICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd2aXNpYmlsaXR5Y2hhbmdlJywgb25WaXNpYmxlKVxuICAgIH1cbiAgfSwgW10pXG4gIC8vIOS7iuaXpeaXoOiwg+eUqO+8iOaIlui/mOayoeafpeWIsO+8ieWwseS4jeWNoOS9je+8mmRvY2sg5piv5bi46am75Yy677yM56m6IHBpbGwg5q+U5rKh5pyJ5pu05ZC144CCXG4gIGlmIChzdGF0ZS5zdGF0dXMgIT09ICdyZWFkeScgfHwgIXN0YXRlLmNhbGxzKSByZXR1cm4gbnVsbFxuICBjb25zdCBwcmljZWQgPSBzdGF0ZS5jb3N0ID4gMFxuICBjb25zdCB2YWx1ZSA9IHByaWNlZCA/IHN0YXRlLnN5bWJvbCArIGNvc3REaWdpdHMoc3RhdGUuY29zdCkgOiB0cignZG9ja1VucHJpY2VkJylcbiAgY29uc3QgaGludCA9IHRyKCdkb2NrSGludCcsIHtcbiAgICBjb3N0OiB2YWx1ZSxcbiAgICBjYWxsczogZm9ybWF0SW50KHN0YXRlLmNhbGxzKSxcbiAgICB0b2tlbnM6IGZvcm1hdEludChzdGF0ZS50b2tlbnMpLFxuICB9KVxuICByZXR1cm4gaCgnc3BhbicsIHtcbiAgICBjbGFzc05hbWU6ICd0c2QtZG9jaycsXG4gICAgdGl0bGU6IGhpbnQsXG4gICAgJ2FyaWEtbGFiZWwnOiBoaW50LFxuICAgICdkYXRhLXVzYWdlLWNvc3QnOiB0cnVlLFxuICB9LFxuICAgIGgoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RzZC1kb2NrLWxhYmVsJyB9LCB0cigndG9kYXknKSksXG4gICAgaCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHNkLWRvY2stdmFsdWUnIH0sIHZhbHVlKSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiDms6jlhozvvJpzZXR0aW5ncy5zZWN0aW9uIOmhtemdolxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuZnVuY3Rpb24gYXBwbHkoY3R4KSB7XG4gIHVzYWdlQ3R4ID0gY3R4XG4gIC8vIE1vdW50IHRoZSBuYXRpdmUgUmVtb3RlIGZhY2Ugb25jZSB0aGUgcGFnZSBpcyB1cDsgdGhlIEZldGNoIHJvdXRlcyBjYXJyeVxuICAvLyBldmVyeSBjYWxsIHVudGlsIGl0IGxhbmRzLlxuICBtb3VudFJlbW90ZUNoYW5uZWwoY3R4KVxuICBfdXNhZ2VQcmljZXNTY29wZSA9IG51bGwgLy8g5q+P5qyh5r+A5rS76YeN57uR77yM6YG/5YWN5aSN55So5bey6YeK5pS+55qEIHNjb3BlXG4gIGN0eC5lZmZlY3QoKCkgPT4ge1xuICAgIGlmICh0eXBlb2Ygc3R5bGVzICE9PSAndW5kZWZpbmVkJyAmJiBzdHlsZXMgJiYgdHlwZW9mIHN0eWxlcy5pbnNlcnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBzdHlsZXMuaW5zZXJ0KENTUylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKVxuICAgICAgZWwuc2V0QXR0cmlidXRlKCdkYXRhLXBsdWdpbicsICdkc2gtcGx1Z2luLXVzYWdlJylcbiAgICAgIGVsLnRleHRDb250ZW50ID0gQ1NTXG4gICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGVsKVxuICAgICAgcmV0dXJuICgpID0+IHsgZWwucmVtb3ZlKCkgfVxuICAgIH1cbiAgfSwgJ3VzYWdlOiBzdHlsZXMnKVxuICBjdHguZWZmZWN0KCgpID0+IGN0eC5sb2NhbGUucmVnaXN0ZXIoTlMsIHsgemg6IFpILCBlbjogRU4gfSksICd1c2FnZTogZGljdGlvbmFyaWVzJylcbiAgY29uc3QgdDAgPSBjdHgubG9jYWxlID8gY3R4LmxvY2FsZS5iaW5kKE5TKSA6IGZhbGxiYWNrVFxuICBjdHguZWZmZWN0KCgpID0+IGluc3RhbGxTZXR0aW5nc05hdkljb24oKCkgPT4gdDAoJ25hdicpKSwgJ3VzYWdlOiBuYXYtaWNvbicpXG4gIC8vIGNvcmRpcyBjdHggaXMgYSBzdHJpY3QgcHJveHk6IERJUkVDVCBwcm9wZXJ0eSBhY2Nlc3Mgb24gYW4gdW4taW5qZWN0ZWRcbiAgLy8gc2VydmljZSB0aHJvd3MgKFwiY2Fubm90IGdldCBwcm9wZXJ0eSBYIHdpdGhvdXQgaW5qZWN0XCIpLCBzbyBhIGJhcmVcbiAgLy8gYGN0eC5zbG90cyA/PyAuLi5gIHdvdWxkIHRocm93IGFuZCBza2lwIHRoZSBmYWxsYmFjay4gUHJvYmUgdmlhIHRoZSBzYWZlXG4gIC8vIGN0eC5nZXQoKSBmaXJzdDsgZmFsbCBiYWNrIHRvIHRoZSBpbmplY3RlZCBwcm9wZXJ0eSAoYXZhaWxhYmxlIG9uY2VcbiAgLy8gJ3Nsb3RzJyBpcyBkZWNsYXJlZCBpbiB0aGUgaW5qZWN0IGxpc3QgYmVsb3cpLlxuICBsZXQgc2xvdHMgPSBudWxsXG4gIHRyeSB7XG4gICAgc2xvdHMgPSB0eXBlb2YgY3R4LmdldCA9PT0gJ2Z1bmN0aW9uJyA/IGN0eC5nZXQoJ3Nsb3RzJykgOiBudWxsXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBzbG90cyA9IG51bGxcbiAgfVxuICBpZiAoIXNsb3RzIHx8IHR5cGVvZiBzbG90cy5pbmplY3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKGN0eC5zbG90cyAmJiB0eXBlb2YgY3R4LnNsb3RzLmluamVjdCA9PT0gJ2Z1bmN0aW9uJykgc2xvdHMgPSBjdHguc2xvdHNcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzbG90cyA9IG51bGxcbiAgICB9XG4gIH1cbiAgaWYgKCFzbG90cyB8fCB0eXBlb2Ygc2xvdHMuaW5qZWN0ICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBzbG90cy5yZWdpc3RlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIGxvZ1dhcm4oJ1t1c2FnZV0gc2V0dGluZ3Muc2VjdGlvbiBzbG90IHVuYXZhaWxhYmxlJylcbiAgICByZXR1cm5cbiAgfVxuICBzbG90cy5pbmplY3QoJ3NldHRpbmdzLnNlY3Rpb24nLCAoKSA9PiBzbG90cy5yZWdpc3RlcihcbiAgICB7IG5hbWU6ICdzZXR0aW5ncy5zZWN0aW9uJywgaWQ6ICd0b2tlbi1zdGF0cycsIG9yZGVyOiAyMCwgbGFiZWw6ICgpID0+IHQwKCduYXYnKSwgbG9jYWxlOiBOUyB9LFxuICAgIChwcm9wcykgPT4gaChTdGF0c0Rhc2hib2FyZCwgcHJvcHMpLFxuICApKVxuXG4gIC8vIOi+k+WFpeWMuuaIkOacrCBwaWxs44CCMC4yLjEg55qEIGNvbXBvc2VyIGRvY2sg5pivIGxpc3Qgc2xvdO+8jOWuv+S4u+iHquW3seWNoOS6hiBhY3Rpdml0eSgwKVxuICAvLyDkuI4gdXNhZ2UoMSnvvIzmj5Lku7bmjpLlnKjlroPku6zkuYvlkI7vvJswLjIuMCDmsqHmnInov5nkuKogc2xvdO+8jOazqOWFpeWksei0peS4jeiDveaLluWeruiuvue9rumhteOAglxuICB0cnkge1xuICAgIHNsb3RzLmluamVjdCgnY29udmVyc2F0aW9uLmNvbXBvc2VyLmRvY2snLCAoKSA9PiBzbG90cy5yZWdpc3RlcihcbiAgICAgIHsgbmFtZTogJ2NvbnZlcnNhdGlvbi5jb21wb3Nlci5kb2NrJywgaWQ6ICd1c2FnZS1jb3N0Jywgb3JkZXI6IDIsIGxvY2FsZTogTlMgfSxcbiAgICAgIChwcm9wcykgPT4gaChDb3N0UGlsbCwgcHJvcHMpLFxuICAgICkpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLndhcm4oJ1t1c2FnZV0gY29tcG9zZXIgZG9jayBzbG90IHVuYXZhaWxhYmxlJywgZSlcbiAgfVxufVxuXG5yZXR1cm4geyBpbmplY3Q6IFsnbG9jYWxlJywgJ3Nsb3RzJ10sIGFwcGx5IH1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
|