guonan
2025-04-14 9e860a560c5a4b81abe2042b8d8698e253730502
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
(function webpackUniversalModuleDefinition(root, factory) {
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory(require("@epicgames-ps/lib-pixelstreamingfrontend-ue5.3"), require("jss"), require("jss-plugin-global"), require("jss-plugin-camel-case"));
    else if(typeof define === 'function' && define.amd)
        define(["@epicgames-ps/lib-pixelstreamingfrontend-ue5.3", "jss", "jss-plugin-global", "jss-plugin-camel-case"], factory);
    else if(typeof exports === 'object')
        exports["lib-pixelstreamingfrontend-ui"] = factory(require("@epicgames-ps/lib-pixelstreamingfrontend-ue5.3"), require("jss"), require("jss-plugin-global"), require("jss-plugin-camel-case"));
    else
        root["lib-pixelstreamingfrontend-ui"] = factory(root["@epicgames-ps/lib-pixelstreamingfrontend-ue5.3"], root["jss"], root["jss-plugin-global"], root["jss-plugin-camel-case"]);
})(this, (__WEBPACK_EXTERNAL_MODULE__epicgames_ps_lib_pixelstreamingfrontend_ue5_3__, __WEBPACK_EXTERNAL_MODULE_jss__, __WEBPACK_EXTERNAL_MODULE_jss_plugin_global__, __WEBPACK_EXTERNAL_MODULE_jss_plugin_camel_case__) => {
return /******/ (() => { // webpackBootstrap
/******/     "use strict";
/******/     var __webpack_modules__ = ({
 
/***/ "./src/Application/Application.ts":
/*!****************************************!*\
  !*** ./src/Application/Application.ts ***!
  \****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "Application": () => (/* binding */ Application)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _Overlay_ConnectOverlay__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Overlay/ConnectOverlay */ "./src/Overlay/ConnectOverlay.ts");
/* harmony import */ var _Overlay_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Overlay/DisconnectOverlay */ "./src/Overlay/DisconnectOverlay.ts");
/* harmony import */ var _Overlay_PlayOverlay__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Overlay/PlayOverlay */ "./src/Overlay/PlayOverlay.ts");
/* harmony import */ var _Overlay_InfoOverlay__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Overlay/InfoOverlay */ "./src/Overlay/InfoOverlay.ts");
/* harmony import */ var _Overlay_ErrorOverlay__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Overlay/ErrorOverlay */ "./src/Overlay/ErrorOverlay.ts");
/* harmony import */ var _Overlay_AFKOverlay__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Overlay/AFKOverlay */ "./src/Overlay/AFKOverlay.ts");
/* harmony import */ var _UI_Controls__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../UI/Controls */ "./src/UI/Controls.ts");
/* harmony import */ var _UI_LabelledButton__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../UI/LabelledButton */ "./src/UI/LabelledButton.ts");
/* harmony import */ var _UI_SettingsPanel__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../UI/SettingsPanel */ "./src/UI/SettingsPanel.ts");
/* harmony import */ var _UI_StatsPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../UI/StatsPanel */ "./src/UI/StatsPanel.ts");
/* harmony import */ var _UI_VideoQpIndicator__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../UI/VideoQpIndicator */ "./src/UI/VideoQpIndicator.ts");
/* harmony import */ var _Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Config/ConfigUI */ "./src/Config/ConfigUI.ts");
/* harmony import */ var _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../UI/UIConfigurationTypes */ "./src/UI/UIConfigurationTypes.ts");
/* harmony import */ var _UI_FullscreenIcon__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../UI/FullscreenIcon */ "./src/UI/FullscreenIcon.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/**
 * An Application is a combination of UI elements to display and manage a WebRTC Pixel Streaming
 * connection. It includes features for controlling a stream with mouse and keyboard,
 * managing connection endpoints, as well as displaying stats and other information about it.
 */
class Application {
    /**
     * @param options - Initialization options
     */
    constructor(options) {
        this._options = options;
        this.stream = options.stream;
        this.onColorModeChanged = options.onColorModeChanged;
        this.configUI = new _Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__.ConfigUI(this.stream.config);
        this.createOverlays();
        if ((0,_UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__.isPanelEnabled)(options.statsPanelConfig)) {
            // Add stats panel
            this.statsPanel = new _UI_StatsPanel__WEBPACK_IMPORTED_MODULE_3__.StatsPanel();
            this.uiFeaturesElement.appendChild(this.statsPanel.rootElement);
        }
        if ((0,_UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__.isPanelEnabled)(options.settingsPanelConfig)) {
            // Add settings panel
            this.settingsPanel = new _UI_SettingsPanel__WEBPACK_IMPORTED_MODULE_4__.SettingsPanel();
            this.uiFeaturesElement.appendChild(this.settingsPanel.rootElement);
            this.configureSettings();
        }
        if (!options.videoQpIndicatorConfig || !options.videoQpIndicatorConfig.disableIndicator) {
            // Add the video stream QP indicator
            this.videoQpIndicator = new _UI_VideoQpIndicator__WEBPACK_IMPORTED_MODULE_5__.VideoQpIndicator();
            this.uiFeaturesElement.appendChild(this.videoQpIndicator.rootElement);
        }
        this.createButtons();
        this.registerCallbacks();
        this.showConnectOrAutoConnectOverlays();
        this.setColorMode(this.configUI.isCustomFlagEnabled(_Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__.LightMode));
    }
    createOverlays() {
        // build all of the overlays
        this.disconnectOverlay = new _Overlay_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_6__.DisconnectOverlay(this.stream.videoElementParent);
        this.connectOverlay = new _Overlay_ConnectOverlay__WEBPACK_IMPORTED_MODULE_7__.ConnectOverlay(this.stream.videoElementParent);
        this.playOverlay = new _Overlay_PlayOverlay__WEBPACK_IMPORTED_MODULE_8__.PlayOverlay(this.stream.videoElementParent);
        this.infoOverlay = new _Overlay_InfoOverlay__WEBPACK_IMPORTED_MODULE_9__.InfoOverlay(this.stream.videoElementParent);
        this.errorOverlay = new _Overlay_ErrorOverlay__WEBPACK_IMPORTED_MODULE_10__.ErrorOverlay(this.stream.videoElementParent);
        this.afkOverlay = new _Overlay_AFKOverlay__WEBPACK_IMPORTED_MODULE_11__.AFKOverlay(this.stream.videoElementParent);
        this.disconnectOverlay.onAction(() => this.stream.reconnect());
        // Build the webRtc connect overlay Event Listener and show the connect overlay
        this.connectOverlay.onAction(() => this.stream.connect());
        // set up the play overlays action
        this.playOverlay.onAction(() => this.stream.play());
    }
    /**
     * Set up button click functions and button functionality
     */
    createButtons() {
        const controlsUIConfig = {
            statsButtonType: !!this._options.statsPanelConfig
                ? this._options.statsPanelConfig.visibilityButtonConfig
                : undefined,
            settingsButtonType: !!this._options.settingsPanelConfig
                ? this._options.settingsPanelConfig.visibilityButtonConfig
                : undefined,
            fullscreenButtonType: this._options.fullScreenControlsConfig,
            xrIconType: this._options.xrControlsConfig
        };
        // Setup controls
        const controls = new _UI_Controls__WEBPACK_IMPORTED_MODULE_12__.Controls(controlsUIConfig);
        this.uiFeaturesElement.appendChild(controls.rootElement);
        // When we fullscreen we want this element to be the root
        const fullScreenButton = 
        // Depending on if we're creating an internal button, or using an external one
        (!!this._options.fullScreenControlsConfig
            && this._options.fullScreenControlsConfig.creationMode === _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__.UIElementCreationMode.UseCustomElement)
            // Either create a fullscreen class based on the external button
            ? new _UI_FullscreenIcon__WEBPACK_IMPORTED_MODULE_13__.FullScreenIconExternal(this._options.fullScreenControlsConfig.customElement)
            // Or use the one created by the Controls initializer earlier
            : controls.fullscreenIcon;
        if (fullScreenButton) {
            fullScreenButton.fullscreenElement = /iPad|iPhone|iPod/.test(navigator.userAgent) ? this.stream.videoElementParent.getElementsByTagName("video")[0] : this.rootElement;
        }
        // Add settings button to controls
        const settingsButton = !!controls.settingsIcon ? controls.settingsIcon.rootElement :
            this._options.settingsPanelConfig.visibilityButtonConfig.customElement;
        if (!!settingsButton)
            settingsButton.onclick = () => this.settingsClicked();
        if (!!this.settingsPanel)
            this.settingsPanel.settingsCloseButton.onclick = () => this.settingsClicked();
        // Add WebXR button to controls
        const xrButton = !!controls.xrIcon ? controls.xrIcon.rootElement :
            this._options.xrControlsConfig.creationMode === _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_2__.UIElementCreationMode.UseCustomElement ?
                this._options.xrControlsConfig.customElement : undefined;
        if (!!xrButton)
            xrButton.onclick = () => this.stream.toggleXR();
        // setup the stats/info button
        const statsButton = !!controls.statsIcon ? controls.statsIcon.rootElement :
            this._options.statsPanelConfig.visibilityButtonConfig.customElement;
        if (!!statsButton)
            statsButton.onclick = () => this.statsClicked();
        if (!!this.statsPanel) {
            this.statsPanel.statsCloseButton.onclick = () => this.statsClicked();
        }
        // Add command buttons (if we have somewhere to add them to)
        if (!!this.settingsPanel) {
            // Add button for toggle fps
            const showFPSButton = new _UI_LabelledButton__WEBPACK_IMPORTED_MODULE_14__.LabelledButton('Show FPS', 'Toggle');
            showFPSButton.addOnClickListener(() => {
                this.stream.requestShowFps();
            });
            // Add button for restart stream
            const restartStreamButton = new _UI_LabelledButton__WEBPACK_IMPORTED_MODULE_14__.LabelledButton('Restart Stream', 'Restart');
            restartStreamButton.addOnClickListener(() => {
                this.stream.reconnect();
            });
            // Add button for request keyframe
            const requestKeyframeButton = new _UI_LabelledButton__WEBPACK_IMPORTED_MODULE_14__.LabelledButton('Request keyframe', 'Request');
            requestKeyframeButton.addOnClickListener(() => {
                this.stream.requestIframe();
            });
            const commandsSectionElem = this.configUI.buildSectionWithHeading(this.settingsPanel.settingsContentElement, 'Commands');
            commandsSectionElem.appendChild(showFPSButton.rootElement);
            commandsSectionElem.appendChild(requestKeyframeButton.rootElement);
            commandsSectionElem.appendChild(restartStreamButton.rootElement);
        }
    }
    /**
     * Configure the settings with on change listeners and any additional per experience settings.
     */
    configureSettings() {
        // This builds all the settings sections and flags under this `settingsContent` element.
        this.configUI.populateSettingsElement(this.settingsPanel.settingsContentElement);
        this.configUI.addCustomFlagOnSettingChangedListener(_Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__.LightMode, (isLightMode) => {
            this.configUI.setCustomFlagLabel(_Config_ConfigUI__WEBPACK_IMPORTED_MODULE_1__.LightMode, `Color Scheme: ${isLightMode ? 'Light' : 'Dark'} Mode`);
            this.setColorMode(isLightMode);
        });
    }
    registerCallbacks() {
        this.stream.addEventListener('afkWarningActivate', ({ data: { countDown, dismissAfk } }) => this.showAfkOverlay(countDown, dismissAfk));
        this.stream.addEventListener('afkWarningUpdate', ({ data: { countDown } }) => this.afkOverlay.updateCountdown(countDown));
        this.stream.addEventListener('afkWarningDeactivate', () => this.afkOverlay.hide());
        this.stream.addEventListener('afkTimedOut', () => this.afkOverlay.hide());
        this.stream.addEventListener('videoEncoderAvgQP', ({ data: { avgQP } }) => this.onVideoEncoderAvgQP(avgQP));
        this.stream.addEventListener('webRtcSdp', () => this.onWebRtcSdp());
        this.stream.addEventListener('webRtcAutoConnect', () => this.onWebRtcAutoConnect());
        this.stream.addEventListener('webRtcConnecting', () => this.onWebRtcConnecting());
        this.stream.addEventListener('webRtcConnected', () => this.onWebRtcConnected());
        this.stream.addEventListener('webRtcFailed', () => this.onWebRtcFailed());
        this.stream.addEventListener('webRtcDisconnected', ({ data: { eventString, allowClickToReconnect } }) => this.onDisconnect(eventString, allowClickToReconnect));
        this.stream.addEventListener('videoInitialized', () => this.onVideoInitialized());
        this.stream.addEventListener('streamLoading', () => this.onStreamLoading());
        this.stream.addEventListener('playStreamError', ({ data: { message } }) => this.onPlayStreamError(message));
        this.stream.addEventListener('playStream', () => this.onPlayStream());
        this.stream.addEventListener('playStreamRejected', ({ data: { reason } }) => this.onPlayStreamRejected(reason));
        this.stream.addEventListener('loadFreezeFrame', ({ data: { shouldShowPlayOverlay } }) => this.onLoadFreezeFrame(shouldShowPlayOverlay));
        this.stream.addEventListener('statsReceived', ({ data: { aggregatedStats } }) => this.onStatsReceived(aggregatedStats));
        this.stream.addEventListener('latencyTestResult', ({ data: { latencyTimings } }) => this.onLatencyTestResults(latencyTimings));
        this.stream.addEventListener('dataChannelLatencyTestResult', ({ data: { result } }) => this.onDataChannelLatencyTestResults(result));
        this.stream.addEventListener('streamerListMessage', ({ data: { messageStreamerList, autoSelectedStreamerId, wantedStreamerId } }) => this.handleStreamerListMessage(messageStreamerList, autoSelectedStreamerId, wantedStreamerId));
        this.stream.addEventListener('settingsChanged', (event) => this.configUI.onSettingsChanged(event));
        this.stream.addEventListener('playerCount', ({ data: { count } }) => this.onPlayerCount(count));
    }
    /**
     * Gets the rootElement of the application, video stream and all UI are children of this element.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('div');
            this._rootElement.id = 'playerUI';
            this._rootElement.classList.add('noselect');
            this._rootElement.appendChild(this.stream.videoElementParent);
            this._rootElement.appendChild(this.uiFeaturesElement);
        }
        return this._rootElement;
    }
    /**
     * Gets the element that contains all the UI features, like the stats and settings panels.
     */
    get uiFeaturesElement() {
        if (!this._uiFeatureElement) {
            this._uiFeatureElement = document.createElement('div');
            this._uiFeatureElement.id = 'uiFeatures';
        }
        return this._uiFeatureElement;
    }
    /**
     * Shows the disconnect overlay
     * @param updateText - the text that will be displayed in the overlay
     */
    showDisconnectOverlay(updateText) {
        this.hideCurrentOverlay();
        this.updateDisconnectOverlay(updateText);
        this.disconnectOverlay.show();
        this.currentOverlay = this.disconnectOverlay;
    }
    /**
     * Update the disconnect overlays span text
     * @param updateText - the new countdown number
     */
    updateDisconnectOverlay(updateText) {
        this.disconnectOverlay.update(updateText);
    }
    /**
     * Activates the disconnect overlays action
     */
    onDisconnectionAction() {
        this.disconnectOverlay.activate();
    }
    /**
     * Hides the current overlay
     */
    hideCurrentOverlay() {
        if (this.currentOverlay != null) {
            this.currentOverlay.hide();
            this.currentOverlay = null;
        }
    }
    /**
     * Shows the connect overlay
     */
    showConnectOverlay() {
        this.hideCurrentOverlay();
        this.connectOverlay.show();
        this.currentOverlay = this.connectOverlay;
    }
    /**
     * Shows the play overlay
     */
    showPlayOverlay() {
        this.hideCurrentOverlay();
        this.playOverlay.show();
        this.currentOverlay = this.playOverlay;
    }
    /**
     * Shows the text overlay
     * @param text - the text that will be shown in the overlay
     */
    showTextOverlay(text) {
        this.hideCurrentOverlay();
        this.infoOverlay.update(text);
        this.infoOverlay.show();
        this.currentOverlay = this.infoOverlay;
    }
    /**
     * Shows the error overlay
     * @param text - the text that will be shown in the overlay
     */
    showErrorOverlay(text) {
        this.hideCurrentOverlay();
        this.errorOverlay.update(text);
        this.errorOverlay.show();
        this.currentOverlay = this.errorOverlay;
    }
    /**
     * Shows or hides the settings panel if clicked
     */
    settingsClicked() {
        var _a;
        (_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.hide();
        this.settingsPanel.toggleVisibility();
    }
    /**
     * Shows or hides the stats panel if clicked
     */
    statsClicked() {
        var _a;
        (_a = this.settingsPanel) === null || _a === void 0 ? void 0 : _a.hide();
        this.statsPanel.toggleVisibility();
    }
    /**
     * Activates the connect overlays action
     */
    onConnectAction() {
        this.connectOverlay.activate();
    }
    /**
     * Activates the play overlays action
     */
    onPlayAction() {
        this.playOverlay.activate();
    }
    /**
     * Shows the afk overlay
     * @param countDown - the countdown number for the afk countdown
     */
    showAfkOverlay(countDown, dismissAfk) {
        this.hideCurrentOverlay();
        this.afkOverlay.updateCountdown(countDown);
        this.afkOverlay.onAction(() => dismissAfk());
        this.afkOverlay.show();
        this.currentOverlay = this.afkOverlay;
    }
    /**
     * Show the Connect Overlay or auto connect
     */
    showConnectOrAutoConnectOverlays() {
        // set up if the auto play will be used or regular click to start
        if (!this.stream.config.isFlagEnabled(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AutoConnect)) {
            this.showConnectOverlay();
        }
    }
    /**
     * Show the webRtcAutoConnect Overlay and connect
     */
    onWebRtcAutoConnect() {
        this.showTextOverlay('Auto Connecting Now');
    }
    /**
     * Set up functionality to happen when receiving a webRTC answer
     */
    onWebRtcSdp() {
        this.showTextOverlay('WebRTC Connection Negotiated');
    }
    /**
     * Shows a text overlay to alert the user the stream is currently loading
     */
    onStreamLoading() {
        // build the spinner span
        const spinnerSpan = document.createElement('span');
        spinnerSpan.className = 'visually-hidden';
        spinnerSpan.innerHTML = 'Loading...';
        // build the spinner div
        const spinnerDiv = document.createElement('div');
        spinnerDiv.id = 'loading-spinner';
        spinnerDiv.className = 'spinner-border ms-2';
        spinnerDiv.setAttribute('role', 'status');
        // append the spinner to the element
        spinnerDiv.appendChild(spinnerSpan);
        this.showTextOverlay('Loading Stream ' + spinnerDiv.outerHTML);
    }
    /**
     * Event fired when the video is disconnected - displays the error overlay and resets the buttons stream tools upon disconnect
     * @param eventString - the event text that will be shown in the overlay
     * @param allowClickToReconnect - true if we want to allow the user to click to reconnect. Otherwise it's just a message.
     */
    onDisconnect(eventString, allowClickToReconnect) {
        var _a;
        const overlayMessage = 'Disconnected' + (eventString ? `: ${eventString}` : '');
        if (allowClickToReconnect) {
            this.showDisconnectOverlay(`${overlayMessage} Click To Restart.`);
        }
        else {
            this.showErrorOverlay(overlayMessage);
        }
        // disable starting a latency checks
        (_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.onDisconnect();
    }
    /**
     * Handles when Web Rtc is connecting
     */
    onWebRtcConnecting() {
        this.showTextOverlay('Starting connection to server, please wait');
    }
    /**
     * Handles when Web Rtc has connected
     */
    onWebRtcConnected() {
        this.showTextOverlay('WebRTC connected, waiting for video');
    }
    /**
     * Handles when Web Rtc fails to connect
     */
    onWebRtcFailed() {
        this.showErrorOverlay('Unable to setup video');
    }
    onLoadFreezeFrame(shouldShowPlayOverlay) {
        if (shouldShowPlayOverlay === true) {
            _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Log(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), 'showing play overlay');
            this.showPlayOverlay();
        }
    }
    onPlayStream() {
        this.hideCurrentOverlay();
    }
    onPlayStreamError(message) {
        this.showErrorOverlay(message);
    }
    onPlayStreamRejected(onRejectedReason) {
        this.showPlayOverlay();
    }
    onVideoInitialized() {
        var _a;
        if (!this.stream.config.isFlagEnabled(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AutoPlayVideo)) {
            this.showPlayOverlay();
        }
        (_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.onVideoInitialized(this.stream);
    }
    /**
     * Set up functionality to happen when calculating the average video encoder qp
     * @param QP - the quality number of the stream
     */
    onVideoEncoderAvgQP(QP) {
        // Update internal QP indicator if one is present
        if (!!this.videoQpIndicator) {
            this.videoQpIndicator.updateQpTooltip(QP);
        }
    }
    onInitialSettings(settings) {
        var _a;
        if (settings.PixelStreamingSettings) {
            (_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.configure(settings.PixelStreamingSettings);
        }
    }
    onStatsReceived(aggregatedStats) {
        var _a;
        // Grab all stats we can off the aggregated stats
        (_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.handleStats(aggregatedStats);
    }
    onLatencyTestResults(latencyTimings) {
        var _a;
        (_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.latencyTest.handleTestResult(latencyTimings);
    }
    onDataChannelLatencyTestResults(result) {
        var _a;
        (_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.dataChannelLatencyTest.handleTestResult(result);
    }
    onPlayerCount(playerCount) {
        var _a;
        (_a = this.statsPanel) === null || _a === void 0 ? void 0 : _a.handlePlayerCount(playerCount);
    }
    handleStreamerListMessage(messageStreamingList, autoSelectedStreamerId, wantedStreamerId) {
        const waitForStreamer = this.stream.config.isFlagEnabled(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.WaitForStreamer);
        const isReconnecting = this.stream.isReconnecting();
        let message = null;
        let allowRestart = true;
        if (!autoSelectedStreamerId) {
            if (waitForStreamer && wantedStreamerId) {
                if (isReconnecting) {
                    message = `Waiting for ${wantedStreamerId} to become available.`;
                    allowRestart = false;
                }
                else {
                    message = `Gave up waiting for ${wantedStreamerId} to become available. Click to try again`;
                    if (messageStreamingList.ids.length > 0) {
                        message += ` or select a streamer from the settings menu.`;
                    }
                    allowRestart = true;
                }
            }
            else if (messageStreamingList.ids.length == 0) {
                if (isReconnecting) {
                    message = `Waiting for a streamer to become available.`;
                    allowRestart = false;
                }
                else {
                    message = `No streamers available. Click to try again.`;
                    allowRestart = true;
                }
            }
            else {
                message = `Multiple streamers available. Select one from the settings menu.`;
                allowRestart = false;
            }
            if (allowRestart) {
                this.showDisconnectOverlay(message);
            }
            else {
                this.showTextOverlay(message);
            }
        }
    }
    /**
     * Set light/dark color mode
     * @param isLightMode - should we use a light or dark color scheme
     */
    setColorMode(isLightMode) {
        if (this.onColorModeChanged) {
            this.onColorModeChanged(isLightMode);
        }
    }
}
 
 
/***/ }),
 
/***/ "./src/Config/ConfigUI.ts":
/*!********************************!*\
  !*** ./src/Config/ConfigUI.ts ***!
  \********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "ConfigUI": () => (/* binding */ ConfigUI),
/* harmony export */   "LightMode": () => (/* binding */ LightMode)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _SettingUIFlag__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./SettingUIFlag */ "./src/Config/SettingUIFlag.ts");
/* harmony import */ var _SettingUINumber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./SettingUINumber */ "./src/Config/SettingUINumber.ts");
/* harmony import */ var _SettingUIText__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./SettingUIText */ "./src/Config/SettingUIText.ts");
/* harmony import */ var _SettingUIOption__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./SettingUIOption */ "./src/Config/SettingUIOption.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
 
 
 
 
const LightMode = 'LightMode';
class ConfigUI {
    // ------------ Settings -----------------
    constructor(config) {
        this.customFlags = new Map();
        /* A map of flags that can be toggled - options that can be set in the application - e.g. Use Mic? */
        this.flagsUi = new Map();
        /* A map of numerical settings - options that can be in the application - e.g. MinBitrate */
        this.numericParametersUi = new Map();
        /* A map of text settings - e.g. signalling server url */
        this.textParametersUi = new Map();
        /* A map of enum based settings - e.g. preferred codec */
        this.optionParametersUi = new Map();
        this.createCustomUISettings(config.useUrlParams);
        this.registerSettingsUIComponents(config);
    }
    /**
     * Create custom UI settings that are not provided by the Pixel Streaming library.
     */
    createCustomUISettings(useUrlParams) {
        this.customFlags.set(LightMode, new _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.SettingFlag(LightMode, 'Color Scheme: Dark Mode', 'Page styling will be either light or dark', false /*if want to use system pref: (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches)*/, useUrlParams, (isLightMode, setting) => {
            setting.label = `Color Scheme: ${isLightMode ? 'Light' : 'Dark'} Mode`;
        }));
    }
    /**
     * Creates UI wrapper components for each setting element in config.
     * @param config
     */
    registerSettingsUIComponents(config) {
        for (const setting of config.getFlags()) {
            this.flagsUi.set(setting.id, new _SettingUIFlag__WEBPACK_IMPORTED_MODULE_1__.SettingUIFlag(setting));
        }
        for (const setting of Array.from(this.customFlags.values())) {
            this.flagsUi.set(setting.id, new _SettingUIFlag__WEBPACK_IMPORTED_MODULE_1__.SettingUIFlag(setting));
        }
        for (const setting of config.getTextSettings()) {
            this.textParametersUi.set(setting.id, new _SettingUIText__WEBPACK_IMPORTED_MODULE_2__.SettingUIText(setting));
        }
        for (const setting of config.getNumericSettings()) {
            this.numericParametersUi.set(setting.id, new _SettingUINumber__WEBPACK_IMPORTED_MODULE_3__.SettingUINumber(setting));
        }
        for (const setting of config.getOptionSettings()) {
            this.optionParametersUi.set(setting.id, new _SettingUIOption__WEBPACK_IMPORTED_MODULE_4__.SettingUIOption(setting));
        }
    }
    /**
     * Make DOM elements for a settings section with a heading.
     * @param settingsElem The parent container for our DOM elements.
     * @param sectionHeading The heading element to go into the section.
     * @returns The constructed DOM element for the section.
     */
    buildSectionWithHeading(settingsElem, sectionHeading) {
        // make section element
        const sectionElem = document.createElement('section');
        sectionElem.classList.add('settingsContainer');
        // make section heading
        const psSettingsHeader = document.createElement('div');
        psSettingsHeader.classList.add('settingsHeader');
        psSettingsHeader.classList.add('settings-text');
        psSettingsHeader.textContent = sectionHeading;
        // add section and heading to parent settings element
        sectionElem.appendChild(psSettingsHeader);
        settingsElem.appendChild(sectionElem);
        return sectionElem;
    }
    /**
     * Setup flags with their default values and add them to the `Config.flags` map.
     * @param settingsElem - The element that contains all the individual settings sections, flags, and so on.
     */
    populateSettingsElement(settingsElem) {
        /* Setup all Pixel Streaming specific settings */
        const psSettingsSection = this.buildSectionWithHeading(settingsElem, 'Pixel Streaming');
        // make settings show up in DOM
        this.addSettingText(psSettingsSection, this.textParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.TextParameters.SignallingServerUrl));
        this.addSettingOption(psSettingsSection, this.optionParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.OptionParameters.StreamerId));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AutoConnect));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AutoPlayVideo));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.BrowserSendOffer));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.UseMic));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.StartVideoMuted));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.IsQualityController));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.ForceMonoAudio));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.ForceTURN));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.SuppressBrowserKeys));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.AFKDetection));
        this.addSettingFlag(psSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.WaitForStreamer));
        this.addSettingNumeric(psSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.AFKTimeoutSecs));
        this.addSettingNumeric(psSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.MaxReconnectAttempts));
        this.addSettingNumeric(psSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.StreamerAutoJoinInterval));
        /* Setup all view/ui related settings under this section */
        const viewSettingsSection = this.buildSectionWithHeading(settingsElem, 'UI');
        this.addSettingFlag(viewSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.MatchViewportResolution));
        this.addSettingFlag(viewSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.HoveringMouseMode));
        this.addSettingFlag(viewSettingsSection, this.flagsUi.get(LightMode));
        /* Setup all encoder related settings under this section */
        const inputSettingsSection = this.buildSectionWithHeading(settingsElem, 'Input');
        this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.KeyboardInput));
        this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.MouseInput));
        this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.TouchInput));
        this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.GamepadInput));
        this.addSettingFlag(inputSettingsSection, this.flagsUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Flags.XRControllerInput));
        /* Setup all encoder related settings under this section */
        const encoderSettingsSection = this.buildSectionWithHeading(settingsElem, 'Encoder');
        this.addSettingNumeric(encoderSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.MinQP));
        this.addSettingNumeric(encoderSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.MaxQP));
        const preferredCodecOption = this.optionParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.OptionParameters.PreferredCodec);
        this.addSettingOption(encoderSettingsSection, this.optionParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.OptionParameters.PreferredCodec));
        if (preferredCodecOption &&
            [...preferredCodecOption.selector.options]
                .map((o) => o.value)
                .includes('Only available on Chrome')) {
            preferredCodecOption.disable();
        }
        /* Setup all webrtc related settings under this section */
        const webrtcSettingsSection = this.buildSectionWithHeading(settingsElem, 'WebRTC');
        this.addSettingNumeric(webrtcSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.WebRTCFPS));
        this.addSettingNumeric(webrtcSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.WebRTCMinBitrate));
        this.addSettingNumeric(webrtcSettingsSection, this.numericParametersUi.get(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.NumericParameters.WebRTCMaxBitrate));
    }
    /**
     * Add a SettingText element to a particular settings section in the DOM and registers that text in the text settings map.
     * @param settingsSection The settings section HTML element.
     * @param settingText The textual settings object.
     */
    addSettingText(settingsSection, settingText) {
        if (settingText) {
            settingsSection.appendChild(settingText.rootElement);
            this.textParametersUi.set(settingText.setting.id, settingText);
        }
    }
    /**
     * Add a SettingFlag element to a particular settings section in the DOM and registers that flag in the Config.flag map.
     * @param settingsSection The settings section HTML element.
     * @param settingFlag The settings flag object.
     */
    addSettingFlag(settingsSection, settingFlag) {
        if (settingFlag) {
            settingsSection.appendChild(settingFlag.rootElement);
            this.flagsUi.set(settingFlag.setting.id, settingFlag);
        }
    }
    /**
     * Add a numeric setting element to a particular settings section in the DOM and registers that flag in the Config.numericParameters map.
     * @param settingsSection The settings section HTML element.
     * @param settingFlag The settings flag object.
     */
    addSettingNumeric(settingsSection, setting) {
        if (setting) {
            settingsSection.appendChild(setting.rootElement);
            this.numericParametersUi.set(setting.setting.id, setting);
        }
    }
    /**
     * Add an enum based settings element to a particular settings section in the DOM and registers that flag in the Config.enumParameters map.
     * @param settingsSection The settings section HTML element.
     * @param settingFlag The settings flag object.
     */
    addSettingOption(settingsSection, setting) {
        if (setting) {
            settingsSection.appendChild(setting.rootElement);
            this.optionParametersUi.set(setting.setting.id, setting);
        }
    }
    onSettingsChanged({ data: { id, target, type } }) {
        if (type === 'flag') {
            const _id = id;
            const _target = target;
            const setting = this.flagsUi.get(_id);
            if (setting) {
                if (setting.flag !== _target.flag) {
                    setting.flag = _target.flag;
                }
                if (setting.label !== _target.label) {
                    setting.label = _target.label;
                }
            }
        }
        else if (type === 'number') {
            const _id = id;
            const _target = target;
            const setting = this.numericParametersUi.get(_id);
            if (setting) {
                if (setting.number !== _target.number) {
                    setting.number = _target.number;
                }
                if (setting.label !== _target.label) {
                    setting.label = _target.label;
                }
            }
        }
        else if (type === 'text') {
            const _id = id;
            const _target = target;
            const setting = this.textParametersUi.get(_id);
            if (setting) {
                if (setting.text !== _target.text) {
                    setting.text = _target.text;
                }
                if (setting.label !== _target.label) {
                    setting.label = _target.label;
                }
            }
        }
        else if (type === 'option') {
            const _id = id;
            const _target = target;
            const setting = this.optionParametersUi.get(_id);
            if (setting) {
                const uiOptions = setting.options;
                const targetOptions = _target.options;
                if (uiOptions.length !== targetOptions.length ||
                    !uiOptions.every((value) => targetOptions.includes(value))) {
                    setting.options = _target.options;
                }
                if (setting.selected !== _target.selected) {
                    setting.selected = _target.selected;
                }
                if (setting.label !== _target.label) {
                    setting.label = _target.label;
                }
            }
        }
    }
    /**
     * Add a callback to fire when the flag is toggled.
     * @param id The id of the flag.
     * @param onChangeListener The callback to fire when the value changes.
     */
    addCustomFlagOnSettingChangedListener(id, onChangeListener) {
        if (this.customFlags.has(id)) {
            this.customFlags.get(id).onChange = onChangeListener;
        }
    }
    /**
     * Set the label for the flag.
     * @param id The id of the flag.
     * @param label The new label to use for the flag.
     */
    setCustomFlagLabel(id, label) {
        if (!this.customFlags.has(id)) {
            _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Warning(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), `Cannot set label for flag called ${id} - it does not exist in the Config.flags map.`);
        }
        else {
            this.customFlags.get(id).label = label;
            this.flagsUi.get(id).label = label;
        }
    }
    /**
     * Get the value of the configuration flag which has the given id.
     * @param id The unique id for the flag.
     * @returns True if the flag is enabled.
     */
    isCustomFlagEnabled(id) {
        return this.customFlags.get(id).flag;
    }
}
 
 
/***/ }),
 
/***/ "./src/Config/SettingUIBase.ts":
/*!*************************************!*\
  !*** ./src/Config/SettingUIBase.ts ***!
  \*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "SettingUIBase": () => (/* binding */ SettingUIBase)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
 * Base class for a setting that has a text label, an arbitrary setting value it stores, an a HTML element that represents this setting.
 */
class SettingUIBase {
    constructor(setting) {
        this._setting = setting;
    }
    /**
     * @returns The setting component.
     */
    get setting() {
        return this._setting;
    }
    /**
     * @returns Return or creates a HTML element that represents this setting in the DOM.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('div');
        }
        return this._rootElement;
    }
}
 
 
/***/ }),
 
/***/ "./src/Config/SettingUIFlag.ts":
/*!*************************************!*\
  !*** ./src/Config/SettingUIFlag.ts ***!
  \*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "SettingUIFlag": () => (/* binding */ SettingUIFlag)
/* harmony export */ });
/* harmony import */ var _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SettingUIBase */ "./src/Config/SettingUIBase.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
class SettingUIFlag extends _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__.SettingUIBase {
    constructor(setting) {
        super(setting);
        this.label = setting.label;
        this.flag = setting.flag;
    }
    /**
     * @returns The setting component.
     */
    get setting() {
        return this._setting;
    }
    get settingsTextElem() {
        if (!this._settingsTextElem) {
            this._settingsTextElem = document.createElement('div');
            this._settingsTextElem.innerText = this.setting._label;
            this._settingsTextElem.title = this.setting.description;
        }
        return this._settingsTextElem;
    }
    get checkbox() {
        if (!this._checkbox) {
            this._checkbox = document.createElement('input');
            this._checkbox.type = 'checkbox';
        }
        return this._checkbox;
    }
    /**
     * @returns Return or creates a HTML element that represents this setting in the DOM.
     */
    get rootElement() {
        if (!this._rootElement) {
            // create root div with "setting" css class
            this._rootElement = document.createElement('div');
            this._rootElement.id = this.setting.id;
            this._rootElement.classList.add('setting');
            // create div element to contain our setting's text
            this._rootElement.appendChild(this.settingsTextElem);
            // create label element to wrap out input type
            const wrapperLabel = document.createElement('label');
            wrapperLabel.classList.add('tgl-switch');
            this._rootElement.appendChild(wrapperLabel);
            // create input type=checkbox
            this.checkbox.title = this.setting.description;
            this.checkbox.classList.add('tgl');
            this.checkbox.classList.add('tgl-flat');
            const slider = document.createElement('div');
            slider.classList.add('tgl-slider');
            wrapperLabel.appendChild(this.checkbox);
            wrapperLabel.appendChild(slider);
            // setup on change from checkbox
            this.checkbox.addEventListener('change', () => {
                if (this.setting.flag !== this.checkbox.checked) {
                    this.setting.flag = this.checkbox.checked;
                    this.setting.updateURLParams();
                }
            });
        }
        return this._rootElement;
    }
    /**
     * Update the setting's stored value.
     * @param inValue The new value for the setting.
     */
    set flag(inValue) {
        this.checkbox.checked = inValue;
    }
    /**
     * Get value
     */
    get flag() {
        return this.checkbox.checked;
    }
    /**
     * Set the label text for the setting.
     * @param label setting label.
     */
    set label(inLabel) {
        this.settingsTextElem.innerText = inLabel;
    }
    /**
     * Get label
     */
    get label() {
        return this.settingsTextElem.innerText;
    }
}
 
 
/***/ }),
 
/***/ "./src/Config/SettingUINumber.ts":
/*!***************************************!*\
  !*** ./src/Config/SettingUINumber.ts ***!
  \***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "SettingUINumber": () => (/* binding */ SettingUINumber)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _SettingUIBase__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./SettingUIBase */ "./src/Config/SettingUIBase.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
 
/**
 * A number spinner with a text label beside it.
 */
class SettingUINumber extends _SettingUIBase__WEBPACK_IMPORTED_MODULE_1__.SettingUIBase {
    constructor(setting) {
        super(setting);
        this.label = this.setting.label;
        this.number = this.setting.number;
    }
    /**
     * @returns The setting component.
     */
    get setting() {
        return this._setting;
    }
    get settingsTextElem() {
        if (!this._settingsTextElem) {
            this._settingsTextElem = document.createElement('label');
            this._settingsTextElem.innerText = this.setting.label;
            this._settingsTextElem.title = this.setting.description;
        }
        return this._settingsTextElem;
    }
    /**
     * Get the HTMLInputElement for the button.
     */
    get spinner() {
        if (!this._spinner) {
            this._spinner = document.createElement('input');
            this._spinner.type = 'number';
            this._spinner.min = this.setting.min.toString();
            this._spinner.max = this.setting.max.toString();
            this._spinner.value = this.setting.number.toString();
            this._spinner.title = this.setting.description;
            this._spinner.classList.add('form-control');
        }
        return this._spinner;
    }
    /**
     * @returns Return or creates a HTML element that represents this setting in the DOM.
     */
    get rootElement() {
        if (!this._rootElement) {
            // create root div with "setting" css class
            this._rootElement = document.createElement('div');
            this._rootElement.classList.add('setting');
            this._rootElement.classList.add('form-group');
            // create div element to contain our setting's text
            this._rootElement.appendChild(this.settingsTextElem);
            // create label element to wrap out input type
            this._rootElement.appendChild(this.spinner);
            // setup onchange
            this.spinner.onchange = (event) => {
                const inputElem = event.target;
                const parsedValue = Number.parseInt(inputElem.value);
                if (Number.isNaN(parsedValue)) {
                    _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Warning(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), `Could not parse value change into a valid number - value was ${inputElem.value}, resetting value to ${this.setting.min}`);
                    if (this.setting.number !== this.setting.min) {
                        this.setting.number = this.setting.min;
                    }
                }
                else {
                    if (this.setting.number !== parsedValue) {
                        this.setting.number = parsedValue;
                        this.setting.updateURLParams();
                    }
                }
            };
        }
        return this._rootElement;
    }
    /**
     * Set the number in the spinner (will be clamped within range).
     */
    set number(newNumber) {
        this.spinner.value = this.setting.clamp(newNumber).toString();
    }
    /**
     * Get value
     */
    get number() {
        return +this.spinner.value;
    }
    /**
     * Set the label text for the setting.
     * @param label setting label.
     */
    set label(inLabel) {
        this.settingsTextElem.innerText = inLabel;
    }
    /**
     * Get label
     */
    get label() {
        return this.settingsTextElem.innerText;
    }
}
 
 
/***/ }),
 
/***/ "./src/Config/SettingUIOption.ts":
/*!***************************************!*\
  !*** ./src/Config/SettingUIOption.ts ***!
  \***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "SettingUIOption": () => (/* binding */ SettingUIOption)
/* harmony export */ });
/* harmony import */ var _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SettingUIBase */ "./src/Config/SettingUIBase.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
class SettingUIOption extends _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__.SettingUIBase {
    constructor(setting) {
        super(setting);
        this.label = this.setting.label;
        this.options = this.setting.options;
        this.selected = this.setting.selected;
    }
    /**
     * @returns The setting component.
     */
    get setting() {
        return this._setting;
    }
    get selector() {
        if (!this._selector) {
            this._selector = document.createElement('select');
            this._selector.classList.add('form-control');
            this._selector.classList.add('settings-option');
        }
        return this._selector;
    }
    get settingsTextElem() {
        if (!this._settingsTextElem) {
            this._settingsTextElem = document.createElement('div');
            this._settingsTextElem.innerText = this.setting.label;
            this._settingsTextElem.title = this.setting.description;
        }
        return this._settingsTextElem;
    }
    /**
     * Set the label text for the setting.
     * @param label setting label.
     */
    set label(inLabel) {
        this.settingsTextElem.innerText = inLabel;
    }
    /**
     * Get label
     */
    get label() {
        return this.settingsTextElem.innerText;
    }
    /**
     * @returns Return or creates a HTML element that represents this setting in the DOM.
     */
    get rootElement() {
        if (!this._rootElement) {
            // create root div with "setting" css class
            this._rootElement = document.createElement('div');
            this._rootElement.id = this.setting.id;
            this._rootElement.classList.add('setting');
            this._rootElement.classList.add('form-group');
            // create div element to contain our setting's text
            this._rootElement.appendChild(this.settingsTextElem);
            // create label element to wrap out input type
            const wrapperLabel = document.createElement('label');
            this._rootElement.appendChild(wrapperLabel);
            // create select element
            this.selector.title = this.setting.description;
            wrapperLabel.appendChild(this.selector);
            // setup on change from selector
            this.selector.onchange = () => {
                if (this.setting.selected !== this.selector.value) {
                    this.setting.selected = this.selector.value;
                    this.setting.updateURLParams();
                }
            };
        }
        return this._rootElement;
    }
    set options(values) {
        for (let i = this.selector.options.length - 1; i >= 0; i--) {
            this.selector.remove(i);
        }
        values.forEach((value) => {
            const opt = document.createElement('option');
            opt.value = value;
            opt.innerHTML = value;
            this.selector.appendChild(opt);
        });
    }
    get options() {
        return [...this.selector.options].map((o) => o.value);
    }
    set selected(value) {
        // A user may not specify the full possible value so we instead use the closest match.
        // eg ?xxx=H264 would select 'H264 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f'
        const filteredList = this.options.filter((option) => option.indexOf(value) !== -1);
        if (filteredList.length) {
            this.selector.value = filteredList[0];
        }
    }
    get selected() {
        return this.selector.value;
    }
    disable() {
        this.selector.disabled = true;
    }
    enable() {
        this.selector.disabled = false;
    }
}
 
 
/***/ }),
 
/***/ "./src/Config/SettingUIText.ts":
/*!*************************************!*\
  !*** ./src/Config/SettingUIText.ts ***!
  \*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "SettingUIText": () => (/* binding */ SettingUIText)
/* harmony export */ });
/* harmony import */ var _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SettingUIBase */ "./src/Config/SettingUIBase.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
class SettingUIText extends _SettingUIBase__WEBPACK_IMPORTED_MODULE_0__.SettingUIBase {
    constructor(setting) {
        super(setting);
        this.label = this.setting.label;
        this.text = this.setting.text;
    }
    /**
     * @returns The setting component.
     */
    get setting() {
        return this._setting;
    }
    get settingsTextElem() {
        if (!this._settingsTextElem) {
            this._settingsTextElem = document.createElement('div');
            this._settingsTextElem.innerText = this.setting.label;
            this._settingsTextElem.title = this.setting.description;
        }
        return this._settingsTextElem;
    }
    get textbox() {
        if (!this._textbox) {
            this._textbox = document.createElement('input');
            this._textbox.classList.add('form-control');
            this._textbox.type = 'textbox';
        }
        return this._textbox;
    }
    /**
     * @returns Return or creates a HTML element that represents this setting in the DOM.
     */
    get rootElement() {
        if (!this._rootElement) {
            // create root div with "setting" css class
            this._rootElement = document.createElement('div');
            this._rootElement.id = this.setting.id;
            this._rootElement.classList.add('setting');
            // create div element to contain our setting's text
            this._rootElement.appendChild(this.settingsTextElem);
            // create label element to wrap out input type
            const wrapperLabel = document.createElement('label');
            this._rootElement.appendChild(wrapperLabel);
            // create input type=checkbox
            this.textbox.title = this.setting.description;
            wrapperLabel.appendChild(this.textbox);
            // setup on change from checkbox
            this.textbox.addEventListener('input', () => {
                if (this.setting.text !== this.textbox.value) {
                    this.setting.text = this.textbox.value;
                    this.setting.updateURLParams();
                }
            });
        }
        return this._rootElement;
    }
    /**
     * Update the setting's stored value.
     * @param inValue The new value for the setting.
     */
    set text(inValue) {
        this.textbox.value = inValue;
    }
    /**
     * Get value
     */
    get text() {
        return this.textbox.value;
    }
    /**
     * Set the label text for the setting.
     * @param label setting label.
     */
    set label(inLabel) {
        this.settingsTextElem.innerText = inLabel;
    }
    /**
     * Get label
     */
    get label() {
        return this.settingsTextElem.innerText;
    }
}
 
 
/***/ }),
 
/***/ "./src/Overlay/AFKOverlay.ts":
/*!***********************************!*\
  !*** ./src/Overlay/AFKOverlay.ts ***!
  \***********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "AFKOverlay": () => (/* binding */ AFKOverlay)
/* harmony export */ });
/* harmony import */ var _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
/**
 * Show an overlay for when the session is unattended, it begins a countdown timer, which when elapsed will disconnect the stream.
 */
class AFKOverlay extends _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__.ActionOverlay {
    /**
     * @returns The created root element of this overlay.
     */
    static createRootElement() {
        const afkOverlayHtml = document.createElement('div');
        afkOverlayHtml.id = 'afkOverlay';
        afkOverlayHtml.className = 'clickableState';
        return afkOverlayHtml;
    }
    /**
     * @returns The created content element of this overlay, which contain some text for an afk count down.
     */
    static createContentElement() {
        const afkOverlayHtmlInner = document.createElement('div');
        afkOverlayHtmlInner.id = 'afkOverlayInner';
        afkOverlayHtmlInner.innerHTML =
            '<center>No activity detected<br>Disconnecting in <span id="afkCountDownNumber"></span> seconds<br>Click to continue<br></center>';
        return afkOverlayHtmlInner;
    }
    /**
     * Construct an Afk overlay
     * @param parentElement the element this overlay will be inserted into
     */
    constructor(rootDiv) {
        super(rootDiv, AFKOverlay.createRootElement(), AFKOverlay.createContentElement());
        this.rootElement.addEventListener('click', () => {
            this.activate();
        });
    }
    /**
     * Update the count down spans number for the overlay
     * @param countdown the count down number to be inserted into the span for updating
     */
    updateCountdown(countdown) {
        this.textElement.innerHTML = `<center>No activity detected<br>Disconnecting in <span id="afkCountDownNumber">${countdown}</span> seconds<br>Click to continue<br></center>`;
    }
}
 
 
/***/ }),
 
/***/ "./src/Overlay/ActionOverlay.ts":
/*!**************************************!*\
  !*** ./src/Overlay/ActionOverlay.ts ***!
  \**************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "ActionOverlay": () => (/* binding */ ActionOverlay)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _BaseOverlay__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./BaseOverlay */ "./src/Overlay/BaseOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
 
/**
 * Class for the base action overlay structure
 */
class ActionOverlay extends _BaseOverlay__WEBPACK_IMPORTED_MODULE_1__.OverlayBase {
    /**
     * Construct an action overlay
     * @param rootDiv the root element this overlay will be inserted into
     * @param rootElement the root element that is the overlay
     * @param contentElement an element that contains text for the action overlay
     */
    constructor(rootDiv, rootElement, contentElement) {
        super(rootDiv, rootElement, contentElement);
        this.onActionCallback = () => {
            /* do nothing */ _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Info(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), 'Did you forget to set the onAction callback in your overlay?');
        };
    }
    /**
     * Update the text overlays inner text
     * @param text the update text to be inserted into the overlay
     */
    update(text) {
        if (text != null || text != undefined) {
            this.textElement.innerHTML = text;
        }
    }
    /**
     * Set a method as an event emitter callback
     * @param callBack the method that is to be called when the event is emitted
     */
    onAction(callBack) {
        this.onActionCallback = callBack;
    }
    /**
     * Activate an event that is attached to the event emitter
     */
    activate() {
        this.onActionCallback();
    }
}
 
 
/***/ }),
 
/***/ "./src/Overlay/BaseOverlay.ts":
/*!************************************!*\
  !*** ./src/Overlay/BaseOverlay.ts ***!
  \************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "OverlayBase": () => (/* binding */ OverlayBase)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
 * Class for the base overlay structure
 */
class OverlayBase {
    /**
     * Construct an overlay
     * @param rootDiv the root element this overlay will be inserted into
     * @param rootElement the root element that is the overlay
     */
    constructor(rootDiv, rootElement, textElement) {
        this.rootDiv = rootDiv;
        this.rootElement = rootElement;
        this.textElement = textElement;
        this.rootElement.appendChild(this.textElement);
        this.hide();
        this.rootDiv.appendChild(this.rootElement);
    }
    /**
     * Show the overlay
     */
    show() {
        this.rootElement.classList.remove('hiddenState');
    }
    /**
     * Hide the overlay
     */
    hide() {
        this.rootElement.classList.add('hiddenState');
    }
}
 
 
/***/ }),
 
/***/ "./src/Overlay/ConnectOverlay.ts":
/*!***************************************!*\
  !*** ./src/Overlay/ConnectOverlay.ts ***!
  \***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "ConnectOverlay": () => (/* binding */ ConnectOverlay)
/* harmony export */ });
/* harmony import */ var _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
/**
 * Overlay shown during connection, has a button that can be clicked to initiate a connection.
 */
class ConnectOverlay extends _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__.ActionOverlay {
    /**
     * @returns The created root element of this overlay.
     */
    static createRootElement() {
        const connectElem = document.createElement('div');
        connectElem.id = 'connectOverlay';
        connectElem.className = 'clickableState';
        return connectElem;
    }
    /**
     * @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
     */
    static createContentElement() {
        const connectContentElem = document.createElement('div');
        connectContentElem.id = 'connectButton';
        connectContentElem.innerHTML = 'Click to start';
        return connectContentElem;
    }
    /**
     * Construct a connect overlay with a connection button.
     * @param parentElem the parent element this overlay will be inserted into.
     */
    constructor(parentElem) {
        super(parentElem, ConnectOverlay.createRootElement(), ConnectOverlay.createContentElement());
        // add the new event listener
        this.rootElement.addEventListener('click', () => {
            this.activate();
        });
    }
}
 
 
/***/ }),
 
/***/ "./src/Overlay/DisconnectOverlay.ts":
/*!******************************************!*\
  !*** ./src/Overlay/DisconnectOverlay.ts ***!
  \******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "DisconnectOverlay": () => (/* binding */ DisconnectOverlay)
/* harmony export */ });
/* harmony import */ var _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
/**
 * Overlay shown during disconnection, has a reconnection element that can be clicked to reconnect.
 */
class DisconnectOverlay extends _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__.ActionOverlay {
    /**
     * @returns The created root element of this overlay.
     */
    static createRootElement() {
        const disconnectOverlayHtml = document.createElement('div');
        disconnectOverlayHtml.id = 'disconnectOverlay';
        disconnectOverlayHtml.className = 'clickableState';
        return disconnectOverlayHtml;
    }
    /**
     * @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
     */
    static createContentElement() {
        // build the inner html container
        const disconnectOverlayHtmlContainer = document.createElement('div');
        disconnectOverlayHtmlContainer.id = 'disconnectButton';
        disconnectOverlayHtmlContainer.innerHTML = 'Click To Restart';
        return disconnectOverlayHtmlContainer;
    }
    /**
     * Construct a disconnect overlay with a retry connection icon.
     * @param parentElem the parent element this overlay will be inserted into.
     */
    constructor(parentElem) {
        super(parentElem, DisconnectOverlay.createRootElement(), DisconnectOverlay.createContentElement());
        // add the new event listener
        this.rootElement.addEventListener('click', () => {
            this.activate();
        });
    }
}
 
 
/***/ }),
 
/***/ "./src/Overlay/ErrorOverlay.ts":
/*!*************************************!*\
  !*** ./src/Overlay/ErrorOverlay.ts ***!
  \*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "ErrorOverlay": () => (/* binding */ ErrorOverlay)
/* harmony export */ });
/* harmony import */ var _TextOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./TextOverlay */ "./src/Overlay/TextOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
/**
 * Generic overlay used to show textual error info to the user.
 */
class ErrorOverlay extends _TextOverlay__WEBPACK_IMPORTED_MODULE_0__.TextOverlay {
    /**
     * @returns The created root element of this overlay.
     */
    static createRootElement() {
        const errorOverlayHtml = document.createElement('div');
        errorOverlayHtml.id = 'errorOverlay';
        errorOverlayHtml.className = 'textDisplayState';
        return errorOverlayHtml;
    }
    /**
     * @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
     */
    static createContentElement() {
        const errorOverlayHtmlInner = document.createElement('div');
        errorOverlayHtmlInner.id = 'errorOverlayInner';
        return errorOverlayHtmlInner;
    }
    /**
     * Construct a connect overlay with a connection button.
     * @param parentElem the parent element this overlay will be inserted into.
     */
    constructor(parentElem) {
        super(parentElem, ErrorOverlay.createRootElement(), ErrorOverlay.createContentElement());
    }
}
 
 
/***/ }),
 
/***/ "./src/Overlay/InfoOverlay.ts":
/*!************************************!*\
  !*** ./src/Overlay/InfoOverlay.ts ***!
  \************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "InfoOverlay": () => (/* binding */ InfoOverlay)
/* harmony export */ });
/* harmony import */ var _TextOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./TextOverlay */ "./src/Overlay/TextOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
/**
 * Generic overlay used to show textual info to the user.
 */
class InfoOverlay extends _TextOverlay__WEBPACK_IMPORTED_MODULE_0__.TextOverlay {
    /**
     * @returns The created root element of this overlay.
     */
    static createRootElement() {
        const infoOverlayHtml = document.createElement('div');
        infoOverlayHtml.id = 'infoOverlay';
        infoOverlayHtml.className = 'textDisplayState';
        return infoOverlayHtml;
    }
    /**
     * @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
     */
    static createContentElement() {
        const infoOverlayHtmlInner = document.createElement('div');
        infoOverlayHtmlInner.id = 'messageOverlayInner';
        return infoOverlayHtmlInner;
    }
    /**
     * Construct a connect overlay with a connection button.
     * @param parentElem the parent element this overlay will be inserted into.
     */
    constructor(parentElem) {
        super(parentElem, InfoOverlay.createRootElement(), InfoOverlay.createContentElement());
    }
}
 
 
/***/ }),
 
/***/ "./src/Overlay/PlayOverlay.ts":
/*!************************************!*\
  !*** ./src/Overlay/PlayOverlay.ts ***!
  \************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "PlayOverlay": () => (/* binding */ PlayOverlay)
/* harmony export */ });
/* harmony import */ var _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
/**
 * Overlay shown when stream is ready to play.
 */
class PlayOverlay extends _ActionOverlay__WEBPACK_IMPORTED_MODULE_0__.ActionOverlay {
    /**
     * @returns The created root element of this overlay.
     */
    static createRootElement() {
        const playElem = document.createElement('div');
        playElem.id = 'playOverlay';
        playElem.className = 'clickableState';
        return playElem;
    }
    /**
     * @returns The created content element of this overlay, which contain whatever content this element contains, like text or a button.
     */
    static createContentElement() {
        // todo: change this to an svg
        const playOverlayHtmlInner = document.createElement('img');
        playOverlayHtmlInner.id = 'playButton';
        playOverlayHtmlInner.src =
            'data:image/png;base64,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';
        playOverlayHtmlInner.alt = 'Start Streaming';
        return playOverlayHtmlInner;
    }
    /**
     * Construct a connect overlay with a connection button.
     * @param parentElem the parent element this overlay will be inserted into.
     */
    constructor(parentElem) {
        super(parentElem, PlayOverlay.createRootElement(), PlayOverlay.createContentElement());
        // add the new event listener
        this.rootElement.addEventListener('click', () => {
            this.activate();
        });
    }
}
 
 
/***/ }),
 
/***/ "./src/Overlay/TextOverlay.ts":
/*!************************************!*\
  !*** ./src/Overlay/TextOverlay.ts ***!
  \************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "TextOverlay": () => (/* binding */ TextOverlay)
/* harmony export */ });
/* harmony import */ var _BaseOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BaseOverlay */ "./src/Overlay/BaseOverlay.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
/**
 * Class for the text overlay base
 */
class TextOverlay extends _BaseOverlay__WEBPACK_IMPORTED_MODULE_0__.OverlayBase {
    /**
     * Construct a text overlay
     * @param rootDiv the root element this overlay will be inserted into
     * @param rootElement the root element that is the overlay
     * @param textElement an element that contains text for the action overlay
     */
    constructor(rootDiv, rootElement, textElement) {
        super(rootDiv, rootElement, textElement);
    }
    /**
     * Update the text overlays inner text
     * @param text the update text to be inserted into the overlay
     */
    update(text) {
        if (text != null || text != undefined) {
            this.textElement.innerHTML = text;
        }
    }
}
 
 
/***/ }),
 
/***/ "./src/Styles/PixelStreamingApplicationStyles.ts":
/*!*******************************************************!*\
  !*** ./src/Styles/PixelStreamingApplicationStyles.ts ***!
  \*******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "PixelStreamingApplicationStyle": () => (/* binding */ PixelStreamingApplicationStyle)
/* harmony export */ });
/* harmony import */ var jss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jss */ "jss");
/* harmony import */ var jss__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jss__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var jss_plugin_global__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jss-plugin-global */ "jss-plugin-global");
/* harmony import */ var jss_plugin_global__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jss_plugin_global__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var jss_plugin_camel_case__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! jss-plugin-camel-case */ "jss-plugin-camel-case");
/* harmony import */ var jss_plugin_camel_case__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(jss_plugin_camel_case__WEBPACK_IMPORTED_MODULE_2__);
/* Copyright Epic Games, Inc. All Rights Reserved. */
 
 
 
class PixelStreamingApplicationStyle {
    constructor(options) {
        this.defaultLightModePalette = {
            '--color0': '#e2e0dd80',
            '--color1': '#FFFFFF',
            '--color2': '#000000',
            '--color3': '#0585fe',
            '--color4': '#35b350',
            '--color5': '#ffab00',
            '--color6': '#e1e2dd',
            '--color7': '#c3c4bf'
        };
        this.defaultDarkModePalette = {
            '--color0': '#1D1F2280',
            '--color1': '#000000',
            '--color2': '#FFFFFF',
            '--color3': '#0585fe',
            '--color4': '#35b350',
            '--color5': '#ffab00',
            '--color6': '#1e1d22',
            '--color7': '#3c3b40'
        };
        this.defaultStyles = {
            ':root': {
                '--color0': '#1D1F2280',
                '--color1': '#000000',
                '--color2': '#FFFFFF',
                '--color3': '#0585fe',
                '--color4': '#35b350',
                '--color5': '#ffab00',
                '--color6': '#1e1d22',
                '--color7': '#3c3b40',
                '--color8': '#41008c',
                '--color9': '#3e0070',
                '--color10': '#2e0052',
                '--color11': 'rgba(65,0,139,1)'
            },
            '.noselect': {
                userSelect: 'none'
            },
            '#playerUI': {
                width: '100%',
                height: '100%',
                position: 'relative'
            },
            '#videoElementParent': {
                width: '100%',
                height: '100%',
                position: 'absolute',
                backgroundColor: 'var(--color1)'
            },
            '#uiFeatures': {
                width: '100%',
                height: '100%',
                zIndex: '30',
                position: 'relative',
                color: 'var(--color2)',
                pointerEvents: 'none',
                overflow: 'hidden'
            },
            '.UiTool .tooltiptext': {
                visibility: 'hidden',
                width: 'auto',
                color: 'var(--color2)',
                textAlign: 'center',
                borderRadius: '15px',
                padding: '0px 10px',
                fontFamily: "'Montserrat', sans-serif",
                fontSize: '0.75rem',
                letterSpacing: '0.75px',
                position: 'absolute',
                top: '0',
                transform: 'translateY(25%)',
                left: '125%',
                zIndex: '20'
            },
            '.UiTool:hover .tooltiptext': {
                visibility: 'visible',
                backgroundColor: 'var(--color7)'
            },
            '#connection .tooltiptext': {
                top: '125%',
                transform: 'translateX(-25%)',
                left: '0',
                zIndex: '20',
                padding: '5px 10px'
            },
            '#connection': {
                position: 'absolute',
                bottom: '8%',
                left: '5%',
                fontFamily: "'Michroma', sans-serif",
                height: '3rem',
                width: '3rem',
                pointerEvents: 'all'
            },
            '#settings-panel .tooltiptext': {
                display: 'block',
                top: '125%',
                transform: 'translateX(-50%)',
                left: '0',
                zIndex: '20',
                padding: '5px 10px',
                border: '3px solid var(--color3)',
                width: 'max-content',
                fallbacks: [
                    {
                        width: 'max-content'
                    },
                    {
                        border: '3px solid var(--color3)'
                    },
                    {
                        padding: '5px 10px'
                    },
                    {
                        zIndex: '20'
                    },
                    {
                        left: '0'
                    },
                    {
                        transform: 'translateX(-50%)'
                    },
                    {
                        top: '125%'
                    },
                    {
                        display: 'block'
                    }
                ]
            },
            '#controls': {
                position: 'absolute',
                top: '3%',
                left: '2%',
                fontFamily: "'Michroma', sans-serif",
                pointerEvents: 'all',
                display: 'block'
            },
            '#controls>*': {
                marginBottom: '0.5rem',
                borderRadius: '50%',
                display: 'block',
                height: '2rem',
                lineHeight: '1.75rem',
                padding: '0.5rem'
            },
            '#controls #additionalinfo': {
                textAlign: 'center',
                fontFamily: "'Montserrat', sans-serif"
            },
            '#fullscreen-btn': {
                padding: '0.6rem !important'
            },
            '#minimizeIcon': {
                display: 'none'
            },
            '#settingsBtn, #statsBtn': {
                cursor: 'pointer'
            },
            '#uiFeatures button': {
                backgroundColor: 'var(--color7)',
                border: '1px solid var(--color7)',
                color: 'var(--color2)',
                position: 'relative',
                width: '3rem',
                height: '3rem',
                padding: '0.5rem',
                textAlign: 'center'
            },
            '#uiFeatures button:hover': {
                backgroundColor: 'var(--color3)',
                border: '3px solid var(--color3)',
                transition: '0.25s ease',
                paddingLeft: '0.55rem',
                paddingTop: '0.55rem'
            },
            '#uiFeatures button:active': {
                border: '3px solid var(--color3)',
                backgroundColor: 'var(--color7)',
                paddingLeft: '0.55rem',
                paddingTop: '0.55rem'
            },
            '.btn-flat': {
                backgroundColor: 'transparent',
                color: 'var(--color2)',
                fontFamily: "'Montserrat'",
                fontWeight: 'bold',
                border: '3px solid var(--color3)',
                borderRadius: '1rem',
                fontSize: '0.75rem',
                paddingLeft: '0.5rem',
                paddingRight: '0.5rem',
                cursor: 'pointer',
                textAlign: 'center'
            },
            '.btn-flat:hover': {
                backgroundColor: 'var(--color3)',
                transition: 'ease 0.3s'
            },
            '.btn-flat:disabled': {
                background: 'var(--color7)',
                borderColor: 'var(--color3)',
                color: 'var(--color3)',
                cursor: 'default'
            },
            '.btn-flat:active': {
                backgroundColor: 'transparent'
            },
            '.btn-flat:focus': {
                outline: 'none'
            },
            '#uiFeatures img': {
                width: '100%',
                height: '100%'
            },
            '.panel-wrap': {
                position: 'absolute',
                top: '0',
                bottom: '0',
                right: '0',
                height: '100%',
                minWidth: '20vw',
                maxWidth: '90vw',
                transform: 'translateX(100%)',
                transition: '.3s ease-out',
                pointerEvents: 'all',
                backdropFilter: 'blur(10px)',
                '-webkit-backdrop-filter': 'blur(10px)',
                overflowY: 'auto',
                overflowX: 'hidden',
                backgroundColor: 'var(--color0)'
            },
            '.panel-wrap-visible': {
                transform: 'translateX(0%)'
            },
            '.panel': {
                overflowY: 'auto',
                padding: '1em'
            },
            '#settingsHeading, #statsHeading': {
                display: 'inline-block',
                fontSize: '2em',
                marginBlockStart: '0.67em',
                marginBlockEnd: '0.67em',
                marginInlineStart: '0px',
                marginInlineEnd: '0px',
                position: 'relative',
                padding: '0 0 0 2rem'
            },
            '#settingsClose, #statsClose': {
                margin: '0.5rem',
                paddingTop: '0.5rem',
                paddingBottom: '0.5rem',
                paddingRight: '0.5rem',
                fontSize: '2em',
                float: 'right'
            },
            '#settingsClose:after, #statsClose:after': {
                paddingLeft: '0.5rem',
                display: 'inline-block',
                content: '"\\00d7"'
            },
            '#settingsClose:hover, #statsClose:hover': {
                color: 'var(--color3)',
                transition: 'ease 0.3s'
            },
            '#settingsContent, #statsContent': {
                marginLeft: '2rem',
                marginRight: '2rem'
            },
            '.setting': {
                display: 'flex',
                flexDirection: 'row',
                justifyContent: 'space-between',
                padding: '0.15rem 10px 0.15rem 10px'
            },
            '.settings-text': {
                color: 'var(--color2)',
                verticalAlign: 'middle',
                fontWeight: 'normal'
            },
            '.settings-option': {
                width: '100%',
                textOverflow: 'ellipsis',
                whiteSpace: 'nowrap'
            },
            '#connectOverlay, #playOverlay, #infoOverlay, #errorOverlay, #afkOverlay, #disconnectOverlay': {
                zIndex: '30',
                position: 'absolute',
                color: 'var(--color2)',
                fontSize: '1.8em',
                width: '100%',
                height: '100%',
                backgroundColor: 'var(--color1)',
                alignItems: 'center',
                justifyContent: 'center',
                textTransform: 'uppercase'
            },
            '.clickableState': {
                alignItems: 'center',
                justifyContent: 'center',
                display: 'flex',
                cursor: 'pointer'
            },
            '.textDisplayState': {
                display: 'flex'
            },
            '.hiddenState': {
                display: 'none'
            },
            '#playButton, #connectButton': {
                display: 'inline-block',
                height: 'auto',
                zIndex: '30'
            },
            'img#playButton': {
                maxWidth: '241px',
                width: '10%'
            },
            '#uiInteraction': {
                position: 'fixed'
            },
            '#UIInteractionButtonBoundary': {
                padding: '2px'
            },
            '#UIInteractionButton': {
                cursor: 'pointer'
            },
            '#hiddenInput': {
                position: 'absolute',
                left: '-10%',
                width: '0px',
                opacity: '0'
            },
            '#editTextButton': {
                position: 'absolute',
                height: '40px',
                width: '40px'
            },
            '.btn-overlay': {
                verticalAlign: 'middle',
                display: 'inline-block'
            },
            '.tgl-switch': {
                verticalAlign: 'middle',
                display: 'inline-block'
            },
            '.tgl-switch .tgl': {
                display: 'none'
            },
            '.tgl, .tgl:after, .tgl:before, .tgl *, .tgl *:after, .tgl *:before, .tgl+.tgl-slider': {
                '-webkit-box-sizing': 'border-box',
                boxSizing: 'border-box'
            },
            '.tgl::-moz-selection, .tgl:after::-moz-selection, .tgl:before::-moz-selection, .tgl *::-moz-selection, .tgl *:after::-moz-selection, .tgl *:before::-moz-selection, .tgl+.tgl-slider::-moz-selection': {
                background: 'none'
            },
            '.tgl::selection, .tgl:after::selection, .tgl:before::selection, .tgl *::selection, .tgl *:after::selection, .tgl *:before::selection, .tgl+.tgl-slider::selection': {
                background: 'none'
            },
            '.tgl-slider': {},
            '.tgl+.tgl-slider': {
                outline: '0',
                display: 'block',
                width: '40px',
                height: '18px',
                position: 'relative',
                cursor: 'pointer',
                userSelect: 'none'
            },
            '.tgl+.tgl-slider:after, .tgl+.tgl-slider:before': {
                position: 'relative',
                display: 'block',
                content: '""',
                width: '50%',
                height: '100%'
            },
            '.tgl+.tgl-slider:after': {
                left: '0'
            },
            '.tgl+.tgl-slider:before': {
                display: 'none'
            },
            '.tgl-flat+.tgl-slider': {
                padding: '2px',
                '-webkit-transition': 'all .2s ease',
                transition: 'all .2s ease',
                background: 'var(--color6)',
                border: '3px solid var(--color7)',
                borderRadius: '2em'
            },
            '.tgl-flat+.tgl-slider:after': {
                '-webkit-transition': 'all .2s ease',
                transition: 'all .2s ease',
                background: 'var(--color7)',
                content: '""',
                borderRadius: '1em'
            },
            '.tgl-flat:checked+.tgl-slider': {
                border: '3px solid var(--color3)'
            },
            '.tgl-flat:checked+.tgl-slider:after': {
                left: '50%',
                background: 'var(--color3)'
            },
            '.btn-apply': {
                display: 'block !important',
                marginLeft: 'auto',
                marginRight: 'auto',
                width: '40%'
            },
            '.form-control': {
                backgroundColor: 'var(--color7)',
                border: '2px solid var(--color7)',
                borderRadius: '4px',
                color: 'var(--color2)',
                textAlign: 'right',
                fontFamily: 'inherit'
            },
            '.form-control:hover': {
                borderColor: 'var(--color7)'
            },
            '.form-group': {
                paddingTop: '4px',
                display: 'grid',
                gridTemplateColumns: '80% 20%',
                rowGap: '4px',
                paddingRight: '10px',
                paddingLeft: '10px'
            },
            '.form-group label': {
                verticalAlign: 'middle',
                fontWeight: 'normal'
            },
            '.settingsContainer': {
                display: 'flex',
                flexDirection: 'column',
                borderBottom: '1px solid var(--color7)',
                paddingTop: '10px',
                paddingBottom: '10px'
            },
            '.settingsContainer> :first-child': {
                marginTop: '4px',
                marginBottom: '4px',
                fontWeight: 'bold',
                justifyContent: 'space-between',
                display: 'flex',
                flexDirection: 'row',
                alignItems: 'baseline'
            },
            '.collapse': {
                paddingLeft: '5%'
            },
            '#streamTools': {
                borderBottomRightRadius: '5px',
                borderBottomLeftRadius: '5px',
                userSelect: 'none',
                position: 'absolute',
                top: '0',
                right: '2%',
                zIndex: '100',
                border: '4px solid var(--colour8)',
                borderTopWidth: '0px'
            },
            '.settingsHeader': {
                fontStyle: 'italic'
            },
            '#streamToolsHeader': {
                display: 'flex',
                flexDirection: 'row',
                justifyContent: 'space-between',
                borderBottom: '1px solid var(--colour8)',
                backgroundColor: 'var(--color7)'
            },
            '.streamTools': {
                backgroundColor: 'var(--color2)',
                fontFamily: 'var(--buttonFont)',
                fontWeight: 'lighter',
                color: 'var(--color7)'
            },
            '.streamTools-shown>#streamToolsSettings, .streamTools-shown>#streamToolsStats': {
                display: 'block'
            },
            '#streamToolsToggle': {
                width: '100%'
            },
            '#qualityStatus': {
                fontSize: '37px',
                paddingRight: '4px'
            },
            '.svgIcon': {
                fill: 'var(--color2)'
            }
        };
        const { customStyles, lightModePalette, darkModePalette, jssInsertionPoint } = options !== null && options !== void 0 ? options : {};
        // One time setup with default plugins and settings.
        const jssOptions = {
            // JSS has many interesting plugins we may wish to turn on
            //plugins: [functions(), template(), global(), extend(), nested(), compose(), camelCase(), defaultUnit(options.defaultUnit), expand(), vendorPrefixer(), propsSort()]
            plugins: [jss_plugin_global__WEBPACK_IMPORTED_MODULE_1___default()(), jss_plugin_camel_case__WEBPACK_IMPORTED_MODULE_2___default()()],
            insertionPoint: jssInsertionPoint
        };
        jss__WEBPACK_IMPORTED_MODULE_0___default().setup(jssOptions);
        this.customStyles = customStyles;
        this.lightModePalette =
            lightModePalette !== null && lightModePalette !== void 0 ? lightModePalette : this.defaultLightModePalette;
        this.darkModePalette = darkModePalette !== null && darkModePalette !== void 0 ? darkModePalette : this.defaultDarkModePalette;
    }
    applyStyleSheet() {
        // Todo: refactor codebase to use jss at a component level, classes can be grabbed like so:
        //const {pixelStreamingClasses} = jss.createStyleSheet(styles).attach();
        // attach generated style sheet to page
        jss__WEBPACK_IMPORTED_MODULE_0___default().createStyleSheet({
            '@global': Object.assign(Object.assign({}, this.defaultStyles), this.customStyles)
        }).attach();
    }
    applyPalette(palette) {
        const rootElement = document.querySelector(':root');
        rootElement.style.setProperty('--color0', palette['--color0']);
        rootElement.style.setProperty('--color1', palette['--color1']);
        rootElement.style.setProperty('--color2', palette['--color2']);
        rootElement.style.setProperty('--color3', palette['--color3']);
        rootElement.style.setProperty('--color4', palette['--color4']);
        rootElement.style.setProperty('--color5', palette['--color5']);
        rootElement.style.setProperty('--color6', palette['--color6']);
        rootElement.style.setProperty('--color7', palette['--color7']);
    }
    /**
     * Update the players color variables
     * @param isLightMode - should we use a light or dark color scheme
     */
    setColorMode(isLightMode) {
        if (isLightMode) {
            this.applyPalette(this.lightModePalette);
        }
        else {
            this.applyPalette(this.darkModePalette);
        }
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/Controls.ts":
/*!****************************!*\
  !*** ./src/UI/Controls.ts ***!
  \****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "Controls": () => (/* binding */ Controls)
/* harmony export */ });
/* harmony import */ var _FullscreenIcon__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./FullscreenIcon */ "./src/UI/FullscreenIcon.ts");
/* harmony import */ var _SettingsIcon__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./SettingsIcon */ "./src/UI/SettingsIcon.ts");
/* harmony import */ var _StatsIcon__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./StatsIcon */ "./src/UI/StatsIcon.ts");
/* harmony import */ var _XRIcon__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./XRIcon */ "./src/UI/XRIcon.ts");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../UI/UIConfigurationTypes */ "./src/UI/UIConfigurationTypes.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
 
 
 
 
 
// If there isn't a type provided, default behaviour is to create the element.
function shouldCreateButton(type) {
    return (type == undefined) ? true : (type.creationMode === _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_1__.UIElementCreationMode.CreateDefaultElement);
}
/**
 * Element containing various controls like stats, settings, fullscreen.
 */
class Controls {
    /**
     * Construct the controls
     */
    constructor(config) {
        if (!config || shouldCreateButton(config.statsButtonType)) {
            this.statsIcon = new _StatsIcon__WEBPACK_IMPORTED_MODULE_2__.StatsIcon();
        }
        if (!config || shouldCreateButton(config.settingsButtonType)) {
            this.settingsIcon = new _SettingsIcon__WEBPACK_IMPORTED_MODULE_3__.SettingsIcon();
        }
        if (!config || shouldCreateButton(config.fullscreenButtonType)) {
            this.fullscreenIcon = new _FullscreenIcon__WEBPACK_IMPORTED_MODULE_4__.FullScreenIcon();
        }
        if (!config || shouldCreateButton(config.xrIconType)) {
            this.xrIcon = new _XRIcon__WEBPACK_IMPORTED_MODULE_5__.XRIcon();
        }
    }
    /**
     * Get the element containing the controls.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('div');
            this._rootElement.id = 'controls';
            if (!!this.fullscreenIcon) {
                this._rootElement.appendChild(this.fullscreenIcon.rootElement);
            }
            if (!!this.settingsIcon) {
                this._rootElement.appendChild(this.settingsIcon.rootElement);
            }
            if (!!this.statsIcon) {
                this._rootElement.appendChild(this.statsIcon.rootElement);
            }
            if (!!this.xrIcon) {
                _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.WebXRController.isSessionSupported('immersive-vr').then((supported) => {
                    if (supported) {
                        this._rootElement.appendChild(this.xrIcon.rootElement);
                    }
                });
            }
            ;
        }
        return this._rootElement;
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/DataChannelLatencyTest.ts":
/*!******************************************!*\
  !*** ./src/UI/DataChannelLatencyTest.ts ***!
  \******************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "DataChannelLatencyTest": () => (/* binding */ DataChannelLatencyTest)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__);
// Copyright Epic Games, Inc. All Rights Reserved.
 
/**
 * DataChannel Latency test UI elements and results handling.
 */
class DataChannelLatencyTest {
    /**
     * Get the button containing the stats icon.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('section');
            this._rootElement.classList.add('settingsContainer');
            // make heading
            const heading = document.createElement('div');
            heading.id = 'dataChannelLatencyTestHeader';
            heading.classList.add('settings-text');
            heading.classList.add('settingsHeader');
            this._rootElement.appendChild(heading);
            const headingText = document.createElement('div');
            headingText.innerHTML = 'Data Channel Latency Test';
            heading.appendChild(headingText);
            heading.appendChild(this.latencyTestButton);
            // make test results element
            const resultsParentElem = document.createElement('div');
            resultsParentElem.id = 'dataChannelLatencyTestContainer';
            resultsParentElem.classList.add('d-none');
            this._rootElement.appendChild(resultsParentElem);
            resultsParentElem.appendChild(this.latencyTestResultsElement);
        }
        return this._rootElement;
    }
    get latencyTestResultsElement() {
        if (!this._latencyTestResultsElement) {
            this._latencyTestResultsElement = document.createElement('div');
            this._latencyTestResultsElement.id = 'dataChannelLatencyStatsResults';
            this._latencyTestResultsElement.classList.add('StatsResult');
        }
        return this._latencyTestResultsElement;
    }
    get latencyTestButton() {
        if (!this._latencyTestButton) {
            this._latencyTestButton = document.createElement('input');
            this._latencyTestButton.type = 'button';
            this._latencyTestButton.value = 'Run Test';
            this._latencyTestButton.id = 'btn-start-data-channel-latency-test';
            this._latencyTestButton.classList.add('streamTools-button');
            this._latencyTestButton.classList.add('btn-flat');
        }
        return this._latencyTestButton;
    }
    /**
     * Populate the UI based on the latency test's results.
     * @param result The latency test results.
     */
    handleTestResult(result) {
        _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Log(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), result.toString(), 6);
        /**
         * Check we have results, NaN would mean that UE version we talk to doesn't support our test
         */
        if (isNaN(result.dataChannelRtt)) {
            this.latencyTestResultsElement.innerHTML = '<div>Not supported</div>';
            return;
        }
        let latencyStatsInnerHTML = '';
        latencyStatsInnerHTML +=
            '<div>Data channel RTT (ms): ' +
                result.dataChannelRtt +
                '</div>';
        /**
         * Separate path time discovery works only when UE and Player clocks have been synchronized.
         */
        if (result.playerToStreamerTime >= 0 && result.streamerToPlayerTime >= 0) {
            latencyStatsInnerHTML +=
                '<div>Player to Streamer path (ms): ' + result.playerToStreamerTime + '</div>';
            latencyStatsInnerHTML +=
                '<div>Streamer to Player path (ms): ' +
                    result.streamerToPlayerTime +
                    '</div>';
        }
        this.latencyTestResultsElement.innerHTML = latencyStatsInnerHTML;
        //setup button to download the detailed results
        let downloadButton = document.createElement('input');
        downloadButton.type = 'button';
        downloadButton.value = 'Download';
        downloadButton.classList.add('streamTools-button');
        downloadButton.classList.add('btn-flat');
        downloadButton.onclick = () => {
            let file = new Blob([result.exportLatencyAsCSV()], { type: 'text/plain' });
            let a = document.createElement("a"), url = URL.createObjectURL(file);
            a.href = url;
            a.download = "data_channel_latency_test_results.csv";
            document.body.appendChild(a);
            a.click();
            setTimeout(function () {
                document.body.removeChild(a);
                window.URL.revokeObjectURL(url);
            }, 0);
        };
        this.latencyTestResultsElement.appendChild(downloadButton);
    }
    handleTestStart() {
        this.latencyTestResultsElement.innerHTML =
            '<div>Test in progress</div>';
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/FullscreenIcon.ts":
/*!**********************************!*\
  !*** ./src/UI/FullscreenIcon.ts ***!
  \**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "FullScreenIcon": () => (/* binding */ FullScreenIcon),
/* harmony export */   "FullScreenIconBase": () => (/* binding */ FullScreenIconBase),
/* harmony export */   "FullScreenIconExternal": () => (/* binding */ FullScreenIconExternal)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
 * Base class for an element (i.e. button) that, when clicked, will toggle fullscreen of a given element.
 * Can be initialized with any HTMLElement, if it is set as rootElement in the constructor.
 */
class FullScreenIconBase {
    get rootElement() {
        return this._rootElement;
    }
    set rootElement(element) {
        element.onclick = () => this.toggleFullscreen();
        this._rootElement = element;
    }
    constructor() {
        this.isFullscreen = false;
        // set up the full screen events
        document.addEventListener('webkitfullscreenchange', () => this.onFullscreenChange(), false);
        document.addEventListener('mozfullscreenchange', () => this.onFullscreenChange(), false);
        document.addEventListener('fullscreenchange', () => this.onFullscreenChange(), false);
        document.addEventListener('MSFullscreenChange', () => this.onFullscreenChange(), false);
    }
    /**
     * Makes the document or fullscreenElement fullscreen.
     */
    toggleFullscreen() {
        // if already full screen; exit
        // else go fullscreen
        if (document.fullscreenElement ||
            document.webkitFullscreenElement ||
            document.mozFullScreenElement ||
            document.msFullscreenElement) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            }
            else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            }
            else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            }
            else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
        else {
            const element = this.fullscreenElement;
            if (!element) {
                return;
            }
            if (element.requestFullscreen) {
                element.requestFullscreen();
            }
            else if (element.mozRequestFullscreen) {
                element.mozRequestFullscreen();
            }
            else if (element.webkitRequestFullscreen) {
                element.webkitRequestFullscreen();
            }
            else if (element.msRequestFullscreen) {
                element.msRequestFullscreen();
            }
            else if (element.webkitEnterFullscreen) {
                element.webkitEnterFullscreen(); //for iphone this code worked
            }
        }
        this.onFullscreenChange();
    }
    /**
     * Handles the fullscreen button on change
     */
    onFullscreenChange() {
        this.isFullscreen =
            document.webkitIsFullScreen ||
                document.mozFullScreen ||
                (document.msFullscreenElement &&
                    document.msFullscreenElement !== null) ||
                (document.fullscreenElement && document.fullscreenElement !== null);
    }
}
/**
 * An implementation of FullScreenIconBase that uses an externally
 * provided HTMLElement for toggling full screen.
 */
class FullScreenIconExternal extends FullScreenIconBase {
    constructor(externalButton) {
        super();
        this.rootElement = externalButton;
    }
}
/**
 * The default fullscreen icon that contains a button and svgs for each state.
 */
class FullScreenIcon extends FullScreenIconBase {
    constructor() {
        super();
        const createdButton = document.createElement('button');
        createdButton.type = 'button';
        createdButton.classList.add('UiTool');
        createdButton.id = 'fullscreen-btn';
        createdButton.appendChild(this.maximizeIcon);
        createdButton.appendChild(this.minimizeIcon);
        createdButton.appendChild(this.tooltipText);
        this.rootElement = createdButton;
    }
    get tooltipText() {
        if (!this._tooltipText) {
            this._tooltipText = document.createElement('span');
            this._tooltipText.classList.add('tooltiptext');
            this._tooltipText.innerHTML = 'Fullscreen';
        }
        return this._tooltipText;
    }
    get maximizeIcon() {
        if (!this._maximizeIcon) {
            this._maximizeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            this._maximizeIcon.setAttributeNS(null, 'id', 'maximizeIcon');
            this._maximizeIcon.setAttributeNS(null, 'x', '0px');
            this._maximizeIcon.setAttributeNS(null, 'y', '0px');
            this._maximizeIcon.setAttributeNS(null, 'viewBox', '0 0 384.97 384.97');
            // create svg group for the paths
            const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
            svgGroup.classList.add('svgIcon');
            this._maximizeIcon.appendChild(svgGroup);
            // create paths for the icon itself, one for each corner
            const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path1.setAttributeNS(null, 'd', 'M384.97,12.03c0-6.713-5.317-12.03-12.03-12.03H264.847c-6.833,0-11.922,5.39-11.934,12.223c0,6.821,5.101,11.838,11.934,11.838h96.062l-0.193,96.519c0,6.833,5.197,12.03,12.03,12.03c6.833-0.012,12.03-5.197,12.03-12.03l0.193-108.369c0-0.036-0.012-0.06-0.012-0.084C384.958,12.09,384.97,12.066,384.97,12.03z');
            const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path2.setAttributeNS(null, 'd', 'M120.496,0H12.403c-0.036,0-0.06,0.012-0.096,0.012C12.283,0.012,12.247,0,12.223,0C5.51,0,0.192,5.317,0.192,12.03L0,120.399c0,6.833,5.39,11.934,12.223,11.934c6.821,0,11.838-5.101,11.838-11.934l0.192-96.339h96.242c6.833,0,12.03-5.197,12.03-12.03C132.514,5.197,127.317,0,120.496,0z');
            const path3 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path3.setAttributeNS(null, 'd', 'M120.123,360.909H24.061v-96.242c0-6.833-5.197-12.03-12.03-12.03S0,257.833,0,264.667v108.092c0,0.036,0.012,0.06,0.012,0.084c0,0.036-0.012,0.06-0.012,0.096c0,6.713,5.317,12.03,12.03,12.03h108.092c6.833,0,11.922-5.39,11.934-12.223C132.057,365.926,126.956,360.909,120.123,360.909z');
            const path4 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path4.setAttributeNS(null, 'd', 'M372.747,252.913c-6.833,0-11.85,5.101-11.838,11.934v96.062h-96.242c-6.833,0-12.03,5.197-12.03,12.03s5.197,12.03,12.03,12.03h108.092c0.036,0,0.06-0.012,0.084-0.012c0.036-0.012,0.06,0.012,0.096,0.012c6.713,0,12.03-5.317,12.03-12.03V264.847C384.97,258.014,379.58,252.913,372.747,252.913z');
            svgGroup.appendChild(path1);
            svgGroup.appendChild(path2);
            svgGroup.appendChild(path3);
            svgGroup.appendChild(path4);
        }
        return this._maximizeIcon;
    }
    get minimizeIcon() {
        if (!this._minimizeIcon) {
            this._minimizeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            this._minimizeIcon.setAttributeNS(null, 'id', 'minimizeIcon');
            this._minimizeIcon.setAttributeNS(null, 'x', '0px');
            this._minimizeIcon.setAttributeNS(null, 'y', '0px');
            this._minimizeIcon.setAttributeNS(null, 'viewBox', '0 0 385.331 385.331');
            // create svg group for the paths
            const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
            svgGroup.classList.add('svgIcon');
            this._minimizeIcon.appendChild(svgGroup);
            // create paths for the icon itself, one for each corner
            const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path1.setAttributeNS(null, 'd', 'M264.943,156.665h108.273c6.833,0,11.934-5.39,11.934-12.211c0-6.833-5.101-11.85-11.934-11.838h-96.242V36.181c0-6.833-5.197-12.03-12.03-12.03s-12.03,5.197-12.03,12.03v108.273c0,0.036,0.012,0.06,0.012,0.084c0,0.036-0.012,0.06-0.012,0.096C252.913,151.347,258.23,156.677,264.943,156.665z');
            const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path2.setAttributeNS(null, 'd', 'M120.291,24.247c-6.821,0-11.838,5.113-11.838,11.934v96.242H12.03c-6.833,0-12.03,5.197-12.03,12.03c0,6.833,5.197,12.03,12.03,12.03h108.273c0.036,0,0.06-0.012,0.084-0.012c0.036,0,0.06,0.012,0.096,0.012c6.713,0,12.03-5.317,12.03-12.03V36.181C132.514,29.36,127.124,24.259,120.291,24.247z');
            const path3 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path3.setAttributeNS(null, 'd', 'M120.387,228.666H12.115c-6.833,0.012-11.934,5.39-11.934,12.223c0,6.833,5.101,11.85,11.934,11.838h96.242v96.423c0,6.833,5.197,12.03,12.03,12.03c6.833,0,12.03-5.197,12.03-12.03V240.877c0-0.036-0.012-0.06-0.012-0.084c0-0.036,0.012-0.06,0.012-0.096C132.418,233.983,127.1,228.666,120.387,228.666z');
            const path4 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path4.setAttributeNS(null, 'd', 'M373.3,228.666H265.028c-0.036,0-0.06,0.012-0.084,0.012c-0.036,0-0.06-0.012-0.096-0.012c-6.713,0-12.03,5.317-12.03,12.03v108.273c0,6.833,5.39,11.922,12.223,11.934c6.821,0.012,11.838-5.101,11.838-11.922v-96.242H373.3c6.833,0,12.03-5.197,12.03-12.03S380.134,228.678,373.3,228.666z');
            svgGroup.appendChild(path1);
            svgGroup.appendChild(path2);
            svgGroup.appendChild(path3);
            svgGroup.appendChild(path4);
        }
        return this._minimizeIcon;
    }
    onFullscreenChange() {
        super.onFullscreenChange();
        const minimize = this.minimizeIcon;
        const maximize = this.maximizeIcon;
        if (this.isFullscreen) {
            minimize.style.display = 'inline';
            //ios disappearing svg fix
            minimize.style.transform = 'translate(0, 0)';
            maximize.style.display = 'none';
        }
        else {
            minimize.style.display = 'none';
            maximize.style.display = 'inline';
            //ios disappearing svg fix
            maximize.style.transform = 'translate(0, 0)';
        }
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/LabelledButton.ts":
/*!**********************************!*\
  !*** ./src/UI/LabelledButton.ts ***!
  \**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "LabelledButton": () => (/* binding */ LabelledButton)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
 * A button with a text label beside it.
 */
class LabelledButton {
    constructor(label, buttonText) {
        this._label = label;
        this._buttonText = buttonText;
    }
    /**
     * Add a click listener to the button element.
     */
    addOnClickListener(onClickFunc) {
        this.button.addEventListener('click', onClickFunc);
    }
    /**
     * Get the HTMLInputElement for the button.
     */
    get button() {
        if (!this._button) {
            this._button = document.createElement('input');
            this._button.type = 'button';
            this._button.value = this._buttonText;
            this._button.classList.add('overlay-button');
            this._button.classList.add('btn-flat');
        }
        return this._button;
    }
    /**
     * @returns Return or creates a HTML element that represents this setting in the DOM.
     */
    get rootElement() {
        if (!this._rootElement) {
            // create root div with "setting" css class
            this._rootElement = document.createElement('div');
            this._rootElement.classList.add('setting');
            // create div element to contain our setting's text
            const settingsTextElem = document.createElement('div');
            settingsTextElem.innerText = this._label;
            this._rootElement.appendChild(settingsTextElem);
            // create label element to wrap out input type
            const wrapperLabel = document.createElement('label');
            wrapperLabel.classList.add('btn-overlay');
            this._rootElement.appendChild(wrapperLabel);
            wrapperLabel.appendChild(this.button);
        }
        return this._rootElement;
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/LatencyTest.ts":
/*!*******************************!*\
  !*** ./src/UI/LatencyTest.ts ***!
  \*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "LatencyTest": () => (/* binding */ LatencyTest)
/* harmony export */ });
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__);
// Copyright Epic Games, Inc. All Rights Reserved.
 
/**
 * Latency test UI elements and results handling.
 */
class LatencyTest {
    /**
     * Get the the button containing the stats icon.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('section');
            this._rootElement.classList.add('settingsContainer');
            // make heading
            const heading = document.createElement('div');
            heading.id = 'latencyTestHeader';
            heading.classList.add('settings-text');
            heading.classList.add('settingsHeader');
            this._rootElement.appendChild(heading);
            const headingText = document.createElement('div');
            headingText.innerHTML = 'Latency Test';
            heading.appendChild(headingText);
            heading.appendChild(this.latencyTestButton);
            // make test results element
            const resultsParentElem = document.createElement('div');
            resultsParentElem.id = 'latencyTestContainer';
            resultsParentElem.classList.add('d-none');
            this._rootElement.appendChild(resultsParentElem);
            resultsParentElem.appendChild(this.latencyTestResultsElement);
        }
        return this._rootElement;
    }
    get latencyTestResultsElement() {
        if (!this._latencyTestResultsElement) {
            this._latencyTestResultsElement = document.createElement('div');
            this._latencyTestResultsElement.id = 'latencyStatsResults';
            this._latencyTestResultsElement.classList.add('StatsResult');
        }
        return this._latencyTestResultsElement;
    }
    get latencyTestButton() {
        if (!this._latencyTestButton) {
            this._latencyTestButton = document.createElement('input');
            this._latencyTestButton.type = 'button';
            this._latencyTestButton.value = 'Run Test';
            this._latencyTestButton.id = 'btn-start-latency-test';
            this._latencyTestButton.classList.add('streamTools-button');
            this._latencyTestButton.classList.add('btn-flat');
        }
        return this._latencyTestButton;
    }
    /**
     * Populate the UI based on the latency test's results.
     * @param latencyTimings The latency test results.
     */
    handleTestResult(latencyTimings) {
        _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Log(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), latencyTimings.toString(), 6);
        let latencyStatsInnerHTML = '';
        latencyStatsInnerHTML +=
            '<div>Net latency RTT (ms): ' +
                latencyTimings.networkLatency +
                '</div>';
        latencyStatsInnerHTML +=
            '<div>UE Encode (ms): ' + latencyTimings.EncodeMs + '</div>';
        latencyStatsInnerHTML +=
            '<div>UE Capture (ms): ' +
                latencyTimings.CaptureToSendMs +
                '</div>';
        latencyStatsInnerHTML +=
            '<div>Browser send latency (ms): ' +
                latencyTimings.browserSendLatency +
                '</div>';
        latencyStatsInnerHTML +=
            latencyTimings.frameDisplayDeltaTimeMs &&
                latencyTimings.browserReceiptTimeMs
                ? '<div>Browser receive latency (ms): ' +
                    latencyTimings.frameDisplayDeltaTimeMs +
                    '</div>'
                : '';
        latencyStatsInnerHTML +=
            '<div>Total latency (excluding browser) (ms): ' +
                latencyTimings.latencyExcludingDecode +
                '</div>';
        latencyStatsInnerHTML += latencyTimings.endToEndLatency
            ? '<div>Total latency (ms): ' +
                latencyTimings.endToEndLatency +
                '</div>'
            : '';
        this.latencyTestResultsElement.innerHTML = latencyStatsInnerHTML;
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/SettingsIcon.ts":
/*!********************************!*\
  !*** ./src/UI/SettingsIcon.ts ***!
  \********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "SettingsIcon": () => (/* binding */ SettingsIcon)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
 * Settings icon that can be clicked.
 */
class SettingsIcon {
    /**
     * Get the the button containing the settings icon.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('button');
            this._rootElement.type = 'button';
            this._rootElement.classList.add('UiTool');
            this._rootElement.id = 'settingsBtn';
            this._rootElement.appendChild(this.settingsIcon);
            this._rootElement.appendChild(this.tooltipText);
        }
        return this._rootElement;
    }
    get tooltipText() {
        if (!this._tooltipText) {
            this._tooltipText = document.createElement('span');
            this._tooltipText.classList.add('tooltiptext');
            this._tooltipText.innerHTML = 'Settings';
        }
        return this._tooltipText;
    }
    get settingsIcon() {
        if (!this._settingsIcon) {
            this._settingsIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            this._settingsIcon.setAttributeNS(null, 'id', 'settingsIcon');
            this._settingsIcon.setAttributeNS(null, 'x', '0px');
            this._settingsIcon.setAttributeNS(null, 'y', '0px');
            this._settingsIcon.setAttributeNS(null, 'viewBox', '0 0 478.703 478.703');
            // create svg group for the paths
            const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
            svgGroup.classList.add('svgIcon');
            this._settingsIcon.appendChild(svgGroup);
            // create paths for the icon itself, the inner and out path of a cog
            const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path1.setAttributeNS(null, 'd', 'M454.2,189.101l-33.6-5.7c-3.5-11.3-8-22.2-13.5-32.6l19.8-27.7c8.4-11.8,7.1-27.9-3.2-38.1l-29.8-29.8\
            c-5.6-5.6-13-8.7-20.9-8.7c-6.2,0-12.1,1.9-17.1,5.5l-27.8,19.8c-10.8-5.7-22.1-10.4-33.8-13.9l-5.6-33.2\
            c-2.4-14.3-14.7-24.7-29.2-24.7h-42.1c-14.5,0-26.8,10.4-29.2,24.7l-5.8,34c-11.2,3.5-22.1,8.1-32.5,13.7l-27.5-19.8\
            c-5-3.6-11-5.5-17.2-5.5c-7.9,0-15.4,3.1-20.9,8.7l-29.9,29.8c-10.2,10.2-11.6,26.3-3.2,38.1l20,28.1\
            c-5.5,10.5-9.9,21.4-13.3,32.7l-33.2,5.6c-14.3,2.4-24.7,14.7-24.7,29.2v42.1c0,14.5,10.4,26.8,24.7,29.2l34,5.8\
            c3.5,11.2,8.1,22.1,13.7,32.5l-19.7,27.4c-8.4,11.8-7.1,27.9,3.2,38.1l29.8,29.8c5.6,5.6,13,8.7,20.9,8.7c6.2,0,12.1-1.9,17.1-5.5\
            l28.1-20c10.1,5.3,20.7,9.6,31.6,13l5.6,33.6c2.4,14.3,14.7,24.7,29.2,24.7h42.2c14.5,0,26.8-10.4,29.2-24.7l5.7-33.6\
            c11.3-3.5,22.2-8,32.6-13.5l27.7,19.8c5,3.6,11,5.5,17.2,5.5l0,0c7.9,0,15.3-3.1,20.9-8.7l29.8-29.8c10.2-10.2,11.6-26.3,3.2-38.1\
            l-19.8-27.8c5.5-10.5,10.1-21.4,13.5-32.6l33.6-5.6c14.3-2.4,24.7-14.7,24.7-29.2v-42.1\
            C478.9,203.801,468.5,191.501,454.2,189.101z M451.9,260.401c0,1.3-0.9,2.4-2.2,2.6l-42,7c-5.3,0.9-9.5,4.8-10.8,9.9\
            c-3.8,14.7-9.6,28.8-17.4,41.9c-2.7,4.6-2.5,10.3,0.6,14.7l24.7,34.8c0.7,1,0.6,2.5-0.3,3.4l-29.8,29.8c-0.7,0.7-1.4,0.8-1.9,0.8\
            c-0.6,0-1.1-0.2-1.5-0.5l-34.7-24.7c-4.3-3.1-10.1-3.3-14.7-0.6c-13.1,7.8-27.2,13.6-41.9,17.4c-5.2,1.3-9.1,5.6-9.9,10.8l-7.1,42\
            c-0.2,1.3-1.3,2.2-2.6,2.2h-42.1c-1.3,0-2.4-0.9-2.6-2.2l-7-42c-0.9-5.3-4.8-9.5-9.9-10.8c-14.3-3.7-28.1-9.4-41-16.8\
            c-2.1-1.2-4.5-1.8-6.8-1.8c-2.7,0-5.5,0.8-7.8,2.5l-35,24.9c-0.5,0.3-1,0.5-1.5,0.5c-0.4,0-1.2-0.1-1.9-0.8l-29.8-29.8\
            c-0.9-0.9-1-2.3-0.3-3.4l24.6-34.5c3.1-4.4,3.3-10.2,0.6-14.8c-7.8-13-13.8-27.1-17.6-41.8c-1.4-5.1-5.6-9-10.8-9.9l-42.3-7.2\
            c-1.3-0.2-2.2-1.3-2.2-2.6v-42.1c0-1.3,0.9-2.4,2.2-2.6l41.7-7c5.3-0.9,9.6-4.8,10.9-10c3.7-14.7,9.4-28.9,17.1-42\
            c2.7-4.6,2.4-10.3-0.7-14.6l-24.9-35c-0.7-1-0.6-2.5,0.3-3.4l29.8-29.8c0.7-0.7,1.4-0.8,1.9-0.8c0.6,0,1.1,0.2,1.5,0.5l34.5,24.6\
            c4.4,3.1,10.2,3.3,14.8,0.6c13-7.8,27.1-13.8,41.8-17.6c5.1-1.4,9-5.6,9.9-10.8l7.2-42.3c0.2-1.3,1.3-2.2,2.6-2.2h42.1\
            c1.3,0,2.4,0.9,2.6,2.2l7,41.7c0.9,5.3,4.8,9.6,10,10.9c15.1,3.8,29.5,9.7,42.9,17.6c4.6,2.7,10.3,2.5,14.7-0.6l34.5-24.8\
            c0.5-0.3,1-0.5,1.5-0.5c0.4,0,1.2,0.1,1.9,0.8l29.8,29.8c0.9,0.9,1,2.3,0.3,3.4l-24.7,34.7c-3.1,4.3-3.3,10.1-0.6,14.7\
            c7.8,13.1,13.6,27.2,17.4,41.9c1.3,5.2,5.6,9.1,10.8,9.9l42,7.1c1.3,0.2,2.2,1.3,2.2,2.6v42.1H451.9z');
            const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path2.setAttributeNS(null, 'd', 'M239.4,136.001c-57,0-103.3,46.3-103.3,103.3s46.3,103.3,103.3,103.3s103.3-46.3,103.3-103.3S296.4,136.001,239.4,136.001z M239.4,315.601c-42.1,0-76.3-34.2-76.3-76.3s34.2-76.3,76.3-76.3s76.3,34.2,76.3,76.3S281.5,315.601,239.4,315.601z');
            svgGroup.appendChild(path1);
            svgGroup.appendChild(path2);
        }
        return this._settingsIcon;
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/SettingsPanel.ts":
/*!*********************************!*\
  !*** ./src/UI/SettingsPanel.ts ***!
  \*********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "SettingsPanel": () => (/* binding */ SettingsPanel)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
 * A UI component containing all the settings for the application.
 */
class SettingsPanel {
    constructor() {
        this._rootElement = null;
    }
    /**
     * @returns Return or creates a HTML element that represents this setting in the DOM.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('div');
            this._rootElement.id = 'settings-panel';
            this._rootElement.classList.add('panel-wrap');
            const panelElem = document.createElement('div');
            panelElem.classList.add('panel');
            this._rootElement.appendChild(panelElem);
            const settingsHeading = document.createElement('div');
            settingsHeading.id = 'settingsHeading';
            settingsHeading.textContent = 'Settings';
            panelElem.appendChild(settingsHeading);
            panelElem.appendChild(this.settingsCloseButton);
            panelElem.appendChild(this.settingsContentElement);
        }
        return this._rootElement;
    }
    get settingsContentElement() {
        if (!this._settingsContentElement) {
            this._settingsContentElement = document.createElement('div');
            this._settingsContentElement.id = 'settingsContent';
        }
        return this._settingsContentElement;
    }
    get settingsCloseButton() {
        if (!this._settingsCloseButton) {
            this._settingsCloseButton = document.createElement('div');
            this._settingsCloseButton.id = 'settingsClose';
        }
        return this._settingsCloseButton;
    }
    /**
     * Show settings panel.
     */
    show() {
        if (!this.rootElement.classList.contains('panel-wrap-visible')) {
            this.rootElement.classList.add('panel-wrap-visible');
        }
    }
    /**
     * Toggle the visibility of the settings panel.
     */
    toggleVisibility() {
        this.rootElement.classList.toggle('panel-wrap-visible');
    }
    /**
     * Hide settings panel.
     */
    hide() {
        if (this.rootElement.classList.contains('panel-wrap-visible')) {
            this.rootElement.classList.remove('panel-wrap-visible');
        }
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/StatsIcon.ts":
/*!*****************************!*\
  !*** ./src/UI/StatsIcon.ts ***!
  \*****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "StatsIcon": () => (/* binding */ StatsIcon)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
 * Stats icon that can be clicked.
 */
class StatsIcon {
    /**
     * Get the the button containing the stats icon.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('button');
            this._rootElement.type = 'button';
            this._rootElement.classList.add('UiTool');
            this._rootElement.id = 'statsBtn';
            this._rootElement.appendChild(this.statsIcon);
            this._rootElement.appendChild(this.tooltipText);
        }
        return this._rootElement;
    }
    get tooltipText() {
        if (!this._tooltipText) {
            this._tooltipText = document.createElement('span');
            this._tooltipText.classList.add('tooltiptext');
            this._tooltipText.innerHTML = 'Information';
        }
        return this._tooltipText;
    }
    get statsIcon() {
        if (!this._statsIcon) {
            this._statsIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            this._statsIcon.setAttributeNS(null, 'id', 'statsIcon');
            this._statsIcon.setAttributeNS(null, 'x', '0px');
            this._statsIcon.setAttributeNS(null, 'y', '0px');
            this._statsIcon.setAttributeNS(null, 'viewBox', '0 0 330 330');
            // create svg group for the paths
            const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
            svgGroup.classList.add('svgIcon');
            this._statsIcon.appendChild(svgGroup);
            // create paths for the icon itself, the inner and out path of a cog
            const path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path1.setAttributeNS(null, 'd', 'M165,0.008C74.019,0.008,0,74.024,0,164.999c0,90.977,74.019,164.992,165,164.992s165-74.015,165-164.992C330,74.024,255.981,0.008,165,0.008z M165,299.992c-74.439,0-135-60.557-135-134.992S90.561,30.008,165,30.008s135,60.557,135,134.991C300,239.436,239.439,299.992,165,299.992z');
            const path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path2.setAttributeNS(null, 'd', 'M165,130.008c-8.284,0-15,6.716-15,15v99.983c0,8.284,6.716,15,15,15s15-6.716,15-15v-99.983C180,136.725,173.284,130.008,165,130.008z');
            const path3 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path3.setAttributeNS(null, 'd', 'M165,70.011c-3.95,0-7.811,1.6-10.61,4.39c-2.79,2.79-4.39,6.66-4.39,10.61s1.6,7.81,4.39,10.61c2.79,2.79,6.66,4.39,10.61,4.39s7.81-1.6,10.609-4.39c2.79-2.8,4.391-6.66,4.391-10.61s-1.601-7.82-4.391-10.61C172.81,71.61,168.95,70.011,165,70.011z');
            svgGroup.appendChild(path1);
            svgGroup.appendChild(path2);
            svgGroup.appendChild(path3);
        }
        return this._statsIcon;
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/StatsPanel.ts":
/*!******************************!*\
  !*** ./src/UI/StatsPanel.ts ***!
  \******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "Stat": () => (/* binding */ Stat),
/* harmony export */   "StatsPanel": () => (/* binding */ StatsPanel)
/* harmony export */ });
/* harmony import */ var _LatencyTest__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./LatencyTest */ "./src/UI/LatencyTest.ts");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @epicgames-ps/lib-pixelstreamingfrontend-ue5.3 */ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3");
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _Util_MathUtils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Util/MathUtils */ "./src/Util/MathUtils.ts");
/* harmony import */ var _DataChannelLatencyTest__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./DataChannelLatencyTest */ "./src/UI/DataChannelLatencyTest.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
 
 
 
/**
 * A stat structure, an id, the stat string, and the element where it is rendered.
 */
class Stat {
}
/**
 * A UI component containing all the stats for the application.
 */
class StatsPanel {
    constructor() {
        /* A map stats we are storing/rendering */
        this.statsMap = new Map();
        this.latencyTest = new _LatencyTest__WEBPACK_IMPORTED_MODULE_1__.LatencyTest();
        this.dataChannelLatencyTest = new _DataChannelLatencyTest__WEBPACK_IMPORTED_MODULE_2__.DataChannelLatencyTest();
    }
    /**
     * @returns Return or creates a HTML element that represents this setting in the DOM.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('div');
            this._rootElement.id = 'stats-panel';
            this._rootElement.classList.add('panel-wrap');
            const panelElem = document.createElement('div');
            panelElem.classList.add('panel');
            this._rootElement.appendChild(panelElem);
            const statsHeading = document.createElement('div');
            statsHeading.id = 'statsHeading';
            statsHeading.textContent = 'Information';
            panelElem.appendChild(statsHeading);
            panelElem.appendChild(this.statsCloseButton);
            panelElem.appendChild(this.statsContentElement);
        }
        return this._rootElement;
    }
    get statsContentElement() {
        if (!this._statsContentElement) {
            this._statsContentElement = document.createElement('div');
            this._statsContentElement.id = 'statsContent';
            const streamToolStats = document.createElement('div');
            streamToolStats.id = 'streamToolsStats';
            streamToolStats.classList.add('container');
            const controlStats = document.createElement('div');
            controlStats.id = 'ControlStats';
            controlStats.classList.add('row');
            const statistics = document.createElement('section');
            statistics.id = 'statistics';
            statistics.classList.add('settingsContainer');
            const statisticsHeader = document.createElement('div');
            statisticsHeader.id = 'statisticsHeader';
            statisticsHeader.classList.add('settings-text');
            statisticsHeader.classList.add('settingsHeader');
            const sessionStats = document.createElement('div');
            sessionStats.innerHTML = 'Session Stats';
            this._statsContentElement.appendChild(streamToolStats);
            streamToolStats.appendChild(controlStats);
            controlStats.appendChild(statistics);
            statistics.appendChild(statisticsHeader);
            statisticsHeader.appendChild(sessionStats);
            statistics.appendChild(this.statisticsContainer);
            controlStats.appendChild(this.latencyTest.rootElement);
            controlStats.appendChild(this.dataChannelLatencyTest.rootElement);
        }
        return this._statsContentElement;
    }
    get statisticsContainer() {
        if (!this._statisticsContainer) {
            this._statisticsContainer = document.createElement('div');
            this._statisticsContainer.id = 'statisticsContainer';
            this._statisticsContainer.classList.add('d-none');
            this._statisticsContainer.appendChild(this.statsResult);
        }
        return this._statisticsContainer;
    }
    get statsResult() {
        if (!this._statsResult) {
            this._statsResult = document.createElement('div');
            this._statsResult.id = 'statisticsResult';
            this._statsResult.classList.add('StatsResult');
        }
        return this._statsResult;
    }
    get statsCloseButton() {
        if (!this._statsCloseButton) {
            this._statsCloseButton = document.createElement('div');
            this._statsCloseButton.id = 'statsClose';
        }
        return this._statsCloseButton;
    }
    onDisconnect() {
        this.latencyTest.latencyTestButton.onclick = () => {
            // do nothing
        };
        this.dataChannelLatencyTest.latencyTestButton.onclick = () => {
            //do nothing
        };
    }
    onVideoInitialized(stream) {
        // starting a latency check
        this.latencyTest.latencyTestButton.onclick = () => {
            stream.requestLatencyTest();
        };
        this.dataChannelLatencyTest.latencyTestButton.onclick = () => {
            let started = stream.requestDataChannelLatencyTest({
                duration: 1000,
                rps: 10,
                requestSize: 200,
                responseSize: 200
            });
            if (started) {
                this.dataChannelLatencyTest.handleTestStart();
            }
        };
    }
    configure(settings) {
        if (settings.DisableLatencyTest) {
            this.latencyTest.latencyTestButton.disabled = true;
            this.latencyTest.latencyTestButton.title =
                'Disabled by -PixelStreamingDisableLatencyTester=true';
            this.dataChannelLatencyTest.latencyTestButton.disabled = true;
            this.dataChannelLatencyTest.latencyTestButton.title =
                'Disabled by -PixelStreamingDisableLatencyTester=true';
            _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Info(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), '-PixelStreamingDisableLatencyTester=true, requesting latency report from the the browser to UE is disabled.');
        }
    }
    /**
     * Show stats panel.
     */
    show() {
        if (!this.rootElement.classList.contains('panel-wrap-visible')) {
            this.rootElement.classList.add('panel-wrap-visible');
        }
    }
    /**
     * Toggle the visibility of the stats panel.
     */
    toggleVisibility() {
        this.rootElement.classList.toggle('panel-wrap-visible');
    }
    /**
     * Hide the stats panel.
     */
    hide() {
        if (this.rootElement.classList.contains('panel-wrap-visible')) {
            this.rootElement.classList.remove('panel-wrap-visible');
        }
    }
    handlePlayerCount(playerCount) {
        this.addOrUpdateStat('PlayerCountStat', 'Players', playerCount.toString());
    }
    /**
     * Handle stats coming in from browser/UE
     * @param stats the stats structure
     */
    handleStats(stats) {
        var _a, _b, _c, _d, _e;
        // format numbering based on the browser language
        const numberFormat = new Intl.NumberFormat(window.navigator.language, {
            maximumFractionDigits: 0
        });
        // Inbound data
        const inboundData = _Util_MathUtils__WEBPACK_IMPORTED_MODULE_3__.MathUtils.formatBytes(stats.inboundVideoStats.bytesReceived, 2);
        this.addOrUpdateStat('InboundDataStat', 'Received', inboundData);
        // Packets lost
        const packetsLostStat = Object.prototype.hasOwnProperty.call(stats.inboundVideoStats, 'packetsLost')
            ? numberFormat.format(stats.inboundVideoStats.packetsLost)
            : 'Chrome only';
        this.addOrUpdateStat('PacketsLostStat', 'Packets Lost', packetsLostStat);
        // Bitrate
        if (stats.inboundVideoStats.bitrate) {
            this.addOrUpdateStat('VideoBitrateStat', 'Video Bitrate (kbps)', stats.inboundVideoStats.bitrate.toString());
        }
        if (stats.inboundAudioStats.bitrate) {
            this.addOrUpdateStat('AudioBitrateStat', 'Audio Bitrate (kbps)', stats.inboundAudioStats.bitrate.toString());
        }
        // Video resolution
        const resStat = Object.prototype.hasOwnProperty.call(stats.inboundVideoStats, 'frameWidth') &&
            stats.inboundVideoStats.frameWidth &&
            Object.prototype.hasOwnProperty.call(stats.inboundVideoStats, 'frameHeight') &&
            stats.inboundVideoStats.frameHeight
            ? stats.inboundVideoStats.frameWidth +
                'x' +
                stats.inboundVideoStats.frameHeight
            : 'Chrome only';
        this.addOrUpdateStat('VideoResStat', 'Video resolution', resStat);
        // Frames decoded
        const framesDecoded = Object.prototype.hasOwnProperty.call(stats.inboundVideoStats, 'framesDecoded')
            ? numberFormat.format(stats.inboundVideoStats.framesDecoded)
            : 'Chrome only';
        this.addOrUpdateStat('FramesDecodedStat', 'Frames Decoded', framesDecoded);
        // Framerate
        if (stats.inboundVideoStats.framesPerSecond) {
            this.addOrUpdateStat('FramerateStat', 'Framerate', stats.inboundVideoStats.framesPerSecond.toString());
        }
        // Frames dropped
        this.addOrUpdateStat('FramesDroppedStat', 'Frames dropped', (_a = stats.inboundVideoStats.framesDropped) === null || _a === void 0 ? void 0 : _a.toString());
        if (stats.inboundVideoStats.codecId) {
            this.addOrUpdateStat('VideoCodecStat', 'Video codec', 
            // Split the codec to remove the Fmtp line
            (_c = (_b = stats.codecs
                .get(stats.inboundVideoStats.codecId)) === null || _b === void 0 ? void 0 : _b.split(' ')[0]) !== null && _c !== void 0 ? _c : '');
        }
        if (stats.inboundAudioStats.codecId) {
            this.addOrUpdateStat('AudioCodecStat', 'Audio codec', 
            // Split the codec to remove the Fmtp line
            (_e = (_d = stats.codecs
                .get(stats.inboundAudioStats.codecId)) === null || _d === void 0 ? void 0 : _d.split(' ')[0]) !== null && _e !== void 0 ? _e : '');
        }
        // RTT
        const netRTT = Object.prototype.hasOwnProperty.call(stats.candidatePair, 'currentRoundTripTime') && stats.isNumber(stats.candidatePair.currentRoundTripTime)
            ? numberFormat.format(stats.candidatePair.currentRoundTripTime * 1000)
            : "Can't calculate";
        this.addOrUpdateStat('RTTStat', 'Net RTT (ms)', netRTT);
        this.addOrUpdateStat('DurationStat', 'Duration', stats.sessionStats.runTime);
        this.addOrUpdateStat('ControlsInputStat', 'Controls stream input', stats.sessionStats.controlsStreamInput);
        // QP
        this.addOrUpdateStat('QPStat', 'Video quantization parameter', stats.sessionStats.videoEncoderAvgQP.toString());
        // todo:
        //statsText += `<div>Browser receive to composite (ms): ${stats.inboundVideoStats.receiveToCompositeMs}</div>`;
        _epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.Log(_epicgames_ps_lib_pixelstreamingfrontend_ue5_3__WEBPACK_IMPORTED_MODULE_0__.Logger.GetStackTrace(), `--------- Stats ---------\n ${stats}\n------------------------`, 6);
    }
    /**
     * Adds a new stat to the stats results in the DOM or updates an exiting stat.
     * @param id The id of the stat to add/update.
     * @param stat The contents of the stat.
     */
    addOrUpdateStat(id, statLabel, stat) {
        const statHTML = `${statLabel}: ${stat}`;
        if (!this.statsMap.has(id)) {
            // create the stat
            const newStat = new Stat();
            newStat.id = id;
            newStat.stat = stat;
            newStat.title = statLabel;
            newStat.element = document.createElement('div');
            newStat.element.innerHTML = statHTML;
            // add the stat to the dom
            this.statsResult.appendChild(newStat.element);
            this.statsMap.set(id, newStat);
        }
        // update the existing stat
        else {
            const value = this.statsMap.get(id);
            if (value !== undefined) {
                value.element.innerHTML = statHTML;
            }
        }
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/UIConfigurationTypes.ts":
/*!****************************************!*\
  !*** ./src/UI/UIConfigurationTypes.ts ***!
  \****************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "UIElementCreationMode": () => (/* binding */ UIElementCreationMode),
/* harmony export */   "isPanelEnabled": () => (/* binding */ isPanelEnabled)
/* harmony export */ });
/** Whether a stream UI element is internally made, externally provided, or disabled. */
var UIElementCreationMode;
(function (UIElementCreationMode) {
    UIElementCreationMode[UIElementCreationMode["CreateDefaultElement"] = 0] = "CreateDefaultElement";
    UIElementCreationMode[UIElementCreationMode["UseCustomElement"] = 1] = "UseCustomElement";
    UIElementCreationMode[UIElementCreationMode["Disable"] = 2] = "Disable";
})(UIElementCreationMode || (UIElementCreationMode = {}));
function isPanelEnabled(config) {
    return !config || (!!config && config.isEnabled);
}
 
 
/***/ }),
 
/***/ "./src/UI/VideoQpIndicator.ts":
/*!************************************!*\
  !*** ./src/UI/VideoQpIndicator.ts ***!
  \************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "VideoQpIndicator": () => (/* binding */ VideoQpIndicator)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
 * A UI element showing the QP (quantization parameter) of the video stream at the last encoded frame (well, last transmitted QP really).
 * A blockier encoding will have a higher QP and this will make the indicator turn more red.
 * A non-blocky stream will have a lower QP and this will make the indicator turn more green.
 * The QP indicator is represented visually using a WiFi icon.
 */
class VideoQpIndicator {
    constructor() {
        this.videoEncoderAvgQP = -1;
        // non html elements
        this.statsText = '';
        this.color = '';
        // qp colors
        this.orangeQP = 26;
        this.redQP = 35;
    }
    /**
     * Get the root element of the QP indicator.
     */
    get rootElement() {
        if (!this._rootElement) {
            // make the root element that contains the svg for the connection
            this._rootElement = document.createElement('div');
            this._rootElement.id = 'connection';
            this._rootElement.classList.add('UiTool');
            // add svg icon for the connection strength
            this._rootElement.appendChild(this.qualityStatus);
            // add the text underneath the connection
            this._rootElement.appendChild(this.qualityText);
            // set colors to not connected initially
            this.updateQpTooltip(-1);
        }
        return this._rootElement;
    }
    /**
     * Get the text that displays under the icon.
     */
    get qualityText() {
        if (!this._qualityText) {
            this._qualityText = document.createElement('span');
            this._qualityText.id = 'qualityText';
            this._qualityText.classList.add('tooltiptext');
        }
        return this._qualityText;
    }
    /**
     * Get the icon.
     */
    get qualityStatus() {
        if (!this._qualityStatus) {
            this._qualityStatus = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            this._qualityStatus.setAttributeNS(null, 'id', 'connectionStrength');
            this._qualityStatus.setAttributeNS(null, 'x', '0px');
            this._qualityStatus.setAttributeNS(null, 'y', '0px');
            this._qualityStatus.setAttributeNS(null, 'viewBox', '0 0 494.45 494.45');
            // build wifi icon
            this.qualityStatus.appendChild(this.dot);
            this.qualityStatus.appendChild(this.middle);
            this.qualityStatus.appendChild(this.outer);
            this.qualityStatus.appendChild(this.inner);
        }
        return this._qualityStatus;
    }
    /**
     * Get the dot at the bottom of the wifi icon.
     */
    get dot() {
        if (!this._dot) {
            this._dot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
            this._dot.setAttributeNS(null, 'id', 'dot');
            this._dot.setAttributeNS(null, 'cx', '247.125');
            this._dot.setAttributeNS(null, 'cy', '398.925');
            this._dot.setAttributeNS(null, 'r', '35.3');
        }
        return this._dot;
    }
    /**
     * Get the outer arc of the wifi icon.
     */
    get outer() {
        if (!this._outer) {
            this._outer = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            this._outer.setAttributeNS(null, 'id', 'outer');
            this._outer.setAttributeNS(null, 'd', 'M467.925,204.625c-6.8,0-13.5-2.6-18.7-7.8c-111.5-111.4-292.7-111.4-404.1,0c-10.3,10.3-27.1,10.3-37.4,0s-10.3-27.1,0-37.4c64-64,149-99.2,239.5-99.2s175.5,35.2,239.5,99.2c10.3,10.3,10.3,27.1,0,37.4C481.425,202.025,474.625,204.625,467.925,204.625z');
        }
        return this._outer;
    }
    /**
     * Get the middle arc of the wifi icon.
     */
    get middle() {
        if (!this._middle) {
            this._middle = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            this._middle.setAttributeNS(null, 'id', 'middle');
            this._middle.setAttributeNS(null, 'd', 'M395.225,277.325c-6.8,0-13.5-2.6-18.7-7.8c-71.4-71.3-187.4-71.3-258.8,0c-10.3,10.3-27.1,10.3-37.4,0s-10.3-27.1,0-37.4c92-92,241.6-92,333.6,0c10.3,10.3,10.3,27.1,0,37.4C408.725,274.725,401.925,277.325,395.225,277.325z');
        }
        return this._middle;
    }
    /**
     * Get the inner arc of the wifi icon.
     */
    get inner() {
        if (!this._inner) {
            this._inner = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            this._inner.setAttributeNS(null, 'id', 'inner');
            this._inner.setAttributeNS(null, 'd', 'M323.625,348.825c-6.8,0-13.5-2.6-18.7-7.8c-15.4-15.4-36-23.9-57.8-23.9s-42.4,8.5-57.8,23.9c-10.3,10.3-27.1,10.3-37.4,0c-10.3-10.3-10.3-27.1,0-37.4c25.4-25.4,59.2-39.4,95.2-39.4s69.8,14,95.2,39.5c10.3,10.3,10.3,27.1,0,37.4C337.225,346.225,330.425,348.825,323.625,348.825z');
        }
        return this._inner;
    }
    /**
     * Used to set the speed of the status light.
     * @param speed - Set the speed of the blink, higher numbers make the status light blink faster.
     */
    blinkVideoQualityStatus(speed) {
        let iteration = speed;
        let opacity = 1;
        const tickID = setInterval(() => {
            opacity -= 0.1;
            this.qualityText.style.opacity = String(Math.abs((opacity - 0.5) * 2));
            if (opacity <= 0.1) {
                if (--iteration == 0) {
                    clearInterval(tickID);
                }
                else {
                    opacity = 1;
                }
            }
        }, 100 / speed);
    }
    /**
     * updates the QP tooltip by converting the Video Encoder QP to a color light
     * @param QP - The video encoder QP number needed to find the average
     */
    updateQpTooltip(QP) {
        this.videoEncoderAvgQP = QP;
        if (QP > this.redQP) {
            this.color = 'red';
            this.blinkVideoQualityStatus(2);
            this.statsText = `<div style="color: ${this.color}">Poor encoding quality</div>`;
            this.outer.setAttributeNS(null, 'fill', '#3c3b40');
            this.middle.setAttributeNS(null, 'fill', '#3c3b40');
            this.inner.setAttributeNS(null, 'fill', this.color);
            this.dot.setAttributeNS(null, 'fill', this.color);
        }
        else if (QP > this.orangeQP) {
            this.color = 'orange';
            this.blinkVideoQualityStatus(1);
            this.statsText = `<div style="color: ${this.color}">Blocky encoding quality</div>`;
            this.outer.setAttributeNS(null, 'fill', '#3c3b40');
            this.middle.setAttributeNS(null, 'fill', this.color);
            this.inner.setAttributeNS(null, 'fill', this.color);
            this.dot.setAttributeNS(null, 'fill', this.color);
        }
        else if (QP <= 0) {
            this.color = '#b0b0b0';
            this.outer.setAttributeNS(null, 'fill', '#3c3b40');
            this.middle.setAttributeNS(null, 'fill', '#3c3b40');
            this.inner.setAttributeNS(null, 'fill', '#3c3b40');
            this.dot.setAttributeNS(null, 'fill', '#3c3b40');
            this.statsText = `<div style="color: ${this.color}">Not connected</div>`;
        }
        else {
            this.color = 'lime';
            this.qualityStatus.style.opacity = '1';
            this.statsText = `<div style="color: ${this.color}">Clear encoding quality</div>`;
            this.outer.setAttributeNS(null, 'fill', this.color);
            this.middle.setAttributeNS(null, 'fill', this.color);
            this.inner.setAttributeNS(null, 'fill', this.color);
            this.dot.setAttributeNS(null, 'fill', this.color);
        }
        this.qualityText.innerHTML = this.statsText;
    }
}
 
 
/***/ }),
 
/***/ "./src/UI/XRIcon.ts":
/*!**************************!*\
  !*** ./src/UI/XRIcon.ts ***!
  \**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "XRIcon": () => (/* binding */ XRIcon)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
/**
 * XR icon that can be clicked.
 */
class XRIcon {
    /**
     * Get the the button containing the XR icon.
     */
    get rootElement() {
        if (!this._rootElement) {
            this._rootElement = document.createElement('button');
            this._rootElement.type = 'button';
            this._rootElement.classList.add('UiTool');
            this._rootElement.id = 'xrBtn';
            this._rootElement.appendChild(this.xrIcon);
            this._rootElement.appendChild(this.tooltipText);
        }
        return this._rootElement;
    }
    get tooltipText() {
        if (!this._tooltipText) {
            this._tooltipText = document.createElement('span');
            this._tooltipText.classList.add('tooltiptext');
            this._tooltipText.innerHTML = 'XR';
        }
        return this._tooltipText;
    }
    get xrIcon() {
        if (!this._xrIcon) {
            this._xrIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            this._xrIcon.setAttributeNS(null, 'id', 'xrIcon');
            this._xrIcon.setAttributeNS(null, 'x', '0px');
            this._xrIcon.setAttributeNS(null, 'y', '0px');
            this._xrIcon.setAttributeNS(null, 'viewBox', '0 0 100 100');
            // create svg group for the paths
            const svgGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
            svgGroup.classList.add('svgIcon');
            this._xrIcon.appendChild(svgGroup);
            // create paths for the icon itself, the path of the xr headset
            const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
            path.setAttributeNS(null, 'd', 'M29 41c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 14c-2.8 0-5-2.2-5-5s2.2-5 5-5 5 2.2 5 5-2.2 5-5 5zm42-14c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm0 14c-2.8 0-5-2.2-5-5s2.2-5 5-5 5 2.2 5 5-2.2 5-5 5zm12-31H17c-6.6 0-12 5.4-12 12v28c0 6.6 5.4 12 12 12h14.5c3.5 0 6.8-1.5 9-4.1l3.5-4c1.5-1.7 3.7-2.7 6-2.7s4.5 1 6 2.7l3.5 4c2.3 2.6 5.6 4.1 9 4.1H83c6.6 0 12-5.4 12-12V36c0-6.6-5.4-12-12-12zm8 40c0 4.4-3.6 8-8 8H68.5c-2.3 0-4.5-1-6-2.7l-3.5-4c-2.3-2.6-5.6-4.1-9-4.1-3.5 0-6.8 1.5-9 4.1l-3.5 4C36 71 33.8 72 31.5 72H17c-4.4 0-8-3.6-8-8V36c0-4.4 3.6-8 8-8h66c4.4 0 8 3.6 8 8v28z');
            svgGroup.appendChild(path);
        }
        return this._xrIcon;
    }
}
 
 
/***/ }),
 
/***/ "./src/Util/MathUtils.ts":
/*!*******************************!*\
  !*** ./src/Util/MathUtils.ts ***!
  \*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "MathUtils": () => (/* binding */ MathUtils)
/* harmony export */ });
// Copyright Epic Games, Inc. All Rights Reserved.
class MathUtils {
    /**
     * formats Bytes coming in for video stats
     * @param bytes number to convert
     * @param decimals number of decimal places
     */
    static formatBytes(bytes, decimals) {
        if (bytes === 0) {
            return '0';
        }
        const factor = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = [
            'Bytes',
            'KiB',
            'MiB',
            'GiB',
            'TiB',
            'PiB',
            'EiB',
            'ZiB',
            'YiB'
        ];
        const i = Math.floor(Math.log(bytes) / Math.log(factor));
        return (parseFloat((bytes / Math.pow(factor, i)).toFixed(dm)) +
            ' ' +
            sizes[i]);
    }
}
 
 
/***/ }),
 
/***/ "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3":
/*!*****************************************************************!*\
  !*** external "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3" ***!
  \*****************************************************************/
/***/ ((module) => {
 
module.exports = __WEBPACK_EXTERNAL_MODULE__epicgames_ps_lib_pixelstreamingfrontend_ue5_3__;
 
/***/ }),
 
/***/ "jss":
/*!**********************!*\
  !*** external "jss" ***!
  \**********************/
/***/ ((module) => {
 
module.exports = __WEBPACK_EXTERNAL_MODULE_jss__;
 
/***/ }),
 
/***/ "jss-plugin-camel-case":
/*!****************************************!*\
  !*** external "jss-plugin-camel-case" ***!
  \****************************************/
/***/ ((module) => {
 
module.exports = __WEBPACK_EXTERNAL_MODULE_jss_plugin_camel_case__;
 
/***/ }),
 
/***/ "jss-plugin-global":
/*!************************************!*\
  !*** external "jss-plugin-global" ***!
  \************************************/
/***/ ((module) => {
 
module.exports = __WEBPACK_EXTERNAL_MODULE_jss_plugin_global__;
 
/***/ })
 
/******/     });
/************************************************************************/
/******/     // The module cache
/******/     var __webpack_module_cache__ = {};
/******/     
/******/     // The require function
/******/     function __webpack_require__(moduleId) {
/******/         // Check if module is in cache
/******/         var cachedModule = __webpack_module_cache__[moduleId];
/******/         if (cachedModule !== undefined) {
/******/             return cachedModule.exports;
/******/         }
/******/         // Create a new module (and put it into the cache)
/******/         var module = __webpack_module_cache__[moduleId] = {
/******/             // no module.id needed
/******/             // no module.loaded needed
/******/             exports: {}
/******/         };
/******/     
/******/         // Execute the module function
/******/         __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/     
/******/         // Return the exports of the module
/******/         return module.exports;
/******/     }
/******/     
/************************************************************************/
/******/     /* webpack/runtime/compat get default export */
/******/     (() => {
/******/         // getDefaultExport function for compatibility with non-harmony modules
/******/         __webpack_require__.n = (module) => {
/******/             var getter = module && module.__esModule ?
/******/                 () => (module['default']) :
/******/                 () => (module);
/******/             __webpack_require__.d(getter, { a: getter });
/******/             return getter;
/******/         };
/******/     })();
/******/     
/******/     /* webpack/runtime/define property getters */
/******/     (() => {
/******/         // define getter functions for harmony exports
/******/         __webpack_require__.d = (exports, definition) => {
/******/             for(var key in definition) {
/******/                 if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/                     Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/                 }
/******/             }
/******/         };
/******/     })();
/******/     
/******/     /* webpack/runtime/hasOwnProperty shorthand */
/******/     (() => {
/******/         __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/     })();
/******/     
/******/     /* webpack/runtime/make namespace object */
/******/     (() => {
/******/         // define __esModule on exports
/******/         __webpack_require__.r = (exports) => {
/******/             if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/                 Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/             }
/******/             Object.defineProperty(exports, '__esModule', { value: true });
/******/         };
/******/     })();
/******/     
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
/*!******************************************!*\
  !*** ./src/pixelstreamingfrontend-ui.ts ***!
  \******************************************/
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "AFKOverlay": () => (/* reexport safe */ _Overlay_AFKOverlay__WEBPACK_IMPORTED_MODULE_2__.AFKOverlay),
/* harmony export */   "ActionOverlay": () => (/* reexport safe */ _Overlay_ActionOverlay__WEBPACK_IMPORTED_MODULE_3__.ActionOverlay),
/* harmony export */   "Application": () => (/* reexport safe */ _Application_Application__WEBPACK_IMPORTED_MODULE_0__.Application),
/* harmony export */   "ConfigUI": () => (/* reexport safe */ _Config_ConfigUI__WEBPACK_IMPORTED_MODULE_11__.ConfigUI),
/* harmony export */   "ConnectOverlay": () => (/* reexport safe */ _Overlay_ConnectOverlay__WEBPACK_IMPORTED_MODULE_5__.ConnectOverlay),
/* harmony export */   "DisconnectOverlay": () => (/* reexport safe */ _Overlay_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_6__.DisconnectOverlay),
/* harmony export */   "ErrorOverlay": () => (/* reexport safe */ _Overlay_ErrorOverlay__WEBPACK_IMPORTED_MODULE_7__.ErrorOverlay),
/* harmony export */   "InfoOverlay": () => (/* reexport safe */ _Overlay_InfoOverlay__WEBPACK_IMPORTED_MODULE_8__.InfoOverlay),
/* harmony export */   "OverlayBase": () => (/* reexport safe */ _Overlay_BaseOverlay__WEBPACK_IMPORTED_MODULE_4__.OverlayBase),
/* harmony export */   "PixelStreamingApplicationStyle": () => (/* reexport safe */ _Styles_PixelStreamingApplicationStyles__WEBPACK_IMPORTED_MODULE_1__.PixelStreamingApplicationStyle),
/* harmony export */   "PlayOverlay": () => (/* reexport safe */ _Overlay_PlayOverlay__WEBPACK_IMPORTED_MODULE_9__.PlayOverlay),
/* harmony export */   "SettingUIBase": () => (/* reexport safe */ _Config_SettingUIBase__WEBPACK_IMPORTED_MODULE_12__.SettingUIBase),
/* harmony export */   "SettingUIFlag": () => (/* reexport safe */ _Config_SettingUIFlag__WEBPACK_IMPORTED_MODULE_13__.SettingUIFlag),
/* harmony export */   "SettingUINumber": () => (/* reexport safe */ _Config_SettingUINumber__WEBPACK_IMPORTED_MODULE_14__.SettingUINumber),
/* harmony export */   "SettingUIOption": () => (/* reexport safe */ _Config_SettingUIOption__WEBPACK_IMPORTED_MODULE_15__.SettingUIOption),
/* harmony export */   "SettingUIText": () => (/* reexport safe */ _Config_SettingUIText__WEBPACK_IMPORTED_MODULE_16__.SettingUIText),
/* harmony export */   "TextOverlay": () => (/* reexport safe */ _Overlay_TextOverlay__WEBPACK_IMPORTED_MODULE_10__.TextOverlay),
/* harmony export */   "UIElementCreationMode": () => (/* reexport safe */ _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_17__.UIElementCreationMode)
/* harmony export */ });
/* harmony import */ var _Application_Application__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Application/Application */ "./src/Application/Application.ts");
/* harmony import */ var _Styles_PixelStreamingApplicationStyles__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Styles/PixelStreamingApplicationStyles */ "./src/Styles/PixelStreamingApplicationStyles.ts");
/* harmony import */ var _Overlay_AFKOverlay__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Overlay/AFKOverlay */ "./src/Overlay/AFKOverlay.ts");
/* harmony import */ var _Overlay_ActionOverlay__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Overlay/ActionOverlay */ "./src/Overlay/ActionOverlay.ts");
/* harmony import */ var _Overlay_BaseOverlay__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Overlay/BaseOverlay */ "./src/Overlay/BaseOverlay.ts");
/* harmony import */ var _Overlay_ConnectOverlay__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Overlay/ConnectOverlay */ "./src/Overlay/ConnectOverlay.ts");
/* harmony import */ var _Overlay_DisconnectOverlay__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Overlay/DisconnectOverlay */ "./src/Overlay/DisconnectOverlay.ts");
/* harmony import */ var _Overlay_ErrorOverlay__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Overlay/ErrorOverlay */ "./src/Overlay/ErrorOverlay.ts");
/* harmony import */ var _Overlay_InfoOverlay__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Overlay/InfoOverlay */ "./src/Overlay/InfoOverlay.ts");
/* harmony import */ var _Overlay_PlayOverlay__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Overlay/PlayOverlay */ "./src/Overlay/PlayOverlay.ts");
/* harmony import */ var _Overlay_TextOverlay__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Overlay/TextOverlay */ "./src/Overlay/TextOverlay.ts");
/* harmony import */ var _Config_ConfigUI__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./Config/ConfigUI */ "./src/Config/ConfigUI.ts");
/* harmony import */ var _Config_SettingUIBase__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Config/SettingUIBase */ "./src/Config/SettingUIBase.ts");
/* harmony import */ var _Config_SettingUIFlag__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Config/SettingUIFlag */ "./src/Config/SettingUIFlag.ts");
/* harmony import */ var _Config_SettingUINumber__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Config/SettingUINumber */ "./src/Config/SettingUINumber.ts");
/* harmony import */ var _Config_SettingUIOption__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Config/SettingUIOption */ "./src/Config/SettingUIOption.ts");
/* harmony import */ var _Config_SettingUIText__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Config/SettingUIText */ "./src/Config/SettingUIText.ts");
/* harmony import */ var _UI_UIConfigurationTypes__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./UI/UIConfigurationTypes */ "./src/UI/UIConfigurationTypes.ts");
// Copyright Epic Games, Inc. All Rights Reserved.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
})();
 
/******/     return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,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YTtXQUM3RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ05BLGtEQUFrRDtBQUV5QztBQUVEO0FBRXhDO0FBQ007QUFDSjtBQUNNO0FBQ007QUFDVjtBQUNGO0FBQ0E7QUFDQTtBQUNQO0FBQ1U7QUFDQTtBQUNJO0FBQ0E7QUFDSjtBQUMrQyIsInNvdXJjZXMiOlsid2VicGFjazovL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpL3dlYnBhY2svdW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbiIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9BcHBsaWNhdGlvbi9BcHBsaWNhdGlvbi50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9Db25maWcvQ29uZmlnVUkudHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvQ29uZmlnL1NldHRpbmdVSUJhc2UudHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvQ29uZmlnL1NldHRpbmdVSUZsYWcudHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvQ29uZmlnL1NldHRpbmdVSU51bWJlci50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9Db25maWcvU2V0dGluZ1VJT3B0aW9uLnRzIiwid2VicGFjazovL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLy4vc3JjL0NvbmZpZy9TZXR0aW5nVUlUZXh0LnRzIiwid2VicGFjazovL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLy4vc3JjL092ZXJsYXkvQUZLT3ZlcmxheS50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9PdmVybGF5L0FjdGlvbk92ZXJsYXkudHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvT3ZlcmxheS9CYXNlT3ZlcmxheS50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9PdmVybGF5L0Nvbm5lY3RPdmVybGF5LnRzIiwid2VicGFjazovL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLy4vc3JjL092ZXJsYXkvRGlzY29ubmVjdE92ZXJsYXkudHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvT3ZlcmxheS9FcnJvck92ZXJsYXkudHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvT3ZlcmxheS9JbmZvT3ZlcmxheS50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9PdmVybGF5L1BsYXlPdmVybGF5LnRzIiwid2VicGFjazovL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLy4vc3JjL092ZXJsYXkvVGV4dE92ZXJsYXkudHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvU3R5bGVzL1BpeGVsU3RyZWFtaW5nQXBwbGljYXRpb25TdHlsZXMudHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvVUkvQ29udHJvbHMudHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvVUkvRGF0YUNoYW5uZWxMYXRlbmN5VGVzdC50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9VSS9GdWxsc2NyZWVuSWNvbi50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9VSS9MYWJlbGxlZEJ1dHRvbi50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9VSS9MYXRlbmN5VGVzdC50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9VSS9TZXR0aW5nc0ljb24udHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvVUkvU2V0dGluZ3NQYW5lbC50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9VSS9TdGF0c0ljb24udHMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvLi9zcmMvVUkvU3RhdHNQYW5lbC50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9VSS9VSUNvbmZpZ3VyYXRpb25UeXBlcy50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9VSS9WaWRlb1FwSW5kaWNhdG9yLnRzIiwid2VicGFjazovL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLy4vc3JjL1VJL1hSSWNvbi50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS8uL3NyYy9VdGlsL01hdGhVdGlscy50cyIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS9leHRlcm5hbCB1bWQgXCJAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zXCIiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvZXh0ZXJuYWwgdW1kIFwianNzXCIiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvZXh0ZXJuYWwgdW1kIFwianNzLXBsdWdpbi1jYW1lbC1jYXNlXCIiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvZXh0ZXJuYWwgdW1kIFwianNzLXBsdWdpbi1nbG9iYWxcIiIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS93ZWJwYWNrL3J1bnRpbWUvY29tcGF0IGdldCBkZWZhdWx0IGV4cG9ydCIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkvd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aS93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVpLy4vc3JjL3BpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuM1wiKSwgcmVxdWlyZShcImpzc1wiKSwgcmVxdWlyZShcImpzcy1wbHVnaW4tZ2xvYmFsXCIpLCByZXF1aXJlKFwianNzLXBsdWdpbi1jYW1lbC1jYXNlXCIpKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtcIkBlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjNcIiwgXCJqc3NcIiwgXCJqc3MtcGx1Z2luLWdsb2JhbFwiLCBcImpzcy1wbHVnaW4tY2FtZWwtY2FzZVwiXSwgZmFjdG9yeSk7XG5cdGVsc2UgaWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKVxuXHRcdGV4cG9ydHNbXCJsaWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11aVwiXSA9IGZhY3RvcnkocmVxdWlyZShcIkBlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjNcIiksIHJlcXVpcmUoXCJqc3NcIiksIHJlcXVpcmUoXCJqc3MtcGx1Z2luLWdsb2JhbFwiKSwgcmVxdWlyZShcImpzcy1wbHVnaW4tY2FtZWwtY2FzZVwiKSk7XG5cdGVsc2Vcblx0XHRyb290W1wibGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWlcIl0gPSBmYWN0b3J5KHJvb3RbXCJAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zXCJdLCByb290W1wianNzXCJdLCByb290W1wianNzLXBsdWdpbi1nbG9iYWxcIl0sIHJvb3RbXCJqc3MtcGx1Z2luLWNhbWVsLWNhc2VcIl0pO1xufSkodGhpcywgKF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfX2VwaWNnYW1lc19wc19saWJfcGl4ZWxzdHJlYW1pbmdmcm9udGVuZF91ZTVfM19fLCBfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFX2pzc19fLCBfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFX2pzc19wbHVnaW5fZ2xvYmFsX18sIF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfanNzX3BsdWdpbl9jYW1lbF9jYXNlX18pID0+IHtcbnJldHVybiAiLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQge1xuICAgIFBpeGVsU3RyZWFtaW5nLFxuICAgIEZsYWdzLFxuICAgIExvZ2dlcixcbiAgICBBZ2dyZWdhdGVkU3RhdHMsXG4gICAgTGF0ZW5jeVRlc3RSZXN1bHRzLFxuICAgIEluaXRpYWxTZXR0aW5ncyxcbiAgICBNZXNzYWdlU3RyZWFtZXJMaXN0XG59IGZyb20gJ0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMnO1xuaW1wb3J0IHsgT3ZlcmxheUJhc2UgfSBmcm9tICcuLi9PdmVybGF5L0Jhc2VPdmVybGF5JztcbmltcG9ydCB7IEFjdGlvbk92ZXJsYXkgfSBmcm9tICcuLi9PdmVybGF5L0FjdGlvbk92ZXJsYXknO1xuaW1wb3J0IHsgVGV4dE92ZXJsYXkgfSBmcm9tICcuLi9PdmVybGF5L1RleHRPdmVybGF5JztcbmltcG9ydCB7IENvbm5lY3RPdmVybGF5IH0gZnJvbSAnLi4vT3ZlcmxheS9Db25uZWN0T3ZlcmxheSc7XG5pbXBvcnQgeyBEaXNjb25uZWN0T3ZlcmxheSB9IGZyb20gJy4uL092ZXJsYXkvRGlzY29ubmVjdE92ZXJsYXknO1xuaW1wb3J0IHsgUGxheU92ZXJsYXkgfSBmcm9tICcuLi9PdmVybGF5L1BsYXlPdmVybGF5JztcbmltcG9ydCB7IEluZm9PdmVybGF5IH0gZnJvbSAnLi4vT3ZlcmxheS9JbmZvT3ZlcmxheSc7XG5pbXBvcnQgeyBFcnJvck92ZXJsYXkgfSBmcm9tICcuLi9PdmVybGF5L0Vycm9yT3ZlcmxheSc7XG5pbXBvcnQgeyBBRktPdmVybGF5IH0gZnJvbSAnLi4vT3ZlcmxheS9BRktPdmVybGF5JztcbmltcG9ydCB7IENvbnRyb2xzLCBDb250cm9sc1VJQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL1VJL0NvbnRyb2xzJztcbmltcG9ydCB7IExhYmVsbGVkQnV0dG9uIH0gZnJvbSAnLi4vVUkvTGFiZWxsZWRCdXR0b24nO1xuaW1wb3J0IHsgU2V0dGluZ3NQYW5lbCB9IGZyb20gJy4uL1VJL1NldHRpbmdzUGFuZWwnO1xuaW1wb3J0IHsgU3RhdHNQYW5lbCB9IGZyb20gJy4uL1VJL1N0YXRzUGFuZWwnO1xuaW1wb3J0IHsgVmlkZW9RcEluZGljYXRvciB9IGZyb20gJy4uL1VJL1ZpZGVvUXBJbmRpY2F0b3InO1xuaW1wb3J0IHsgQ29uZmlnVUksIExpZ2h0TW9kZSB9IGZyb20gJy4uL0NvbmZpZy9Db25maWdVSSc7XG5pbXBvcnQgeyBcbiAgICBVSUVsZW1lbnRDcmVhdGlvbk1vZGUsIFxuICAgIFBhbmVsQ29uZmlndXJhdGlvbiwgXG4gICAgaXNQYW5lbEVuYWJsZWQsXG4gICAgVUlFbGVtZW50Q29uZmlnXG59IGZyb20gJy4uL1VJL1VJQ29uZmlndXJhdGlvblR5cGVzJ1xuaW1wb3J0IHsgRnVsbFNjcmVlbkljb25CYXNlLCBGdWxsU2NyZWVuSWNvbkV4dGVybmFsIH0gZnJvbSAnLi4vVUkvRnVsbHNjcmVlbkljb24nO1xuaW1wb3J0IHtcbiAgICBEYXRhQ2hhbm5lbExhdGVuY3lUZXN0UmVzdWx0XG59IGZyb20gXCJAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zL3R5cGVzL0RhdGFDaGFubmVsL0RhdGFDaGFubmVsTGF0ZW5jeVRlc3RSZXN1bHRzXCI7XG5cblxuLyoqIFxuICogQ29uZmlndXJhdGlvbiBvZiB0aGUgaW50ZXJuYWwgdmlkZW8gUVAgaW5kaWNhdG9yIGVsZW1lbnQuXG4gKiBCeSBkZWZhdWx0LCBvbmUgd2lsbCBiZSBtYWRlLCBidXQgaWYgbmVlZGVkIHRoaXMgY2FuIGJlIGRpc2FibGVkLlxuICogXG4gKiBOb3RlOiBGb3IgY3VzdG9tIFVJIGVsZW1lbnRzIHRvIHJlYWN0IHRvIHRoZSBRUCBiZWluZyBjaGFuZ2VkLCB1c2UgYSBQaXhlbFN0cmVhbWluZyBcbiAqIG9iamVjdCdzIGFkZEV2ZW50TGlzdGVuZXIoJ3ZpZGVvRW5jb2RlckF2Z1FQJywgLi4uKSBvciByZW1vdmVFdmVudExpc3RlbmVyKC4uLikuXG4gKi9cbmV4cG9ydCB0eXBlIFZpZGVvUVBJbmRpY2F0b3JDb25maWcgPSB7XG4gICAgZGlzYWJsZUluZGljYXRvcj86IGJvb2xlYW5cbn1cblxuLyoqXG4gKiBVSSBPcHRpb25zIGNhbiBiZSBwcm92aWRlZCB3aGVuIGNyZWF0aW5nIGFuIEFwcGxpY2F0aW9uLCB0byBjb25maWd1cmUgaXQncyBpbnRlcm5hbFxuICogYW5kIGV4dGVybmFsIGJlaGF2aW91ciwgZW5hYmxlL2Rpc2FibGUgZmVhdHVyZXMsIGFuZCBjb25uZWN0IHRvIGV4dGVybmFsIFVJLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFVJT3B0aW9ucyB7XG4gICAgc3RyZWFtOiBQaXhlbFN0cmVhbWluZztcbiAgICBvbkNvbG9yTW9kZUNoYW5nZWQ/OiAoaXNMaWdodE1vZGU6IGJvb2xlYW4pID0+IHZvaWQ7XG4gICAgLyoqIEJ5IGRlZmF1bHQsIGEgc2V0dGluZ3MgcGFuZWwgYW5kIGFzc29jaWF0ZSB2aXNpYmlsaXR5IHRvZ2dsZSBidXR0b24gd2lsbCBiZSBtYWRlLlxuICAgICAgKiBJZiBuZWVkZWQsIHRoaXMgYmVoYXZpb3VyIGNhbiBiZSBjb25maWd1cmVkLiAqL1xuICAgIHNldHRpbmdzUGFuZWxDb25maWc/OiBQYW5lbENvbmZpZ3VyYXRpb247XG4gICAgLyoqIEJ5IGRlZmF1bHQsIGEgc3RhdHMgcGFuZWwgYW5kIGFzc29jaWF0ZSB2aXNpYmlsaXR5IHRvZ2dsZSBidXR0b24gd2lsbCBiZSBtYWRlLlxuICAgICAgKiBJZiBuZWVkZWQsIHRoaXMgYmVoYXZpb3VyIGNhbiBiZSBjb25maWd1cmVkLiAqL1xuICAgIHN0YXRzUGFuZWxDb25maWc/OiBQYW5lbENvbmZpZ3VyYXRpb247XG4gICAgLyoqIElmIG5lZWRlZCwgdGhlIGZ1bGwgc2NyZWVuIGJ1dHRvbiBjYW4gYmUgZXh0ZXJuYWwgb3IgZGlzYWJsZWQuICovXG4gICAgZnVsbFNjcmVlbkNvbnRyb2xzQ29uZmlnPyA6IFVJRWxlbWVudENvbmZpZyxcbiAgICAvKiogSWYgbmVlZGVkLCBYUiBidXR0b24gY2FuIGJlIGV4dGVybmFsIG9yIGRpc2FibGVkLiAqL1xuICAgIHhyQ29udHJvbHNDb25maWc/IDogVUlFbGVtZW50Q29uZmlnLFxuICAgIC8qKiBDb25maWd1cmF0aW9uIG9mIHRoZSB2aWRlbyBRUCBpbmRpY2F0b3IuICovXG4gICAgdmlkZW9RcEluZGljYXRvckNvbmZpZz8gOiBWaWRlb1FQSW5kaWNhdG9yQ29uZmlnXG59XG5cbi8qKlxuICogQW4gQXBwbGljYXRpb24gaXMgYSBjb21iaW5hdGlvbiBvZiBVSSBlbGVtZW50cyB0byBkaXNwbGF5IGFuZCBtYW5hZ2UgYSBXZWJSVEMgUGl4ZWwgU3RyZWFtaW5nXG4gKiBjb25uZWN0aW9uLiBJdCBpbmNsdWRlcyBmZWF0dXJlcyBmb3IgY29udHJvbGxpbmcgYSBzdHJlYW0gd2l0aCBtb3VzZSBhbmQga2V5Ym9hcmQsIFxuICogbWFuYWdpbmcgY29ubmVjdGlvbiBlbmRwb2ludHMsIGFzIHdlbGwgYXMgZGlzcGxheWluZyBzdGF0cyBhbmQgb3RoZXIgaW5mb3JtYXRpb24gYWJvdXQgaXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBBcHBsaWNhdGlvbiB7XG4gICAgc3RyZWFtOiBQaXhlbFN0cmVhbWluZztcblxuICAgIF9yb290RWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgX3VpRmVhdHVyZUVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLy8gc2V0IHRoZSBvdmVybGF5IHBsYWNlaG9sZGVyc1xuICAgIGN1cnJlbnRPdmVybGF5OiBPdmVybGF5QmFzZSB8IG51bGw7XG4gICAgZGlzY29ubmVjdE92ZXJsYXk6IEFjdGlvbk92ZXJsYXk7XG4gICAgY29ubmVjdE92ZXJsYXk6IEFjdGlvbk92ZXJsYXk7XG4gICAgcGxheU92ZXJsYXk6IEFjdGlvbk92ZXJsYXk7XG4gICAgaW5mb092ZXJsYXk6IFRleHRPdmVybGF5O1xuICAgIGVycm9yT3ZlcmxheTogVGV4dE92ZXJsYXk7XG4gICAgYWZrT3ZlcmxheTogQUZLT3ZlcmxheTtcblxuICAgIGNvbnRyb2xzOiBDb250cm9scztcblxuICAgIHNldHRpbmdzUGFuZWw6IFNldHRpbmdzUGFuZWw7XG4gICAgc3RhdHNQYW5lbDogU3RhdHNQYW5lbDtcbiAgICB2aWRlb1FwSW5kaWNhdG9yOiBWaWRlb1FwSW5kaWNhdG9yO1xuXG4gICAgY29uZmlnVUk6IENvbmZpZ1VJO1xuXG4gICAgb25Db2xvck1vZGVDaGFuZ2VkOiBVSU9wdGlvbnNbXCJvbkNvbG9yTW9kZUNoYW5nZWRcIl07XG5cbiAgICBwcm90ZWN0ZWQgX29wdGlvbnMgOiBVSU9wdGlvbnM7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIEluaXRpYWxpemF0aW9uIG9wdGlvbnNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zOiBVSU9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5fb3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIFxuICAgICAgICB0aGlzLnN0cmVhbSA9IG9wdGlvbnMuc3RyZWFtO1xuICAgICAgICB0aGlzLm9uQ29sb3JNb2RlQ2hhbmdlZCA9IG9wdGlvbnMub25Db2xvck1vZGVDaGFuZ2VkO1xuICAgICAgICB0aGlzLmNvbmZpZ1VJID0gbmV3IENvbmZpZ1VJKHRoaXMuc3RyZWFtLmNvbmZpZyk7XG5cbiAgICAgICAgdGhpcy5jcmVhdGVPdmVybGF5cygpO1xuXG4gICAgICAgIGlmIChpc1BhbmVsRW5hYmxlZChvcHRpb25zLnN0YXRzUGFuZWxDb25maWcpKSB7XG4gICAgICAgICAgICAvLyBBZGQgc3RhdHMgcGFuZWxcbiAgICAgICAgICAgIHRoaXMuc3RhdHNQYW5lbCA9IG5ldyBTdGF0c1BhbmVsKCk7XG4gICAgICAgICAgICB0aGlzLnVpRmVhdHVyZXNFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc3RhdHNQYW5lbC5yb290RWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGlmIChpc1BhbmVsRW5hYmxlZChvcHRpb25zLnNldHRpbmdzUGFuZWxDb25maWcpKSB7XG4gICAgICAgICAgICAvLyBBZGQgc2V0dGluZ3MgcGFuZWxcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3NQYW5lbCA9IG5ldyBTZXR0aW5nc1BhbmVsKCk7XG4gICAgICAgICAgICB0aGlzLnVpRmVhdHVyZXNFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc2V0dGluZ3NQYW5lbC5yb290RWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyZVNldHRpbmdzKCk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGlmICghb3B0aW9ucy52aWRlb1FwSW5kaWNhdG9yQ29uZmlnIHx8ICFvcHRpb25zLnZpZGVvUXBJbmRpY2F0b3JDb25maWcuZGlzYWJsZUluZGljYXRvcikge1xuICAgICAgICAgICAgLy8gQWRkIHRoZSB2aWRlbyBzdHJlYW0gUVAgaW5kaWNhdG9yXG4gICAgICAgICAgICB0aGlzLnZpZGVvUXBJbmRpY2F0b3IgPSBuZXcgVmlkZW9RcEluZGljYXRvcigpO1xuICAgICAgICAgICAgdGhpcy51aUZlYXR1cmVzRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUXBJbmRpY2F0b3Iucm9vdEVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jcmVhdGVCdXR0b25zKCk7XG5cbiAgICAgICAgdGhpcy5yZWdpc3RlckNhbGxiYWNrcygpO1xuXG4gICAgICAgIHRoaXMuc2hvd0Nvbm5lY3RPckF1dG9Db25uZWN0T3ZlcmxheXMoKTtcblxuICAgICAgICB0aGlzLnNldENvbG9yTW9kZSh0aGlzLmNvbmZpZ1VJLmlzQ3VzdG9tRmxhZ0VuYWJsZWQoTGlnaHRNb2RlKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGNyZWF0ZU92ZXJsYXlzKCk6IHZvaWQge1xuICAgICAgICAvLyBidWlsZCBhbGwgb2YgdGhlIG92ZXJsYXlzXG4gICAgICAgIHRoaXMuZGlzY29ubmVjdE92ZXJsYXkgPSBuZXcgRGlzY29ubmVjdE92ZXJsYXkoXG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0VsZW1lbnRQYXJlbnRcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5jb25uZWN0T3ZlcmxheSA9IG5ldyBDb25uZWN0T3ZlcmxheShcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRWxlbWVudFBhcmVudFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnBsYXlPdmVybGF5ID0gbmV3IFBsYXlPdmVybGF5KFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9FbGVtZW50UGFyZW50XG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuaW5mb092ZXJsYXkgPSBuZXcgSW5mb092ZXJsYXkoXG4gICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0VsZW1lbnRQYXJlbnRcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5lcnJvck92ZXJsYXkgPSBuZXcgRXJyb3JPdmVybGF5KFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9FbGVtZW50UGFyZW50XG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWZrT3ZlcmxheSA9IG5ldyBBRktPdmVybGF5KFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9FbGVtZW50UGFyZW50XG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5kaXNjb25uZWN0T3ZlcmxheS5vbkFjdGlvbigoKSA9PiB0aGlzLnN0cmVhbS5yZWNvbm5lY3QoKSk7XG5cbiAgICAgICAgLy8gQnVpbGQgdGhlIHdlYlJ0YyBjb25uZWN0IG92ZXJsYXkgRXZlbnQgTGlzdGVuZXIgYW5kIHNob3cgdGhlIGNvbm5lY3Qgb3ZlcmxheVxuICAgICAgICB0aGlzLmNvbm5lY3RPdmVybGF5Lm9uQWN0aW9uKCgpID0+IHRoaXMuc3RyZWFtLmNvbm5lY3QoKSk7XG5cbiAgICAgICAgLy8gc2V0IHVwIHRoZSBwbGF5IG92ZXJsYXlzIGFjdGlvblxuICAgICAgICB0aGlzLnBsYXlPdmVybGF5Lm9uQWN0aW9uKCgpID0+IHRoaXMuc3RyZWFtLnBsYXkoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHVwIGJ1dHRvbiBjbGljayBmdW5jdGlvbnMgYW5kIGJ1dHRvbiBmdW5jdGlvbmFsaXR5XG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUJ1dHRvbnMoKSB7XG4gICAgICAgIGNvbnN0IGNvbnRyb2xzVUlDb25maWcgOiBDb250cm9sc1VJQ29uZmlndXJhdGlvbiA9IHtcbiAgICAgICAgICAgIHN0YXRzQnV0dG9uVHlwZSA6ICEhdGhpcy5fb3B0aW9ucy5zdGF0c1BhbmVsQ29uZmlnXG4gICAgICAgICAgICAgICAgPyB0aGlzLl9vcHRpb25zLnN0YXRzUGFuZWxDb25maWcudmlzaWJpbGl0eUJ1dHRvbkNvbmZpZ1xuICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgc2V0dGluZ3NCdXR0b25UeXBlOiAhIXRoaXMuX29wdGlvbnMuc2V0dGluZ3NQYW5lbENvbmZpZ1xuICAgICAgICAgICAgICAgID8gdGhpcy5fb3B0aW9ucy5zZXR0aW5nc1BhbmVsQ29uZmlnLnZpc2liaWxpdHlCdXR0b25Db25maWdcbiAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGZ1bGxzY3JlZW5CdXR0b25UeXBlOiB0aGlzLl9vcHRpb25zLmZ1bGxTY3JlZW5Db250cm9sc0NvbmZpZyxcbiAgICAgICAgICAgIHhySWNvblR5cGU6IHRoaXMuX29wdGlvbnMueHJDb250cm9sc0NvbmZpZ1xuICAgICAgICB9XG4gICAgICAgIC8vIFNldHVwIGNvbnRyb2xzXG4gICAgICAgIGNvbnN0IGNvbnRyb2xzID0gbmV3IENvbnRyb2xzKGNvbnRyb2xzVUlDb25maWcpO1xuICAgICAgICB0aGlzLnVpRmVhdHVyZXNFbGVtZW50LmFwcGVuZENoaWxkKGNvbnRyb2xzLnJvb3RFbGVtZW50KTtcblxuICAgICAgICAvLyBXaGVuIHdlIGZ1bGxzY3JlZW4gd2Ugd2FudCB0aGlzIGVsZW1lbnQgdG8gYmUgdGhlIHJvb3RcbiAgICAgICAgY29uc3QgZnVsbFNjcmVlbkJ1dHRvbiA6IEZ1bGxTY3JlZW5JY29uQmFzZSB8IHVuZGVmaW5lZCA9IFxuICAgICAgICAgICAgLy8gRGVwZW5kaW5nIG9uIGlmIHdlJ3JlIGNyZWF0aW5nIGFuIGludGVybmFsIGJ1dHRvbiwgb3IgdXNpbmcgYW4gZXh0ZXJuYWwgb25lXG4gICAgICAgICAgICAoISF0aGlzLl9vcHRpb25zLmZ1bGxTY3JlZW5Db250cm9sc0NvbmZpZyBcbiAgICAgICAgICAgICAgICAmJiB0aGlzLl9vcHRpb25zLmZ1bGxTY3JlZW5Db250cm9sc0NvbmZpZy5jcmVhdGlvbk1vZGUgPT09IFVJRWxlbWVudENyZWF0aW9uTW9kZS5Vc2VDdXN0b21FbGVtZW50KVxuICAgICAgICAgICAgLy8gRWl0aGVyIGNyZWF0ZSBhIGZ1bGxzY3JlZW4gY2xhc3MgYmFzZWQgb24gdGhlIGV4dGVybmFsIGJ1dHRvblxuICAgICAgICAgICAgPyBuZXcgRnVsbFNjcmVlbkljb25FeHRlcm5hbCh0aGlzLl9vcHRpb25zLmZ1bGxTY3JlZW5Db250cm9sc0NvbmZpZy5jdXN0b21FbGVtZW50KVxuICAgICAgICAgICAgLy8gT3IgdXNlIHRoZSBvbmUgY3JlYXRlZCBieSB0aGUgQ29udHJvbHMgaW5pdGlhbGl6ZXIgZWFybGllclxuICAgICAgICAgICAgOiBjb250cm9scy5mdWxsc2NyZWVuSWNvbjtcbiAgICAgICAgaWYgKGZ1bGxTY3JlZW5CdXR0b24pIHtcbiAgICAgICAgICAgIGZ1bGxTY3JlZW5CdXR0b24uZnVsbHNjcmVlbkVsZW1lbnQgPSAvaVBhZHxpUGhvbmV8aVBvZC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSA/IHRoaXMuc3RyZWFtLnZpZGVvRWxlbWVudFBhcmVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInZpZGVvXCIpWzBdIDogdGhpcy5yb290RWxlbWVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBzZXR0aW5ncyBidXR0b24gdG8gY29udHJvbHNcbiAgICAgICAgY29uc3Qgc2V0dGluZ3NCdXR0b24gOiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCA9IFxuICAgICAgICAgICAgISFjb250cm9scy5zZXR0aW5nc0ljb24gPyBjb250cm9scy5zZXR0aW5nc0ljb24ucm9vdEVsZW1lbnQgOiBcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuc2V0dGluZ3NQYW5lbENvbmZpZy52aXNpYmlsaXR5QnV0dG9uQ29uZmlnLmN1c3RvbUVsZW1lbnQ7XG4gICAgICAgIGlmICghIXNldHRpbmdzQnV0dG9uKSBzZXR0aW5nc0J1dHRvbi5vbmNsaWNrID0gKCkgPT5cbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3NDbGlja2VkKCk7XG4gICAgICAgIGlmICghIXRoaXMuc2V0dGluZ3NQYW5lbCkgdGhpcy5zZXR0aW5nc1BhbmVsLnNldHRpbmdzQ2xvc2VCdXR0b24ub25jbGljayA9ICgpID0+XG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzQ2xpY2tlZCgpO1xuXG4gICAgICAgIC8vIEFkZCBXZWJYUiBidXR0b24gdG8gY29udHJvbHNcbiAgICAgICAgY29uc3QgeHJCdXR0b24gOiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCA9IFxuICAgICAgICAgICAgISFjb250cm9scy54ckljb24gPyBjb250cm9scy54ckljb24ucm9vdEVsZW1lbnQgOiBcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMueHJDb250cm9sc0NvbmZpZy5jcmVhdGlvbk1vZGUgPT09IFVJRWxlbWVudENyZWF0aW9uTW9kZS5Vc2VDdXN0b21FbGVtZW50ID9cbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMueHJDb250cm9sc0NvbmZpZy5jdXN0b21FbGVtZW50IDogdW5kZWZpbmVkO1xuICAgICAgICBpZiAoISF4ckJ1dHRvbikgeHJCdXR0b24ub25jbGljayA9ICgpID0+XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS50b2dnbGVYUigpO1xuXG4gICAgICAgIC8vIHNldHVwIHRoZSBzdGF0cy9pbmZvIGJ1dHRvblxuICAgICAgICBjb25zdCBzdGF0c0J1dHRvbiA6IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkID0gXG4gICAgICAgICAgICAhIWNvbnRyb2xzLnN0YXRzSWNvbiA/IGNvbnRyb2xzLnN0YXRzSWNvbi5yb290RWxlbWVudCA6IFxuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucy5zdGF0c1BhbmVsQ29uZmlnLnZpc2liaWxpdHlCdXR0b25Db25maWcuY3VzdG9tRWxlbWVudDtcbiAgICAgICAgaWYgKCEhc3RhdHNCdXR0b24pIHN0YXRzQnV0dG9uLm9uY2xpY2sgPSAoKSA9PiB0aGlzLnN0YXRzQ2xpY2tlZCgpXG5cbiAgICAgICAgaWYgKCEhdGhpcy5zdGF0c1BhbmVsKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRzUGFuZWwuc3RhdHNDbG9zZUJ1dHRvbi5vbmNsaWNrID0gKCkgPT4gdGhpcy5zdGF0c0NsaWNrZWQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBjb21tYW5kIGJ1dHRvbnMgKGlmIHdlIGhhdmUgc29tZXdoZXJlIHRvIGFkZCB0aGVtIHRvKVxuICAgICAgICBpZiAoISF0aGlzLnNldHRpbmdzUGFuZWwpIHtcbiAgICAgICAgICAgIC8vIEFkZCBidXR0b24gZm9yIHRvZ2dsZSBmcHNcbiAgICAgICAgICAgIGNvbnN0IHNob3dGUFNCdXR0b24gPSBuZXcgTGFiZWxsZWRCdXR0b24oJ1Nob3cgRlBTJywgJ1RvZ2dsZScpO1xuICAgICAgICAgICAgc2hvd0ZQU0J1dHRvbi5hZGRPbkNsaWNrTGlzdGVuZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnJlcXVlc3RTaG93RnBzKCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gQWRkIGJ1dHRvbiBmb3IgcmVzdGFydCBzdHJlYW1cbiAgICAgICAgICAgIGNvbnN0IHJlc3RhcnRTdHJlYW1CdXR0b24gPSBuZXcgTGFiZWxsZWRCdXR0b24oXG4gICAgICAgICAgICAgICAgJ1Jlc3RhcnQgU3RyZWFtJyxcbiAgICAgICAgICAgICAgICAnUmVzdGFydCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXN0YXJ0U3RyZWFtQnV0dG9uLmFkZE9uQ2xpY2tMaXN0ZW5lcigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0ucmVjb25uZWN0KCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gQWRkIGJ1dHRvbiBmb3IgcmVxdWVzdCBrZXlmcmFtZVxuICAgICAgICAgICAgY29uc3QgcmVxdWVzdEtleWZyYW1lQnV0dG9uID0gbmV3IExhYmVsbGVkQnV0dG9uKFxuICAgICAgICAgICAgICAgICdSZXF1ZXN0IGtleWZyYW1lJyxcbiAgICAgICAgICAgICAgICAnUmVxdWVzdCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXF1ZXN0S2V5ZnJhbWVCdXR0b24uYWRkT25DbGlja0xpc3RlbmVyKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5yZXF1ZXN0SWZyYW1lKCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY29uc3QgY29tbWFuZHNTZWN0aW9uRWxlbSA9IHRoaXMuY29uZmlnVUkuYnVpbGRTZWN0aW9uV2l0aEhlYWRpbmcoXG4gICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5nc1BhbmVsLnNldHRpbmdzQ29udGVudEVsZW1lbnQsXG4gICAgICAgICAgICAgICAgJ0NvbW1hbmRzJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbW1hbmRzU2VjdGlvbkVsZW0uYXBwZW5kQ2hpbGQoc2hvd0ZQU0J1dHRvbi5yb290RWxlbWVudCk7XG4gICAgICAgICAgICBjb21tYW5kc1NlY3Rpb25FbGVtLmFwcGVuZENoaWxkKHJlcXVlc3RLZXlmcmFtZUJ1dHRvbi5yb290RWxlbWVudCk7XG4gICAgICAgICAgICBjb21tYW5kc1NlY3Rpb25FbGVtLmFwcGVuZENoaWxkKHJlc3RhcnRTdHJlYW1CdXR0b24ucm9vdEVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uZmlndXJlIHRoZSBzZXR0aW5ncyB3aXRoIG9uIGNoYW5nZSBsaXN0ZW5lcnMgYW5kIGFueSBhZGRpdGlvbmFsIHBlciBleHBlcmllbmNlIHNldHRpbmdzLlxuICAgICAqL1xuICAgIGNvbmZpZ3VyZVNldHRpbmdzKCk6IHZvaWQge1xuICAgICAgICAvLyBUaGlzIGJ1aWxkcyBhbGwgdGhlIHNldHRpbmdzIHNlY3Rpb25zIGFuZCBmbGFncyB1bmRlciB0aGlzIGBzZXR0aW5nc0NvbnRlbnRgIGVsZW1lbnQuXG4gICAgICAgIHRoaXMuY29uZmlnVUkucG9wdWxhdGVTZXR0aW5nc0VsZW1lbnQoXG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzUGFuZWwuc2V0dGluZ3NDb250ZW50RWxlbWVudFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuY29uZmlnVUkuYWRkQ3VzdG9tRmxhZ09uU2V0dGluZ0NoYW5nZWRMaXN0ZW5lcihcbiAgICAgICAgICAgIExpZ2h0TW9kZSxcbiAgICAgICAgICAgIChpc0xpZ2h0TW9kZTogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnVUkuc2V0Q3VzdG9tRmxhZ0xhYmVsKFxuICAgICAgICAgICAgICAgICAgICBMaWdodE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGBDb2xvciBTY2hlbWU6ICR7aXNMaWdodE1vZGUgPyAnTGlnaHQnIDogJ0RhcmsnfSBNb2RlYFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRDb2xvck1vZGUoaXNMaWdodE1vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHJlZ2lzdGVyQ2FsbGJhY2tzKCkge1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ2Fma1dhcm5pbmdBY3RpdmF0ZScsXG4gICAgICAgICAgICAoeyBkYXRhOiB7IGNvdW50RG93biwgZGlzbWlzc0FmayB9IH0pID0+XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93QWZrT3ZlcmxheShjb3VudERvd24sIGRpc21pc3NBZmspXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnYWZrV2FybmluZ1VwZGF0ZScsXG4gICAgICAgICAgICAoeyBkYXRhOiB7IGNvdW50RG93biB9IH0pID0+XG4gICAgICAgICAgICAgICAgdGhpcy5hZmtPdmVybGF5LnVwZGF0ZUNvdW50ZG93bihjb3VudERvd24pXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnYWZrV2FybmluZ0RlYWN0aXZhdGUnLFxuICAgICAgICAgICAgKCkgPT4gdGhpcy5hZmtPdmVybGF5LmhpZGUoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCdhZmtUaW1lZE91dCcsICgpID0+XG4gICAgICAgICAgICB0aGlzLmFma092ZXJsYXkuaGlkZSgpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAndmlkZW9FbmNvZGVyQXZnUVAnLFxuICAgICAgICAgICAgKHsgZGF0YTogeyBhdmdRUCB9IH0pID0+IHRoaXMub25WaWRlb0VuY29kZXJBdmdRUChhdmdRUClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignd2ViUnRjU2RwJywgKCkgPT5cbiAgICAgICAgICAgIHRoaXMub25XZWJSdGNTZHAoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCd3ZWJSdGNBdXRvQ29ubmVjdCcsICgpID0+XG4gICAgICAgICAgICB0aGlzLm9uV2ViUnRjQXV0b0Nvbm5lY3QoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCd3ZWJSdGNDb25uZWN0aW5nJywgKCkgPT5cbiAgICAgICAgICAgIHRoaXMub25XZWJSdGNDb25uZWN0aW5nKClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcignd2ViUnRjQ29ubmVjdGVkJywgKCkgPT5cbiAgICAgICAgICAgIHRoaXMub25XZWJSdGNDb25uZWN0ZWQoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKCd3ZWJSdGNGYWlsZWQnLCAoKSA9PlxuICAgICAgICAgICAgdGhpcy5vbldlYlJ0Y0ZhaWxlZCgpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnd2ViUnRjRGlzY29ubmVjdGVkJyxcbiAgICAgICAgICAgICh7IGRhdGE6IHsgZXZlbnRTdHJpbmcsIGFsbG93Q2xpY2tUb1JlY29ubmVjdCB9IH0pID0+XG4gICAgICAgICAgICAgICAgdGhpcy5vbkRpc2Nvbm5lY3QoZXZlbnRTdHJpbmcsIGFsbG93Q2xpY2tUb1JlY29ubmVjdClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcigndmlkZW9Jbml0aWFsaXplZCcsICgpID0+XG4gICAgICAgICAgICB0aGlzLm9uVmlkZW9Jbml0aWFsaXplZCgpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoJ3N0cmVhbUxvYWRpbmcnLCAoKSA9PlxuICAgICAgICAgICAgdGhpcy5vblN0cmVhbUxvYWRpbmcoKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ3BsYXlTdHJlYW1FcnJvcicsXG4gICAgICAgICAgICAoeyBkYXRhOiB7IG1lc3NhZ2UgfSB9KSA9PiB0aGlzLm9uUGxheVN0cmVhbUVycm9yKG1lc3NhZ2UpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoJ3BsYXlTdHJlYW0nLCAoKSA9PlxuICAgICAgICAgICAgdGhpcy5vblBsYXlTdHJlYW0oKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ3BsYXlTdHJlYW1SZWplY3RlZCcsXG4gICAgICAgICAgICAoeyBkYXRhOiB7IHJlYXNvbiB9IH0pID0+IHRoaXMub25QbGF5U3RyZWFtUmVqZWN0ZWQocmVhc29uKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ2xvYWRGcmVlemVGcmFtZScsXG4gICAgICAgICAgICAoeyBkYXRhOiB7IHNob3VsZFNob3dQbGF5T3ZlcmxheSB9IH0pID0+XG4gICAgICAgICAgICAgICAgdGhpcy5vbkxvYWRGcmVlemVGcmFtZShzaG91bGRTaG93UGxheU92ZXJsYXkpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnc3RhdHNSZWNlaXZlZCcsXG4gICAgICAgICAgICAoeyBkYXRhOiB7IGFnZ3JlZ2F0ZWRTdGF0cyB9IH0pID0+XG4gICAgICAgICAgICAgICAgdGhpcy5vblN0YXRzUmVjZWl2ZWQoYWdncmVnYXRlZFN0YXRzKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ2xhdGVuY3lUZXN0UmVzdWx0JyxcbiAgICAgICAgICAgICh7IGRhdGE6IHsgbGF0ZW5jeVRpbWluZ3MgfSB9KSA9PlxuICAgICAgICAgICAgICAgIHRoaXMub25MYXRlbmN5VGVzdFJlc3VsdHMobGF0ZW5jeVRpbWluZ3MpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnZGF0YUNoYW5uZWxMYXRlbmN5VGVzdFJlc3VsdCcsXG4gICAgICAgICAgICAoe2RhdGE6IHsgcmVzdWx0IH0gfSkgPT5cbiAgICAgICAgICAgICAgICB0aGlzLm9uRGF0YUNoYW5uZWxMYXRlbmN5VGVzdFJlc3VsdHMocmVzdWx0KVxuICAgICAgICApXG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnc3RyZWFtZXJMaXN0TWVzc2FnZScsXG4gICAgICAgICAgICAoeyBkYXRhOiB7IG1lc3NhZ2VTdHJlYW1lckxpc3QsIGF1dG9TZWxlY3RlZFN0cmVhbWVySWQsIHdhbnRlZFN0cmVhbWVySWQgfSB9KSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlU3RyZWFtZXJMaXN0TWVzc2FnZShtZXNzYWdlU3RyZWFtZXJMaXN0LCBhdXRvU2VsZWN0ZWRTdHJlYW1lcklkLCB3YW50ZWRTdHJlYW1lcklkKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ3NldHRpbmdzQ2hhbmdlZCcsXG4gICAgICAgICAgICAoZXZlbnQpID0+IHRoaXMuY29uZmlnVUkub25TZXR0aW5nc0NoYW5nZWQoZXZlbnQpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAncGxheWVyQ291bnQnLCBcbiAgICAgICAgICAgICh7IGRhdGE6IHsgY291bnQgfX0pID0+IFxuICAgICAgICAgICAgICAgIHRoaXMub25QbGF5ZXJDb3VudChjb3VudClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSByb290RWxlbWVudCBvZiB0aGUgYXBwbGljYXRpb24sIHZpZGVvIHN0cmVhbSBhbmQgYWxsIFVJIGFyZSBjaGlsZHJlbiBvZiB0aGlzIGVsZW1lbnQuXG4gICAgICovXG4gICAgcHVibGljIGdldCByb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5pZCA9ICdwbGF5ZXJVSSc7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdub3NlbGVjdCcpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQoXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9FbGVtZW50UGFyZW50XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy51aUZlYXR1cmVzRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGVsZW1lbnQgdGhhdCBjb250YWlucyBhbGwgdGhlIFVJIGZlYXR1cmVzLCBsaWtlIHRoZSBzdGF0cyBhbmQgc2V0dGluZ3MgcGFuZWxzLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgdWlGZWF0dXJlc0VsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3VpRmVhdHVyZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3VpRmVhdHVyZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3VpRmVhdHVyZUVsZW1lbnQuaWQgPSAndWlGZWF0dXJlcyc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3VpRmVhdHVyZUVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIGRpc2Nvbm5lY3Qgb3ZlcmxheVxuICAgICAqIEBwYXJhbSB1cGRhdGVUZXh0IC0gdGhlIHRleHQgdGhhdCB3aWxsIGJlIGRpc3BsYXllZCBpbiB0aGUgb3ZlcmxheVxuICAgICAqL1xuICAgIHNob3dEaXNjb25uZWN0T3ZlcmxheSh1cGRhdGVUZXh0OiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5oaWRlQ3VycmVudE92ZXJsYXkoKTtcbiAgICAgICAgdGhpcy51cGRhdGVEaXNjb25uZWN0T3ZlcmxheSh1cGRhdGVUZXh0KTtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0T3ZlcmxheS5zaG93KCk7XG4gICAgICAgIHRoaXMuY3VycmVudE92ZXJsYXkgPSB0aGlzLmRpc2Nvbm5lY3RPdmVybGF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgZGlzY29ubmVjdCBvdmVybGF5cyBzcGFuIHRleHRcbiAgICAgKiBAcGFyYW0gdXBkYXRlVGV4dCAtIHRoZSBuZXcgY291bnRkb3duIG51bWJlclxuICAgICAqL1xuICAgIHVwZGF0ZURpc2Nvbm5lY3RPdmVybGF5KHVwZGF0ZVRleHQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RPdmVybGF5LnVwZGF0ZSh1cGRhdGVUZXh0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBY3RpdmF0ZXMgdGhlIGRpc2Nvbm5lY3Qgb3ZlcmxheXMgYWN0aW9uXG4gICAgICovXG4gICAgb25EaXNjb25uZWN0aW9uQWN0aW9uKCkge1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RPdmVybGF5LmFjdGl2YXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGlkZXMgdGhlIGN1cnJlbnQgb3ZlcmxheVxuICAgICAqL1xuICAgIGhpZGVDdXJyZW50T3ZlcmxheSgpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudE92ZXJsYXkgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50T3ZlcmxheS5oaWRlKCk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRPdmVybGF5ID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBjb25uZWN0IG92ZXJsYXlcbiAgICAgKi9cbiAgICBzaG93Q29ubmVjdE92ZXJsYXkoKSB7XG4gICAgICAgIHRoaXMuaGlkZUN1cnJlbnRPdmVybGF5KCk7XG4gICAgICAgIHRoaXMuY29ubmVjdE92ZXJsYXkuc2hvdygpO1xuICAgICAgICB0aGlzLmN1cnJlbnRPdmVybGF5ID0gdGhpcy5jb25uZWN0T3ZlcmxheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyB0aGUgcGxheSBvdmVybGF5XG4gICAgICovXG4gICAgc2hvd1BsYXlPdmVybGF5KCkge1xuICAgICAgICB0aGlzLmhpZGVDdXJyZW50T3ZlcmxheSgpO1xuICAgICAgICB0aGlzLnBsYXlPdmVybGF5LnNob3coKTtcbiAgICAgICAgdGhpcy5jdXJyZW50T3ZlcmxheSA9IHRoaXMucGxheU92ZXJsYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIHRleHQgb3ZlcmxheVxuICAgICAqIEBwYXJhbSB0ZXh0IC0gdGhlIHRleHQgdGhhdCB3aWxsIGJlIHNob3duIGluIHRoZSBvdmVybGF5XG4gICAgICovXG4gICAgc2hvd1RleHRPdmVybGF5KHRleHQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLmhpZGVDdXJyZW50T3ZlcmxheSgpO1xuICAgICAgICB0aGlzLmluZm9PdmVybGF5LnVwZGF0ZSh0ZXh0KTtcbiAgICAgICAgdGhpcy5pbmZvT3ZlcmxheS5zaG93KCk7XG4gICAgICAgIHRoaXMuY3VycmVudE92ZXJsYXkgPSB0aGlzLmluZm9PdmVybGF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3dzIHRoZSBlcnJvciBvdmVybGF5XG4gICAgICogQHBhcmFtIHRleHQgLSB0aGUgdGV4dCB0aGF0IHdpbGwgYmUgc2hvd24gaW4gdGhlIG92ZXJsYXlcbiAgICAgKi9cbiAgICBzaG93RXJyb3JPdmVybGF5KHRleHQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLmhpZGVDdXJyZW50T3ZlcmxheSgpO1xuICAgICAgICB0aGlzLmVycm9yT3ZlcmxheS51cGRhdGUodGV4dCk7XG4gICAgICAgIHRoaXMuZXJyb3JPdmVybGF5LnNob3coKTtcbiAgICAgICAgdGhpcy5jdXJyZW50T3ZlcmxheSA9IHRoaXMuZXJyb3JPdmVybGF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3dzIG9yIGhpZGVzIHRoZSBzZXR0aW5ncyBwYW5lbCBpZiBjbGlja2VkXG4gICAgICovXG4gICAgc2V0dGluZ3NDbGlja2VkKCkge1xuICAgICAgICB0aGlzLnN0YXRzUGFuZWw/LmhpZGUoKTtcbiAgICAgICAgdGhpcy5zZXR0aW5nc1BhbmVsLnRvZ2dsZVZpc2liaWxpdHkoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyBvciBoaWRlcyB0aGUgc3RhdHMgcGFuZWwgaWYgY2xpY2tlZFxuICAgICAqL1xuICAgIHN0YXRzQ2xpY2tlZCgpIHtcbiAgICAgICAgdGhpcy5zZXR0aW5nc1BhbmVsPy5oaWRlKCk7XG4gICAgICAgIHRoaXMuc3RhdHNQYW5lbC50b2dnbGVWaXNpYmlsaXR5KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWN0aXZhdGVzIHRoZSBjb25uZWN0IG92ZXJsYXlzIGFjdGlvblxuICAgICAqL1xuICAgIG9uQ29ubmVjdEFjdGlvbigpIHtcbiAgICAgICAgdGhpcy5jb25uZWN0T3ZlcmxheS5hY3RpdmF0ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjdGl2YXRlcyB0aGUgcGxheSBvdmVybGF5cyBhY3Rpb25cbiAgICAgKi9cbiAgICBvblBsYXlBY3Rpb24oKSB7XG4gICAgICAgIHRoaXMucGxheU92ZXJsYXkuYWN0aXZhdGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93cyB0aGUgYWZrIG92ZXJsYXlcbiAgICAgKiBAcGFyYW0gY291bnREb3duIC0gdGhlIGNvdW50ZG93biBudW1iZXIgZm9yIHRoZSBhZmsgY291bnRkb3duXG4gICAgICovXG4gICAgc2hvd0Fma092ZXJsYXkoY291bnREb3duOiBudW1iZXIsIGRpc21pc3NBZms6ICgpID0+IHZvaWQpIHtcbiAgICAgICAgdGhpcy5oaWRlQ3VycmVudE92ZXJsYXkoKTtcbiAgICAgICAgdGhpcy5hZmtPdmVybGF5LnVwZGF0ZUNvdW50ZG93bihjb3VudERvd24pO1xuICAgICAgICB0aGlzLmFma092ZXJsYXkub25BY3Rpb24oKCkgPT4gZGlzbWlzc0FmaygpKTtcbiAgICAgICAgdGhpcy5hZmtPdmVybGF5LnNob3coKTtcbiAgICAgICAgdGhpcy5jdXJyZW50T3ZlcmxheSA9IHRoaXMuYWZrT3ZlcmxheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IHRoZSBDb25uZWN0IE92ZXJsYXkgb3IgYXV0byBjb25uZWN0XG4gICAgICovXG4gICAgc2hvd0Nvbm5lY3RPckF1dG9Db25uZWN0T3ZlcmxheXMoKSB7XG4gICAgICAgIC8vIHNldCB1cCBpZiB0aGUgYXV0byBwbGF5IHdpbGwgYmUgdXNlZCBvciByZWd1bGFyIGNsaWNrIHRvIHN0YXJ0XG4gICAgICAgIGlmICghdGhpcy5zdHJlYW0uY29uZmlnLmlzRmxhZ0VuYWJsZWQoRmxhZ3MuQXV0b0Nvbm5lY3QpKSB7XG4gICAgICAgICAgICB0aGlzLnNob3dDb25uZWN0T3ZlcmxheSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyB0aGUgd2ViUnRjQXV0b0Nvbm5lY3QgT3ZlcmxheSBhbmQgY29ubmVjdFxuICAgICAqL1xuICAgIG9uV2ViUnRjQXV0b0Nvbm5lY3QoKSB7XG4gICAgICAgIHRoaXMuc2hvd1RleHRPdmVybGF5KCdBdXRvIENvbm5lY3RpbmcgTm93Jyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHVwIGZ1bmN0aW9uYWxpdHkgdG8gaGFwcGVuIHdoZW4gcmVjZWl2aW5nIGEgd2ViUlRDIGFuc3dlclxuICAgICAqL1xuICAgIG9uV2ViUnRjU2RwKCkge1xuICAgICAgICB0aGlzLnNob3dUZXh0T3ZlcmxheSgnV2ViUlRDIENvbm5lY3Rpb24gTmVnb3RpYXRlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3dzIGEgdGV4dCBvdmVybGF5IHRvIGFsZXJ0IHRoZSB1c2VyIHRoZSBzdHJlYW0gaXMgY3VycmVudGx5IGxvYWRpbmdcbiAgICAgKi9cbiAgICBvblN0cmVhbUxvYWRpbmcoKSB7XG4gICAgICAgIC8vIGJ1aWxkIHRoZSBzcGlubmVyIHNwYW5cbiAgICAgICAgY29uc3Qgc3Bpbm5lclNwYW46IEhUTUxTcGFuRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgc3Bpbm5lclNwYW4uY2xhc3NOYW1lID0gJ3Zpc3VhbGx5LWhpZGRlbic7XG4gICAgICAgIHNwaW5uZXJTcGFuLmlubmVySFRNTCA9ICdMb2FkaW5nLi4uJztcblxuICAgICAgICAvLyBidWlsZCB0aGUgc3Bpbm5lciBkaXZcbiAgICAgICAgY29uc3Qgc3Bpbm5lckRpdjogSFRNTERpdkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgc3Bpbm5lckRpdi5pZCA9ICdsb2FkaW5nLXNwaW5uZXInO1xuICAgICAgICBzcGlubmVyRGl2LmNsYXNzTmFtZSA9ICdzcGlubmVyLWJvcmRlciBtcy0yJztcbiAgICAgICAgc3Bpbm5lckRpdi5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnc3RhdHVzJyk7XG5cbiAgICAgICAgLy8gYXBwZW5kIHRoZSBzcGlubmVyIHRvIHRoZSBlbGVtZW50XG4gICAgICAgIHNwaW5uZXJEaXYuYXBwZW5kQ2hpbGQoc3Bpbm5lclNwYW4pO1xuXG4gICAgICAgIHRoaXMuc2hvd1RleHRPdmVybGF5KCdMb2FkaW5nIFN0cmVhbSAnICsgc3Bpbm5lckRpdi5vdXRlckhUTUwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV2ZW50IGZpcmVkIHdoZW4gdGhlIHZpZGVvIGlzIGRpc2Nvbm5lY3RlZCAtIGRpc3BsYXlzIHRoZSBlcnJvciBvdmVybGF5IGFuZCByZXNldHMgdGhlIGJ1dHRvbnMgc3RyZWFtIHRvb2xzIHVwb24gZGlzY29ubmVjdFxuICAgICAqIEBwYXJhbSBldmVudFN0cmluZyAtIHRoZSBldmVudCB0ZXh0IHRoYXQgd2lsbCBiZSBzaG93biBpbiB0aGUgb3ZlcmxheVxuICAgICAqIEBwYXJhbSBhbGxvd0NsaWNrVG9SZWNvbm5lY3QgLSB0cnVlIGlmIHdlIHdhbnQgdG8gYWxsb3cgdGhlIHVzZXIgdG8gY2xpY2sgdG8gcmVjb25uZWN0LiBPdGhlcndpc2UgaXQncyBqdXN0IGEgbWVzc2FnZS5cbiAgICAgKi9cbiAgICBvbkRpc2Nvbm5lY3QoZXZlbnRTdHJpbmc6IHN0cmluZywgYWxsb3dDbGlja1RvUmVjb25uZWN0OiBib29sZWFuKSB7XG4gICAgICAgIGNvbnN0IG92ZXJsYXlNZXNzYWdlID0gJ0Rpc2Nvbm5lY3RlZCcgKyAoZXZlbnRTdHJpbmcgPyBgOiAke2V2ZW50U3RyaW5nfWAgOiAnJyk7XG4gICAgICAgIGlmIChhbGxvd0NsaWNrVG9SZWNvbm5lY3QpIHtcbiAgICAgICAgICAgIHRoaXMuc2hvd0Rpc2Nvbm5lY3RPdmVybGF5KGAke292ZXJsYXlNZXNzYWdlfSBDbGljayBUbyBSZXN0YXJ0LmApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zaG93RXJyb3JPdmVybGF5KG92ZXJsYXlNZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBkaXNhYmxlIHN0YXJ0aW5nIGEgbGF0ZW5jeSBjaGVja3NcbiAgICAgICAgdGhpcy5zdGF0c1BhbmVsPy5vbkRpc2Nvbm5lY3QoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIHdoZW4gV2ViIFJ0YyBpcyBjb25uZWN0aW5nXG4gICAgICovXG4gICAgb25XZWJSdGNDb25uZWN0aW5nKCkge1xuICAgICAgICB0aGlzLnNob3dUZXh0T3ZlcmxheSgnU3RhcnRpbmcgY29ubmVjdGlvbiB0byBzZXJ2ZXIsIHBsZWFzZSB3YWl0Jyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyB3aGVuIFdlYiBSdGMgaGFzIGNvbm5lY3RlZFxuICAgICAqL1xuICAgIG9uV2ViUnRjQ29ubmVjdGVkKCkge1xuICAgICAgICB0aGlzLnNob3dUZXh0T3ZlcmxheSgnV2ViUlRDIGNvbm5lY3RlZCwgd2FpdGluZyBmb3IgdmlkZW8nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIHdoZW4gV2ViIFJ0YyBmYWlscyB0byBjb25uZWN0XG4gICAgICovXG4gICAgb25XZWJSdGNGYWlsZWQoKSB7XG4gICAgICAgIHRoaXMuc2hvd0Vycm9yT3ZlcmxheSgnVW5hYmxlIHRvIHNldHVwIHZpZGVvJyk7XG4gICAgfVxuXG4gICAgb25Mb2FkRnJlZXplRnJhbWUoc2hvdWxkU2hvd1BsYXlPdmVybGF5OiBib29sZWFuKSB7XG4gICAgICAgIGlmIChzaG91bGRTaG93UGxheU92ZXJsYXkgPT09IHRydWUpIHtcbiAgICAgICAgICAgIExvZ2dlci5Mb2coTG9nZ2VyLkdldFN0YWNrVHJhY2UoKSwgJ3Nob3dpbmcgcGxheSBvdmVybGF5Jyk7XG4gICAgICAgICAgICB0aGlzLnNob3dQbGF5T3ZlcmxheSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25QbGF5U3RyZWFtKCkge1xuICAgICAgICB0aGlzLmhpZGVDdXJyZW50T3ZlcmxheSgpO1xuICAgIH1cblxuICAgIG9uUGxheVN0cmVhbUVycm9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgICB0aGlzLnNob3dFcnJvck92ZXJsYXkobWVzc2FnZSk7XG4gICAgfVxuXG4gICAgb25QbGF5U3RyZWFtUmVqZWN0ZWQob25SZWplY3RlZFJlYXNvbjogdW5rbm93bikge1xuICAgICAgICB0aGlzLnNob3dQbGF5T3ZlcmxheSgpO1xuICAgIH1cblxuICAgIG9uVmlkZW9Jbml0aWFsaXplZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5jb25maWcuaXNGbGFnRW5hYmxlZChGbGFncy5BdXRvUGxheVZpZGVvKSkge1xuICAgICAgICAgICAgdGhpcy5zaG93UGxheU92ZXJsYXkoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXRzUGFuZWw/Lm9uVmlkZW9Jbml0aWFsaXplZCh0aGlzLnN0cmVhbSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHVwIGZ1bmN0aW9uYWxpdHkgdG8gaGFwcGVuIHdoZW4gY2FsY3VsYXRpbmcgdGhlIGF2ZXJhZ2UgdmlkZW8gZW5jb2RlciBxcFxuICAgICAqIEBwYXJhbSBRUCAtIHRoZSBxdWFsaXR5IG51bWJlciBvZiB0aGUgc3RyZWFtXG4gICAgICovXG4gICAgb25WaWRlb0VuY29kZXJBdmdRUChRUDogbnVtYmVyKSB7XG4gICAgICAgIC8vIFVwZGF0ZSBpbnRlcm5hbCBRUCBpbmRpY2F0b3IgaWYgb25lIGlzIHByZXNlbnRcbiAgICAgICAgaWYgKCEhdGhpcy52aWRlb1FwSW5kaWNhdG9yKSB7XG4gICAgICAgICAgICB0aGlzLnZpZGVvUXBJbmRpY2F0b3IudXBkYXRlUXBUb29sdGlwKFFQKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uSW5pdGlhbFNldHRpbmdzKHNldHRpbmdzOiBJbml0aWFsU2V0dGluZ3MpIHtcbiAgICAgICAgaWYgKHNldHRpbmdzLlBpeGVsU3RyZWFtaW5nU2V0dGluZ3MpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNQYW5lbD8uY29uZmlndXJlKHNldHRpbmdzLlBpeGVsU3RyZWFtaW5nU2V0dGluZ3MpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25TdGF0c1JlY2VpdmVkKGFnZ3JlZ2F0ZWRTdGF0czogQWdncmVnYXRlZFN0YXRzKSB7XG4gICAgICAgIC8vIEdyYWIgYWxsIHN0YXRzIHdlIGNhbiBvZmYgdGhlIGFnZ3JlZ2F0ZWQgc3RhdHNcbiAgICAgICAgdGhpcy5zdGF0c1BhbmVsPy5oYW5kbGVTdGF0cyhhZ2dyZWdhdGVkU3RhdHMpO1xuICAgIH1cblxuICAgIG9uTGF0ZW5jeVRlc3RSZXN1bHRzKGxhdGVuY3lUaW1pbmdzOiBMYXRlbmN5VGVzdFJlc3VsdHMpIHtcbiAgICAgICAgdGhpcy5zdGF0c1BhbmVsPy5sYXRlbmN5VGVzdC5oYW5kbGVUZXN0UmVzdWx0KGxhdGVuY3lUaW1pbmdzKTtcbiAgICB9XG5cbiAgICBvbkRhdGFDaGFubmVsTGF0ZW5jeVRlc3RSZXN1bHRzKHJlc3VsdDogRGF0YUNoYW5uZWxMYXRlbmN5VGVzdFJlc3VsdCkge1xuICAgICAgICB0aGlzLnN0YXRzUGFuZWw/LmRhdGFDaGFubmVsTGF0ZW5jeVRlc3QuaGFuZGxlVGVzdFJlc3VsdChyZXN1bHQpO1xuICAgIH1cblxuICAgIG9uUGxheWVyQ291bnQocGxheWVyQ291bnQ6IG51bWJlcikge1xuICAgICAgICB0aGlzLnN0YXRzUGFuZWw/LmhhbmRsZVBsYXllckNvdW50KHBsYXllckNvdW50KTtcbiAgICB9XG5cbiAgICBoYW5kbGVTdHJlYW1lckxpc3RNZXNzYWdlKG1lc3NhZ2VTdHJlYW1pbmdMaXN0OiBNZXNzYWdlU3RyZWFtZXJMaXN0LCBhdXRvU2VsZWN0ZWRTdHJlYW1lcklkOiBzdHJpbmcsIHdhbnRlZFN0cmVhbWVySWQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCB3YWl0Rm9yU3RyZWFtZXIgPSB0aGlzLnN0cmVhbS5jb25maWcuaXNGbGFnRW5hYmxlZChGbGFncy5XYWl0Rm9yU3RyZWFtZXIpO1xuICAgICAgICBjb25zdCBpc1JlY29ubmVjdGluZyA9IHRoaXMuc3RyZWFtLmlzUmVjb25uZWN0aW5nKCk7XG4gICAgICAgIGxldCBtZXNzYWdlOiBzdHJpbmcgPSBudWxsO1xuICAgICAgICBsZXQgYWxsb3dSZXN0YXJ0OiBib29sZWFuID0gdHJ1ZTtcblxuICAgICAgICBpZiAoIWF1dG9TZWxlY3RlZFN0cmVhbWVySWQpIHtcbiAgICAgICAgICAgIGlmICh3YWl0Rm9yU3RyZWFtZXIgJiYgd2FudGVkU3RyZWFtZXJJZCkge1xuICAgICAgICAgICAgICAgIGlmIChpc1JlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gYFdhaXRpbmcgZm9yICR7d2FudGVkU3RyZWFtZXJJZH0gdG8gYmVjb21lIGF2YWlsYWJsZS5gO1xuICAgICAgICAgICAgICAgICAgICBhbGxvd1Jlc3RhcnQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gYEdhdmUgdXAgd2FpdGluZyBmb3IgJHt3YW50ZWRTdHJlYW1lcklkfSB0byBiZWNvbWUgYXZhaWxhYmxlLiBDbGljayB0byB0cnkgYWdhaW5gO1xuICAgICAgICAgICAgICAgICAgICBpZiAobWVzc2FnZVN0cmVhbWluZ0xpc3QuaWRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgKz0gYCBvciBzZWxlY3QgYSBzdHJlYW1lciBmcm9tIHRoZSBzZXR0aW5ncyBtZW51LmA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYWxsb3dSZXN0YXJ0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2VTdHJlYW1pbmdMaXN0Lmlkcy5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgICAgIGlmIChpc1JlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gYFdhaXRpbmcgZm9yIGEgc3RyZWFtZXIgdG8gYmVjb21lIGF2YWlsYWJsZS5gO1xuICAgICAgICAgICAgICAgICAgICBhbGxvd1Jlc3RhcnQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gYE5vIHN0cmVhbWVycyBhdmFpbGFibGUuIENsaWNrIHRvIHRyeSBhZ2Fpbi5gO1xuICAgICAgICAgICAgICAgICAgICBhbGxvd1Jlc3RhcnQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGBNdWx0aXBsZSBzdHJlYW1lcnMgYXZhaWxhYmxlLiBTZWxlY3Qgb25lIGZyb20gdGhlIHNldHRpbmdzIG1lbnUuYDtcbiAgICAgICAgICAgICAgICBhbGxvd1Jlc3RhcnQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGFsbG93UmVzdGFydCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2hvd0Rpc2Nvbm5lY3RPdmVybGF5KG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNob3dUZXh0T3ZlcmxheShtZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBsaWdodC9kYXJrIGNvbG9yIG1vZGVcbiAgICAgKiBAcGFyYW0gaXNMaWdodE1vZGUgLSBzaG91bGQgd2UgdXNlIGEgbGlnaHQgb3IgZGFyayBjb2xvciBzY2hlbWVcbiAgICAgKi9cbiAgICBzZXRDb2xvck1vZGUoaXNMaWdodE1vZGU6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHRoaXMub25Db2xvck1vZGVDaGFuZ2VkKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ29sb3JNb2RlQ2hhbmdlZChpc0xpZ2h0TW9kZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQge1xuICAgIENvbmZpZyxcbiAgICBGbGFnc0lkcyxcbiAgICBOdW1lcmljUGFyYW1ldGVyc0lkcyxcbiAgICBPcHRpb25QYXJhbWV0ZXJzSWRzLFxuICAgIFRleHRQYXJhbWV0ZXJzSWRzLFxuICAgIFRleHRQYXJhbWV0ZXJzLFxuICAgIE9wdGlvblBhcmFtZXRlcnMsXG4gICAgRmxhZ3MsXG4gICAgTnVtZXJpY1BhcmFtZXRlcnMsXG4gICAgU2V0dGluZ3NDaGFuZ2VkRXZlbnQsXG4gICAgU2V0dGluZ0ZsYWcsXG4gICAgU2V0dGluZ051bWJlcixcbiAgICBTZXR0aW5nVGV4dCxcbiAgICBTZXR0aW5nT3B0aW9uLFxuICAgIExvZ2dlcixcbiAgICBTZXR0aW5nQmFzZVxufSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcbmltcG9ydCB7IFNldHRpbmdVSUZsYWcgfSBmcm9tICcuL1NldHRpbmdVSUZsYWcnO1xuaW1wb3J0IHsgU2V0dGluZ1VJTnVtYmVyIH0gZnJvbSAnLi9TZXR0aW5nVUlOdW1iZXInO1xuaW1wb3J0IHsgU2V0dGluZ1VJVGV4dCB9IGZyb20gJy4vU2V0dGluZ1VJVGV4dCc7XG5pbXBvcnQgeyBTZXR0aW5nVUlPcHRpb24gfSBmcm9tICcuL1NldHRpbmdVSU9wdGlvbic7XG5cbmV4cG9ydCBjb25zdCBMaWdodE1vZGUgPSAnTGlnaHRNb2RlJyBhcyBjb25zdDtcbnR5cGUgRXh0cmFGbGFncyA9IHR5cGVvZiBMaWdodE1vZGU7XG5leHBvcnQgdHlwZSBGbGFnc0lkc0V4dGVuZGVkID0gRmxhZ3NJZHMgfCBFeHRyYUZsYWdzO1xuXG5leHBvcnQgY2xhc3MgQ29uZmlnVUkge1xuICAgIHByaXZhdGUgY3VzdG9tRmxhZ3MgPSBuZXcgTWFwPFxuICAgICAgICBGbGFnc0lkc0V4dGVuZGVkLFxuICAgICAgICBTZXR0aW5nRmxhZzxGbGFnc0lkc0V4dGVuZGVkPlxuICAgID4oKTtcblxuICAgIC8qIEEgbWFwIG9mIGZsYWdzIHRoYXQgY2FuIGJlIHRvZ2dsZWQgLSBvcHRpb25zIHRoYXQgY2FuIGJlIHNldCBpbiB0aGUgYXBwbGljYXRpb24gLSBlLmcuIFVzZSBNaWM/ICovXG4gICAgcHJpdmF0ZSBmbGFnc1VpID0gbmV3IE1hcDxcbiAgICAgICAgRmxhZ3NJZHNFeHRlbmRlZCxcbiAgICAgICAgU2V0dGluZ1VJRmxhZzxGbGFnc0lkc0V4dGVuZGVkPlxuICAgID4oKTtcblxuICAgIC8qIEEgbWFwIG9mIG51bWVyaWNhbCBzZXR0aW5ncyAtIG9wdGlvbnMgdGhhdCBjYW4gYmUgaW4gdGhlIGFwcGxpY2F0aW9uIC0gZS5nLiBNaW5CaXRyYXRlICovXG4gICAgcHJpdmF0ZSBudW1lcmljUGFyYW1ldGVyc1VpID0gbmV3IE1hcDxcbiAgICAgICAgTnVtZXJpY1BhcmFtZXRlcnNJZHMsXG4gICAgICAgIFNldHRpbmdVSU51bWJlclxuICAgID4oKTtcblxuICAgIC8qIEEgbWFwIG9mIHRleHQgc2V0dGluZ3MgLSBlLmcuIHNpZ25hbGxpbmcgc2VydmVyIHVybCAqL1xuICAgIHByaXZhdGUgdGV4dFBhcmFtZXRlcnNVaSA9IG5ldyBNYXA8VGV4dFBhcmFtZXRlcnNJZHMsIFNldHRpbmdVSVRleHQ+KCk7XG5cbiAgICAvKiBBIG1hcCBvZiBlbnVtIGJhc2VkIHNldHRpbmdzIC0gZS5nLiBwcmVmZXJyZWQgY29kZWMgKi9cbiAgICBwcml2YXRlIG9wdGlvblBhcmFtZXRlcnNVaSA9IG5ldyBNYXA8XG4gICAgICAgIE9wdGlvblBhcmFtZXRlcnNJZHMsXG4gICAgICAgIFNldHRpbmdVSU9wdGlvblxuICAgID4oKTtcblxuICAgIC8vIC0tLS0tLS0tLS0tLSBTZXR0aW5ncyAtLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgY29uc3RydWN0b3IoY29uZmlnOiBDb25maWcpIHtcbiAgICAgICAgdGhpcy5jcmVhdGVDdXN0b21VSVNldHRpbmdzKGNvbmZpZy51c2VVcmxQYXJhbXMpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyU2V0dGluZ3NVSUNvbXBvbmVudHMoY29uZmlnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgY3VzdG9tIFVJIHNldHRpbmdzIHRoYXQgYXJlIG5vdCBwcm92aWRlZCBieSB0aGUgUGl4ZWwgU3RyZWFtaW5nIGxpYnJhcnkuXG4gICAgICovXG4gICAgY3JlYXRlQ3VzdG9tVUlTZXR0aW5ncyh1c2VVcmxQYXJhbXM6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5jdXN0b21GbGFncy5zZXQoXG4gICAgICAgICAgICBMaWdodE1vZGUsXG4gICAgICAgICAgICBuZXcgU2V0dGluZ0ZsYWc8RmxhZ3NJZHNFeHRlbmRlZD4oXG4gICAgICAgICAgICAgICAgTGlnaHRNb2RlLFxuICAgICAgICAgICAgICAgICdDb2xvciBTY2hlbWU6IERhcmsgTW9kZScsXG4gICAgICAgICAgICAgICAgJ1BhZ2Ugc3R5bGluZyB3aWxsIGJlIGVpdGhlciBsaWdodCBvciBkYXJrJyxcbiAgICAgICAgICAgICAgICBmYWxzZSAvKmlmIHdhbnQgdG8gdXNlIHN5c3RlbSBwcmVmOiAod2luZG93Lm1hdGNoTWVkaWEgJiYgd2luZG93Lm1hdGNoTWVkaWEoJyhwcmVmZXJzLWNvbG9yLXNjaGVtZTogbGlnaHQpJykubWF0Y2hlcykqLyxcbiAgICAgICAgICAgICAgICB1c2VVcmxQYXJhbXMsXG4gICAgICAgICAgICAgICAgKGlzTGlnaHRNb2RlOiBib29sZWFuLCBzZXR0aW5nOiBTZXR0aW5nQmFzZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzZXR0aW5nLmxhYmVsID0gYENvbG9yIFNjaGVtZTogJHtpc0xpZ2h0TW9kZSA/ICdMaWdodCcgOiAnRGFyayd9IE1vZGVgO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIFVJIHdyYXBwZXIgY29tcG9uZW50cyBmb3IgZWFjaCBzZXR0aW5nIGVsZW1lbnQgaW4gY29uZmlnLlxuICAgICAqIEBwYXJhbSBjb25maWdcbiAgICAgKi9cbiAgICByZWdpc3RlclNldHRpbmdzVUlDb21wb25lbnRzKGNvbmZpZzogQ29uZmlnKSB7XG4gICAgICAgIGZvciAoY29uc3Qgc2V0dGluZyBvZiBjb25maWcuZ2V0RmxhZ3MoKSkge1xuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLnNldChzZXR0aW5nLmlkLCBuZXcgU2V0dGluZ1VJRmxhZyhzZXR0aW5nKSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBzZXR0aW5nIG9mIEFycmF5LmZyb20odGhpcy5jdXN0b21GbGFncy52YWx1ZXMoKSkpIHtcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5zZXQoXG4gICAgICAgICAgICAgICAgc2V0dGluZy5pZCxcbiAgICAgICAgICAgICAgICBuZXcgU2V0dGluZ1VJRmxhZzxGbGFnc0lkc0V4dGVuZGVkPihzZXR0aW5nKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IHNldHRpbmcgb2YgY29uZmlnLmdldFRleHRTZXR0aW5ncygpKSB7XG4gICAgICAgICAgICB0aGlzLnRleHRQYXJhbWV0ZXJzVWkuc2V0KHNldHRpbmcuaWQsIG5ldyBTZXR0aW5nVUlUZXh0KHNldHRpbmcpKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IHNldHRpbmcgb2YgY29uZmlnLmdldE51bWVyaWNTZXR0aW5ncygpKSB7XG4gICAgICAgICAgICB0aGlzLm51bWVyaWNQYXJhbWV0ZXJzVWkuc2V0KFxuICAgICAgICAgICAgICAgIHNldHRpbmcuaWQsXG4gICAgICAgICAgICAgICAgbmV3IFNldHRpbmdVSU51bWJlcihzZXR0aW5nKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IHNldHRpbmcgb2YgY29uZmlnLmdldE9wdGlvblNldHRpbmdzKCkpIHtcbiAgICAgICAgICAgIHRoaXMub3B0aW9uUGFyYW1ldGVyc1VpLnNldChcbiAgICAgICAgICAgICAgICBzZXR0aW5nLmlkLFxuICAgICAgICAgICAgICAgIG5ldyBTZXR0aW5nVUlPcHRpb24oc2V0dGluZylcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlIERPTSBlbGVtZW50cyBmb3IgYSBzZXR0aW5ncyBzZWN0aW9uIHdpdGggYSBoZWFkaW5nLlxuICAgICAqIEBwYXJhbSBzZXR0aW5nc0VsZW0gVGhlIHBhcmVudCBjb250YWluZXIgZm9yIG91ciBET00gZWxlbWVudHMuXG4gICAgICogQHBhcmFtIHNlY3Rpb25IZWFkaW5nIFRoZSBoZWFkaW5nIGVsZW1lbnQgdG8gZ28gaW50byB0aGUgc2VjdGlvbi5cbiAgICAgKiBAcmV0dXJucyBUaGUgY29uc3RydWN0ZWQgRE9NIGVsZW1lbnQgZm9yIHRoZSBzZWN0aW9uLlxuICAgICAqL1xuICAgIGJ1aWxkU2VjdGlvbldpdGhIZWFkaW5nKHNldHRpbmdzRWxlbTogSFRNTEVsZW1lbnQsIHNlY3Rpb25IZWFkaW5nOiBzdHJpbmcpIHtcbiAgICAgICAgLy8gbWFrZSBzZWN0aW9uIGVsZW1lbnRcbiAgICAgICAgY29uc3Qgc2VjdGlvbkVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzZWN0aW9uJyk7XG4gICAgICAgIHNlY3Rpb25FbGVtLmNsYXNzTGlzdC5hZGQoJ3NldHRpbmdzQ29udGFpbmVyJyk7XG5cbiAgICAgICAgLy8gbWFrZSBzZWN0aW9uIGhlYWRpbmdcbiAgICAgICAgY29uc3QgcHNTZXR0aW5nc0hlYWRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBwc1NldHRpbmdzSGVhZGVyLmNsYXNzTGlzdC5hZGQoJ3NldHRpbmdzSGVhZGVyJyk7XG4gICAgICAgIHBzU2V0dGluZ3NIZWFkZXIuY2xhc3NMaXN0LmFkZCgnc2V0dGluZ3MtdGV4dCcpO1xuICAgICAgICBwc1NldHRpbmdzSGVhZGVyLnRleHRDb250ZW50ID0gc2VjdGlvbkhlYWRpbmc7XG5cbiAgICAgICAgLy8gYWRkIHNlY3Rpb24gYW5kIGhlYWRpbmcgdG8gcGFyZW50IHNldHRpbmdzIGVsZW1lbnRcbiAgICAgICAgc2VjdGlvbkVsZW0uYXBwZW5kQ2hpbGQocHNTZXR0aW5nc0hlYWRlcik7XG4gICAgICAgIHNldHRpbmdzRWxlbS5hcHBlbmRDaGlsZChzZWN0aW9uRWxlbSk7XG4gICAgICAgIHJldHVybiBzZWN0aW9uRWxlbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXR1cCBmbGFncyB3aXRoIHRoZWlyIGRlZmF1bHQgdmFsdWVzIGFuZCBhZGQgdGhlbSB0byB0aGUgYENvbmZpZy5mbGFnc2AgbWFwLlxuICAgICAqIEBwYXJhbSBzZXR0aW5nc0VsZW0gLSBUaGUgZWxlbWVudCB0aGF0IGNvbnRhaW5zIGFsbCB0aGUgaW5kaXZpZHVhbCBzZXR0aW5ncyBzZWN0aW9ucywgZmxhZ3MsIGFuZCBzbyBvbi5cbiAgICAgKi9cbiAgICBwb3B1bGF0ZVNldHRpbmdzRWxlbWVudChzZXR0aW5nc0VsZW06IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIC8qIFNldHVwIGFsbCBQaXhlbCBTdHJlYW1pbmcgc3BlY2lmaWMgc2V0dGluZ3MgKi9cbiAgICAgICAgY29uc3QgcHNTZXR0aW5nc1NlY3Rpb24gPSB0aGlzLmJ1aWxkU2VjdGlvbldpdGhIZWFkaW5nKFxuICAgICAgICAgICAgc2V0dGluZ3NFbGVtLFxuICAgICAgICAgICAgJ1BpeGVsIFN0cmVhbWluZydcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBtYWtlIHNldHRpbmdzIHNob3cgdXAgaW4gRE9NXG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ1RleHQoXG4gICAgICAgICAgICBwc1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMudGV4dFBhcmFtZXRlcnNVaS5nZXQoVGV4dFBhcmFtZXRlcnMuU2lnbmFsbGluZ1NlcnZlclVybClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nT3B0aW9uKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLm9wdGlvblBhcmFtZXRlcnNVaS5nZXQoT3B0aW9uUGFyYW1ldGVycy5TdHJlYW1lcklkKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLkF1dG9Db25uZWN0KVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLkF1dG9QbGF5VmlkZW8pXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ0ZsYWcoXG4gICAgICAgICAgICBwc1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5nZXQoRmxhZ3MuQnJvd3NlclNlbmRPZmZlcilcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLCBcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5nZXQoRmxhZ3MuVXNlTWljKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLlN0YXJ0VmlkZW9NdXRlZClcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5Jc1F1YWxpdHlDb250cm9sbGVyKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLkZvcmNlTW9ub0F1ZGlvKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLkZvcmNlVFVSTilcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5TdXBwcmVzc0Jyb3dzZXJLZXlzKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgcHNTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLkFGS0RldGVjdGlvbilcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHBzU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5XYWl0Rm9yU3RyZWFtZXIpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ051bWVyaWMoXG4gICAgICAgICAgICBwc1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMubnVtZXJpY1BhcmFtZXRlcnNVaS5nZXQoTnVtZXJpY1BhcmFtZXRlcnMuQUZLVGltZW91dFNlY3MpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ051bWVyaWMoXG4gICAgICAgICAgICBwc1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMubnVtZXJpY1BhcmFtZXRlcnNVaS5nZXQoTnVtZXJpY1BhcmFtZXRlcnMuTWF4UmVjb25uZWN0QXR0ZW1wdHMpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ051bWVyaWMoXG4gICAgICAgICAgICBwc1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMubnVtZXJpY1BhcmFtZXRlcnNVaS5nZXQoTnVtZXJpY1BhcmFtZXRlcnMuU3RyZWFtZXJBdXRvSm9pbkludGVydmFsKVxuICAgICAgICApO1xuXG4gICAgICAgIC8qIFNldHVwIGFsbCB2aWV3L3VpIHJlbGF0ZWQgc2V0dGluZ3MgdW5kZXIgdGhpcyBzZWN0aW9uICovXG4gICAgICAgIGNvbnN0IHZpZXdTZXR0aW5nc1NlY3Rpb24gPSB0aGlzLmJ1aWxkU2VjdGlvbldpdGhIZWFkaW5nKFxuICAgICAgICAgICAgc2V0dGluZ3NFbGVtLFxuICAgICAgICAgICAgJ1VJJ1xuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgdmlld1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5nZXQoRmxhZ3MuTWF0Y2hWaWV3cG9ydFJlc29sdXRpb24pXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIHZpZXdTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLkhvdmVyaW5nTW91c2VNb2RlKVxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ0ZsYWcodmlld1NldHRpbmdzU2VjdGlvbiwgdGhpcy5mbGFnc1VpLmdldChMaWdodE1vZGUpKTtcblxuICAgICAgICAvKiBTZXR1cCBhbGwgZW5jb2RlciByZWxhdGVkIHNldHRpbmdzIHVuZGVyIHRoaXMgc2VjdGlvbiAqL1xuICAgICAgICBjb25zdCBpbnB1dFNldHRpbmdzU2VjdGlvbiA9IHRoaXMuYnVpbGRTZWN0aW9uV2l0aEhlYWRpbmcoXG4gICAgICAgICAgICBzZXR0aW5nc0VsZW0sXG4gICAgICAgICAgICAnSW5wdXQnXG4gICAgICAgICk7XG4gICAgICAgIFxuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgaW5wdXRTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLktleWJvYXJkSW5wdXQpXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgICAgIGlucHV0U2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5mbGFnc1VpLmdldChGbGFncy5Nb3VzZUlucHV0KVxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ0ZsYWcoXG4gICAgICAgICAgICBpbnB1dFNldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5nZXQoRmxhZ3MuVG91Y2hJbnB1dClcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgaW5wdXRTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLkdhbWVwYWRJbnB1dClcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLmFkZFNldHRpbmdGbGFnKFxuICAgICAgICAgICAgaW5wdXRTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLmZsYWdzVWkuZ2V0KEZsYWdzLlhSQ29udHJvbGxlcklucHV0KVxuICAgICAgICApO1xuXG4gICAgICAgIC8qIFNldHVwIGFsbCBlbmNvZGVyIHJlbGF0ZWQgc2V0dGluZ3MgdW5kZXIgdGhpcyBzZWN0aW9uICovXG4gICAgICAgIGNvbnN0IGVuY29kZXJTZXR0aW5nc1NlY3Rpb24gPSB0aGlzLmJ1aWxkU2VjdGlvbldpdGhIZWFkaW5nKFxuICAgICAgICAgICAgc2V0dGluZ3NFbGVtLFxuICAgICAgICAgICAgJ0VuY29kZXInXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nTnVtZXJpYyhcbiAgICAgICAgICAgIGVuY29kZXJTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLm51bWVyaWNQYXJhbWV0ZXJzVWkuZ2V0KE51bWVyaWNQYXJhbWV0ZXJzLk1pblFQKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdOdW1lcmljKFxuICAgICAgICAgICAgZW5jb2RlclNldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMubnVtZXJpY1BhcmFtZXRlcnNVaS5nZXQoTnVtZXJpY1BhcmFtZXRlcnMuTWF4UVApXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgcHJlZmVycmVkQ29kZWNPcHRpb24gPSB0aGlzLm9wdGlvblBhcmFtZXRlcnNVaS5nZXQoXG4gICAgICAgICAgICBPcHRpb25QYXJhbWV0ZXJzLlByZWZlcnJlZENvZGVjXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkU2V0dGluZ09wdGlvbihcbiAgICAgICAgICAgIGVuY29kZXJTZXR0aW5nc1NlY3Rpb24sXG4gICAgICAgICAgICB0aGlzLm9wdGlvblBhcmFtZXRlcnNVaS5nZXQoT3B0aW9uUGFyYW1ldGVycy5QcmVmZXJyZWRDb2RlYylcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgcHJlZmVycmVkQ29kZWNPcHRpb24gJiZcbiAgICAgICAgICAgIFsuLi5wcmVmZXJyZWRDb2RlY09wdGlvbi5zZWxlY3Rvci5vcHRpb25zXVxuICAgICAgICAgICAgICAgIC5tYXAoKG8pID0+IG8udmFsdWUpXG4gICAgICAgICAgICAgICAgLmluY2x1ZGVzKCdPbmx5IGF2YWlsYWJsZSBvbiBDaHJvbWUnKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHByZWZlcnJlZENvZGVjT3B0aW9uLmRpc2FibGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qIFNldHVwIGFsbCB3ZWJydGMgcmVsYXRlZCBzZXR0aW5ncyB1bmRlciB0aGlzIHNlY3Rpb24gKi9cbiAgICAgICAgY29uc3Qgd2VicnRjU2V0dGluZ3NTZWN0aW9uID0gdGhpcy5idWlsZFNlY3Rpb25XaXRoSGVhZGluZyhcbiAgICAgICAgICAgIHNldHRpbmdzRWxlbSxcbiAgICAgICAgICAgICdXZWJSVEMnXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5hZGRTZXR0aW5nTnVtZXJpYyhcbiAgICAgICAgICAgIHdlYnJ0Y1NldHRpbmdzU2VjdGlvbixcbiAgICAgICAgICAgIHRoaXMubnVtZXJpY1BhcmFtZXRlcnNVaS5nZXQoTnVtZXJpY1BhcmFtZXRlcnMuV2ViUlRDRlBTKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdOdW1lcmljKFxuICAgICAgICAgICAgd2VicnRjU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5udW1lcmljUGFyYW1ldGVyc1VpLmdldChOdW1lcmljUGFyYW1ldGVycy5XZWJSVENNaW5CaXRyYXRlKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmFkZFNldHRpbmdOdW1lcmljKFxuICAgICAgICAgICAgd2VicnRjU2V0dGluZ3NTZWN0aW9uLFxuICAgICAgICAgICAgdGhpcy5udW1lcmljUGFyYW1ldGVyc1VpLmdldChOdW1lcmljUGFyYW1ldGVycy5XZWJSVENNYXhCaXRyYXRlKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhIFNldHRpbmdUZXh0IGVsZW1lbnQgdG8gYSBwYXJ0aWN1bGFyIHNldHRpbmdzIHNlY3Rpb24gaW4gdGhlIERPTSBhbmQgcmVnaXN0ZXJzIHRoYXQgdGV4dCBpbiB0aGUgdGV4dCBzZXR0aW5ncyBtYXAuXG4gICAgICogQHBhcmFtIHNldHRpbmdzU2VjdGlvbiBUaGUgc2V0dGluZ3Mgc2VjdGlvbiBIVE1MIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHNldHRpbmdUZXh0IFRoZSB0ZXh0dWFsIHNldHRpbmdzIG9iamVjdC5cbiAgICAgKi9cbiAgICBhZGRTZXR0aW5nVGV4dChcbiAgICAgICAgc2V0dGluZ3NTZWN0aW9uOiBIVE1MRWxlbWVudCxcbiAgICAgICAgc2V0dGluZ1RleHQ/OiBTZXR0aW5nVUlUZXh0XG4gICAgKTogdm9pZCB7XG4gICAgICAgIGlmIChzZXR0aW5nVGV4dCkge1xuICAgICAgICAgICAgc2V0dGluZ3NTZWN0aW9uLmFwcGVuZENoaWxkKHNldHRpbmdUZXh0LnJvb3RFbGVtZW50KTtcbiAgICAgICAgICAgIHRoaXMudGV4dFBhcmFtZXRlcnNVaS5zZXQoc2V0dGluZ1RleHQuc2V0dGluZy5pZCwgc2V0dGluZ1RleHQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgU2V0dGluZ0ZsYWcgZWxlbWVudCB0byBhIHBhcnRpY3VsYXIgc2V0dGluZ3Mgc2VjdGlvbiBpbiB0aGUgRE9NIGFuZCByZWdpc3RlcnMgdGhhdCBmbGFnIGluIHRoZSBDb25maWcuZmxhZyBtYXAuXG4gICAgICogQHBhcmFtIHNldHRpbmdzU2VjdGlvbiBUaGUgc2V0dGluZ3Mgc2VjdGlvbiBIVE1MIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHNldHRpbmdGbGFnIFRoZSBzZXR0aW5ncyBmbGFnIG9iamVjdC5cbiAgICAgKi9cbiAgICBhZGRTZXR0aW5nRmxhZyhcbiAgICAgICAgc2V0dGluZ3NTZWN0aW9uOiBIVE1MRWxlbWVudCxcbiAgICAgICAgc2V0dGluZ0ZsYWc/OiBTZXR0aW5nVUlGbGFnPEZsYWdzSWRzRXh0ZW5kZWQ+XG4gICAgKTogdm9pZCB7XG4gICAgICAgIGlmIChzZXR0aW5nRmxhZykge1xuICAgICAgICAgICAgc2V0dGluZ3NTZWN0aW9uLmFwcGVuZENoaWxkKHNldHRpbmdGbGFnLnJvb3RFbGVtZW50KTtcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5zZXQoc2V0dGluZ0ZsYWcuc2V0dGluZy5pZCwgc2V0dGluZ0ZsYWcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgbnVtZXJpYyBzZXR0aW5nIGVsZW1lbnQgdG8gYSBwYXJ0aWN1bGFyIHNldHRpbmdzIHNlY3Rpb24gaW4gdGhlIERPTSBhbmQgcmVnaXN0ZXJzIHRoYXQgZmxhZyBpbiB0aGUgQ29uZmlnLm51bWVyaWNQYXJhbWV0ZXJzIG1hcC5cbiAgICAgKiBAcGFyYW0gc2V0dGluZ3NTZWN0aW9uIFRoZSBzZXR0aW5ncyBzZWN0aW9uIEhUTUwgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0gc2V0dGluZ0ZsYWcgVGhlIHNldHRpbmdzIGZsYWcgb2JqZWN0LlxuICAgICAqL1xuICAgIGFkZFNldHRpbmdOdW1lcmljKFxuICAgICAgICBzZXR0aW5nc1NlY3Rpb246IEhUTUxFbGVtZW50LFxuICAgICAgICBzZXR0aW5nPzogU2V0dGluZ1VJTnVtYmVyXG4gICAgKTogdm9pZCB7XG4gICAgICAgIGlmIChzZXR0aW5nKSB7XG4gICAgICAgICAgICBzZXR0aW5nc1NlY3Rpb24uYXBwZW5kQ2hpbGQoc2V0dGluZy5yb290RWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLm51bWVyaWNQYXJhbWV0ZXJzVWkuc2V0KHNldHRpbmcuc2V0dGluZy5pZCwgc2V0dGluZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gZW51bSBiYXNlZCBzZXR0aW5ncyBlbGVtZW50IHRvIGEgcGFydGljdWxhciBzZXR0aW5ncyBzZWN0aW9uIGluIHRoZSBET00gYW5kIHJlZ2lzdGVycyB0aGF0IGZsYWcgaW4gdGhlIENvbmZpZy5lbnVtUGFyYW1ldGVycyBtYXAuXG4gICAgICogQHBhcmFtIHNldHRpbmdzU2VjdGlvbiBUaGUgc2V0dGluZ3Mgc2VjdGlvbiBIVE1MIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHNldHRpbmdGbGFnIFRoZSBzZXR0aW5ncyBmbGFnIG9iamVjdC5cbiAgICAgKi9cbiAgICBhZGRTZXR0aW5nT3B0aW9uKFxuICAgICAgICBzZXR0aW5nc1NlY3Rpb246IEhUTUxFbGVtZW50LFxuICAgICAgICBzZXR0aW5nPzogU2V0dGluZ1VJT3B0aW9uXG4gICAgKTogdm9pZCB7XG4gICAgICAgIGlmIChzZXR0aW5nKSB7XG4gICAgICAgICAgICBzZXR0aW5nc1NlY3Rpb24uYXBwZW5kQ2hpbGQoc2V0dGluZy5yb290RWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLm9wdGlvblBhcmFtZXRlcnNVaS5zZXQoc2V0dGluZy5zZXR0aW5nLmlkLCBzZXR0aW5nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uU2V0dGluZ3NDaGFuZ2VkKHsgZGF0YTogeyBpZCwgdGFyZ2V0LCB0eXBlIH0gfTogU2V0dGluZ3NDaGFuZ2VkRXZlbnQpIHtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdmbGFnJykge1xuICAgICAgICAgICAgY29uc3QgX2lkID0gaWQgYXMgRmxhZ3NJZHM7XG4gICAgICAgICAgICBjb25zdCBfdGFyZ2V0ID0gdGFyZ2V0IGFzIFNldHRpbmdGbGFnO1xuICAgICAgICAgICAgY29uc3Qgc2V0dGluZyA9IHRoaXMuZmxhZ3NVaS5nZXQoX2lkKTtcbiAgICAgICAgICAgIGlmIChzZXR0aW5nKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNldHRpbmcuZmxhZyAhPT0gX3RhcmdldC5mbGFnKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmcuZmxhZyA9IF90YXJnZXQuZmxhZztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHNldHRpbmcubGFiZWwgIT09IF90YXJnZXQubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZy5sYWJlbCA9IF90YXJnZXQubGFiZWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBjb25zdCBfaWQgPSBpZCBhcyBOdW1lcmljUGFyYW1ldGVyc0lkcztcbiAgICAgICAgICAgIGNvbnN0IF90YXJnZXQgPSB0YXJnZXQgYXMgU2V0dGluZ051bWJlcjtcbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmcgPSB0aGlzLm51bWVyaWNQYXJhbWV0ZXJzVWkuZ2V0KF9pZCk7XG4gICAgICAgICAgICBpZiAoc2V0dGluZykge1xuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5nLm51bWJlciAhPT0gX3RhcmdldC5udW1iZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZy5udW1iZXIgPSBfdGFyZ2V0Lm51bWJlcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHNldHRpbmcubGFiZWwgIT09IF90YXJnZXQubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZy5sYWJlbCA9IF90YXJnZXQubGFiZWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgICAgICAgY29uc3QgX2lkID0gaWQgYXMgVGV4dFBhcmFtZXRlcnNJZHM7XG4gICAgICAgICAgICBjb25zdCBfdGFyZ2V0ID0gdGFyZ2V0IGFzIFNldHRpbmdUZXh0O1xuICAgICAgICAgICAgY29uc3Qgc2V0dGluZyA9IHRoaXMudGV4dFBhcmFtZXRlcnNVaS5nZXQoX2lkKTtcbiAgICAgICAgICAgIGlmIChzZXR0aW5nKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNldHRpbmcudGV4dCAhPT0gX3RhcmdldC50ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmcudGV4dCA9IF90YXJnZXQudGV4dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHNldHRpbmcubGFiZWwgIT09IF90YXJnZXQubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZy5sYWJlbCA9IF90YXJnZXQubGFiZWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvcHRpb24nKSB7XG4gICAgICAgICAgICBjb25zdCBfaWQgPSBpZCBhcyBPcHRpb25QYXJhbWV0ZXJzSWRzO1xuICAgICAgICAgICAgY29uc3QgX3RhcmdldCA9IHRhcmdldCBhcyBTZXR0aW5nT3B0aW9uO1xuICAgICAgICAgICAgY29uc3Qgc2V0dGluZyA9IHRoaXMub3B0aW9uUGFyYW1ldGVyc1VpLmdldChfaWQpO1xuICAgICAgICAgICAgaWYgKHNldHRpbmcpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB1aU9wdGlvbnMgPSBzZXR0aW5nLm9wdGlvbnM7XG4gICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0T3B0aW9ucyA9IF90YXJnZXQub3B0aW9ucztcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHVpT3B0aW9ucy5sZW5ndGggIT09IHRhcmdldE9wdGlvbnMubGVuZ3RoIHx8XG4gICAgICAgICAgICAgICAgICAgICF1aU9wdGlvbnMuZXZlcnkoKHZhbHVlKSA9PiB0YXJnZXRPcHRpb25zLmluY2x1ZGVzKHZhbHVlKSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZy5vcHRpb25zID0gX3RhcmdldC5vcHRpb25zO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc2V0dGluZy5zZWxlY3RlZCAhPT0gX3RhcmdldC5zZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICBzZXR0aW5nLnNlbGVjdGVkID0gX3RhcmdldC5zZWxlY3RlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHNldHRpbmcubGFiZWwgIT09IF90YXJnZXQubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZy5sYWJlbCA9IF90YXJnZXQubGFiZWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgY2FsbGJhY2sgdG8gZmlyZSB3aGVuIHRoZSBmbGFnIGlzIHRvZ2dsZWQuXG4gICAgICogQHBhcmFtIGlkIFRoZSBpZCBvZiB0aGUgZmxhZy5cbiAgICAgKiBAcGFyYW0gb25DaGFuZ2VMaXN0ZW5lciBUaGUgY2FsbGJhY2sgdG8gZmlyZSB3aGVuIHRoZSB2YWx1ZSBjaGFuZ2VzLlxuICAgICAqL1xuICAgIGFkZEN1c3RvbUZsYWdPblNldHRpbmdDaGFuZ2VkTGlzdGVuZXIoXG4gICAgICAgIGlkOiBFeHRyYUZsYWdzLFxuICAgICAgICBvbkNoYW5nZUxpc3RlbmVyOiAobmV3RmxhZ1ZhbHVlOiBib29sZWFuKSA9PiB2b2lkXG4gICAgKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmN1c3RvbUZsYWdzLmhhcyhpZCkpIHtcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tRmxhZ3MuZ2V0KGlkKS5vbkNoYW5nZSA9IG9uQ2hhbmdlTGlzdGVuZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxhYmVsIGZvciB0aGUgZmxhZy5cbiAgICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBmbGFnLlxuICAgICAqIEBwYXJhbSBsYWJlbCBUaGUgbmV3IGxhYmVsIHRvIHVzZSBmb3IgdGhlIGZsYWcuXG4gICAgICovXG4gICAgc2V0Q3VzdG9tRmxhZ0xhYmVsKGlkOiBFeHRyYUZsYWdzLCBsYWJlbDogc3RyaW5nKSB7XG4gICAgICAgIGlmICghdGhpcy5jdXN0b21GbGFncy5oYXMoaWQpKSB7XG4gICAgICAgICAgICBMb2dnZXIuV2FybmluZyhcbiAgICAgICAgICAgICAgICBMb2dnZXIuR2V0U3RhY2tUcmFjZSgpLFxuICAgICAgICAgICAgICAgIGBDYW5ub3Qgc2V0IGxhYmVsIGZvciBmbGFnIGNhbGxlZCAke2lkfSAtIGl0IGRvZXMgbm90IGV4aXN0IGluIHRoZSBDb25maWcuZmxhZ3MgbWFwLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmN1c3RvbUZsYWdzLmdldChpZCkubGFiZWwgPSBsYWJlbDtcbiAgICAgICAgICAgIHRoaXMuZmxhZ3NVaS5nZXQoaWQpLmxhYmVsID0gbGFiZWw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIHRoZSBjb25maWd1cmF0aW9uIGZsYWcgd2hpY2ggaGFzIHRoZSBnaXZlbiBpZC5cbiAgICAgKiBAcGFyYW0gaWQgVGhlIHVuaXF1ZSBpZCBmb3IgdGhlIGZsYWcuXG4gICAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgZmxhZyBpcyBlbmFibGVkLlxuICAgICAqL1xuICAgIGlzQ3VzdG9tRmxhZ0VuYWJsZWQoaWQ6IEV4dHJhRmxhZ3MpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3VzdG9tRmxhZ3MuZ2V0KGlkKS5mbGFnIGFzIGJvb2xlYW47XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgU2V0dGluZ0Jhc2UgfSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBhIHNldHRpbmcgdGhhdCBoYXMgYSB0ZXh0IGxhYmVsLCBhbiBhcmJpdHJhcnkgc2V0dGluZyB2YWx1ZSBpdCBzdG9yZXMsIGFuIGEgSFRNTCBlbGVtZW50IHRoYXQgcmVwcmVzZW50cyB0aGlzIHNldHRpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXR0aW5nVUlCYXNlIHtcbiAgICBfc2V0dGluZzogU2V0dGluZ0Jhc2U7XG4gICAgX3Jvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIGNvbnN0cnVjdG9yKHNldHRpbmc6IFNldHRpbmdCYXNlKSB7XG4gICAgICAgIHRoaXMuX3NldHRpbmcgPSBzZXR0aW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBzZXR0aW5nIGNvbXBvbmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHNldHRpbmcoKTogU2V0dGluZ0Jhc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBSZXR1cm4gb3IgY3JlYXRlcyBhIEhUTUwgZWxlbWVudCB0aGF0IHJlcHJlc2VudHMgdGhpcyBzZXR0aW5nIGluIHRoZSBET00uXG4gICAgICovXG4gICAgcHVibGljIGdldCByb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB0eXBlIHtcbiAgICBGbGFnc0lkcyxcbiAgICBTZXR0aW5nRmxhZ1xufSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcbmltcG9ydCB7IFNldHRpbmdVSUJhc2UgfSBmcm9tICcuL1NldHRpbmdVSUJhc2UnO1xuXG5leHBvcnQgY2xhc3MgU2V0dGluZ1VJRmxhZzxcbiAgICBDdXN0b21JZHMgZXh0ZW5kcyBzdHJpbmcgPSBGbGFnc0lkc1xuPiBleHRlbmRzIFNldHRpbmdVSUJhc2Uge1xuICAgIC8qIFdlIHRvZ2dsZSB0aGlzIGNoZWNrYm94IHRvIHJlZmxlY3QgdGhlIHZhbHVlIG9mIG91ciBzZXR0aW5nJ3MgYm9vbGVhbiBmbGFnLiAqL1xuICAgIF9jaGVja2JveDogSFRNTElucHV0RWxlbWVudDsgLy8gaW5wdXQgdHlwZT1cImNoZWNrYm94XCJcblxuICAgIC8qIFRoaXMgZWxlbWVudCBjb250YWlucyBhIHRleHQgbm9kZSB0aGF0IHJlZmxlY3RzIHRoZSBzZXR0aW5nJ3MgdGV4dCBsYWJlbC4gKi9cbiAgICBfc2V0dGluZ3NUZXh0RWxlbTogSFRNTEVsZW1lbnQ7XG5cbiAgICBvbkNoYW5nZUVtaXQ6IChjaGFuZ2VkVmFsdWU6IGJvb2xlYW4pID0+IHZvaWQ7XG5cbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5nOiBTZXR0aW5nRmxhZzxDdXN0b21JZHM+KSB7XG4gICAgICAgIHN1cGVyKHNldHRpbmcpO1xuXG4gICAgICAgIHRoaXMubGFiZWwgPSBzZXR0aW5nLmxhYmVsO1xuICAgICAgICB0aGlzLmZsYWcgPSBzZXR0aW5nLmZsYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIHNldHRpbmcgY29tcG9uZW50LlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgc2V0dGluZygpOiBTZXR0aW5nRmxhZzxDdXN0b21JZHM+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmcgYXMgU2V0dGluZ0ZsYWc8Q3VzdG9tSWRzPjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHNldHRpbmdzVGV4dEVsZW0oKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3NldHRpbmdzVGV4dEVsZW0pIHtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0ID0gdGhpcy5zZXR0aW5nLl9sYWJlbDtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0udGl0bGUgPSB0aGlzLnNldHRpbmcuZGVzY3JpcHRpb247XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzVGV4dEVsZW07XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBjaGVja2JveCgpOiBIVE1MSW5wdXRFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9jaGVja2JveCkge1xuICAgICAgICAgICAgdGhpcy5fY2hlY2tib3ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICAgICAgdGhpcy5fY2hlY2tib3gudHlwZSA9ICdjaGVja2JveCc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2NoZWNrYm94O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFJldHVybiBvciBjcmVhdGVzIGEgSFRNTCBlbGVtZW50IHRoYXQgcmVwcmVzZW50cyB0aGlzIHNldHRpbmcgaW4gdGhlIERPTS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIHJvb3QgZGl2IHdpdGggXCJzZXR0aW5nXCIgY3NzIGNsYXNzXG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaWQgPSB0aGlzLnNldHRpbmcuaWQ7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nJyk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBkaXYgZWxlbWVudCB0byBjb250YWluIG91ciBzZXR0aW5nJ3MgdGV4dFxuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zZXR0aW5nc1RleHRFbGVtKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGxhYmVsIGVsZW1lbnQgdG8gd3JhcCBvdXQgaW5wdXQgdHlwZVxuICAgICAgICAgICAgY29uc3Qgd3JhcHBlckxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgICAgICAgICAgIHdyYXBwZXJMYWJlbC5jbGFzc0xpc3QuYWRkKCd0Z2wtc3dpdGNoJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh3cmFwcGVyTGFiZWwpO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgaW5wdXQgdHlwZT1jaGVja2JveFxuICAgICAgICAgICAgdGhpcy5jaGVja2JveC50aXRsZSA9IHRoaXMuc2V0dGluZy5kZXNjcmlwdGlvbjtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tib3guY2xhc3NMaXN0LmFkZCgndGdsJyk7XG4gICAgICAgICAgICB0aGlzLmNoZWNrYm94LmNsYXNzTGlzdC5hZGQoJ3RnbC1mbGF0Jyk7XG4gICAgICAgICAgICBjb25zdCBzbGlkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHNsaWRlci5jbGFzc0xpc3QuYWRkKCd0Z2wtc2xpZGVyJyk7XG4gICAgICAgICAgICB3cmFwcGVyTGFiZWwuYXBwZW5kQ2hpbGQodGhpcy5jaGVja2JveCk7XG4gICAgICAgICAgICB3cmFwcGVyTGFiZWwuYXBwZW5kQ2hpbGQoc2xpZGVyKTtcblxuICAgICAgICAgICAgLy8gc2V0dXAgb24gY2hhbmdlIGZyb20gY2hlY2tib3hcbiAgICAgICAgICAgIHRoaXMuY2hlY2tib3guYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmcuZmxhZyAhPT0gdGhpcy5jaGVja2JveC5jaGVja2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZy5mbGFnID0gdGhpcy5jaGVja2JveC5jaGVja2VkO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmcudXBkYXRlVVJMUGFyYW1zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgc2V0dGluZydzIHN0b3JlZCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gaW5WYWx1ZSBUaGUgbmV3IHZhbHVlIGZvciB0aGUgc2V0dGluZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IGZsYWcoaW5WYWx1ZTogYm9vbGVhbikge1xuICAgICAgICB0aGlzLmNoZWNrYm94LmNoZWNrZWQgPSBpblZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB2YWx1ZVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZmxhZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hlY2tib3guY2hlY2tlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxhYmVsIHRleHQgZm9yIHRoZSBzZXR0aW5nLlxuICAgICAqIEBwYXJhbSBsYWJlbCBzZXR0aW5nIGxhYmVsLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXQgbGFiZWwoaW5MYWJlbDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2V0dGluZ3NUZXh0RWxlbS5pbm5lclRleHQgPSBpbkxhYmVsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBsYWJlbFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgbGFiZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0O1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB0eXBlIHtcbiAgICBOdW1lcmljUGFyYW1ldGVyc0lkcyxcbiAgICBTZXR0aW5nTnVtYmVyXG59IGZyb20gJ0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5pbXBvcnQgeyBTZXR0aW5nVUlCYXNlIH0gZnJvbSAnLi9TZXR0aW5nVUlCYXNlJztcblxuLyoqXG4gKiBBIG51bWJlciBzcGlubmVyIHdpdGggYSB0ZXh0IGxhYmVsIGJlc2lkZSBpdC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNldHRpbmdVSU51bWJlcjxcbiAgICBDdXN0b21JZHMgZXh0ZW5kcyBzdHJpbmcgPSBOdW1lcmljUGFyYW1ldGVyc0lkc1xuPiBleHRlbmRzIFNldHRpbmdVSUJhc2Uge1xuICAgIF9zcGlubmVyOiBIVE1MSW5wdXRFbGVtZW50O1xuXG4gICAgLyogVGhpcyBlbGVtZW50IGNvbnRhaW5zIGEgdGV4dCBub2RlIHRoYXQgcmVmbGVjdHMgdGhlIHNldHRpbmcncyB0ZXh0IGxhYmVsLiAqL1xuICAgIF9zZXR0aW5nc1RleHRFbGVtOiBIVE1MRWxlbWVudDtcblxuICAgIGNvbnN0cnVjdG9yKHNldHRpbmc6IFNldHRpbmdOdW1iZXI8Q3VzdG9tSWRzPikge1xuICAgICAgICBzdXBlcihzZXR0aW5nKTtcblxuICAgICAgICB0aGlzLmxhYmVsID0gdGhpcy5zZXR0aW5nLmxhYmVsO1xuICAgICAgICB0aGlzLm51bWJlciA9IHRoaXMuc2V0dGluZy5udW1iZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIHNldHRpbmcgY29tcG9uZW50LlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgc2V0dGluZygpOiBTZXR0aW5nTnVtYmVyPEN1c3RvbUlkcz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZyBhcyBTZXR0aW5nTnVtYmVyPEN1c3RvbUlkcz47XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzZXR0aW5nc1RleHRFbGVtKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5nc1RleHRFbGVtKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc1RleHRFbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0ID0gdGhpcy5zZXR0aW5nLmxhYmVsO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NUZXh0RWxlbS50aXRsZSA9IHRoaXMuc2V0dGluZy5kZXNjcmlwdGlvbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3NUZXh0RWxlbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIEhUTUxJbnB1dEVsZW1lbnQgZm9yIHRoZSBidXR0b24uXG4gICAgICovXG4gICAgcHVibGljIGdldCBzcGlubmVyKCk6IEhUTUxJbnB1dEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3NwaW5uZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX3NwaW5uZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICAgICAgdGhpcy5fc3Bpbm5lci50eXBlID0gJ251bWJlcic7XG4gICAgICAgICAgICB0aGlzLl9zcGlubmVyLm1pbiA9IHRoaXMuc2V0dGluZy5taW4udG9TdHJpbmcoKTtcbiAgICAgICAgICAgIHRoaXMuX3NwaW5uZXIubWF4ID0gdGhpcy5zZXR0aW5nLm1heC50b1N0cmluZygpO1xuICAgICAgICAgICAgdGhpcy5fc3Bpbm5lci52YWx1ZSA9IHRoaXMuc2V0dGluZy5udW1iZXIudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIHRoaXMuX3NwaW5uZXIudGl0bGUgPSB0aGlzLnNldHRpbmcuZGVzY3JpcHRpb247XG4gICAgICAgICAgICB0aGlzLl9zcGlubmVyLmNsYXNzTGlzdC5hZGQoJ2Zvcm0tY29udHJvbCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9zcGlubmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFJldHVybiBvciBjcmVhdGVzIGEgSFRNTCBlbGVtZW50IHRoYXQgcmVwcmVzZW50cyB0aGlzIHNldHRpbmcgaW4gdGhlIERPTS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIHJvb3QgZGl2IHdpdGggXCJzZXR0aW5nXCIgY3NzIGNsYXNzXG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnc2V0dGluZycpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZm9ybS1ncm91cCcpO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgZGl2IGVsZW1lbnQgdG8gY29udGFpbiBvdXIgc2V0dGluZydzIHRleHRcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc2V0dGluZ3NUZXh0RWxlbSk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBsYWJlbCBlbGVtZW50IHRvIHdyYXAgb3V0IGlucHV0IHR5cGVcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc3Bpbm5lcik7XG5cbiAgICAgICAgICAgIC8vIHNldHVwIG9uY2hhbmdlXG4gICAgICAgICAgICB0aGlzLnNwaW5uZXIub25jaGFuZ2UgPSAoZXZlbnQ6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5wdXRFbGVtID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWRWYWx1ZSA9IE51bWJlci5wYXJzZUludChpbnB1dEVsZW0udmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKE51bWJlci5pc05hTihwYXJzZWRWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLldhcm5pbmcoXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuR2V0U3RhY2tUcmFjZSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgYENvdWxkIG5vdCBwYXJzZSB2YWx1ZSBjaGFuZ2UgaW50byBhIHZhbGlkIG51bWJlciAtIHZhbHVlIHdhcyAke2lucHV0RWxlbS52YWx1ZX0sIHJlc2V0dGluZyB2YWx1ZSB0byAke3RoaXMuc2V0dGluZy5taW59YFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR0aW5nLm51bWJlciAhPT0gdGhpcy5zZXR0aW5nLm1pbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5nLm51bWJlciA9IHRoaXMuc2V0dGluZy5taW47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR0aW5nLm51bWJlciAhPT0gcGFyc2VkVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZy5udW1iZXIgPSBwYXJzZWRWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZy51cGRhdGVVUkxQYXJhbXMoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgbnVtYmVyIGluIHRoZSBzcGlubmVyICh3aWxsIGJlIGNsYW1wZWQgd2l0aGluIHJhbmdlKS5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IG51bWJlcihuZXdOdW1iZXI6IG51bWJlcikge1xuICAgICAgICB0aGlzLnNwaW5uZXIudmFsdWUgPSB0aGlzLnNldHRpbmcuY2xhbXAobmV3TnVtYmVyKS50b1N0cmluZygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB2YWx1ZVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgbnVtYmVyKCkge1xuICAgICAgICByZXR1cm4gK3RoaXMuc3Bpbm5lci52YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxhYmVsIHRleHQgZm9yIHRoZSBzZXR0aW5nLlxuICAgICAqIEBwYXJhbSBsYWJlbCBzZXR0aW5nIGxhYmVsLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXQgbGFiZWwoaW5MYWJlbDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2V0dGluZ3NUZXh0RWxlbS5pbm5lclRleHQgPSBpbkxhYmVsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBsYWJlbFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgbGFiZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0O1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB0eXBlIHtcbiAgICBPcHRpb25QYXJhbWV0ZXJzSWRzLFxuICAgIFNldHRpbmdPcHRpb25cbn0gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5pbXBvcnQgeyBTZXR0aW5nVUlCYXNlIH0gZnJvbSAnLi9TZXR0aW5nVUlCYXNlJztcblxuZXhwb3J0IGNsYXNzIFNldHRpbmdVSU9wdGlvbjxcbiAgICBDdXN0b21JZHMgZXh0ZW5kcyBzdHJpbmcgPSBPcHRpb25QYXJhbWV0ZXJzSWRzXG4+IGV4dGVuZHMgU2V0dGluZ1VJQmFzZSB7XG4gICAgLyogQSBzZWxlY3QgZWxlbWVudCB0aGF0IHJlZmxlY3RzIHRoZSB2YWx1ZSBvZiB0aGlzIHNldHRpbmcuICovXG4gICAgX3NlbGVjdG9yOiBIVE1MU2VsZWN0RWxlbWVudDsgLy8gPHNlbGVjdD48L3NlbGVjdD5cblxuICAgIC8qIFRoaXMgZWxlbWVudCBjb250YWlucyBhIHRleHQgbm9kZSB0aGF0IHJlZmxlY3RzIHRoZSBzZXR0aW5nJ3MgdGV4dCBsYWJlbC4gKi9cbiAgICBfc2V0dGluZ3NUZXh0RWxlbTogSFRNTEVsZW1lbnQ7XG5cbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5nOiBTZXR0aW5nT3B0aW9uPEN1c3RvbUlkcz4pIHtcbiAgICAgICAgc3VwZXIoc2V0dGluZyk7XG5cbiAgICAgICAgdGhpcy5sYWJlbCA9IHRoaXMuc2V0dGluZy5sYWJlbDtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gdGhpcy5zZXR0aW5nLm9wdGlvbnM7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWQgPSB0aGlzLnNldHRpbmcuc2VsZWN0ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIHNldHRpbmcgY29tcG9uZW50LlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgc2V0dGluZygpOiBTZXR0aW5nT3B0aW9uPEN1c3RvbUlkcz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZyBhcyBTZXR0aW5nT3B0aW9uPEN1c3RvbUlkcz47XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzZWxlY3RvcigpOiBIVE1MU2VsZWN0RWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fc2VsZWN0b3IpIHtcbiAgICAgICAgICAgIHRoaXMuX3NlbGVjdG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VsZWN0Jyk7XG4gICAgICAgICAgICB0aGlzLl9zZWxlY3Rvci5jbGFzc0xpc3QuYWRkKCdmb3JtLWNvbnRyb2wnKTtcbiAgICAgICAgICAgIHRoaXMuX3NlbGVjdG9yLmNsYXNzTGlzdC5hZGQoJ3NldHRpbmdzLW9wdGlvbicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9zZWxlY3RvcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHNldHRpbmdzVGV4dEVsZW0oKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3NldHRpbmdzVGV4dEVsZW0pIHtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0ID0gdGhpcy5zZXR0aW5nLmxhYmVsO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NUZXh0RWxlbS50aXRsZSA9IHRoaXMuc2V0dGluZy5kZXNjcmlwdGlvbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3NUZXh0RWxlbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxhYmVsIHRleHQgZm9yIHRoZSBzZXR0aW5nLlxuICAgICAqIEBwYXJhbSBsYWJlbCBzZXR0aW5nIGxhYmVsLlxuICAgICAqL1xuICAgIHB1YmxpYyBzZXQgbGFiZWwoaW5MYWJlbDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2V0dGluZ3NUZXh0RWxlbS5pbm5lclRleHQgPSBpbkxhYmVsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBsYWJlbFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgbGFiZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzVGV4dEVsZW0uaW5uZXJUZXh0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFJldHVybiBvciBjcmVhdGVzIGEgSFRNTCBlbGVtZW50IHRoYXQgcmVwcmVzZW50cyB0aGlzIHNldHRpbmcgaW4gdGhlIERPTS5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgLy8gY3JlYXRlIHJvb3QgZGl2IHdpdGggXCJzZXR0aW5nXCIgY3NzIGNsYXNzXG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaWQgPSB0aGlzLnNldHRpbmcuaWQ7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdmb3JtLWdyb3VwJyk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBkaXYgZWxlbWVudCB0byBjb250YWluIG91ciBzZXR0aW5nJ3MgdGV4dFxuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zZXR0aW5nc1RleHRFbGVtKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGxhYmVsIGVsZW1lbnQgdG8gd3JhcCBvdXQgaW5wdXQgdHlwZVxuICAgICAgICAgICAgY29uc3Qgd3JhcHBlckxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHdyYXBwZXJMYWJlbCk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBzZWxlY3QgZWxlbWVudFxuICAgICAgICAgICAgdGhpcy5zZWxlY3Rvci50aXRsZSA9IHRoaXMuc2V0dGluZy5kZXNjcmlwdGlvbjtcbiAgICAgICAgICAgIHdyYXBwZXJMYWJlbC5hcHBlbmRDaGlsZCh0aGlzLnNlbGVjdG9yKTtcblxuICAgICAgICAgICAgLy8gc2V0dXAgb24gY2hhbmdlIGZyb20gc2VsZWN0b3JcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0b3Iub25jaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZy5zZWxlY3RlZCAhPT0gdGhpcy5zZWxlY3Rvci52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmcuc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdG9yLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmcudXBkYXRlVVJMUGFyYW1zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIHNldCBvcHRpb25zKHZhbHVlczogQXJyYXk8c3RyaW5nPikge1xuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5zZWxlY3Rvci5vcHRpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdG9yLnJlbW92ZShpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhbHVlcy5mb3JFYWNoKCh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBvcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvcHRpb24nKTtcbiAgICAgICAgICAgIG9wdC52YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgb3B0LmlubmVySFRNTCA9IHZhbHVlO1xuICAgICAgICAgICAgdGhpcy5zZWxlY3Rvci5hcHBlbmRDaGlsZChvcHQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IG9wdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiBbLi4udGhpcy5zZWxlY3Rvci5vcHRpb25zXS5tYXAoKG8pID0+IG8udmFsdWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXQgc2VsZWN0ZWQodmFsdWU6IHN0cmluZykge1xuICAgICAgICAvLyBBIHVzZXIgbWF5IG5vdCBzcGVjaWZ5IHRoZSBmdWxsIHBvc3NpYmxlIHZhbHVlIHNvIHdlIGluc3RlYWQgdXNlIHRoZSBjbG9zZXN0IG1hdGNoLlxuICAgICAgICAvLyBlZyA/eHh4PUgyNjQgd291bGQgc2VsZWN0ICdIMjY0IGxldmVsLWFzeW1tZXRyeS1hbGxvd2VkPTE7cGFja2V0aXphdGlvbi1tb2RlPTE7cHJvZmlsZS1sZXZlbC1pZD00MjAwMWYnXG4gICAgICAgIGNvbnN0IGZpbHRlcmVkTGlzdCA9IHRoaXMub3B0aW9ucy5maWx0ZXIoXG4gICAgICAgICAgICAob3B0aW9uOiBzdHJpbmcpID0+IG9wdGlvbi5pbmRleE9mKHZhbHVlKSAhPT0gLTFcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZpbHRlcmVkTGlzdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0b3IudmFsdWUgPSBmaWx0ZXJlZExpc3RbMF07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHNlbGVjdGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3Rvci52YWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGlzYWJsZSgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3Rvci5kaXNhYmxlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIGVuYWJsZSgpIHtcbiAgICAgICAgdGhpcy5zZWxlY3Rvci5kaXNhYmxlZCA9IGZhbHNlO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB0eXBlIHtcbiAgICBTZXR0aW5nVGV4dCxcbiAgICBUZXh0UGFyYW1ldGVyc0lkc1xufSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcbmltcG9ydCB7IFNldHRpbmdVSUJhc2UgfSBmcm9tICcuL1NldHRpbmdVSUJhc2UnO1xuXG5leHBvcnQgY2xhc3MgU2V0dGluZ1VJVGV4dDxcbiAgICBDdXN0b21JZHMgZXh0ZW5kcyBzdHJpbmcgPSBUZXh0UGFyYW1ldGVyc0lkc1xuPiBleHRlbmRzIFNldHRpbmdVSUJhc2Uge1xuICAgIC8qIEEgdGV4dCBib3ggdGhhdCByZWZsZWN0cyB0aGUgdmFsdWUgb2YgdGhpcyBzZXR0aW5nLiAqL1xuICAgIF90ZXh0Ym94OiBIVE1MSW5wdXRFbGVtZW50OyAvLyBpbnB1dCB0eXBlPVwidGV4dFwiXG5cbiAgICAvKiBUaGlzIGVsZW1lbnQgY29udGFpbnMgYSB0ZXh0IG5vZGUgdGhhdCByZWZsZWN0cyB0aGUgc2V0dGluZydzIHRleHQgbGFiZWwuICovXG4gICAgX3NldHRpbmdzVGV4dEVsZW06IEhUTUxFbGVtZW50O1xuXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZzogU2V0dGluZ1RleHQ8Q3VzdG9tSWRzPikge1xuICAgICAgICBzdXBlcihzZXR0aW5nKTtcblxuICAgICAgICB0aGlzLmxhYmVsID0gdGhpcy5zZXR0aW5nLmxhYmVsO1xuICAgICAgICB0aGlzLnRleHQgPSB0aGlzLnNldHRpbmcudGV4dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgc2V0dGluZyBjb21wb25lbnQuXG4gICAgICovXG4gICAgcHVibGljIGdldCBzZXR0aW5nKCk6IFNldHRpbmdUZXh0PEN1c3RvbUlkcz4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZyBhcyBTZXR0aW5nVGV4dDxDdXN0b21JZHM+O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgc2V0dGluZ3NUZXh0RWxlbSgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fc2V0dGluZ3NUZXh0RWxlbSkge1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NUZXh0RWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NUZXh0RWxlbS5pbm5lclRleHQgPSB0aGlzLnNldHRpbmcubGFiZWw7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc1RleHRFbGVtLnRpdGxlID0gdGhpcy5zZXR0aW5nLmRlc2NyaXB0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXR0aW5nc1RleHRFbGVtO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgdGV4dGJveCgpOiBIVE1MSW5wdXRFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl90ZXh0Ym94KSB7XG4gICAgICAgICAgICB0aGlzLl90ZXh0Ym94ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgICAgIHRoaXMuX3RleHRib3guY2xhc3NMaXN0LmFkZCgnZm9ybS1jb250cm9sJyk7XG4gICAgICAgICAgICB0aGlzLl90ZXh0Ym94LnR5cGUgPSAndGV4dGJveCc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3RleHRib3g7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgUmV0dXJuIG9yIGNyZWF0ZXMgYSBIVE1MIGVsZW1lbnQgdGhhdCByZXByZXNlbnRzIHRoaXMgc2V0dGluZyBpbiB0aGUgRE9NLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgcm9vdCBkaXYgd2l0aCBcInNldHRpbmdcIiBjc3MgY2xhc3NcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5pZCA9IHRoaXMuc2V0dGluZy5pZDtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3NldHRpbmcnKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGRpdiBlbGVtZW50IHRvIGNvbnRhaW4gb3VyIHNldHRpbmcncyB0ZXh0XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnNldHRpbmdzVGV4dEVsZW0pO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgbGFiZWwgZWxlbWVudCB0byB3cmFwIG91dCBpbnB1dCB0eXBlXG4gICAgICAgICAgICBjb25zdCB3cmFwcGVyTGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQod3JhcHBlckxhYmVsKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIGlucHV0IHR5cGU9Y2hlY2tib3hcbiAgICAgICAgICAgIHRoaXMudGV4dGJveC50aXRsZSA9IHRoaXMuc2V0dGluZy5kZXNjcmlwdGlvbjtcbiAgICAgICAgICAgIHdyYXBwZXJMYWJlbC5hcHBlbmRDaGlsZCh0aGlzLnRleHRib3gpO1xuXG4gICAgICAgICAgICAvLyBzZXR1cCBvbiBjaGFuZ2UgZnJvbSBjaGVja2JveFxuICAgICAgICAgICAgdGhpcy50ZXh0Ym94LmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmcudGV4dCAhPT0gdGhpcy50ZXh0Ym94LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0dGluZy50ZXh0ID0gdGhpcy50ZXh0Ym94LnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldHRpbmcudXBkYXRlVVJMUGFyYW1zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgc2V0dGluZydzIHN0b3JlZCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gaW5WYWx1ZSBUaGUgbmV3IHZhbHVlIGZvciB0aGUgc2V0dGluZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IHRleHQoaW5WYWx1ZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMudGV4dGJveC52YWx1ZSA9IGluVmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHZhbHVlXG4gICAgICovXG4gICAgcHVibGljIGdldCB0ZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy50ZXh0Ym94LnZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgbGFiZWwgdGV4dCBmb3IgdGhlIHNldHRpbmcuXG4gICAgICogQHBhcmFtIGxhYmVsIHNldHRpbmcgbGFiZWwuXG4gICAgICovXG4gICAgcHVibGljIHNldCBsYWJlbChpbkxhYmVsOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zZXR0aW5nc1RleHRFbGVtLmlubmVyVGV4dCA9IGluTGFiZWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGxhYmVsXG4gICAgICovXG4gICAgcHVibGljIGdldCBsYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0dGluZ3NUZXh0RWxlbS5pbm5lclRleHQ7XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgQWN0aW9uT3ZlcmxheSB9IGZyb20gJy4vQWN0aW9uT3ZlcmxheSc7XG5cbi8qKlxuICogU2hvdyBhbiBvdmVybGF5IGZvciB3aGVuIHRoZSBzZXNzaW9uIGlzIHVuYXR0ZW5kZWQsIGl0IGJlZ2lucyBhIGNvdW50ZG93biB0aW1lciwgd2hpY2ggd2hlbiBlbGFwc2VkIHdpbGwgZGlzY29ubmVjdCB0aGUgc3RyZWFtLlxuICovXG5leHBvcnQgY2xhc3MgQUZLT3ZlcmxheSBleHRlbmRzIEFjdGlvbk92ZXJsYXkge1xuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIHJvb3QgZWxlbWVudCBvZiB0aGlzIG92ZXJsYXkuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGVSb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGNvbnN0IGFma092ZXJsYXlIdG1sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGFma092ZXJsYXlIdG1sLmlkID0gJ2Fma092ZXJsYXknO1xuICAgICAgICBhZmtPdmVybGF5SHRtbC5jbGFzc05hbWUgPSAnY2xpY2thYmxlU3RhdGUnO1xuICAgICAgICByZXR1cm4gYWZrT3ZlcmxheUh0bWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgY29udGVudCBlbGVtZW50IG9mIHRoaXMgb3ZlcmxheSwgd2hpY2ggY29udGFpbiBzb21lIHRleHQgZm9yIGFuIGFmayBjb3VudCBkb3duLlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlQ29udGVudEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBjb25zdCBhZmtPdmVybGF5SHRtbElubmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGFma092ZXJsYXlIdG1sSW5uZXIuaWQgPSAnYWZrT3ZlcmxheUlubmVyJztcbiAgICAgICAgYWZrT3ZlcmxheUh0bWxJbm5lci5pbm5lckhUTUwgPVxuICAgICAgICAgICAgJzxjZW50ZXI+Tm8gYWN0aXZpdHkgZGV0ZWN0ZWQ8YnI+RGlzY29ubmVjdGluZyBpbiA8c3BhbiBpZD1cImFma0NvdW50RG93bk51bWJlclwiPjwvc3Bhbj4gc2Vjb25kczxicj5DbGljayB0byBjb250aW51ZTxicj48L2NlbnRlcj4nO1xuICAgICAgICByZXR1cm4gYWZrT3ZlcmxheUh0bWxJbm5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3QgYW4gQWZrIG92ZXJsYXlcbiAgICAgKiBAcGFyYW0gcGFyZW50RWxlbWVudCB0aGUgZWxlbWVudCB0aGlzIG92ZXJsYXkgd2lsbCBiZSBpbnNlcnRlZCBpbnRvXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHJvb3REaXY6IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHN1cGVyKFxuICAgICAgICAgICAgcm9vdERpdixcbiAgICAgICAgICAgIEFGS092ZXJsYXkuY3JlYXRlUm9vdEVsZW1lbnQoKSxcbiAgICAgICAgICAgIEFGS092ZXJsYXkuY3JlYXRlQ29udGVudEVsZW1lbnQoKVxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMucm9vdEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgY291bnQgZG93biBzcGFucyBudW1iZXIgZm9yIHRoZSBvdmVybGF5XG4gICAgICogQHBhcmFtIGNvdW50ZG93biB0aGUgY291bnQgZG93biBudW1iZXIgdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGUgc3BhbiBmb3IgdXBkYXRpbmdcbiAgICAgKi9cbiAgICBwdWJsaWMgdXBkYXRlQ291bnRkb3duKGNvdW50ZG93bjogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMudGV4dEVsZW1lbnQuaW5uZXJIVE1MID0gYDxjZW50ZXI+Tm8gYWN0aXZpdHkgZGV0ZWN0ZWQ8YnI+RGlzY29ubmVjdGluZyBpbiA8c3BhbiBpZD1cImFma0NvdW50RG93bk51bWJlclwiPiR7Y291bnRkb3dufTwvc3Bhbj4gc2Vjb25kczxicj5DbGljayB0byBjb250aW51ZTxicj48L2NlbnRlcj5gO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJ0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMnO1xuXG5pbXBvcnQgeyBPdmVybGF5QmFzZSB9IGZyb20gJy4vQmFzZU92ZXJsYXknO1xuXG4vKipcbiAqIENsYXNzIGZvciB0aGUgYmFzZSBhY3Rpb24gb3ZlcmxheSBzdHJ1Y3R1cmVcbiAqL1xuZXhwb3J0IGNsYXNzIEFjdGlvbk92ZXJsYXkgZXh0ZW5kcyBPdmVybGF5QmFzZSB7XG4gICAgb25BY3Rpb25DYWxsYmFjazogKC4uLmFyZ3M6IFtdKSA9PiB2b2lkO1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0IGFuIGFjdGlvbiBvdmVybGF5XG4gICAgICogQHBhcmFtIHJvb3REaXYgdGhlIHJvb3QgZWxlbWVudCB0aGlzIG92ZXJsYXkgd2lsbCBiZSBpbnNlcnRlZCBpbnRvXG4gICAgICogQHBhcmFtIHJvb3RFbGVtZW50IHRoZSByb290IGVsZW1lbnQgdGhhdCBpcyB0aGUgb3ZlcmxheVxuICAgICAqIEBwYXJhbSBjb250ZW50RWxlbWVudCBhbiBlbGVtZW50IHRoYXQgY29udGFpbnMgdGV4dCBmb3IgdGhlIGFjdGlvbiBvdmVybGF5XG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgICAgICByb290RGl2OiBIVE1MRWxlbWVudCxcbiAgICAgICAgcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50LFxuICAgICAgICBjb250ZW50RWxlbWVudDogSFRNTEVsZW1lbnRcbiAgICApIHtcbiAgICAgICAgc3VwZXIocm9vdERpdiwgcm9vdEVsZW1lbnQsIGNvbnRlbnRFbGVtZW50KTtcbiAgICAgICAgdGhpcy5vbkFjdGlvbkNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgLyogZG8gbm90aGluZyAqLyBMb2dnZXIuSW5mbyhcbiAgICAgICAgICAgICAgICBMb2dnZXIuR2V0U3RhY2tUcmFjZSgpLFxuICAgICAgICAgICAgICAgICdEaWQgeW91IGZvcmdldCB0byBzZXQgdGhlIG9uQWN0aW9uIGNhbGxiYWNrIGluIHlvdXIgb3ZlcmxheT8nXG4gICAgICAgICAgICApO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgdGV4dCBvdmVybGF5cyBpbm5lciB0ZXh0XG4gICAgICogQHBhcmFtIHRleHQgdGhlIHVwZGF0ZSB0ZXh0IHRvIGJlIGluc2VydGVkIGludG8gdGhlIG92ZXJsYXlcbiAgICAgKi9cbiAgICBwdWJsaWMgdXBkYXRlKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBpZiAodGV4dCAhPSBudWxsIHx8IHRleHQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLnRleHRFbGVtZW50LmlubmVySFRNTCA9IHRleHQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYSBtZXRob2QgYXMgYW4gZXZlbnQgZW1pdHRlciBjYWxsYmFja1xuICAgICAqIEBwYXJhbSBjYWxsQmFjayB0aGUgbWV0aG9kIHRoYXQgaXMgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWRcbiAgICAgKi9cbiAgICBvbkFjdGlvbihjYWxsQmFjazogKC4uLmFyZ3M6IFtdKSA9PiB2b2lkKSB7XG4gICAgICAgIHRoaXMub25BY3Rpb25DYWxsYmFjayA9IGNhbGxCYWNrO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjdGl2YXRlIGFuIGV2ZW50IHRoYXQgaXMgYXR0YWNoZWQgdG8gdGhlIGV2ZW50IGVtaXR0ZXJcbiAgICAgKi9cbiAgICBhY3RpdmF0ZSgpIHtcbiAgICAgICAgdGhpcy5vbkFjdGlvbkNhbGxiYWNrKCk7XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuLyoqXG4gKiBDbGFzcyBmb3IgdGhlIGJhc2Ugb3ZlcmxheSBzdHJ1Y3R1cmVcbiAqL1xuZXhwb3J0IGNsYXNzIE92ZXJsYXlCYXNlIHtcbiAgICBwcm90ZWN0ZWQgcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIHByb3RlY3RlZCByb290RGl2OiBIVE1MRWxlbWVudDtcbiAgICBwdWJsaWMgdGV4dEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0IGFuIG92ZXJsYXlcbiAgICAgKiBAcGFyYW0gcm9vdERpdiB0aGUgcm9vdCBlbGVtZW50IHRoaXMgb3ZlcmxheSB3aWxsIGJlIGluc2VydGVkIGludG9cbiAgICAgKiBAcGFyYW0gcm9vdEVsZW1lbnQgdGhlIHJvb3QgZWxlbWVudCB0aGF0IGlzIHRoZSBvdmVybGF5XG4gICAgICovXG4gICAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgICAgICByb290RGl2OiBIVE1MRWxlbWVudCxcbiAgICAgICAgcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50LFxuICAgICAgICB0ZXh0RWxlbWVudDogSFRNTEVsZW1lbnRcbiAgICApIHtcbiAgICAgICAgdGhpcy5yb290RGl2ID0gcm9vdERpdjtcbiAgICAgICAgdGhpcy5yb290RWxlbWVudCA9IHJvb3RFbGVtZW50O1xuICAgICAgICB0aGlzLnRleHRFbGVtZW50ID0gdGV4dEVsZW1lbnQ7XG4gICAgICAgIHRoaXMucm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy50ZXh0RWxlbWVudCk7XG4gICAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgICB0aGlzLnJvb3REaXYuYXBwZW5kQ2hpbGQodGhpcy5yb290RWxlbWVudCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyB0aGUgb3ZlcmxheVxuICAgICAqL1xuICAgIHB1YmxpYyBzaG93KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlblN0YXRlJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGlkZSB0aGUgb3ZlcmxheVxuICAgICAqL1xuICAgIHB1YmxpYyBoaWRlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2hpZGRlblN0YXRlJyk7XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgQWN0aW9uT3ZlcmxheSB9IGZyb20gJy4vQWN0aW9uT3ZlcmxheSc7XG5cbi8qKlxuICogT3ZlcmxheSBzaG93biBkdXJpbmcgY29ubmVjdGlvbiwgaGFzIGEgYnV0dG9uIHRoYXQgY2FuIGJlIGNsaWNrZWQgdG8gaW5pdGlhdGUgYSBjb25uZWN0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdE92ZXJsYXkgZXh0ZW5kcyBBY3Rpb25PdmVybGF5IHtcbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCByb290IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlUm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBjb25zdCBjb25uZWN0RWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBjb25uZWN0RWxlbS5pZCA9ICdjb25uZWN0T3ZlcmxheSc7XG4gICAgICAgIGNvbm5lY3RFbGVtLmNsYXNzTmFtZSA9ICdjbGlja2FibGVTdGF0ZSc7XG4gICAgICAgIHJldHVybiBjb25uZWN0RWxlbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBjb250ZW50IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LCB3aGljaCBjb250YWluIHdoYXRldmVyIGNvbnRlbnQgdGhpcyBlbGVtZW50IGNvbnRhaW5zLCBsaWtlIHRleHQgb3IgYSBidXR0b24uXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGVDb250ZW50RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3RDb250ZW50RWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBjb25uZWN0Q29udGVudEVsZW0uaWQgPSAnY29ubmVjdEJ1dHRvbic7XG4gICAgICAgIGNvbm5lY3RDb250ZW50RWxlbS5pbm5lckhUTUwgPSAnQ2xpY2sgdG8gc3RhcnQnO1xuICAgICAgICByZXR1cm4gY29ubmVjdENvbnRlbnRFbGVtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBhIGNvbm5lY3Qgb3ZlcmxheSB3aXRoIGEgY29ubmVjdGlvbiBidXR0b24uXG4gICAgICogQHBhcmFtIHBhcmVudEVsZW0gdGhlIHBhcmVudCBlbGVtZW50IHRoaXMgb3ZlcmxheSB3aWxsIGJlIGluc2VydGVkIGludG8uXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmVudEVsZW06IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHN1cGVyKFxuICAgICAgICAgICAgcGFyZW50RWxlbSxcbiAgICAgICAgICAgIENvbm5lY3RPdmVybGF5LmNyZWF0ZVJvb3RFbGVtZW50KCksXG4gICAgICAgICAgICBDb25uZWN0T3ZlcmxheS5jcmVhdGVDb250ZW50RWxlbWVudCgpXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gYWRkIHRoZSBuZXcgZXZlbnQgbGlzdGVuZXJcbiAgICAgICAgdGhpcy5yb290RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgQWN0aW9uT3ZlcmxheSB9IGZyb20gJy4vQWN0aW9uT3ZlcmxheSc7XG5cbi8qKlxuICogT3ZlcmxheSBzaG93biBkdXJpbmcgZGlzY29ubmVjdGlvbiwgaGFzIGEgcmVjb25uZWN0aW9uIGVsZW1lbnQgdGhhdCBjYW4gYmUgY2xpY2tlZCB0byByZWNvbm5lY3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBEaXNjb25uZWN0T3ZlcmxheSBleHRlbmRzIEFjdGlvbk92ZXJsYXkge1xuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIHJvb3QgZWxlbWVudCBvZiB0aGlzIG92ZXJsYXkuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGVSb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGNvbnN0IGRpc2Nvbm5lY3RPdmVybGF5SHRtbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBkaXNjb25uZWN0T3ZlcmxheUh0bWwuaWQgPSAnZGlzY29ubmVjdE92ZXJsYXknO1xuICAgICAgICBkaXNjb25uZWN0T3ZlcmxheUh0bWwuY2xhc3NOYW1lID0gJ2NsaWNrYWJsZVN0YXRlJztcbiAgICAgICAgcmV0dXJuIGRpc2Nvbm5lY3RPdmVybGF5SHRtbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBjb250ZW50IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LCB3aGljaCBjb250YWluIHdoYXRldmVyIGNvbnRlbnQgdGhpcyBlbGVtZW50IGNvbnRhaW5zLCBsaWtlIHRleHQgb3IgYSBidXR0b24uXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGVDb250ZW50RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIC8vIGJ1aWxkIHRoZSBpbm5lciBodG1sIGNvbnRhaW5lclxuICAgICAgICBjb25zdCBkaXNjb25uZWN0T3ZlcmxheUh0bWxDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZGlzY29ubmVjdE92ZXJsYXlIdG1sQ29udGFpbmVyLmlkID0gJ2Rpc2Nvbm5lY3RCdXR0b24nO1xuICAgICAgICBkaXNjb25uZWN0T3ZlcmxheUh0bWxDb250YWluZXIuaW5uZXJIVE1MID0gJ0NsaWNrIFRvIFJlc3RhcnQnO1xuXG4gICAgICAgIHJldHVybiBkaXNjb25uZWN0T3ZlcmxheUh0bWxDb250YWluZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0IGEgZGlzY29ubmVjdCBvdmVybGF5IHdpdGggYSByZXRyeSBjb25uZWN0aW9uIGljb24uXG4gICAgICogQHBhcmFtIHBhcmVudEVsZW0gdGhlIHBhcmVudCBlbGVtZW50IHRoaXMgb3ZlcmxheSB3aWxsIGJlIGluc2VydGVkIGludG8uXG4gICAgICovXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmVudEVsZW06IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHN1cGVyKFxuICAgICAgICAgICAgcGFyZW50RWxlbSxcbiAgICAgICAgICAgIERpc2Nvbm5lY3RPdmVybGF5LmNyZWF0ZVJvb3RFbGVtZW50KCksXG4gICAgICAgICAgICBEaXNjb25uZWN0T3ZlcmxheS5jcmVhdGVDb250ZW50RWxlbWVudCgpXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gYWRkIHRoZSBuZXcgZXZlbnQgbGlzdGVuZXJcbiAgICAgICAgdGhpcy5yb290RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgVGV4dE92ZXJsYXkgfSBmcm9tICcuL1RleHRPdmVybGF5JztcblxuLyoqXG4gKiBHZW5lcmljIG92ZXJsYXkgdXNlZCB0byBzaG93IHRleHR1YWwgZXJyb3IgaW5mbyB0byB0aGUgdXNlci5cbiAqL1xuZXhwb3J0IGNsYXNzIEVycm9yT3ZlcmxheSBleHRlbmRzIFRleHRPdmVybGF5IHtcbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCByb290IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlUm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBjb25zdCBlcnJvck92ZXJsYXlIdG1sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGVycm9yT3ZlcmxheUh0bWwuaWQgPSAnZXJyb3JPdmVybGF5JztcbiAgICAgICAgZXJyb3JPdmVybGF5SHRtbC5jbGFzc05hbWUgPSAndGV4dERpc3BsYXlTdGF0ZSc7XG4gICAgICAgIHJldHVybiBlcnJvck92ZXJsYXlIdG1sO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIGNvbnRlbnQgZWxlbWVudCBvZiB0aGlzIG92ZXJsYXksIHdoaWNoIGNvbnRhaW4gd2hhdGV2ZXIgY29udGVudCB0aGlzIGVsZW1lbnQgY29udGFpbnMsIGxpa2UgdGV4dCBvciBhIGJ1dHRvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZUNvbnRlbnRFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgY29uc3QgZXJyb3JPdmVybGF5SHRtbElubmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGVycm9yT3ZlcmxheUh0bWxJbm5lci5pZCA9ICdlcnJvck92ZXJsYXlJbm5lcic7XG4gICAgICAgIHJldHVybiBlcnJvck92ZXJsYXlIdG1sSW5uZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0IGEgY29ubmVjdCBvdmVybGF5IHdpdGggYSBjb25uZWN0aW9uIGJ1dHRvbi5cbiAgICAgKiBAcGFyYW0gcGFyZW50RWxlbSB0aGUgcGFyZW50IGVsZW1lbnQgdGhpcyBvdmVybGF5IHdpbGwgYmUgaW5zZXJ0ZWQgaW50by5cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocGFyZW50RWxlbTogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgc3VwZXIoXG4gICAgICAgICAgICBwYXJlbnRFbGVtLFxuICAgICAgICAgICAgRXJyb3JPdmVybGF5LmNyZWF0ZVJvb3RFbGVtZW50KCksXG4gICAgICAgICAgICBFcnJvck92ZXJsYXkuY3JlYXRlQ29udGVudEVsZW1lbnQoKVxuICAgICAgICApO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IFRleHRPdmVybGF5IH0gZnJvbSAnLi9UZXh0T3ZlcmxheSc7XG5cbi8qKlxuICogR2VuZXJpYyBvdmVybGF5IHVzZWQgdG8gc2hvdyB0ZXh0dWFsIGluZm8gdG8gdGhlIHVzZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBJbmZvT3ZlcmxheSBleHRlbmRzIFRleHRPdmVybGF5IHtcbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCByb290IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LlxuICAgICAqL1xuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlUm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBjb25zdCBpbmZvT3ZlcmxheUh0bWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgaW5mb092ZXJsYXlIdG1sLmlkID0gJ2luZm9PdmVybGF5JztcbiAgICAgICAgaW5mb092ZXJsYXlIdG1sLmNsYXNzTmFtZSA9ICd0ZXh0RGlzcGxheVN0YXRlJztcbiAgICAgICAgcmV0dXJuIGluZm9PdmVybGF5SHRtbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBjb250ZW50IGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LCB3aGljaCBjb250YWluIHdoYXRldmVyIGNvbnRlbnQgdGhpcyBlbGVtZW50IGNvbnRhaW5zLCBsaWtlIHRleHQgb3IgYSBidXR0b24uXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGVDb250ZW50RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGNvbnN0IGluZm9PdmVybGF5SHRtbElubmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGluZm9PdmVybGF5SHRtbElubmVyLmlkID0gJ21lc3NhZ2VPdmVybGF5SW5uZXInO1xuICAgICAgICByZXR1cm4gaW5mb092ZXJsYXlIdG1sSW5uZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0IGEgY29ubmVjdCBvdmVybGF5IHdpdGggYSBjb25uZWN0aW9uIGJ1dHRvbi5cbiAgICAgKiBAcGFyYW0gcGFyZW50RWxlbSB0aGUgcGFyZW50IGVsZW1lbnQgdGhpcyBvdmVybGF5IHdpbGwgYmUgaW5zZXJ0ZWQgaW50by5cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocGFyZW50RWxlbTogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgc3VwZXIoXG4gICAgICAgICAgICBwYXJlbnRFbGVtLFxuICAgICAgICAgICAgSW5mb092ZXJsYXkuY3JlYXRlUm9vdEVsZW1lbnQoKSxcbiAgICAgICAgICAgIEluZm9PdmVybGF5LmNyZWF0ZUNvbnRlbnRFbGVtZW50KClcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgeyBBY3Rpb25PdmVybGF5IH0gZnJvbSAnLi9BY3Rpb25PdmVybGF5JztcblxuLyoqXG4gKiBPdmVybGF5IHNob3duIHdoZW4gc3RyZWFtIGlzIHJlYWR5IHRvIHBsYXkuXG4gKi9cbmV4cG9ydCBjbGFzcyBQbGF5T3ZlcmxheSBleHRlbmRzIEFjdGlvbk92ZXJsYXkge1xuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIHJvb3QgZWxlbWVudCBvZiB0aGlzIG92ZXJsYXkuXG4gICAgICovXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGVSb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGNvbnN0IHBsYXlFbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIHBsYXlFbGVtLmlkID0gJ3BsYXlPdmVybGF5JztcbiAgICAgICAgcGxheUVsZW0uY2xhc3NOYW1lID0gJ2NsaWNrYWJsZVN0YXRlJztcbiAgICAgICAgcmV0dXJuIHBsYXlFbGVtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIGNvbnRlbnQgZWxlbWVudCBvZiB0aGlzIG92ZXJsYXksIHdoaWNoIGNvbnRhaW4gd2hhdGV2ZXIgY29udGVudCB0aGlzIGVsZW1lbnQgY29udGFpbnMsIGxpa2UgdGV4dCBvciBhIGJ1dHRvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZUNvbnRlbnRFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgLy8gdG9kbzogY2hhbmdlIHRoaXMgdG8gYW4gc3ZnXG4gICAgICAgIGNvbnN0IHBsYXlPdmVybGF5SHRtbElubmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJyk7XG4gICAgICAgIHBsYXlPdmVybGF5SHRtbElubmVyLmlkID0gJ3BsYXlCdXR0b24nO1xuICAgICAgICBwbGF5T3ZlcmxheUh0bWxJbm5lci5zcmMgPVxuICAgICAgICAgICAgJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBUEVBQUFENUNBWUFBQUQybU5Oa0FBQUFBWE5TUjBJQXJzNGM2UUFBQUFSblFVMUJBQUN4and2OFlRVUFBQUFKY0VoWmN3QUFEc01BQUE3REFjZHZxR1FBQUFBWmRFVllkRk52Wm5SM1lYSmxBSEJoYVc1MExtNWxkQ0EwTGpBdU1qSHhJR21WQUFBU2drbEVRVlI0WHUyZEM3QmRWWDJIcVVDQ0lSQVNDUGpBRklRUkVCUkJCU1JZYkZPdDhsSXJGVVdSRnFYV3NUNXdiSXRVcUZXczBLcUlNUEtvWUVXcFJTMDZLRGpTMUJlVkZrVlFiQ3crd0NmaUF3R2hDS1dQOVB1WnRVMjR1VGU1OXp6MjJZL3ZtL25Ha1h0ejdqbHJyOStzZGZaZWEvMDNXYjE2OVF0eEdXNjJpWWkwRDhMN05id1lqOEVkY2RQeUl4RnBBNFQyUC9GLzhVYThDSS9HaFBuWHlxK0lTSk1ockFseHhYOWhSdVlMOFNoOFNQazFFV2txQkhYZEVGZmNnNnZ3M2ZoczNLYjh1b2cwRFFJNlhZZ3I4ck92WXNKOE9NNHYvMHhFbWtJSjZvYjRQOHpJZkFOZWdDdlFNSXMwQlFLNXNSQlhKTXkvd0l6TTUrQnlYRkJlUmtRbUJVR2NiWWpYNVM1TW1NL0FBM0NMOG5JaVVqY0VjSkFRVjl5Qlg4YS93U2VpejVoRjZvYmdEUlBpa0dmTUNmT1g4RFRjdTd5MGlOUUJvUnMyeEJYL2czZGl3dndtM0tuOENSRVpKNFJ0VkNHdXFNS2N1OWtuNHhKMDlaZkl1Q0Jnb3c1eHlKM3NUTE56QXl3cndGNkoyNk5oRmhrMUJHc2NJVjZYaFBsdXZBNlB4eDNLbnhhUlVVQ294aDNpaW9RNXo1bi9CWS9GSmVVdGlNZ3dFS2E2UWx5Uk1OK0huOEhuNFpibHJZaklJQkNpdWtNYzhwMjVXczZaTUQrenZCMFJtU3NFYUJJaG5rcmV3NVY0RUhyQ2lNaGNLQUZxQ3YrTmwrSit1QkM5bXkyeU1RaEtrMEpja2UvTTc4R3N5MDZZSDFUZXJvaE1oWUEwTWNRVlA4Tno4VURjQ2wyYkxUSVZndEhrRUZkOEQ4L0UvWEZyZEdRV3FTQVFiUWh4eUtPcG0vQjAzQWM5TWtna0VJYTJoTGdpTjc4UzVsUHgwYmdJdlFFbS9ZVUF0QzNFRlFuenpmZ251RGM2elpaK1FzZHZhNGpYNVN2NGF0d1hIWm1sWDlEaHV4RGlrQzJRbjhkWFlVYm1SZVVqaW5RYk9udFhRbHlSVFJhZndsZGd3cnhWK2FnaTNZUk8zclVRVi93Y1YrTEw4REhveVp6U1RlamNYUTF4UmM3L3VoeXpsM2t2M0x4OGRKRnVRS2Z1ZW9oRG5qRm5aUDRvL2o3bTBaUUg0RXMzb0RQM0ljUVYyZjZZTUYrQ09aamdVZWlaMmRKdTZNUjlDdkc2M0lMdng0ek1DZk84MGlRaTdZTE8yOWNRVjN3YjM0c3BzcjRydW1CRTJnV2R0dThoRGxuOTlTMU1YZVlYNE02bGVVU2FEeDNXRUs4bFJkWVQ1bFIvelBsZm5zd3B6WWVPYW9qWEo0Y1NmQjNQdytmZ3R1ZzBXNW9KbmRNUVQwL3VaR2VhWFpWeWZUWnVWNXBOcERuUU1RM3h4c2swTzlVZno4WkRjZHZTZkNLVGh3NXBpR2RQMmlvRjQ5NkpUMGMzV2Nqa0tSMVQ1a1lXakNUTTc4RGZRaGVNeU9TZ0F4cml3Y2gzNWxSL3ZBYlB3T1hvelMrcEh6cWVJUjZPYWwxMnd2eDJmQnk2eVVMcWd3NW5pRWREd3B5UitWcE1rZlhzbUhJcHA0d2ZPcG9oSGoyMzRSZndGTndEbldiTCtLQ0RHZUx4a0pINXAzZzF2ZzUzSzAwdU1scm9YSVo0dkdUQlNNSjhGZVprem1XbDZVVkdBNTNLRU5mRC9aaXlOQ215bnZPL0ZwZExJREljZENaRFhDOFptZk9kK2Qvd0plalpYekljZENKRFhEOTV4cHdqZG5QK1Y3NHpINFd1L3BMQm9QTVk0c21TTU4rRktiSitCQnBtbVJ0MEdrUGNEQkxtdS9GamVBaTZsRk5tQjUzRkVEZUhUTFB6YUNvajgwZHdCZnFNV1RZTW5jUVFONWVzQVBzdzdsY3VsOGo2MEVFTWNmUEpEYkQzWVU3bDNLeGNPcEUxMENrTWNUdklWRHZmbWMvRTNYRUx0UHFqR09LV2toVmdwK0dlbUREN3ZiblAwQUVNY1h0SmtmVTM0R054QVRveTl4RXV2Q0Z1UDZ2d0pNeU9xWVhsMGtwZjRLSWI0bTVRbmN5WlRSYXBaR0dZK3dJWDJ4QjNpM3Z4T3N3bWkxM1FhWGJYNFFJYjRtNlNZM2EvaU1kaDdtWWI1cTdDaFRYRTNhWGFhTEVTcTdyTVc1WkxMMTJCaTJxSSs4RTllRGttekx1aFllNEtYRXhEM0I4eU10K09sK0tMMENMclhZQ0xhSWo3UjhKOEsxNkNSNlBMT2RzTUY4OFE5NWZzbVBvUlhvelB4ZHpOZHZWWDIrQ2lHV0xKemErRU9YV1pqOFNkMEFQdzJ3SVh5eEJMcVBZeTM0TG5ZOEs4REExejArRWlHV0taU2dKOUk3NExVMlI5UjNTYTNWUzRPSVpZWnFKYXlua1dwc2o2dzB1M2tTYkJoVEhFc2pIdXd4c3dwVndQdzZXbCswZ1Q0SUlZWXBrTm1XS25yMXlQcWY1NEtHNVZ1cEZNa25KaFJHWkx3cHpWWDZuKytEWjhHcnBqYXBKd0FReXhERUxDbkIxVHFXVHgxL2dVZEdTZUJEUzhJWlpCU1pCanp2NzZQUDRWSG9TR3VVNW9jRU1zb3lCaFRzRzRWSDk4SXg2QTgwczNrM0ZDUXh0aUdTVlpNUElUL0N3bXpQdWh6NWpIQ1Exc2lHVWNaQ2xud3Z4cFBBWDNMRjFPUmcyTmE0aGxYR1NLblFVakNmTm44UFg0Q055MGREOFpCVFNvSVpaeGt6QlhJL1BuOEFUTXVtekRQQXBvU0VNc2RaRXc1enZ6RHpIVDdKZGp3dXpaWDhOQUF4cGltUVNaWmlmTW44VGo4YUdsUzhwY29mRU1zVXlLak13NWxUT25qSHdjYzJUUWt0STFaYmJRYUlaWUprM0NuRTBXR1ptdndPZWgrNWhuQzQxbGlLVXBWQ056d3Z3SlBCeTkrYlV4YUNSRExFMGpZYjRmVS8weDAreUQ4Y0dseThwVWFCeERMRTBrUWE3Q2ZDZm1NTDhEMFNOMnAwS2pHR0pwT2dsenRXZ2toL2s5Q1QxaXQ0TEdNTVRTRmhMbUxCckozZXh6Y0ovU2pmc05EV0dJcFkwazBEL0FNL0dScFR2M0V4ckFFRXVicVZhQW5ZNUxzWDkzcy9uUWhsaTZRTFVGOG5XWUkzYm5ZVCtXYy9KQkRiRjBoZXFPOWpmd2xmaEluSS9kRGpNZjBCQkxGMG1ZcjhOc3NraU5xUzJ3bTJIbWd4bGk2VEo1enB3amcvNFFkOGJ1TFJyaFF4bGk2UU01WmpkSEJoMkgrYzdjblVVamZCaERMSDBoVSt5N2NDVStIN09YZVY2SlFudmhReGhpNlJzSmMwYm15L0JaK01zYllDVVM3WU0zYjRpbHJ5VE0yUUw1UVV6QnVIeG5idDgwbXpkdGlFVldyNzROTDhLVWNrMlI5ZmFNekx4WlF5eXlob3pNV2NwNUlmNHVKc3pOUDV5QU4ybUlSUjVJVm4vZGpPZmhFZGpzdy94NGM0WllaSHJ5alBrbVBCc1B3WWVWMkRRTDNwZ2hGcG1aVExGelpGRENuTHJNejhEdHNUa2JMWGd6aGxoazR5VE0yY3U4Q3JOaktpTnp3ano1T2xPOENVTXNNamNTNXF6TGZndW15UHIySlU2VGdUZGdpRVVHb3lxeW5yck12NDJUT1RPYlAyeUlSUVluMCt3czVid2FVOHIxTjNIckVxOTY0QThhWXBIaFNaanZ3QlNNUzVnUHducldaZk9IRExISTZNZ3o1aHl4bTRKeGY0a0g0SGpEekI4d3hDS2pKMkhPTlB1ZjhjOXhIeHpQWG1aZTJCQ0xqSWRNc1dNcVdmd1Rub2lQd2RHT3pMeWdJUllaUHdselZXUHF0YmdYam1iQkNDOWtpRVhxSTgrWXM4bmljbndON2xhaU9EaThpQ0VXcVplTXlsbVhuVENuWUZ4TzV0eXhSSEx1OEk4TnNjaGtTSml6THZ2N21KSDVwYmdZNTdaamluOWdpRVVtU3pVeWZ3OVRaUDFZM0xaRWRPUHd5NFpZcEJra3pLbisrQjM4S0I2RjI1V296Z3kvWkloRm1rWENuTE8vdm9zZndwd3lzcWhFZG4zNG9TRVdhU1lKOHk4dzArd1A0R0c0L29JUi9xTWhGbWsyVlpnenpVNllzMk5xN1Q1bS9vOGhGbWtIQ1hPMlB5Yk1GK08rK0NCRExOSXVFdVNzeTg1MzVsdnhaRU1zMGo2cVdzelpKYlhVRUl1MGkxdndyWmhxRlp2NW5WaWtQV1RxZkE1bUY5UUREK2ZqUHhoaWtlYVI3Nzd4ZHJ3QW4xQWl1ejc4MEJDTE5JdnNkTXFCQXFrTnRSdzNYQmVLWHpERUlwTW5vMjdDZXpkZWlrL0dCU1dtRzRaZk5NUWlreVBoelhycFZHWE02UjhyY0c3bFZma0hobGlrZmhMZTdGektvNktWK0h1NDVtN3pYT0VmR21LUmVza2U0b1QzazNnTWJsbmlPQmk4Z0NFV3FZZU12RC9HSy9GNDNLSEVjRGg0SVVNc01sNXl3K3BIbUxPb1g0YURIOFV6SGJ5Z0lSWVpEL25lbTVIM0tqd0JkOExSVjFIa1JRMnh5R2pKM2VhY05aMWlheWZocitQNDZobno0b1pZWkRSazJwendwaDdUWCtDdU9QNzZ4ZndSUXl3eUhObFZWSVgzVkh4OGlWYzk4QWNOc2NqZ1pKRkd5cHErR2ZmSHdaNzFEZ04vMUJDTHpKMmY0Ny9pV3pCbFRJZDcxanNNL0hGRExESTdjcmY1SHJ3RzM0WUhZNzBGeGFlRE4yR0lSVFpNd3B2amNLN0ZkK0JUY2ZMaHJlRE5HR0tSbWNuSWV6MitFdy9GaFRpM01pdmpoamRraUVYV0owZkVmaFhQd21maTRoS1o1c0diTThRaWE4bjY1bFg0TGt6bGhZZVZxRFFYM3FRaEZsbnpyUGMvOEZ6TXRzQmwyS3hwODB6d1JnMng5SjBjeG40ZXBvQlpsa2pXLzZ4M0dIakRobGo2U0paSTVnVEo5K0R6TWVIZHZNU2lYZkRHRGJIMGlXcGJZTXFnSkx5N1lMdEczcW53QVF5eDlJVnNDN3dFWDRDNzQvaDJGdFVKSDhRUVM5ZkpVVGc1UWZJNDNBUG5sZTdmRGZoQWhsaTZTbzUvL1JpK0dCUGV5YTF2SGlkOE1FTXNYU01IMFgwQ1g0Sjc0Y0xTM2JzSkg5QVFTMWZJVGF2czZmMVZlTEVkejNxSGdROXBpS1h0WkhOQzFqZm5FTHBmVHB1eCsrR3Q0TU1hWW1rcm1UWi9HVitMQ1crM3A4MHp3UWMzeE5JMnNrVHlCc3doZEh0aWM3WUZUZ0lhd0JCTG03Z1JUOEhINGRiWW4ybnpUTkFJaGxqYVFDcmt2d2tUM3R5d0d2OHBrbTJCeGpERTBsUnlva2JPc2pvRFV5RS9ONndNNzFSb0ZFTXNUU1BodlJQZmpZL0dCZWkwZVNab0hFTXNUZUoyL0FEdWcrM2NWVlEzTkpRaGxpYVFrZmNmOFNub3FEc1hhREJETEpNaWo0cnV4Y3Z3YWVqSU93ZzBuQ0dXdXNueXlJVDNDandNKzdsSVkxVFFnSVpZNmlBM3F6THlabWRSU24wZWljMDlRYkpOMEpDR1dNWkp3cHVSOXc3OEVyNFF1N2tsY0ZMUW9JWll4a1hxOU9adWMyb1daWE5DdjVkSGpnc2ExaERMcUtuQ20ycUIyWnp3ME5MZFpCelF3SVpZUmtXbXpUL0RoUGRFM0tWME14a25OTFFobG1ISjk5NkVOd1hIc2praHE2eGNIbGtYTkxZaGxrRkplSFBES2h2eXN6a2g0VzMzOGE5dGhFWTN4REpYOHFnb0d4TVMzdFRwZlN6T0wxMUs2b2JHTjhReVd4TGVMSS9NdERtbFB2ZEhwODJUaG90Z2lHVTJaT1N0d3JzQ1hTTFpGTGdZaGxnMnhGMlljNnpPeHFlakN6V2FCaGZGRU10MHBNajJWekIxZWcvQkphWExTTlBnNGhoaXFjamQ1aXpVU0lYOGxQcDhGaTR0WFVXYUNoZkpFRXRJaGZ3VTJiNFFVMlI3TzNSZmJ4dmdRaG5pZnBPRDE3K0pDVzlLZlM1Rjd6aTNDUzZZSWU0bk9YajlXL2gzZUF3K3ZIUUphUnRjUEVQY0wvS3M5MmE4Q0kvRlhkRnBjNXZoQWhyaS92QjkvSHY4QTN3VXVrU3lDM0FoRFhIMytTbitBeDZQcVpEdkVza3V3UVUxeE4ya09nb25KMGltMUdjMkoyeFJMcnQwQ1M2c0llNFcxYzZpajJORzNsUk9tRmN1dDNRUkxyQWg3ZzRKNzVYNFI3ZzNHdDQrd0lVMnhPMG4wK1pQNGFzd0JjZGMzOXdudU9DR3VMM2tXZS9uOERXNEx5NHFsMVg2QkJmZUVMZVRMK0FKK0FUY0JuM1cyMWU0K0lhNFBlU084OWZ3VC9HSnVBaGRJdGwzNkFTR3VQbGtaOUczOGZXWW8zQXk4aHBlV1FPZHdSQTNseHdCZXhPK0dWUHEwN0luc2o1MERFUGNUTEsrK2UyWWM2d1dvOTk1Wlhyb0hJYTRXZHlLT1Fwbk9XYmF2R201VkNMVFF5Y3h4TTBncDBpZWowL0czTEF5dkRJNzZDeUdlSEpVeCtHOEh3OUV3eXR6aDA1amlDZEREcUs3SEEvQWhlaDNYaGtNT284aHJwZTA5NmZ4ZDlEOXZESThwVlBKK0xrWFA0dlBRYWZNTWpyb1VJWjRmT1E3YjlZM1g0VTV4OG9pMnpKNjZGaUdlUFJrZVdST2tmd2lIb2VlM1N6amd3NW1pRWREUnQxNEQrYnc5WmZqRHFXWlJjWUhIYzBRRDA5MUZFNk9nUDB6OU9CMXFRODZteUVlbkt4dFRuZ3o4cjRCSFhtbGZ1aDRobmp1Skx3cDlabHFnYWZoN3FVNVJlcUhEbWlJWjArbXpWa2VlUU8rRlI5Zm1sRmtjdEFSRGZIc1NKM2VmOGRxWjVHSDBFa3pvRE1hNHBuSjNlYTBUMDdUT0FlenZubEJhVHFSWmxBNnFUeVFoRGRybTFmaEJYZ3dHbDVwSm5ST1E3eVc2amx2d3Z0ZWZBWnVYcHBLcEptVVRpdHJwODBwOVpuMXpROHVUU1RTYk9pc2ZROXhwczJwa0ovd1BoZTNLMDBqMGc3b3RIME44ZjM0ZFh3ZkhvMFcyWloyUXVmdFk0aXpQREtuYWJ3SUg0RWUveXJ0aFE3Y2x4Qm5sZFVQOEJKOE1TYTg3dXVWOWtOSDducUljNFpWd3ZzaGZDa3VROE1yM1lFTzNkVVFaNG5rRC9IRG1GS2ZlNVNQTE5JdDZOeGRESEhDK3hGOEJhYnNpU092ZEJjNmVKZENmQnRlaGdsdmltejdyRmU2RHgyOUN5SE9RbzByOE5XWU9yMFcyWmIrUUlkdmE0aXpSRExQZWxkaTZ2U20xT2ZDOHJGRStnTWR2NDBoem51K0dsTWhmei9jRWowT1Ivb0puYjlOSWM1N3ZRWlB4Q2VoSTY5SUNVYlR5ZG5OMStMSm1QQXVLVzlmUkFoRWswT2NaNzNYWXc2aE93Zzl2MWxrS2dTanFTSE81b1JUOFRkd0ticStXV1E2Q0VlVFFwdzd6bG1vY1RxbVRtL09iN2JvbU1pR0lDUk5DSEdtelQvQnN6Q2xQalB5dXNwS1pEWVFsa21IK01mNHQ3Z2N0MGVuelNKemdkQk1Lc1FKNzBYNFZIVGtGUmtVd2xOM2lGTTU0WU40S0c2TEhrUW5NZ3lFcUs0UTUxbnZwWmp3WnVRMXZDS2pnRERWRWVJcjhYQk1lTDNiTERKS0NOVzRRcHlSOXpvOEFyZEJiMWlKakFQQ05lb1FKN3lwRm5nc3prYzNKb2lNRTBJMnFoRG5XVzhLanYweHVqRkJwQzRJM0RBaHpncXJIRVNYVXAvWjAvdVE4cklpVWhjRWI1QVFKN3ozNFRmd0pOeTV2SnlJMUEwQm5HMklFOXlZc2lmZndUZml6dWgzWHBGSlFnaG5FK0o4MzAxNHY0dXBrTDhyK3FoSXBBa1F4ZzJGT09ITnp6TnRQaGYzUkVkZWtTWlJRanFWVEp0emd1U05lRDRlV0g1ZFJKb0dBWjBhNHJ2eG0zZ2hya0NuelNKTmhwQldJYzcvcGxwZ3dwdWRSWjdkTE5JR0NPdnRKYndYNDJHNHVQeElSTm9Bb1UyZDNpTnhVZmxQSXRJYU50bmsvd0VHQm9NZHBFQ0dIQUFBQUFCSlJVNUVya0pnZ2c9PSc7XG4gICAgICAgIHBsYXlPdmVybGF5SHRtbElubmVyLmFsdCA9ICdTdGFydCBTdHJlYW1pbmcnO1xuICAgICAgICByZXR1cm4gcGxheU92ZXJsYXlIdG1sSW5uZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0IGEgY29ubmVjdCBvdmVybGF5IHdpdGggYSBjb25uZWN0aW9uIGJ1dHRvbi5cbiAgICAgKiBAcGFyYW0gcGFyZW50RWxlbSB0aGUgcGFyZW50IGVsZW1lbnQgdGhpcyBvdmVybGF5IHdpbGwgYmUgaW5zZXJ0ZWQgaW50by5cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocGFyZW50RWxlbTogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgc3VwZXIoXG4gICAgICAgICAgICBwYXJlbnRFbGVtLFxuICAgICAgICAgICAgUGxheU92ZXJsYXkuY3JlYXRlUm9vdEVsZW1lbnQoKSxcbiAgICAgICAgICAgIFBsYXlPdmVybGF5LmNyZWF0ZUNvbnRlbnRFbGVtZW50KClcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBhZGQgdGhlIG5ldyBldmVudCBsaXN0ZW5lclxuICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hY3RpdmF0ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgeyBPdmVybGF5QmFzZSB9IGZyb20gJy4vQmFzZU92ZXJsYXknO1xuXG4vKipcbiAqIENsYXNzIGZvciB0aGUgdGV4dCBvdmVybGF5IGJhc2VcbiAqL1xuZXhwb3J0IGNsYXNzIFRleHRPdmVybGF5IGV4dGVuZHMgT3ZlcmxheUJhc2Uge1xuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdCBhIHRleHQgb3ZlcmxheVxuICAgICAqIEBwYXJhbSByb290RGl2IHRoZSByb290IGVsZW1lbnQgdGhpcyBvdmVybGF5IHdpbGwgYmUgaW5zZXJ0ZWQgaW50b1xuICAgICAqIEBwYXJhbSByb290RWxlbWVudCB0aGUgcm9vdCBlbGVtZW50IHRoYXQgaXMgdGhlIG92ZXJsYXlcbiAgICAgKiBAcGFyYW0gdGV4dEVsZW1lbnQgYW4gZWxlbWVudCB0aGF0IGNvbnRhaW5zIHRleHQgZm9yIHRoZSBhY3Rpb24gb3ZlcmxheVxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgICAgcm9vdERpdjogSFRNTEVsZW1lbnQsXG4gICAgICAgIHJvb3RFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICAgICAgdGV4dEVsZW1lbnQ6IEhUTUxFbGVtZW50XG4gICAgKSB7XG4gICAgICAgIHN1cGVyKHJvb3REaXYsIHJvb3RFbGVtZW50LCB0ZXh0RWxlbWVudCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSB0ZXh0IG92ZXJsYXlzIGlubmVyIHRleHRcbiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdXBkYXRlIHRleHQgdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGUgb3ZlcmxheVxuICAgICAqL1xuICAgIHB1YmxpYyB1cGRhdGUodGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGlmICh0ZXh0ICE9IG51bGwgfHwgdGV4dCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMudGV4dEVsZW1lbnQuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIi8qIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICovXG5cbmltcG9ydCBqc3MsIHsgU3R5bGVzIH0gZnJvbSAnanNzJztcbmltcG9ydCBnbG9iYWwgZnJvbSAnanNzLXBsdWdpbi1nbG9iYWwnO1xuaW1wb3J0IGNhbWVsQ2FzZSBmcm9tICdqc3MtcGx1Z2luLWNhbWVsLWNhc2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbG9yUGFsZXR0ZSB7XG4gICAgJy0tY29sb3IwJzogc3RyaW5nO1xuICAgICctLWNvbG9yMSc6IHN0cmluZztcbiAgICAnLS1jb2xvcjInOiBzdHJpbmc7XG4gICAgJy0tY29sb3IzJzogc3RyaW5nO1xuICAgICctLWNvbG9yNCc6IHN0cmluZztcbiAgICAnLS1jb2xvcjUnOiBzdHJpbmc7XG4gICAgJy0tY29sb3I2Jzogc3RyaW5nO1xuICAgICctLWNvbG9yNyc6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFBpeGVsU3RyZWFtaW5nQXBwbGljYXRpb25TdHlsZSB7XG4gICAgZGVmYXVsdExpZ2h0TW9kZVBhbGV0dGU6IENvbG9yUGFsZXR0ZSA9IHtcbiAgICAgICAgJy0tY29sb3IwJzogJyNlMmUwZGQ4MCcsXG4gICAgICAgICctLWNvbG9yMSc6ICcjRkZGRkZGJyxcbiAgICAgICAgJy0tY29sb3IyJzogJyMwMDAwMDAnLFxuICAgICAgICAnLS1jb2xvcjMnOiAnIzA1ODVmZScsXG4gICAgICAgICctLWNvbG9yNCc6ICcjMzViMzUwJyxcbiAgICAgICAgJy0tY29sb3I1JzogJyNmZmFiMDAnLFxuICAgICAgICAnLS1jb2xvcjYnOiAnI2UxZTJkZCcsXG4gICAgICAgICctLWNvbG9yNyc6ICcjYzNjNGJmJ1xuICAgIH07XG5cbiAgICBkZWZhdWx0RGFya01vZGVQYWxldHRlOiBDb2xvclBhbGV0dGUgPSB7XG4gICAgICAgICctLWNvbG9yMCc6ICcjMUQxRjIyODAnLFxuICAgICAgICAnLS1jb2xvcjEnOiAnIzAwMDAwMCcsXG4gICAgICAgICctLWNvbG9yMic6ICcjRkZGRkZGJyxcbiAgICAgICAgJy0tY29sb3IzJzogJyMwNTg1ZmUnLFxuICAgICAgICAnLS1jb2xvcjQnOiAnIzM1YjM1MCcsXG4gICAgICAgICctLWNvbG9yNSc6ICcjZmZhYjAwJyxcbiAgICAgICAgJy0tY29sb3I2JzogJyMxZTFkMjInLFxuICAgICAgICAnLS1jb2xvcjcnOiAnIzNjM2I0MCdcbiAgICB9O1xuXG4gICAgZGVmYXVsdFN0eWxlcyA9IHtcbiAgICAgICAgJzpyb290Jzoge1xuICAgICAgICAgICAgJy0tY29sb3IwJzogJyMxRDFGMjI4MCcsXG4gICAgICAgICAgICAnLS1jb2xvcjEnOiAnIzAwMDAwMCcsXG4gICAgICAgICAgICAnLS1jb2xvcjInOiAnI0ZGRkZGRicsXG4gICAgICAgICAgICAnLS1jb2xvcjMnOiAnIzA1ODVmZScsXG4gICAgICAgICAgICAnLS1jb2xvcjQnOiAnIzM1YjM1MCcsXG4gICAgICAgICAgICAnLS1jb2xvcjUnOiAnI2ZmYWIwMCcsXG4gICAgICAgICAgICAnLS1jb2xvcjYnOiAnIzFlMWQyMicsXG4gICAgICAgICAgICAnLS1jb2xvcjcnOiAnIzNjM2I0MCcsXG4gICAgICAgICAgICAnLS1jb2xvcjgnOiAnIzQxMDA4YycsXG4gICAgICAgICAgICAnLS1jb2xvcjknOiAnIzNlMDA3MCcsXG4gICAgICAgICAgICAnLS1jb2xvcjEwJzogJyMyZTAwNTInLFxuICAgICAgICAgICAgJy0tY29sb3IxMSc6ICdyZ2JhKDY1LDAsMTM5LDEpJ1xuICAgICAgICB9LFxuICAgICAgICAnLm5vc2VsZWN0Jzoge1xuICAgICAgICAgICAgdXNlclNlbGVjdDogJ25vbmUnXG4gICAgICAgIH0sXG4gICAgICAgICcjcGxheWVyVUknOiB7XG4gICAgICAgICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJ1xuICAgICAgICB9LFxuICAgICAgICAnI3ZpZGVvRWxlbWVudFBhcmVudCc6IHtcbiAgICAgICAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICAgICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndmFyKC0tY29sb3IxKSdcbiAgICAgICAgfSxcbiAgICAgICAgJyN1aUZlYXR1cmVzJzoge1xuICAgICAgICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgICAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgICAgICAgekluZGV4OiAnMzAnLFxuICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZScsXG4gICAgICAgICAgICBjb2xvcjogJ3ZhcigtLWNvbG9yMiknLFxuICAgICAgICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLFxuICAgICAgICAgICAgb3ZlcmZsb3c6ICdoaWRkZW4nXG4gICAgICAgIH0sXG4gICAgICAgICcuVWlUb29sIC50b29sdGlwdGV4dCc6IHtcbiAgICAgICAgICAgIHZpc2liaWxpdHk6ICdoaWRkZW4nLFxuICAgICAgICAgICAgd2lkdGg6ICdhdXRvJyxcbiAgICAgICAgICAgIGNvbG9yOiAndmFyKC0tY29sb3IyKScsXG4gICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnMTVweCcsXG4gICAgICAgICAgICBwYWRkaW5nOiAnMHB4IDEwcHgnLFxuICAgICAgICAgICAgZm9udEZhbWlseTogXCInTW9udHNlcnJhdCcsIHNhbnMtc2VyaWZcIixcbiAgICAgICAgICAgIGZvbnRTaXplOiAnMC43NXJlbScsXG4gICAgICAgICAgICBsZXR0ZXJTcGFjaW5nOiAnMC43NXB4JyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgICAgdG9wOiAnMCcsXG4gICAgICAgICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKDI1JSknLFxuICAgICAgICAgICAgbGVmdDogJzEyNSUnLFxuICAgICAgICAgICAgekluZGV4OiAnMjAnXG4gICAgICAgIH0sXG4gICAgICAgICcuVWlUb29sOmhvdmVyIC50b29sdGlwdGV4dCc6IHtcbiAgICAgICAgICAgIHZpc2liaWxpdHk6ICd2aXNpYmxlJyxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWNvbG9yNyknXG4gICAgICAgIH0sXG4gICAgICAgICcjY29ubmVjdGlvbiAudG9vbHRpcHRleHQnOiB7XG4gICAgICAgICAgICB0b3A6ICcxMjUlJyxcbiAgICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoLTI1JSknLFxuICAgICAgICAgICAgbGVmdDogJzAnLFxuICAgICAgICAgICAgekluZGV4OiAnMjAnLFxuICAgICAgICAgICAgcGFkZGluZzogJzVweCAxMHB4J1xuICAgICAgICB9LFxuICAgICAgICAnI2Nvbm5lY3Rpb24nOiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIGJvdHRvbTogJzglJyxcbiAgICAgICAgICAgIGxlZnQ6ICc1JScsXG4gICAgICAgICAgICBmb250RmFtaWx5OiBcIidNaWNocm9tYScsIHNhbnMtc2VyaWZcIixcbiAgICAgICAgICAgIGhlaWdodDogJzNyZW0nLFxuICAgICAgICAgICAgd2lkdGg6ICczcmVtJyxcbiAgICAgICAgICAgIHBvaW50ZXJFdmVudHM6ICdhbGwnXG4gICAgICAgIH0sXG4gICAgICAgICcjc2V0dGluZ3MtcGFuZWwgLnRvb2x0aXB0ZXh0Jzoge1xuICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJyxcbiAgICAgICAgICAgIHRvcDogJzEyNSUnLFxuICAgICAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgtNTAlKScsXG4gICAgICAgICAgICBsZWZ0OiAnMCcsXG4gICAgICAgICAgICB6SW5kZXg6ICcyMCcsXG4gICAgICAgICAgICBwYWRkaW5nOiAnNXB4IDEwcHgnLFxuICAgICAgICAgICAgYm9yZGVyOiAnM3B4IHNvbGlkIHZhcigtLWNvbG9yMyknLFxuICAgICAgICAgICAgd2lkdGg6ICdtYXgtY29udGVudCcsXG4gICAgICAgICAgICBmYWxsYmFja3M6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiAnbWF4LWNvbnRlbnQnXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGJvcmRlcjogJzNweCBzb2xpZCB2YXIoLS1jb2xvcjMpJ1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nOiAnNXB4IDEwcHgnXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHpJbmRleDogJzIwJ1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsZWZ0OiAnMCdcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgtNTAlKSdcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAnMTI1JSdcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgICAgJyNjb250cm9scyc6IHtcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgICAgdG9wOiAnMyUnLFxuICAgICAgICAgICAgbGVmdDogJzIlJyxcbiAgICAgICAgICAgIGZvbnRGYW1pbHk6IFwiJ01pY2hyb21hJywgc2Fucy1zZXJpZlwiLFxuICAgICAgICAgICAgcG9pbnRlckV2ZW50czogJ2FsbCcsXG4gICAgICAgICAgICBkaXNwbGF5OiAnYmxvY2snXG4gICAgICAgIH0sXG4gICAgICAgICcjY29udHJvbHM+Kic6IHtcbiAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzAuNXJlbScsXG4gICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc1MCUnLFxuICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJyxcbiAgICAgICAgICAgIGhlaWdodDogJzJyZW0nLFxuICAgICAgICAgICAgbGluZUhlaWdodDogJzEuNzVyZW0nLFxuICAgICAgICAgICAgcGFkZGluZzogJzAuNXJlbSdcbiAgICAgICAgfSxcbiAgICAgICAgJyNjb250cm9scyAjYWRkaXRpb25hbGluZm8nOiB7XG4gICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgZm9udEZhbWlseTogXCInTW9udHNlcnJhdCcsIHNhbnMtc2VyaWZcIlxuICAgICAgICB9LFxuICAgICAgICAnI2Z1bGxzY3JlZW4tYnRuJzoge1xuICAgICAgICAgICAgcGFkZGluZzogJzAuNnJlbSAhaW1wb3J0YW50J1xuICAgICAgICB9LFxuICAgICAgICAnI21pbmltaXplSWNvbic6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdub25lJ1xuICAgICAgICB9LFxuICAgICAgICAnI3NldHRpbmdzQnRuLCAjc3RhdHNCdG4nOiB7XG4gICAgICAgICAgICBjdXJzb3I6ICdwb2ludGVyJ1xuICAgICAgICB9LFxuICAgICAgICAnI3VpRmVhdHVyZXMgYnV0dG9uJzoge1xuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndmFyKC0tY29sb3I3KScsXG4gICAgICAgICAgICBib3JkZXI6ICcxcHggc29saWQgdmFyKC0tY29sb3I3KScsXG4gICAgICAgICAgICBjb2xvcjogJ3ZhcigtLWNvbG9yMiknLFxuICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZScsXG4gICAgICAgICAgICB3aWR0aDogJzNyZW0nLFxuICAgICAgICAgICAgaGVpZ2h0OiAnM3JlbScsXG4gICAgICAgICAgICBwYWRkaW5nOiAnMC41cmVtJyxcbiAgICAgICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcidcbiAgICAgICAgfSxcbiAgICAgICAgJyN1aUZlYXR1cmVzIGJ1dHRvbjpob3Zlcic6IHtcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWNvbG9yMyknLFxuICAgICAgICAgICAgYm9yZGVyOiAnM3B4IHNvbGlkIHZhcigtLWNvbG9yMyknLFxuICAgICAgICAgICAgdHJhbnNpdGlvbjogJzAuMjVzIGVhc2UnLFxuICAgICAgICAgICAgcGFkZGluZ0xlZnQ6ICcwLjU1cmVtJyxcbiAgICAgICAgICAgIHBhZGRpbmdUb3A6ICcwLjU1cmVtJ1xuICAgICAgICB9LFxuICAgICAgICAnI3VpRmVhdHVyZXMgYnV0dG9uOmFjdGl2ZSc6IHtcbiAgICAgICAgICAgIGJvcmRlcjogJzNweCBzb2xpZCB2YXIoLS1jb2xvcjMpJyxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWNvbG9yNyknLFxuICAgICAgICAgICAgcGFkZGluZ0xlZnQ6ICcwLjU1cmVtJyxcbiAgICAgICAgICAgIHBhZGRpbmdUb3A6ICcwLjU1cmVtJ1xuICAgICAgICB9LFxuICAgICAgICAnLmJ0bi1mbGF0Jzoge1xuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndHJhbnNwYXJlbnQnLFxuICAgICAgICAgICAgY29sb3I6ICd2YXIoLS1jb2xvcjIpJyxcbiAgICAgICAgICAgIGZvbnRGYW1pbHk6IFwiJ01vbnRzZXJyYXQnXCIsXG4gICAgICAgICAgICBmb250V2VpZ2h0OiAnYm9sZCcsXG4gICAgICAgICAgICBib3JkZXI6ICczcHggc29saWQgdmFyKC0tY29sb3IzKScsXG4gICAgICAgICAgICBib3JkZXJSYWRpdXM6ICcxcmVtJyxcbiAgICAgICAgICAgIGZvbnRTaXplOiAnMC43NXJlbScsXG4gICAgICAgICAgICBwYWRkaW5nTGVmdDogJzAuNXJlbScsXG4gICAgICAgICAgICBwYWRkaW5nUmlnaHQ6ICcwLjVyZW0nLFxuICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcicsXG4gICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInXG4gICAgICAgIH0sXG4gICAgICAgICcuYnRuLWZsYXQ6aG92ZXInOiB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd2YXIoLS1jb2xvcjMpJyxcbiAgICAgICAgICAgIHRyYW5zaXRpb246ICdlYXNlIDAuM3MnXG4gICAgICAgIH0sXG4gICAgICAgICcuYnRuLWZsYXQ6ZGlzYWJsZWQnOiB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiAndmFyKC0tY29sb3I3KScsXG4gICAgICAgICAgICBib3JkZXJDb2xvcjogJ3ZhcigtLWNvbG9yMyknLFxuICAgICAgICAgICAgY29sb3I6ICd2YXIoLS1jb2xvcjMpJyxcbiAgICAgICAgICAgIGN1cnNvcjogJ2RlZmF1bHQnXG4gICAgICAgIH0sXG4gICAgICAgICcuYnRuLWZsYXQ6YWN0aXZlJzoge1xuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndHJhbnNwYXJlbnQnXG4gICAgICAgIH0sXG4gICAgICAgICcuYnRuLWZsYXQ6Zm9jdXMnOiB7XG4gICAgICAgICAgICBvdXRsaW5lOiAnbm9uZSdcbiAgICAgICAgfSxcbiAgICAgICAgJyN1aUZlYXR1cmVzIGltZyc6IHtcbiAgICAgICAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICAgICAgICBoZWlnaHQ6ICcxMDAlJ1xuICAgICAgICB9LFxuICAgICAgICAnLnBhbmVsLXdyYXAnOiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIHRvcDogJzAnLFxuICAgICAgICAgICAgYm90dG9tOiAnMCcsXG4gICAgICAgICAgICByaWdodDogJzAnLFxuICAgICAgICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICAgICAgICBtaW5XaWR0aDogJzIwdncnLFxuICAgICAgICAgICAgbWF4V2lkdGg6ICc5MHZ3JyxcbiAgICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMTAwJSknLFxuICAgICAgICAgICAgdHJhbnNpdGlvbjogJy4zcyBlYXNlLW91dCcsXG4gICAgICAgICAgICBwb2ludGVyRXZlbnRzOiAnYWxsJyxcbiAgICAgICAgICAgIGJhY2tkcm9wRmlsdGVyOiAnYmx1cigxMHB4KScsXG4gICAgICAgICAgICAnLXdlYmtpdC1iYWNrZHJvcC1maWx0ZXInOiAnYmx1cigxMHB4KScsXG4gICAgICAgICAgICBvdmVyZmxvd1k6ICdhdXRvJyxcbiAgICAgICAgICAgIG92ZXJmbG93WDogJ2hpZGRlbicsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd2YXIoLS1jb2xvcjApJ1xuICAgICAgICB9LFxuICAgICAgICAnLnBhbmVsLXdyYXAtdmlzaWJsZSc6IHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCUpJ1xuICAgICAgICB9LFxuICAgICAgICAnLnBhbmVsJzoge1xuICAgICAgICAgICAgb3ZlcmZsb3dZOiAnYXV0bycsXG4gICAgICAgICAgICBwYWRkaW5nOiAnMWVtJ1xuICAgICAgICB9LFxuICAgICAgICAnI3NldHRpbmdzSGVhZGluZywgI3N0YXRzSGVhZGluZyc6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdpbmxpbmUtYmxvY2snLFxuICAgICAgICAgICAgZm9udFNpemU6ICcyZW0nLFxuICAgICAgICAgICAgbWFyZ2luQmxvY2tTdGFydDogJzAuNjdlbScsXG4gICAgICAgICAgICBtYXJnaW5CbG9ja0VuZDogJzAuNjdlbScsXG4gICAgICAgICAgICBtYXJnaW5JbmxpbmVTdGFydDogJzBweCcsXG4gICAgICAgICAgICBtYXJnaW5JbmxpbmVFbmQ6ICcwcHgnLFxuICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZScsXG4gICAgICAgICAgICBwYWRkaW5nOiAnMCAwIDAgMnJlbSdcbiAgICAgICAgfSxcbiAgICAgICAgJyNzZXR0aW5nc0Nsb3NlLCAjc3RhdHNDbG9zZSc6IHtcbiAgICAgICAgICAgIG1hcmdpbjogJzAuNXJlbScsXG4gICAgICAgICAgICBwYWRkaW5nVG9wOiAnMC41cmVtJyxcbiAgICAgICAgICAgIHBhZGRpbmdCb3R0b206ICcwLjVyZW0nLFxuICAgICAgICAgICAgcGFkZGluZ1JpZ2h0OiAnMC41cmVtJyxcbiAgICAgICAgICAgIGZvbnRTaXplOiAnMmVtJyxcbiAgICAgICAgICAgIGZsb2F0OiAncmlnaHQnXG4gICAgICAgIH0sXG4gICAgICAgICcjc2V0dGluZ3NDbG9zZTphZnRlciwgI3N0YXRzQ2xvc2U6YWZ0ZXInOiB7XG4gICAgICAgICAgICBwYWRkaW5nTGVmdDogJzAuNXJlbScsXG4gICAgICAgICAgICBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJyxcbiAgICAgICAgICAgIGNvbnRlbnQ6ICdcIlxcXFwwMGQ3XCInXG4gICAgICAgIH0sXG4gICAgICAgICcjc2V0dGluZ3NDbG9zZTpob3ZlciwgI3N0YXRzQ2xvc2U6aG92ZXInOiB7XG4gICAgICAgICAgICBjb2xvcjogJ3ZhcigtLWNvbG9yMyknLFxuICAgICAgICAgICAgdHJhbnNpdGlvbjogJ2Vhc2UgMC4zcydcbiAgICAgICAgfSxcbiAgICAgICAgJyNzZXR0aW5nc0NvbnRlbnQsICNzdGF0c0NvbnRlbnQnOiB7XG4gICAgICAgICAgICBtYXJnaW5MZWZ0OiAnMnJlbScsXG4gICAgICAgICAgICBtYXJnaW5SaWdodDogJzJyZW0nXG4gICAgICAgIH0sXG4gICAgICAgICcuc2V0dGluZyc6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgICAgICAgIGZsZXhEaXJlY3Rpb246ICdyb3cnLFxuICAgICAgICAgICAganVzdGlmeUNvbnRlbnQ6ICdzcGFjZS1iZXR3ZWVuJyxcbiAgICAgICAgICAgIHBhZGRpbmc6ICcwLjE1cmVtIDEwcHggMC4xNXJlbSAxMHB4J1xuICAgICAgICB9LFxuICAgICAgICAnLnNldHRpbmdzLXRleHQnOiB7XG4gICAgICAgICAgICBjb2xvcjogJ3ZhcigtLWNvbG9yMiknLFxuICAgICAgICAgICAgdmVydGljYWxBbGlnbjogJ21pZGRsZScsXG4gICAgICAgICAgICBmb250V2VpZ2h0OiAnbm9ybWFsJ1xuICAgICAgICB9LFxuICAgICAgICAnLnNldHRpbmdzLW9wdGlvbic6IHtcbiAgICAgICAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICAgICAgICB0ZXh0T3ZlcmZsb3c6ICdlbGxpcHNpcycsXG4gICAgICAgICAgICB3aGl0ZVNwYWNlOiAnbm93cmFwJ1xuICAgICAgICB9LFxuICAgICAgICAnI2Nvbm5lY3RPdmVybGF5LCAjcGxheU92ZXJsYXksICNpbmZvT3ZlcmxheSwgI2Vycm9yT3ZlcmxheSwgI2Fma092ZXJsYXksICNkaXNjb25uZWN0T3ZlcmxheSc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgekluZGV4OiAnMzAnLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgICAgICAgIGNvbG9yOiAndmFyKC0tY29sb3IyKScsXG4gICAgICAgICAgICAgICAgZm9udFNpemU6ICcxLjhlbScsXG4gICAgICAgICAgICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd2YXIoLS1jb2xvcjEpJyxcbiAgICAgICAgICAgICAgICBhbGlnbkl0ZW1zOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICBqdXN0aWZ5Q29udGVudDogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgdGV4dFRyYW5zZm9ybTogJ3VwcGVyY2FzZSdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICcuY2xpY2thYmxlU3RhdGUnOiB7XG4gICAgICAgICAgICBhbGlnbkl0ZW1zOiAnY2VudGVyJyxcbiAgICAgICAgICAgIGp1c3RpZnlDb250ZW50OiAnY2VudGVyJyxcbiAgICAgICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgICAgICAgIGN1cnNvcjogJ3BvaW50ZXInXG4gICAgICAgIH0sXG4gICAgICAgICcudGV4dERpc3BsYXlTdGF0ZSc6IHtcbiAgICAgICAgICAgIGRpc3BsYXk6ICdmbGV4J1xuICAgICAgICB9LFxuICAgICAgICAnLmhpZGRlblN0YXRlJzoge1xuICAgICAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICAgIH0sXG4gICAgICAgICcjcGxheUJ1dHRvbiwgI2Nvbm5lY3RCdXR0b24nOiB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJyxcbiAgICAgICAgICAgIGhlaWdodDogJ2F1dG8nLFxuICAgICAgICAgICAgekluZGV4OiAnMzAnXG4gICAgICAgIH0sXG4gICAgICAgICdpbWcjcGxheUJ1dHRvbic6IHtcbiAgICAgICAgICAgIG1heFdpZHRoOiAnMjQxcHgnLFxuICAgICAgICAgICAgd2lkdGg6ICcxMCUnXG4gICAgICAgIH0sXG4gICAgICAgICcjdWlJbnRlcmFjdGlvbic6IHtcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnZml4ZWQnXG4gICAgICAgIH0sXG4gICAgICAgICcjVUlJbnRlcmFjdGlvbkJ1dHRvbkJvdW5kYXJ5Jzoge1xuICAgICAgICAgICAgcGFkZGluZzogJzJweCdcbiAgICAgICAgfSxcbiAgICAgICAgJyNVSUludGVyYWN0aW9uQnV0dG9uJzoge1xuICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcidcbiAgICAgICAgfSxcbiAgICAgICAgJyNoaWRkZW5JbnB1dCc6IHtcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgICAgbGVmdDogJy0xMCUnLFxuICAgICAgICAgICAgd2lkdGg6ICcwcHgnLFxuICAgICAgICAgICAgb3BhY2l0eTogJzAnXG4gICAgICAgIH0sXG4gICAgICAgICcjZWRpdFRleHRCdXR0b24nOiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIGhlaWdodDogJzQwcHgnLFxuICAgICAgICAgICAgd2lkdGg6ICc0MHB4J1xuICAgICAgICB9LFxuICAgICAgICAnLmJ0bi1vdmVybGF5Jzoge1xuICAgICAgICAgICAgdmVydGljYWxBbGlnbjogJ21pZGRsZScsXG4gICAgICAgICAgICBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJ1xuICAgICAgICB9LFxuICAgICAgICAnLnRnbC1zd2l0Y2gnOiB7XG4gICAgICAgICAgICB2ZXJ0aWNhbEFsaWduOiAnbWlkZGxlJyxcbiAgICAgICAgICAgIGRpc3BsYXk6ICdpbmxpbmUtYmxvY2snXG4gICAgICAgIH0sXG4gICAgICAgICcudGdsLXN3aXRjaCAudGdsJzoge1xuICAgICAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICAgIH0sXG4gICAgICAgICcudGdsLCAudGdsOmFmdGVyLCAudGdsOmJlZm9yZSwgLnRnbCAqLCAudGdsICo6YWZ0ZXIsIC50Z2wgKjpiZWZvcmUsIC50Z2wrLnRnbC1zbGlkZXInOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICctd2Via2l0LWJveC1zaXppbmcnOiAnYm9yZGVyLWJveCcsXG4gICAgICAgICAgICAgICAgYm94U2l6aW5nOiAnYm9yZGVyLWJveCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICcudGdsOjotbW96LXNlbGVjdGlvbiwgLnRnbDphZnRlcjo6LW1vei1zZWxlY3Rpb24sIC50Z2w6YmVmb3JlOjotbW96LXNlbGVjdGlvbiwgLnRnbCAqOjotbW96LXNlbGVjdGlvbiwgLnRnbCAqOmFmdGVyOjotbW96LXNlbGVjdGlvbiwgLnRnbCAqOmJlZm9yZTo6LW1vei1zZWxlY3Rpb24sIC50Z2wrLnRnbC1zbGlkZXI6Oi1tb3otc2VsZWN0aW9uJzpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAnbm9uZSdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICcudGdsOjpzZWxlY3Rpb24sIC50Z2w6YWZ0ZXI6OnNlbGVjdGlvbiwgLnRnbDpiZWZvcmU6OnNlbGVjdGlvbiwgLnRnbCAqOjpzZWxlY3Rpb24sIC50Z2wgKjphZnRlcjo6c2VsZWN0aW9uLCAudGdsICo6YmVmb3JlOjpzZWxlY3Rpb24sIC50Z2wrLnRnbC1zbGlkZXI6OnNlbGVjdGlvbic6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ25vbmUnXG4gICAgICAgICAgICB9LFxuICAgICAgICAnLnRnbC1zbGlkZXInOiB7fSxcbiAgICAgICAgJy50Z2wrLnRnbC1zbGlkZXInOiB7XG4gICAgICAgICAgICBvdXRsaW5lOiAnMCcsXG4gICAgICAgICAgICBkaXNwbGF5OiAnYmxvY2snLFxuICAgICAgICAgICAgd2lkdGg6ICc0MHB4JyxcbiAgICAgICAgICAgIGhlaWdodDogJzE4cHgnLFxuICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZScsXG4gICAgICAgICAgICBjdXJzb3I6ICdwb2ludGVyJyxcbiAgICAgICAgICAgIHVzZXJTZWxlY3Q6ICdub25lJ1xuICAgICAgICB9LFxuICAgICAgICAnLnRnbCsudGdsLXNsaWRlcjphZnRlciwgLnRnbCsudGdsLXNsaWRlcjpiZWZvcmUnOiB7XG4gICAgICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJyxcbiAgICAgICAgICAgIGRpc3BsYXk6ICdibG9jaycsXG4gICAgICAgICAgICBjb250ZW50OiAnXCJcIicsXG4gICAgICAgICAgICB3aWR0aDogJzUwJScsXG4gICAgICAgICAgICBoZWlnaHQ6ICcxMDAlJ1xuICAgICAgICB9LFxuICAgICAgICAnLnRnbCsudGdsLXNsaWRlcjphZnRlcic6IHtcbiAgICAgICAgICAgIGxlZnQ6ICcwJ1xuICAgICAgICB9LFxuICAgICAgICAnLnRnbCsudGdsLXNsaWRlcjpiZWZvcmUnOiB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnbm9uZSdcbiAgICAgICAgfSxcbiAgICAgICAgJy50Z2wtZmxhdCsudGdsLXNsaWRlcic6IHtcbiAgICAgICAgICAgIHBhZGRpbmc6ICcycHgnLFxuICAgICAgICAgICAgJy13ZWJraXQtdHJhbnNpdGlvbic6ICdhbGwgLjJzIGVhc2UnLFxuICAgICAgICAgICAgdHJhbnNpdGlvbjogJ2FsbCAuMnMgZWFzZScsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiAndmFyKC0tY29sb3I2KScsXG4gICAgICAgICAgICBib3JkZXI6ICczcHggc29saWQgdmFyKC0tY29sb3I3KScsXG4gICAgICAgICAgICBib3JkZXJSYWRpdXM6ICcyZW0nXG4gICAgICAgIH0sXG4gICAgICAgICcudGdsLWZsYXQrLnRnbC1zbGlkZXI6YWZ0ZXInOiB7XG4gICAgICAgICAgICAnLXdlYmtpdC10cmFuc2l0aW9uJzogJ2FsbCAuMnMgZWFzZScsXG4gICAgICAgICAgICB0cmFuc2l0aW9uOiAnYWxsIC4ycyBlYXNlJyxcbiAgICAgICAgICAgIGJhY2tncm91bmQ6ICd2YXIoLS1jb2xvcjcpJyxcbiAgICAgICAgICAgIGNvbnRlbnQ6ICdcIlwiJyxcbiAgICAgICAgICAgIGJvcmRlclJhZGl1czogJzFlbSdcbiAgICAgICAgfSxcbiAgICAgICAgJy50Z2wtZmxhdDpjaGVja2VkKy50Z2wtc2xpZGVyJzoge1xuICAgICAgICAgICAgYm9yZGVyOiAnM3B4IHNvbGlkIHZhcigtLWNvbG9yMyknXG4gICAgICAgIH0sXG4gICAgICAgICcudGdsLWZsYXQ6Y2hlY2tlZCsudGdsLXNsaWRlcjphZnRlcic6IHtcbiAgICAgICAgICAgIGxlZnQ6ICc1MCUnLFxuICAgICAgICAgICAgYmFja2dyb3VuZDogJ3ZhcigtLWNvbG9yMyknXG4gICAgICAgIH0sXG4gICAgICAgICcuYnRuLWFwcGx5Jzoge1xuICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrICFpbXBvcnRhbnQnLFxuICAgICAgICAgICAgbWFyZ2luTGVmdDogJ2F1dG8nLFxuICAgICAgICAgICAgbWFyZ2luUmlnaHQ6ICdhdXRvJyxcbiAgICAgICAgICAgIHdpZHRoOiAnNDAlJ1xuICAgICAgICB9LFxuICAgICAgICAnLmZvcm0tY29udHJvbCc6IHtcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWNvbG9yNyknLFxuICAgICAgICAgICAgYm9yZGVyOiAnMnB4IHNvbGlkIHZhcigtLWNvbG9yNyknLFxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNHB4JyxcbiAgICAgICAgICAgIGNvbG9yOiAndmFyKC0tY29sb3IyKScsXG4gICAgICAgICAgICB0ZXh0QWxpZ246ICdyaWdodCcsXG4gICAgICAgICAgICBmb250RmFtaWx5OiAnaW5oZXJpdCdcbiAgICAgICAgfSxcbiAgICAgICAgJy5mb3JtLWNvbnRyb2w6aG92ZXInOiB7XG4gICAgICAgICAgICBib3JkZXJDb2xvcjogJ3ZhcigtLWNvbG9yNyknXG4gICAgICAgIH0sXG4gICAgICAgICcuZm9ybS1ncm91cCc6IHtcbiAgICAgICAgICAgIHBhZGRpbmdUb3A6ICc0cHgnLFxuICAgICAgICAgICAgZGlzcGxheTogJ2dyaWQnLFxuICAgICAgICAgICAgZ3JpZFRlbXBsYXRlQ29sdW1uczogJzgwJSAyMCUnLFxuICAgICAgICAgICAgcm93R2FwOiAnNHB4JyxcbiAgICAgICAgICAgIHBhZGRpbmdSaWdodDogJzEwcHgnLFxuICAgICAgICAgICAgcGFkZGluZ0xlZnQ6ICcxMHB4J1xuICAgICAgICB9LFxuICAgICAgICAnLmZvcm0tZ3JvdXAgbGFiZWwnOiB7XG4gICAgICAgICAgICB2ZXJ0aWNhbEFsaWduOiAnbWlkZGxlJyxcbiAgICAgICAgICAgIGZvbnRXZWlnaHQ6ICdub3JtYWwnXG4gICAgICAgIH0sXG4gICAgICAgICcuc2V0dGluZ3NDb250YWluZXInOiB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgICAgICBmbGV4RGlyZWN0aW9uOiAnY29sdW1uJyxcbiAgICAgICAgICAgIGJvcmRlckJvdHRvbTogJzFweCBzb2xpZCB2YXIoLS1jb2xvcjcpJyxcbiAgICAgICAgICAgIHBhZGRpbmdUb3A6ICcxMHB4JyxcbiAgICAgICAgICAgIHBhZGRpbmdCb3R0b206ICcxMHB4J1xuICAgICAgICB9LFxuICAgICAgICAnLnNldHRpbmdzQ29udGFpbmVyPiA6Zmlyc3QtY2hpbGQnOiB7XG4gICAgICAgICAgICBtYXJnaW5Ub3A6ICc0cHgnLFxuICAgICAgICAgICAgbWFyZ2luQm90dG9tOiAnNHB4JyxcbiAgICAgICAgICAgIGZvbnRXZWlnaHQ6ICdib2xkJyxcbiAgICAgICAgICAgIGp1c3RpZnlDb250ZW50OiAnc3BhY2UtYmV0d2VlbicsXG4gICAgICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgICAgICBmbGV4RGlyZWN0aW9uOiAncm93JyxcbiAgICAgICAgICAgIGFsaWduSXRlbXM6ICdiYXNlbGluZSdcbiAgICAgICAgfSxcbiAgICAgICAgJy5jb2xsYXBzZSc6IHtcbiAgICAgICAgICAgIHBhZGRpbmdMZWZ0OiAnNSUnXG4gICAgICAgIH0sXG4gICAgICAgICcjc3RyZWFtVG9vbHMnOiB7XG4gICAgICAgICAgICBib3JkZXJCb3R0b21SaWdodFJhZGl1czogJzVweCcsXG4gICAgICAgICAgICBib3JkZXJCb3R0b21MZWZ0UmFkaXVzOiAnNXB4JyxcbiAgICAgICAgICAgIHVzZXJTZWxlY3Q6ICdub25lJyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgICAgdG9wOiAnMCcsXG4gICAgICAgICAgICByaWdodDogJzIlJyxcbiAgICAgICAgICAgIHpJbmRleDogJzEwMCcsXG4gICAgICAgICAgICBib3JkZXI6ICc0cHggc29saWQgdmFyKC0tY29sb3VyOCknLFxuICAgICAgICAgICAgYm9yZGVyVG9wV2lkdGg6ICcwcHgnXG4gICAgICAgIH0sXG4gICAgICAgICcuc2V0dGluZ3NIZWFkZXInOiB7XG4gICAgICAgICAgICBmb250U3R5bGU6ICdpdGFsaWMnXG4gICAgICAgIH0sXG4gICAgICAgICcjc3RyZWFtVG9vbHNIZWFkZXInOiB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgICAgICBmbGV4RGlyZWN0aW9uOiAncm93JyxcbiAgICAgICAgICAgIGp1c3RpZnlDb250ZW50OiAnc3BhY2UtYmV0d2VlbicsXG4gICAgICAgICAgICBib3JkZXJCb3R0b206ICcxcHggc29saWQgdmFyKC0tY29sb3VyOCknLFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndmFyKC0tY29sb3I3KSdcbiAgICAgICAgfSxcbiAgICAgICAgJy5zdHJlYW1Ub29scyc6IHtcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWNvbG9yMiknLFxuICAgICAgICAgICAgZm9udEZhbWlseTogJ3ZhcigtLWJ1dHRvbkZvbnQpJyxcbiAgICAgICAgICAgIGZvbnRXZWlnaHQ6ICdsaWdodGVyJyxcbiAgICAgICAgICAgIGNvbG9yOiAndmFyKC0tY29sb3I3KSdcbiAgICAgICAgfSxcbiAgICAgICAgJy5zdHJlYW1Ub29scy1zaG93bj4jc3RyZWFtVG9vbHNTZXR0aW5ncywgLnN0cmVhbVRvb2xzLXNob3duPiNzdHJlYW1Ub29sc1N0YXRzJzpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiAnYmxvY2snXG4gICAgICAgICAgICB9LFxuICAgICAgICAnI3N0cmVhbVRvb2xzVG9nZ2xlJzoge1xuICAgICAgICAgICAgd2lkdGg6ICcxMDAlJ1xuICAgICAgICB9LFxuICAgICAgICAnI3F1YWxpdHlTdGF0dXMnOiB7XG4gICAgICAgICAgICBmb250U2l6ZTogJzM3cHgnLFxuICAgICAgICAgICAgcGFkZGluZ1JpZ2h0OiAnNHB4J1xuICAgICAgICB9LFxuICAgICAgICAnLnN2Z0ljb24nOiB7XG4gICAgICAgICAgICBmaWxsOiAndmFyKC0tY29sb3IyKSdcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBjdXN0b21TdHlsZXM/OiBQYXJ0aWFsPFN0eWxlcz47XG4gICAgbGlnaHRNb2RlUGFsZXR0ZTogQ29sb3JQYWxldHRlO1xuICAgIGRhcmtNb2RlUGFsZXR0ZTogQ29sb3JQYWxldHRlO1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9ucz86IHtcbiAgICAgICAgY3VzdG9tU3R5bGVzPzogUGFydGlhbDxTdHlsZXM+O1xuICAgICAgICBsaWdodE1vZGVQYWxldHRlPzogQ29sb3JQYWxldHRlO1xuICAgICAgICBkYXJrTW9kZVBhbGV0dGU/OiBDb2xvclBhbGV0dGU7XG4gICAgICAgIGpzc0luc2VydGlvblBvaW50Pzogc3RyaW5nIHwgSFRNTEVsZW1lbnQ7XG4gICAgfSkge1xuICAgICAgICBjb25zdCB7IGN1c3RvbVN0eWxlcywgbGlnaHRNb2RlUGFsZXR0ZSwgZGFya01vZGVQYWxldHRlLCBqc3NJbnNlcnRpb25Qb2ludCB9ID1cbiAgICAgICAgICAgIG9wdGlvbnMgPz8ge307XG4gICAgICAgIC8vIE9uZSB0aW1lIHNldHVwIHdpdGggZGVmYXVsdCBwbHVnaW5zIGFuZCBzZXR0aW5ncy5cbiAgICAgICAgY29uc3QganNzT3B0aW9ucyA9IHtcbiAgICAgICAgICAgIC8vIEpTUyBoYXMgbWFueSBpbnRlcmVzdGluZyBwbHVnaW5zIHdlIG1heSB3aXNoIHRvIHR1cm4gb25cbiAgICAgICAgICAgIC8vcGx1Z2luczogW2Z1bmN0aW9ucygpLCB0ZW1wbGF0ZSgpLCBnbG9iYWwoKSwgZXh0ZW5kKCksIG5lc3RlZCgpLCBjb21wb3NlKCksIGNhbWVsQ2FzZSgpLCBkZWZhdWx0VW5pdChvcHRpb25zLmRlZmF1bHRVbml0KSwgZXhwYW5kKCksIHZlbmRvclByZWZpeGVyKCksIHByb3BzU29ydCgpXVxuICAgICAgICAgICAgcGx1Z2luczogW2dsb2JhbCgpLCBjYW1lbENhc2UoKV0sXG4gICAgICAgICAgICBpbnNlcnRpb25Qb2ludDoganNzSW5zZXJ0aW9uUG9pbnRcbiAgICAgICAgfTtcblxuICAgICAgICBqc3Muc2V0dXAoanNzT3B0aW9ucyk7XG5cbiAgICAgICAgdGhpcy5jdXN0b21TdHlsZXMgPSBjdXN0b21TdHlsZXM7XG4gICAgICAgIHRoaXMubGlnaHRNb2RlUGFsZXR0ZSA9XG4gICAgICAgICAgICBsaWdodE1vZGVQYWxldHRlID8/IHRoaXMuZGVmYXVsdExpZ2h0TW9kZVBhbGV0dGU7XG4gICAgICAgIHRoaXMuZGFya01vZGVQYWxldHRlID0gZGFya01vZGVQYWxldHRlID8/IHRoaXMuZGVmYXVsdERhcmtNb2RlUGFsZXR0ZTtcbiAgICB9XG5cbiAgICBhcHBseVN0eWxlU2hlZXQoKSB7XG4gICAgICAgIC8vIFRvZG86IHJlZmFjdG9yIGNvZGViYXNlIHRvIHVzZSBqc3MgYXQgYSBjb21wb25lbnQgbGV2ZWwsIGNsYXNzZXMgY2FuIGJlIGdyYWJiZWQgbGlrZSBzbzpcbiAgICAgICAgLy9jb25zdCB7cGl4ZWxTdHJlYW1pbmdDbGFzc2VzfSA9IGpzcy5jcmVhdGVTdHlsZVNoZWV0KHN0eWxlcykuYXR0YWNoKCk7XG5cbiAgICAgICAgLy8gYXR0YWNoIGdlbmVyYXRlZCBzdHlsZSBzaGVldCB0byBwYWdlXG4gICAgICAgIGpzcy5jcmVhdGVTdHlsZVNoZWV0KHtcbiAgICAgICAgICAgICdAZ2xvYmFsJzoge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuZGVmYXVsdFN0eWxlcyxcbiAgICAgICAgICAgICAgICAuLi50aGlzLmN1c3RvbVN0eWxlc1xuICAgICAgICAgICAgfVxuICAgICAgICB9KS5hdHRhY2goKTtcbiAgICB9XG5cbiAgICBhcHBseVBhbGV0dGUocGFsZXR0ZTogQ29sb3JQYWxldHRlKSB7XG4gICAgICAgIGNvbnN0IHJvb3RFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignOnJvb3QnKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgcm9vdEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tY29sb3IwJywgcGFsZXR0ZVsnLS1jb2xvcjAnXSk7XG4gICAgICAgIHJvb3RFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLWNvbG9yMScsIHBhbGV0dGVbJy0tY29sb3IxJ10pO1xuICAgICAgICByb290RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1jb2xvcjInLCBwYWxldHRlWyctLWNvbG9yMiddKTtcbiAgICAgICAgcm9vdEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tY29sb3IzJywgcGFsZXR0ZVsnLS1jb2xvcjMnXSk7XG4gICAgICAgIHJvb3RFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLWNvbG9yNCcsIHBhbGV0dGVbJy0tY29sb3I0J10pO1xuICAgICAgICByb290RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1jb2xvcjUnLCBwYWxldHRlWyctLWNvbG9yNSddKTtcbiAgICAgICAgcm9vdEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tY29sb3I2JywgcGFsZXR0ZVsnLS1jb2xvcjYnXSk7XG4gICAgICAgIHJvb3RFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLWNvbG9yNycsIHBhbGV0dGVbJy0tY29sb3I3J10pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgcGxheWVycyBjb2xvciB2YXJpYWJsZXNcbiAgICAgKiBAcGFyYW0gaXNMaWdodE1vZGUgLSBzaG91bGQgd2UgdXNlIGEgbGlnaHQgb3IgZGFyayBjb2xvciBzY2hlbWVcbiAgICAgKi9cbiAgICBzZXRDb2xvck1vZGUoaXNMaWdodE1vZGU6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKGlzTGlnaHRNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmFwcGx5UGFsZXR0ZSh0aGlzLmxpZ2h0TW9kZVBhbGV0dGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hcHBseVBhbGV0dGUodGhpcy5kYXJrTW9kZVBhbGV0dGUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgRnVsbFNjcmVlbkljb24gfSBmcm9tICcuL0Z1bGxzY3JlZW5JY29uJztcbmltcG9ydCB7IFNldHRpbmdzSWNvbiB9IGZyb20gJy4vU2V0dGluZ3NJY29uJztcbmltcG9ydCB7IFN0YXRzSWNvbiB9IGZyb20gJy4vU3RhdHNJY29uJztcbmltcG9ydCB7IFhSSWNvbiB9IGZyb20gJy4vWFJJY29uJztcbmltcG9ydCB7IFdlYlhSQ29udHJvbGxlciB9IGZyb20gJ0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMnO1xuaW1wb3J0IHsgVUlFbGVtZW50Q29uZmlnLCBVSUVsZW1lbnRDcmVhdGlvbk1vZGUgfSBmcm9tICcuLi9VSS9VSUNvbmZpZ3VyYXRpb25UeXBlcydcblxuLyoqXG4gKiBDb25maWd1cmVzIGhvdyBVSSBlbGVtZW50cyB0byBjb250cm9sIHRoZSBzdHJlYW0gYXJlIGNyZWF0ZWQuIFxuICogQnkgZGVmYXVsdCwgYSBidXR0b24gd2lsbCBiZSBjcmVhdGVkIGZvciBlYWNoIGNvbnRyb2wuIFRoYXQgY2FuIGJlIG92ZXJyaWRlbiBwZXItY29udHJvbFxuICogdG8gdXNlIGFuIGV4dGVybmFsbHkgcHJvdmlkZWQgZWxlbWVudCwgb3IgdG8gZGlzYWJsZSB0aGUgZWxlbWVudCBlbnRpcmVseS5cbiAqL1xuZXhwb3J0IHR5cGUgQ29udHJvbHNVSUNvbmZpZ3VyYXRpb24gPSB7XG4gICAgLy9bUHJvcGVydHkgaW4ga2V5b2YgQ29udHJvbHMgYXMgYCR7UHJvcGVydHl9VHlwZWBdPyA6IFVJRWxlbWVudFR5cGU7XG4gICAgc3RhdHNCdXR0b25UeXBlPyA6IFVJRWxlbWVudENvbmZpZyxcbiAgICBmdWxsc2NyZWVuQnV0dG9uVHlwZT8gOiBVSUVsZW1lbnRDb25maWcsXG4gICAgc2V0dGluZ3NCdXR0b25UeXBlPyA6IFVJRWxlbWVudENvbmZpZyxcbiAgICB4ckljb25UeXBlPyA6IFVJRWxlbWVudENvbmZpZ1xufVxuXG4vLyBJZiB0aGVyZSBpc24ndCBhIHR5cGUgcHJvdmlkZWQsIGRlZmF1bHQgYmVoYXZpb3VyIGlzIHRvIGNyZWF0ZSB0aGUgZWxlbWVudC5cbmZ1bmN0aW9uIHNob3VsZENyZWF0ZUJ1dHRvbih0eXBlIDogVUlFbGVtZW50Q29uZmlnIHwgdW5kZWZpbmVkKSA6IGJvb2xlYW4ge1xuICAgIHJldHVybiAodHlwZSA9PSB1bmRlZmluZWQpID8gdHJ1ZSA6ICh0eXBlLmNyZWF0aW9uTW9kZSA9PT0gVUlFbGVtZW50Q3JlYXRpb25Nb2RlLkNyZWF0ZURlZmF1bHRFbGVtZW50KTtcbn1cblxuLyoqXG4gKiBFbGVtZW50IGNvbnRhaW5pbmcgdmFyaW91cyBjb250cm9scyBsaWtlIHN0YXRzLCBzZXR0aW5ncywgZnVsbHNjcmVlbi5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbnRyb2xzIHtcbiAgICBzdGF0c0ljb246IFN0YXRzSWNvbjtcbiAgICBmdWxsc2NyZWVuSWNvbjogRnVsbFNjcmVlbkljb247XG4gICAgc2V0dGluZ3NJY29uOiBTZXR0aW5nc0ljb247XG4gICAgeHJJY29uOiBYUkljb247XG5cbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogQ29uc3RydWN0IHRoZSBjb250cm9sc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNvbmZpZz8gOiBDb250cm9sc1VJQ29uZmlndXJhdGlvbikge1xuICAgICAgICBpZiAoIWNvbmZpZyB8fCBzaG91bGRDcmVhdGVCdXR0b24oY29uZmlnLnN0YXRzQnV0dG9uVHlwZSkpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNJY29uID0gbmV3IFN0YXRzSWNvbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY29uZmlnIHx8IHNob3VsZENyZWF0ZUJ1dHRvbihjb25maWcuc2V0dGluZ3NCdXR0b25UeXBlKSl7XG4gICAgICAgICAgICB0aGlzLnNldHRpbmdzSWNvbiA9IG5ldyBTZXR0aW5nc0ljb24oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNvbmZpZyB8fCBzaG91bGRDcmVhdGVCdXR0b24oY29uZmlnLmZ1bGxzY3JlZW5CdXR0b25UeXBlKSkge1xuICAgICAgICAgICAgdGhpcy5mdWxsc2NyZWVuSWNvbiA9IG5ldyBGdWxsU2NyZWVuSWNvbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY29uZmlnIHx8IHNob3VsZENyZWF0ZUJ1dHRvbihjb25maWcueHJJY29uVHlwZSkpe1xuICAgICAgICAgICAgdGhpcy54ckljb24gPSBuZXcgWFJJY29uKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGVsZW1lbnQgY29udGFpbmluZyB0aGUgY29udHJvbHMuXG4gICAgICovXG4gICAgcHVibGljIGdldCByb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5pZCA9ICdjb250cm9scyc7XG4gICAgICAgICAgICBpZiAoISF0aGlzLmZ1bGxzY3JlZW5JY29uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5mdWxsc2NyZWVuSWNvbi5yb290RWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLnNldHRpbmdzSWNvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc2V0dGluZ3NJY29uLnJvb3RFbGVtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RhdHNJY29uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5zdGF0c0ljb24ucm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCEhdGhpcy54ckljb24pIHtcbiAgICAgICAgICAgICAgICBXZWJYUkNvbnRyb2xsZXIuaXNTZXNzaW9uU3VwcG9ydGVkKCdpbW1lcnNpdmUtdnInKS50aGVuKFxuICAgICAgICAgICAgICAgIChzdXBwb3J0ZWQ6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy54ckljb24ucm9vdEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG59IiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5pbXBvcnQge1xuICAgIERhdGFDaGFubmVsTGF0ZW5jeVRlc3RSZXN1bHRcbn0gZnJvbSBcIkBlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMvdHlwZXMvRGF0YUNoYW5uZWwvRGF0YUNoYW5uZWxMYXRlbmN5VGVzdFJlc3VsdHNcIjtcblxuLyoqXG4gKiBEYXRhQ2hhbm5lbCBMYXRlbmN5IHRlc3QgVUkgZWxlbWVudHMgYW5kIHJlc3VsdHMgaGFuZGxpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhQ2hhbm5lbExhdGVuY3lUZXN0IHtcbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIF9sYXRlbmN5VGVzdEJ1dHRvbjogSFRNTElucHV0RWxlbWVudDtcbiAgICBfbGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGJ1dHRvbiBjb250YWluaW5nIHRoZSBzdGF0cyBpY29uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NlY3Rpb24nKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3NldHRpbmdzQ29udGFpbmVyJyk7XG5cbiAgICAgICAgICAgIC8vIG1ha2UgaGVhZGluZ1xuICAgICAgICAgICAgY29uc3QgaGVhZGluZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgaGVhZGluZy5pZCA9ICdkYXRhQ2hhbm5lbExhdGVuY3lUZXN0SGVhZGVyJztcbiAgICAgICAgICAgIGhlYWRpbmcuY2xhc3NMaXN0LmFkZCgnc2V0dGluZ3MtdGV4dCcpO1xuICAgICAgICAgICAgaGVhZGluZy5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nc0hlYWRlcicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQoaGVhZGluZyk7XG5cbiAgICAgICAgICAgIGNvbnN0IGhlYWRpbmdUZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBoZWFkaW5nVGV4dC5pbm5lckhUTUwgPSAnRGF0YSBDaGFubmVsIExhdGVuY3kgVGVzdCc7XG4gICAgICAgICAgICBoZWFkaW5nLmFwcGVuZENoaWxkKGhlYWRpbmdUZXh0KTtcbiAgICAgICAgICAgIGhlYWRpbmcuYXBwZW5kQ2hpbGQodGhpcy5sYXRlbmN5VGVzdEJ1dHRvbik7XG5cbiAgICAgICAgICAgIC8vIG1ha2UgdGVzdCByZXN1bHRzIGVsZW1lbnRcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHNQYXJlbnRFbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICByZXN1bHRzUGFyZW50RWxlbS5pZCA9ICdkYXRhQ2hhbm5lbExhdGVuY3lUZXN0Q29udGFpbmVyJztcbiAgICAgICAgICAgIHJlc3VsdHNQYXJlbnRFbGVtLmNsYXNzTGlzdC5hZGQoJ2Qtbm9uZScpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQocmVzdWx0c1BhcmVudEVsZW0pO1xuXG4gICAgICAgICAgICByZXN1bHRzUGFyZW50RWxlbS5hcHBlbmRDaGlsZCh0aGlzLmxhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGxhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQuaWQgPSAnZGF0YUNoYW5uZWxMYXRlbmN5U3RhdHNSZXN1bHRzJztcbiAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQuY2xhc3NMaXN0LmFkZCgnU3RhdHNSZXN1bHQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGxhdGVuY3lUZXN0QnV0dG9uKCk6IEhUTUxJbnB1dEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX2xhdGVuY3lUZXN0QnV0dG9uKSB7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbi50eXBlID0gJ2J1dHRvbic7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbi52YWx1ZSA9ICdSdW4gVGVzdCc7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbi5pZCA9ICdidG4tc3RhcnQtZGF0YS1jaGFubmVsLWxhdGVuY3ktdGVzdCc7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdzdHJlYW1Ub29scy1idXR0b24nKTtcbiAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lUZXN0QnV0dG9uLmNsYXNzTGlzdC5hZGQoJ2J0bi1mbGF0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2xhdGVuY3lUZXN0QnV0dG9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBvcHVsYXRlIHRoZSBVSSBiYXNlZCBvbiB0aGUgbGF0ZW5jeSB0ZXN0J3MgcmVzdWx0cy5cbiAgICAgKiBAcGFyYW0gcmVzdWx0IFRoZSBsYXRlbmN5IHRlc3QgcmVzdWx0cy5cbiAgICAgKi9cbiAgICBwdWJsaWMgaGFuZGxlVGVzdFJlc3VsdChyZXN1bHQ6IERhdGFDaGFubmVsTGF0ZW5jeVRlc3RSZXN1bHQpIHtcbiAgICAgICAgTG9nZ2VyLkxvZyhcbiAgICAgICAgICAgIExvZ2dlci5HZXRTdGFja1RyYWNlKCksXG4gICAgICAgICAgICByZXN1bHQudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIDZcbiAgICAgICAgKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENoZWNrIHdlIGhhdmUgcmVzdWx0cywgTmFOIHdvdWxkIG1lYW4gdGhhdCBVRSB2ZXJzaW9uIHdlIHRhbGsgdG8gZG9lc24ndCBzdXBwb3J0IG91ciB0ZXN0XG4gICAgICAgICAqL1xuICAgICAgICBpZiAoaXNOYU4ocmVzdWx0LmRhdGFDaGFubmVsUnR0KSkge1xuICAgICAgICAgICAgdGhpcy5sYXRlbmN5VGVzdFJlc3VsdHNFbGVtZW50LmlubmVySFRNTCA9ICc8ZGl2Pk5vdCBzdXBwb3J0ZWQ8L2Rpdj4nO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBsYXRlbmN5U3RhdHNJbm5lckhUTUwgPSAnJztcbiAgICAgICAgbGF0ZW5jeVN0YXRzSW5uZXJIVE1MICs9XG4gICAgICAgICAgICAnPGRpdj5EYXRhIGNoYW5uZWwgUlRUIChtcyk6ICcgK1xuICAgICAgICAgICAgcmVzdWx0LmRhdGFDaGFubmVsUnR0ICtcbiAgICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2VwYXJhdGUgcGF0aCB0aW1lIGRpc2NvdmVyeSB3b3JrcyBvbmx5IHdoZW4gVUUgYW5kIFBsYXllciBjbG9ja3MgaGF2ZSBiZWVuIHN5bmNocm9uaXplZC5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChyZXN1bHQucGxheWVyVG9TdHJlYW1lclRpbWUgPj0gMCAmJiByZXN1bHQuc3RyZWFtZXJUb1BsYXllclRpbWUgPj0gMCkge1xuICAgICAgICAgICAgbGF0ZW5jeVN0YXRzSW5uZXJIVE1MICs9XG4gICAgICAgICAgICAgICAgJzxkaXY+UGxheWVyIHRvIFN0cmVhbWVyIHBhdGggKG1zKTogJyArIHJlc3VsdC5wbGF5ZXJUb1N0cmVhbWVyVGltZSArICc8L2Rpdj4nO1xuICAgICAgICAgICAgbGF0ZW5jeVN0YXRzSW5uZXJIVE1MICs9XG4gICAgICAgICAgICAgICAgJzxkaXY+U3RyZWFtZXIgdG8gUGxheWVyIHBhdGggKG1zKTogJyArXG4gICAgICAgICAgICAgICAgcmVzdWx0LnN0cmVhbWVyVG9QbGF5ZXJUaW1lICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQuaW5uZXJIVE1MID0gbGF0ZW5jeVN0YXRzSW5uZXJIVE1MO1xuICAgICAgICAvL3NldHVwIGJ1dHRvbiB0byBkb3dubG9hZCB0aGUgZGV0YWlsZWQgcmVzdWx0c1xuICAgICAgICBsZXQgZG93bmxvYWRCdXR0b246IEhUTUxJbnB1dEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICBkb3dubG9hZEJ1dHRvbi50eXBlID0gJ2J1dHRvbic7XG4gICAgICAgIGRvd25sb2FkQnV0dG9uLnZhbHVlID0gJ0Rvd25sb2FkJztcbiAgICAgICAgZG93bmxvYWRCdXR0b24uY2xhc3NMaXN0LmFkZCgnc3RyZWFtVG9vbHMtYnV0dG9uJyk7XG4gICAgICAgIGRvd25sb2FkQnV0dG9uLmNsYXNzTGlzdC5hZGQoJ2J0bi1mbGF0Jyk7XG4gICAgICAgIGRvd25sb2FkQnV0dG9uLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICBsZXQgZmlsZSA9IG5ldyBCbG9iKFtyZXN1bHQuZXhwb3J0TGF0ZW5jeUFzQ1NWKCldLCB7dHlwZTogJ3RleHQvcGxhaW4nfSk7XG4gICAgICAgICAgICBsZXQgYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpLFxuICAgICAgICAgICAgICAgIHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XG4gICAgICAgICAgICBhLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICBhLmRvd25sb2FkID0gXCJkYXRhX2NoYW5uZWxfbGF0ZW5jeV90ZXN0X3Jlc3VsdHMuY3N2XCI7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGEpO1xuICAgICAgICAgICAgYS5jbGljaygpO1xuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGEpO1xuICAgICAgICAgICAgICAgIHdpbmRvdy5VUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQuYXBwZW5kQ2hpbGQoZG93bmxvYWRCdXR0b24pO1xuICAgIH1cblxuICAgIHB1YmxpYyBoYW5kbGVUZXN0U3RhcnQoKSB7XG4gICAgICAgIHRoaXMubGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudC5pbm5lckhUTUwgPVxuICAgICAgICAgICAgJzxkaXY+VGVzdCBpbiBwcm9ncmVzczwvZGl2Pic7XG4gICAgfVxuXG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG4vKipcbiAqIERlY2xhcmUgYWRkaXRpb25zIHRvIGJhc2UgdHlwZXMgZm9yIGNyb3NzIGJyb3dzZXIgZnVsbHNjcmVlbiBmdW5jdGlvbmFsaXR5LlxuICovXG5kZWNsYXJlIGdsb2JhbCB7XG4gICAgaW50ZXJmYWNlIERvY3VtZW50IHtcbiAgICAgICAgd2Via2l0SXNGdWxsU2NyZWVuPzogYm9vbGVhbjtcbiAgICAgICAgbW96RnVsbFNjcmVlbj86IGJvb2xlYW47XG4gICAgICAgIHdlYmtpdEZ1bGxzY3JlZW5FbmFibGVkPzogYm9vbGVhbjtcbiAgICAgICAgbW96Q2FuY2VsRnVsbFNjcmVlbj86ICgpID0+IFByb21pc2U8dm9pZD47XG4gICAgICAgIG1zRXhpdEZ1bGxzY3JlZW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgICAgICB3ZWJraXRFeGl0RnVsbHNjcmVlbj86ICgpID0+IFByb21pc2U8dm9pZD47XG4gICAgICAgIG1vekZ1bGxTY3JlZW5FbGVtZW50PzogRWxlbWVudDtcbiAgICAgICAgbXNGdWxsc2NyZWVuRWxlbWVudD86IEVsZW1lbnQ7XG4gICAgICAgIHdlYmtpdEZ1bGxzY3JlZW5FbGVtZW50PzogRWxlbWVudDtcbiAgICB9XG5cbiAgICBpbnRlcmZhY2UgSFRNTEVsZW1lbnQge1xuICAgICAgICBtc1JlcXVlc3RGdWxsc2NyZWVuPzogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgICAgICAgbW96UmVxdWVzdEZ1bGxzY3JlZW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgICAgICB3ZWJraXRSZXF1ZXN0RnVsbHNjcmVlbj86ICgpID0+IFByb21pc2U8dm9pZD47XG4gICAgICAgIHdlYmtpdEVudGVyRnVsbHNjcmVlbj86ICgpID0+IHZvaWQ7XG4gICAgfVxufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGFuIGVsZW1lbnQgKGkuZS4gYnV0dG9uKSB0aGF0LCB3aGVuIGNsaWNrZWQsIHdpbGwgdG9nZ2xlIGZ1bGxzY3JlZW4gb2YgYSBnaXZlbiBlbGVtZW50LlxuICogQ2FuIGJlIGluaXRpYWxpemVkIHdpdGggYW55IEhUTUxFbGVtZW50LCBpZiBpdCBpcyBzZXQgYXMgcm9vdEVsZW1lbnQgaW4gdGhlIGNvbnN0cnVjdG9yLlxuICovXG5leHBvcnQgY2xhc3MgRnVsbFNjcmVlbkljb25CYXNlIHtcbiAgICBpc0Z1bGxzY3JlZW4gPSBmYWxzZTtcbiAgICBmdWxsc2NyZWVuRWxlbWVudDogSFRNTEVsZW1lbnQgfCBIVE1MVmlkZW9FbGVtZW50O1xuXG4gICAgX3Jvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IHJvb3RFbGVtZW50KGVsZW1lbnQpIHtcbiAgICAgICAgZWxlbWVudC5vbmNsaWNrID0gKCkgPT4gdGhpcy50b2dnbGVGdWxsc2NyZWVuKCk7XG4gICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcigpIHsgICAgICAgXG4gICAgICAgIC8vIHNldCB1cCB0aGUgZnVsbCBzY3JlZW4gZXZlbnRzXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnd2Via2l0ZnVsbHNjcmVlbmNoYW5nZScsXG4gICAgICAgICAgICAoKSA9PiB0aGlzLm9uRnVsbHNjcmVlbkNoYW5nZSgpLFxuICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAgICdtb3pmdWxsc2NyZWVuY2hhbmdlJyxcbiAgICAgICAgICAgICgpID0+IHRoaXMub25GdWxsc2NyZWVuQ2hhbmdlKCksXG4gICAgICAgICAgICBmYWxzZVxuICAgICAgICApO1xuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgJ2Z1bGxzY3JlZW5jaGFuZ2UnLFxuICAgICAgICAgICAgKCkgPT4gdGhpcy5vbkZ1bGxzY3JlZW5DaGFuZ2UoKSxcbiAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICk7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnTVNGdWxsc2NyZWVuQ2hhbmdlJyxcbiAgICAgICAgICAgICgpID0+IHRoaXMub25GdWxsc2NyZWVuQ2hhbmdlKCksXG4gICAgICAgICAgICBmYWxzZVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ha2VzIHRoZSBkb2N1bWVudCBvciBmdWxsc2NyZWVuRWxlbWVudCBmdWxsc2NyZWVuLlxuICAgICAqL1xuICAgIHRvZ2dsZUZ1bGxzY3JlZW4oKSB7XG4gICAgICAgIC8vIGlmIGFscmVhZHkgZnVsbCBzY3JlZW47IGV4aXRcbiAgICAgICAgLy8gZWxzZSBnbyBmdWxsc2NyZWVuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIGRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50IHx8XG4gICAgICAgICAgICBkb2N1bWVudC53ZWJraXRGdWxsc2NyZWVuRWxlbWVudCB8fFxuICAgICAgICAgICAgZG9jdW1lbnQubW96RnVsbFNjcmVlbkVsZW1lbnQgfHxcbiAgICAgICAgICAgIGRvY3VtZW50Lm1zRnVsbHNjcmVlbkVsZW1lbnRcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBpZiAoZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4pIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5leGl0RnVsbHNjcmVlbigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkb2N1bWVudC5tb3pDYW5jZWxGdWxsU2NyZWVuKSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQubW96Q2FuY2VsRnVsbFNjcmVlbigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkb2N1bWVudC53ZWJraXRFeGl0RnVsbHNjcmVlbikge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LndlYmtpdEV4aXRGdWxsc2NyZWVuKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRvY3VtZW50Lm1zRXhpdEZ1bGxzY3JlZW4pIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5tc0V4aXRGdWxsc2NyZWVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5mdWxsc2NyZWVuRWxlbWVudDtcblxuICAgICAgICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGVsZW1lbnQucmVxdWVzdEZ1bGxzY3JlZW4pIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LnJlcXVlc3RGdWxsc2NyZWVuKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnQubW96UmVxdWVzdEZ1bGxzY3JlZW4pIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50Lm1velJlcXVlc3RGdWxsc2NyZWVuKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnQud2Via2l0UmVxdWVzdEZ1bGxzY3JlZW4pIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LndlYmtpdFJlcXVlc3RGdWxsc2NyZWVuKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnQubXNSZXF1ZXN0RnVsbHNjcmVlbikge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQubXNSZXF1ZXN0RnVsbHNjcmVlbigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50LndlYmtpdEVudGVyRnVsbHNjcmVlbikge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQud2Via2l0RW50ZXJGdWxsc2NyZWVuKCk7IC8vZm9yIGlwaG9uZSB0aGlzIGNvZGUgd29ya2VkXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbkZ1bGxzY3JlZW5DaGFuZ2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIHRoZSBmdWxsc2NyZWVuIGJ1dHRvbiBvbiBjaGFuZ2VcbiAgICAgKi9cbiAgICBvbkZ1bGxzY3JlZW5DaGFuZ2UoKSB7XG4gICAgICAgIHRoaXMuaXNGdWxsc2NyZWVuID1cbiAgICAgICAgICAgIGRvY3VtZW50LndlYmtpdElzRnVsbFNjcmVlbiB8fFxuICAgICAgICAgICAgZG9jdW1lbnQubW96RnVsbFNjcmVlbiB8fFxuICAgICAgICAgICAgKGRvY3VtZW50Lm1zRnVsbHNjcmVlbkVsZW1lbnQgJiZcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5tc0Z1bGxzY3JlZW5FbGVtZW50ICE9PSBudWxsKSB8fFxuICAgICAgICAgICAgKGRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50ICYmIGRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50ICE9PSBudWxsKTtcbiAgICB9XG59XG5cbi8qKlxuICogQW4gaW1wbGVtZW50YXRpb24gb2YgRnVsbFNjcmVlbkljb25CYXNlIHRoYXQgdXNlcyBhbiBleHRlcm5hbGx5XG4gKiBwcm92aWRlZCBIVE1MRWxlbWVudCBmb3IgdG9nZ2xpbmcgZnVsbCBzY3JlZW4uXG4gKi9cbmV4cG9ydCBjbGFzcyBGdWxsU2NyZWVuSWNvbkV4dGVybmFsIGV4dGVuZHMgRnVsbFNjcmVlbkljb25CYXNlIHtcblxuICAgIGNvbnN0cnVjdG9yKGV4dGVybmFsQnV0dG9uIDogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5yb290RWxlbWVudCA9IGV4dGVybmFsQnV0dG9uO1xuICAgIH1cblxufVxuXG4vKipcbiAqIFRoZSBkZWZhdWx0IGZ1bGxzY3JlZW4gaWNvbiB0aGF0IGNvbnRhaW5zIGEgYnV0dG9uIGFuZCBzdmdzIGZvciBlYWNoIHN0YXRlLlxuICovXG5leHBvcnQgY2xhc3MgRnVsbFNjcmVlbkljb24gZXh0ZW5kcyBGdWxsU2NyZWVuSWNvbkJhc2Uge1xuICAgIF9tYXhpbWl6ZUljb246IFNWR0VsZW1lbnQ7XG4gICAgX21pbmltaXplSWNvbjogU1ZHRWxlbWVudDtcbiAgICBfdG9vbHRpcFRleHQ6IEhUTUxFbGVtZW50O1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBjcmVhdGVkQnV0dG9uIDogSFRNTEJ1dHRvbkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICAgICAgY3JlYXRlZEJ1dHRvbi50eXBlID0gJ2J1dHRvbic7XG4gICAgICAgIGNyZWF0ZWRCdXR0b24uY2xhc3NMaXN0LmFkZCgnVWlUb29sJyk7XG4gICAgICAgIGNyZWF0ZWRCdXR0b24uaWQgPSAnZnVsbHNjcmVlbi1idG4nO1xuICAgICAgICBjcmVhdGVkQnV0dG9uLmFwcGVuZENoaWxkKHRoaXMubWF4aW1pemVJY29uKTtcbiAgICAgICAgY3JlYXRlZEJ1dHRvbi5hcHBlbmRDaGlsZCh0aGlzLm1pbmltaXplSWNvbik7XG4gICAgICAgIGNyZWF0ZWRCdXR0b24uYXBwZW5kQ2hpbGQodGhpcy50b29sdGlwVGV4dCk7XG5cbiAgICAgICAgdGhpcy5yb290RWxlbWVudCA9IGNyZWF0ZWRCdXR0b247XG4gICAgfVxuXG4gICAgcHVibGljIGdldCB0b29sdGlwVGV4dCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fdG9vbHRpcFRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcFRleHQuY2xhc3NMaXN0LmFkZCgndG9vbHRpcHRleHQnKTtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0LmlubmVySFRNTCA9ICdGdWxsc2NyZWVuJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fdG9vbHRpcFRleHQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBtYXhpbWl6ZUljb24oKTogU1ZHRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fbWF4aW1pemVJY29uKSB7XG4gICAgICAgICAgICB0aGlzLl9tYXhpbWl6ZUljb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAnc3ZnJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX21heGltaXplSWNvbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnaWQnLCAnbWF4aW1pemVJY29uJyk7XG4gICAgICAgICAgICB0aGlzLl9tYXhpbWl6ZUljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ3gnLCAnMHB4Jyk7XG4gICAgICAgICAgICB0aGlzLl9tYXhpbWl6ZUljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ3knLCAnMHB4Jyk7XG4gICAgICAgICAgICB0aGlzLl9tYXhpbWl6ZUljb24uc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAndmlld0JveCcsXG4gICAgICAgICAgICAgICAgJzAgMCAzODQuOTcgMzg0Ljk3J1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIHN2ZyBncm91cCBmb3IgdGhlIHBhdGhzXG4gICAgICAgICAgICBjb25zdCBzdmdHcm91cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdnJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmNsYXNzTGlzdC5hZGQoJ3N2Z0ljb24nKTtcbiAgICAgICAgICAgIHRoaXMuX21heGltaXplSWNvbi5hcHBlbmRDaGlsZChzdmdHcm91cCk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBwYXRocyBmb3IgdGhlIGljb24gaXRzZWxmLCBvbmUgZm9yIGVhY2ggY29ybmVyXG4gICAgICAgICAgICBjb25zdCBwYXRoMSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgxLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMzg0Ljk3LDEyLjAzYzAtNi43MTMtNS4zMTctMTIuMDMtMTIuMDMtMTIuMDNIMjY0Ljg0N2MtNi44MzMsMC0xMS45MjIsNS4zOS0xMS45MzQsMTIuMjIzYzAsNi44MjEsNS4xMDEsMTEuODM4LDExLjkzNCwxMS44MzhoOTYuMDYybC0wLjE5Myw5Ni41MTljMCw2LjgzMyw1LjE5NywxMi4wMywxMi4wMywxMi4wM2M2LjgzMy0wLjAxMiwxMi4wMy01LjE5NywxMi4wMy0xMi4wM2wwLjE5My0xMDguMzY5YzAtMC4wMzYtMC4wMTItMC4wNi0wLjAxMi0wLjA4NEMzODQuOTU4LDEyLjA5LDM4NC45NywxMi4wNjYsMzg0Ljk3LDEyLjAzeidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhdGgyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3BhdGgnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcGF0aDIuc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAnZCcsXG4gICAgICAgICAgICAgICAgJ00xMjAuNDk2LDBIMTIuNDAzYy0wLjAzNiwwLTAuMDYsMC4wMTItMC4wOTYsMC4wMTJDMTIuMjgzLDAuMDEyLDEyLjI0NywwLDEyLjIyMywwQzUuNTEsMCwwLjE5Miw1LjMxNywwLjE5MiwxMi4wM0wwLDEyMC4zOTljMCw2LjgzMyw1LjM5LDExLjkzNCwxMi4yMjMsMTEuOTM0YzYuODIxLDAsMTEuODM4LTUuMTAxLDExLjgzOC0xMS45MzRsMC4xOTItOTYuMzM5aDk2LjI0MmM2LjgzMywwLDEyLjAzLTUuMTk3LDEyLjAzLTEyLjAzQzEzMi41MTQsNS4xOTcsMTI3LjMxNywwLDEyMC40OTYsMHonXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBwYXRoMyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgzLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMTIwLjEyMywzNjAuOTA5SDI0LjA2MXYtOTYuMjQyYzAtNi44MzMtNS4xOTctMTIuMDMtMTIuMDMtMTIuMDNTMCwyNTcuODMzLDAsMjY0LjY2N3YxMDguMDkyYzAsMC4wMzYsMC4wMTIsMC4wNiwwLjAxMiwwLjA4NGMwLDAuMDM2LTAuMDEyLDAuMDYtMC4wMTIsMC4wOTZjMCw2LjcxMyw1LjMxNywxMi4wMywxMi4wMywxMi4wM2gxMDguMDkyYzYuODMzLDAsMTEuOTIyLTUuMzksMTEuOTM0LTEyLjIyM0MxMzIuMDU3LDM2NS45MjYsMTI2Ljk1NiwzNjAuOTA5LDEyMC4xMjMsMzYwLjkwOXonXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBwYXRoNCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGg0LnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMzcyLjc0NywyNTIuOTEzYy02LjgzMywwLTExLjg1LDUuMTAxLTExLjgzOCwxMS45MzR2OTYuMDYyaC05Ni4yNDJjLTYuODMzLDAtMTIuMDMsNS4xOTctMTIuMDMsMTIuMDNzNS4xOTcsMTIuMDMsMTIuMDMsMTIuMDNoMTA4LjA5MmMwLjAzNiwwLDAuMDYtMC4wMTIsMC4wODQtMC4wMTJjMC4wMzYtMC4wMTIsMC4wNiwwLjAxMiwwLjA5NiwwLjAxMmM2LjcxMywwLDEyLjAzLTUuMzE3LDEyLjAzLTEyLjAzVjI2NC44NDdDMzg0Ljk3LDI1OC4wMTQsMzc5LjU4LDI1Mi45MTMsMzcyLjc0NywyNTIuOTEzeidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgxKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgyKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgzKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGg0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbWF4aW1pemVJY29uO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgbWluaW1pemVJY29uKCk6IFNWR0VsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX21pbmltaXplSWNvbikge1xuICAgICAgICAgICAgdGhpcy5fbWluaW1pemVJY29uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3N2ZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLl9taW5pbWl6ZUljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ2lkJywgJ21pbmltaXplSWNvbicpO1xuICAgICAgICAgICAgdGhpcy5fbWluaW1pemVJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd4JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5fbWluaW1pemVJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd5JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5fbWluaW1pemVJY29uLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ3ZpZXdCb3gnLFxuICAgICAgICAgICAgICAgICcwIDAgMzg1LjMzMSAzODUuMzMxJ1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIHN2ZyBncm91cCBmb3IgdGhlIHBhdGhzXG4gICAgICAgICAgICBjb25zdCBzdmdHcm91cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdnJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmNsYXNzTGlzdC5hZGQoJ3N2Z0ljb24nKTtcbiAgICAgICAgICAgIHRoaXMuX21pbmltaXplSWNvbi5hcHBlbmRDaGlsZChzdmdHcm91cCk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBwYXRocyBmb3IgdGhlIGljb24gaXRzZWxmLCBvbmUgZm9yIGVhY2ggY29ybmVyXG4gICAgICAgICAgICBjb25zdCBwYXRoMSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgxLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMjY0Ljk0MywxNTYuNjY1aDEwOC4yNzNjNi44MzMsMCwxMS45MzQtNS4zOSwxMS45MzQtMTIuMjExYzAtNi44MzMtNS4xMDEtMTEuODUtMTEuOTM0LTExLjgzOGgtOTYuMjQyVjM2LjE4MWMwLTYuODMzLTUuMTk3LTEyLjAzLTEyLjAzLTEyLjAzcy0xMi4wMyw1LjE5Ny0xMi4wMywxMi4wM3YxMDguMjczYzAsMC4wMzYsMC4wMTIsMC4wNiwwLjAxMiwwLjA4NGMwLDAuMDM2LTAuMDEyLDAuMDYtMC4wMTIsMC4wOTZDMjUyLjkxMywxNTEuMzQ3LDI1OC4yMywxNTYuNjc3LDI2NC45NDMsMTU2LjY2NXonXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBwYXRoMiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgyLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMTIwLjI5MSwyNC4yNDdjLTYuODIxLDAtMTEuODM4LDUuMTEzLTExLjgzOCwxMS45MzR2OTYuMjQySDEyLjAzYy02LjgzMywwLTEyLjAzLDUuMTk3LTEyLjAzLDEyLjAzYzAsNi44MzMsNS4xOTcsMTIuMDMsMTIuMDMsMTIuMDNoMTA4LjI3M2MwLjAzNiwwLDAuMDYtMC4wMTIsMC4wODQtMC4wMTJjMC4wMzYsMCwwLjA2LDAuMDEyLDAuMDk2LDAuMDEyYzYuNzEzLDAsMTIuMDMtNS4zMTcsMTIuMDMtMTIuMDNWMzYuMTgxQzEzMi41MTQsMjkuMzYsMTI3LjEyNCwyNC4yNTksMTIwLjI5MSwyNC4yNDd6J1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29uc3QgcGF0aDMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoMy5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTEyMC4zODcsMjI4LjY2NkgxMi4xMTVjLTYuODMzLDAuMDEyLTExLjkzNCw1LjM5LTExLjkzNCwxMi4yMjNjMCw2LjgzMyw1LjEwMSwxMS44NSwxMS45MzQsMTEuODM4aDk2LjI0MnY5Ni40MjNjMCw2LjgzMyw1LjE5NywxMi4wMywxMi4wMywxMi4wM2M2LjgzMywwLDEyLjAzLTUuMTk3LDEyLjAzLTEyLjAzVjI0MC44NzdjMC0wLjAzNi0wLjAxMi0wLjA2LTAuMDEyLTAuMDg0YzAtMC4wMzYsMC4wMTItMC4wNiwwLjAxMi0wLjA5NkMxMzIuNDE4LDIzMy45ODMsMTI3LjEsMjI4LjY2NiwxMjAuMzg3LDIyOC42NjZ6J1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29uc3QgcGF0aDQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwYXRoNC5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTM3My4zLDIyOC42NjZIMjY1LjAyOGMtMC4wMzYsMC0wLjA2LDAuMDEyLTAuMDg0LDAuMDEyYy0wLjAzNiwwLTAuMDYtMC4wMTItMC4wOTYtMC4wMTJjLTYuNzEzLDAtMTIuMDMsNS4zMTctMTIuMDMsMTIuMDN2MTA4LjI3M2MwLDYuODMzLDUuMzksMTEuOTIyLDEyLjIyMywxMS45MzRjNi44MjEsMC4wMTIsMTEuODM4LTUuMTAxLDExLjgzOC0xMS45MjJ2LTk2LjI0MkgzNzMuM2M2LjgzMywwLDEyLjAzLTUuMTk3LDEyLjAzLTEyLjAzUzM4MC4xMzQsMjI4LjY3OCwzNzMuMywyMjguNjY2eidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgxKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgyKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgzKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGg0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbWluaW1pemVJY29uO1xuICAgIH1cblxuICAgIG9uRnVsbHNjcmVlbkNoYW5nZSgpIHtcbiAgICAgICAgc3VwZXIub25GdWxsc2NyZWVuQ2hhbmdlKCk7XG5cbiAgICAgICAgY29uc3QgbWluaW1pemUgPSB0aGlzLm1pbmltaXplSWNvbjtcbiAgICAgICAgY29uc3QgbWF4aW1pemUgPSB0aGlzLm1heGltaXplSWNvbjtcblxuICAgICAgICBpZiAodGhpcy5pc0Z1bGxzY3JlZW4pIHtcbiAgICAgICAgICAgIG1pbmltaXplLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lJztcbiAgICAgICAgICAgIC8vaW9zIGRpc2FwcGVhcmluZyBzdmcgZml4XG4gICAgICAgICAgICBtaW5pbWl6ZS5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlKDAsIDApJztcbiAgICAgICAgICAgIG1heGltaXplLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtaW5pbWl6ZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgbWF4aW1pemUuc3R5bGUuZGlzcGxheSA9ICdpbmxpbmUnO1xuICAgICAgICAgICAgLy9pb3MgZGlzYXBwZWFyaW5nIHN2ZyBmaXhcbiAgICAgICAgICAgIG1heGltaXplLnN0eWxlLnRyYW5zZm9ybSA9ICd0cmFuc2xhdGUoMCwgMCknO1xuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG4vKipcbiAqIEEgYnV0dG9uIHdpdGggYSB0ZXh0IGxhYmVsIGJlc2lkZSBpdC5cbiAqL1xuZXhwb3J0IGNsYXNzIExhYmVsbGVkQnV0dG9uIHtcbiAgICBfbGFiZWw6IHN0cmluZztcbiAgICBfYnV0dG9uVGV4dDogc3RyaW5nO1xuICAgIF9yb290RWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgX2J1dHRvbjogSFRNTElucHV0RWxlbWVudDtcblxuICAgIGNvbnN0cnVjdG9yKGxhYmVsOiBzdHJpbmcsIGJ1dHRvblRleHQ6IHN0cmluZykge1xuICAgICAgICB0aGlzLl9sYWJlbCA9IGxhYmVsO1xuICAgICAgICB0aGlzLl9idXR0b25UZXh0ID0gYnV0dG9uVGV4dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBjbGljayBsaXN0ZW5lciB0byB0aGUgYnV0dG9uIGVsZW1lbnQuXG4gICAgICovXG4gICAgcHVibGljIGFkZE9uQ2xpY2tMaXN0ZW5lcihvbkNsaWNrRnVuYzogKCkgPT4gdm9pZCkge1xuICAgICAgICB0aGlzLmJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIG9uQ2xpY2tGdW5jKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIEhUTUxJbnB1dEVsZW1lbnQgZm9yIHRoZSBidXR0b24uXG4gICAgICovXG4gICAgcHVibGljIGdldCBidXR0b24oKTogSFRNTElucHV0RWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fYnV0dG9uKSB7XG4gICAgICAgICAgICB0aGlzLl9idXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICAgICAgdGhpcy5fYnV0dG9uLnR5cGUgPSAnYnV0dG9uJztcbiAgICAgICAgICAgIHRoaXMuX2J1dHRvbi52YWx1ZSA9IHRoaXMuX2J1dHRvblRleHQ7XG4gICAgICAgICAgICB0aGlzLl9idXR0b24uY2xhc3NMaXN0LmFkZCgnb3ZlcmxheS1idXR0b24nKTtcbiAgICAgICAgICAgIHRoaXMuX2J1dHRvbi5jbGFzc0xpc3QuYWRkKCdidG4tZmxhdCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9idXR0b247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgUmV0dXJuIG9yIGNyZWF0ZXMgYSBIVE1MIGVsZW1lbnQgdGhhdCByZXByZXNlbnRzIHRoaXMgc2V0dGluZyBpbiB0aGUgRE9NLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgcm9vdCBkaXYgd2l0aCBcInNldHRpbmdcIiBjc3MgY2xhc3NcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nJyk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBkaXYgZWxlbWVudCB0byBjb250YWluIG91ciBzZXR0aW5nJ3MgdGV4dFxuICAgICAgICAgICAgY29uc3Qgc2V0dGluZ3NUZXh0RWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgc2V0dGluZ3NUZXh0RWxlbS5pbm5lclRleHQgPSB0aGlzLl9sYWJlbDtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHNldHRpbmdzVGV4dEVsZW0pO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgbGFiZWwgZWxlbWVudCB0byB3cmFwIG91dCBpbnB1dCB0eXBlXG4gICAgICAgICAgICBjb25zdCB3cmFwcGVyTGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuICAgICAgICAgICAgd3JhcHBlckxhYmVsLmNsYXNzTGlzdC5hZGQoJ2J0bi1vdmVybGF5Jyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh3cmFwcGVyTGFiZWwpO1xuXG4gICAgICAgICAgICB3cmFwcGVyTGFiZWwuYXBwZW5kQ2hpbGQodGhpcy5idXR0b24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5pbXBvcnQgeyBMYXRlbmN5VGVzdFJlc3VsdHMgfSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gJ0BlcGljZ2FtZXMtcHMvbGliLXBpeGVsc3RyZWFtaW5nZnJvbnRlbmQtdWU1LjMnO1xuXG4vKipcbiAqIExhdGVuY3kgdGVzdCBVSSBlbGVtZW50cyBhbmQgcmVzdWx0cyBoYW5kbGluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIExhdGVuY3lUZXN0IHtcbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIF9sYXRlbmN5VGVzdEJ1dHRvbjogSFRNTElucHV0RWxlbWVudDtcbiAgICBfbGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRoZSBidXR0b24gY29udGFpbmluZyB0aGUgc3RhdHMgaWNvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzZWN0aW9uJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nc0NvbnRhaW5lcicpO1xuXG4gICAgICAgICAgICAvLyBtYWtlIGhlYWRpbmdcbiAgICAgICAgICAgIGNvbnN0IGhlYWRpbmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGhlYWRpbmcuaWQgPSAnbGF0ZW5jeVRlc3RIZWFkZXInO1xuICAgICAgICAgICAgaGVhZGluZy5jbGFzc0xpc3QuYWRkKCdzZXR0aW5ncy10ZXh0Jyk7XG4gICAgICAgICAgICBoZWFkaW5nLmNsYXNzTGlzdC5hZGQoJ3NldHRpbmdzSGVhZGVyJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZChoZWFkaW5nKTtcblxuICAgICAgICAgICAgY29uc3QgaGVhZGluZ1RleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGhlYWRpbmdUZXh0LmlubmVySFRNTCA9ICdMYXRlbmN5IFRlc3QnO1xuICAgICAgICAgICAgaGVhZGluZy5hcHBlbmRDaGlsZChoZWFkaW5nVGV4dCk7XG4gICAgICAgICAgICBoZWFkaW5nLmFwcGVuZENoaWxkKHRoaXMubGF0ZW5jeVRlc3RCdXR0b24pO1xuXG4gICAgICAgICAgICAvLyBtYWtlIHRlc3QgcmVzdWx0cyBlbGVtZW50XG4gICAgICAgICAgICBjb25zdCByZXN1bHRzUGFyZW50RWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgcmVzdWx0c1BhcmVudEVsZW0uaWQgPSAnbGF0ZW5jeVRlc3RDb250YWluZXInO1xuICAgICAgICAgICAgcmVzdWx0c1BhcmVudEVsZW0uY2xhc3NMaXN0LmFkZCgnZC1ub25lJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZChyZXN1bHRzUGFyZW50RWxlbSk7XG5cbiAgICAgICAgICAgIHJlc3VsdHNQYXJlbnRFbGVtLmFwcGVuZENoaWxkKHRoaXMubGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgbGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fbGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudC5pZCA9ICdsYXRlbmN5U3RhdHNSZXN1bHRzJztcbiAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQuY2xhc3NMaXN0LmFkZCgnU3RhdHNSZXN1bHQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbGF0ZW5jeVRlc3RSZXN1bHRzRWxlbWVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGxhdGVuY3lUZXN0QnV0dG9uKCk6IEhUTUxJbnB1dEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX2xhdGVuY3lUZXN0QnV0dG9uKSB7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbi50eXBlID0gJ2J1dHRvbic7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbi52YWx1ZSA9ICdSdW4gVGVzdCc7XG4gICAgICAgICAgICB0aGlzLl9sYXRlbmN5VGVzdEJ1dHRvbi5pZCA9ICdidG4tc3RhcnQtbGF0ZW5jeS10ZXN0JztcbiAgICAgICAgICAgIHRoaXMuX2xhdGVuY3lUZXN0QnV0dG9uLmNsYXNzTGlzdC5hZGQoJ3N0cmVhbVRvb2xzLWJ1dHRvbicpO1xuICAgICAgICAgICAgdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b24uY2xhc3NMaXN0LmFkZCgnYnRuLWZsYXQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbGF0ZW5jeVRlc3RCdXR0b247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUG9wdWxhdGUgdGhlIFVJIGJhc2VkIG9uIHRoZSBsYXRlbmN5IHRlc3QncyByZXN1bHRzLlxuICAgICAqIEBwYXJhbSBsYXRlbmN5VGltaW5ncyBUaGUgbGF0ZW5jeSB0ZXN0IHJlc3VsdHMuXG4gICAgICovXG4gICAgcHVibGljIGhhbmRsZVRlc3RSZXN1bHQobGF0ZW5jeVRpbWluZ3M6IExhdGVuY3lUZXN0UmVzdWx0cykge1xuICAgICAgICBMb2dnZXIuTG9nKExvZ2dlci5HZXRTdGFja1RyYWNlKCksIGxhdGVuY3lUaW1pbmdzLnRvU3RyaW5nKCksIDYpO1xuICAgICAgICBsZXQgbGF0ZW5jeVN0YXRzSW5uZXJIVE1MID0gJyc7XG4gICAgICAgIGxhdGVuY3lTdGF0c0lubmVySFRNTCArPVxuICAgICAgICAgICAgJzxkaXY+TmV0IGxhdGVuY3kgUlRUIChtcyk6ICcgK1xuICAgICAgICAgICAgbGF0ZW5jeVRpbWluZ3MubmV0d29ya0xhdGVuY3kgK1xuICAgICAgICAgICAgJzwvZGl2Pic7XG4gICAgICAgIGxhdGVuY3lTdGF0c0lubmVySFRNTCArPVxuICAgICAgICAgICAgJzxkaXY+VUUgRW5jb2RlIChtcyk6ICcgKyBsYXRlbmN5VGltaW5ncy5FbmNvZGVNcyArICc8L2Rpdj4nO1xuICAgICAgICBsYXRlbmN5U3RhdHNJbm5lckhUTUwgKz1cbiAgICAgICAgICAgICc8ZGl2PlVFIENhcHR1cmUgKG1zKTogJyArXG4gICAgICAgICAgICBsYXRlbmN5VGltaW5ncy5DYXB0dXJlVG9TZW5kTXMgK1xuICAgICAgICAgICAgJzwvZGl2Pic7XG4gICAgICAgIGxhdGVuY3lTdGF0c0lubmVySFRNTCArPVxuICAgICAgICAgICAgJzxkaXY+QnJvd3NlciBzZW5kIGxhdGVuY3kgKG1zKTogJyArXG4gICAgICAgICAgICBsYXRlbmN5VGltaW5ncy5icm93c2VyU2VuZExhdGVuY3kgK1xuICAgICAgICAgICAgJzwvZGl2Pic7XG4gICAgICAgIGxhdGVuY3lTdGF0c0lubmVySFRNTCArPVxuICAgICAgICAgICAgbGF0ZW5jeVRpbWluZ3MuZnJhbWVEaXNwbGF5RGVsdGFUaW1lTXMgJiZcbiAgICAgICAgICAgIGxhdGVuY3lUaW1pbmdzLmJyb3dzZXJSZWNlaXB0VGltZU1zXG4gICAgICAgICAgICAgICAgPyAnPGRpdj5Ccm93c2VyIHJlY2VpdmUgbGF0ZW5jeSAobXMpOiAnICtcbiAgICAgICAgICAgICAgICAgIGxhdGVuY3lUaW1pbmdzLmZyYW1lRGlzcGxheURlbHRhVGltZU1zICtcbiAgICAgICAgICAgICAgICAgICc8L2Rpdj4nXG4gICAgICAgICAgICAgICAgOiAnJztcbiAgICAgICAgbGF0ZW5jeVN0YXRzSW5uZXJIVE1MICs9XG4gICAgICAgICAgICAnPGRpdj5Ub3RhbCBsYXRlbmN5IChleGNsdWRpbmcgYnJvd3NlcikgKG1zKTogJyArXG4gICAgICAgICAgICBsYXRlbmN5VGltaW5ncy5sYXRlbmN5RXhjbHVkaW5nRGVjb2RlICtcbiAgICAgICAgICAgICc8L2Rpdj4nO1xuICAgICAgICBsYXRlbmN5U3RhdHNJbm5lckhUTUwgKz0gbGF0ZW5jeVRpbWluZ3MuZW5kVG9FbmRMYXRlbmN5XG4gICAgICAgICAgICA/ICc8ZGl2PlRvdGFsIGxhdGVuY3kgKG1zKTogJyArXG4gICAgICAgICAgICAgIGxhdGVuY3lUaW1pbmdzLmVuZFRvRW5kTGF0ZW5jeSArXG4gICAgICAgICAgICAgICc8L2Rpdj4nXG4gICAgICAgICAgICA6ICcnO1xuICAgICAgICB0aGlzLmxhdGVuY3lUZXN0UmVzdWx0c0VsZW1lbnQuaW5uZXJIVE1MID0gbGF0ZW5jeVN0YXRzSW5uZXJIVE1MO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbi8qKlxuICogU2V0dGluZ3MgaWNvbiB0aGF0IGNhbiBiZSBjbGlja2VkLlxuICovXG5leHBvcnQgY2xhc3MgU2V0dGluZ3NJY29uIHtcbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxCdXR0b25FbGVtZW50O1xuICAgIF9zZXR0aW5nc0ljb246IFNWR0VsZW1lbnQ7XG4gICAgX3Rvb2x0aXBUZXh0OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGhlIGJ1dHRvbiBjb250YWluaW5nIHRoZSBzZXR0aW5ncyBpY29uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEJ1dHRvbkVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQudHlwZSA9ICdidXR0b24nO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnVWlUb29sJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5pZCA9ICdzZXR0aW5nc0J0bic7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnNldHRpbmdzSWNvbik7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnRvb2x0aXBUZXh0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCB0b29sdGlwVGV4dCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fdG9vbHRpcFRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcFRleHQuY2xhc3NMaXN0LmFkZCgndG9vbHRpcHRleHQnKTtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0LmlubmVySFRNTCA9ICdTZXR0aW5ncyc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rvb2x0aXBUZXh0O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgc2V0dGluZ3NJY29uKCk6IFNWR0VsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3NldHRpbmdzSWNvbikge1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NJY29uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3N2ZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc0ljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ2lkJywgJ3NldHRpbmdzSWNvbicpO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd4JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd5JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3NJY29uLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ3ZpZXdCb3gnLFxuICAgICAgICAgICAgICAgICcwIDAgNDc4LjcwMyA0NzguNzAzJ1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIHN2ZyBncm91cCBmb3IgdGhlIHBhdGhzXG4gICAgICAgICAgICBjb25zdCBzdmdHcm91cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdnJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmNsYXNzTGlzdC5hZGQoJ3N2Z0ljb24nKTtcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzSWNvbi5hcHBlbmRDaGlsZChzdmdHcm91cCk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBwYXRocyBmb3IgdGhlIGljb24gaXRzZWxmLCB0aGUgaW5uZXIgYW5kIG91dCBwYXRoIG9mIGEgY29nXG4gICAgICAgICAgICBjb25zdCBwYXRoMSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgxLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNNDU0LjIsMTg5LjEwMWwtMzMuNi01LjdjLTMuNS0xMS4zLTgtMjIuMi0xMy41LTMyLjZsMTkuOC0yNy43YzguNC0xMS44LDcuMS0yNy45LTMuMi0zOC4xbC0yOS44LTI5LjhcXFxuXHRcdFx0Yy01LjYtNS42LTEzLTguNy0yMC45LTguN2MtNi4yLDAtMTIuMSwxLjktMTcuMSw1LjVsLTI3LjgsMTkuOGMtMTAuOC01LjctMjIuMS0xMC40LTMzLjgtMTMuOWwtNS42LTMzLjJcXFxuXHRcdFx0Yy0yLjQtMTQuMy0xNC43LTI0LjctMjkuMi0yNC43aC00Mi4xYy0xNC41LDAtMjYuOCwxMC40LTI5LjIsMjQuN2wtNS44LDM0Yy0xMS4yLDMuNS0yMi4xLDguMS0zMi41LDEzLjdsLTI3LjUtMTkuOFxcXG5cdFx0XHRjLTUtMy42LTExLTUuNS0xNy4yLTUuNWMtNy45LDAtMTUuNCwzLjEtMjAuOSw4LjdsLTI5LjksMjkuOGMtMTAuMiwxMC4yLTExLjYsMjYuMy0zLjIsMzguMWwyMCwyOC4xXFxcblx0XHRcdGMtNS41LDEwLjUtOS45LDIxLjQtMTMuMywzMi43bC0zMy4yLDUuNmMtMTQuMywyLjQtMjQuNywxNC43LTI0LjcsMjkuMnY0Mi4xYzAsMTQuNSwxMC40LDI2LjgsMjQuNywyOS4ybDM0LDUuOFxcXG5cdFx0XHRjMy41LDExLjIsOC4xLDIyLjEsMTMuNywzMi41bC0xOS43LDI3LjRjLTguNCwxMS44LTcuMSwyNy45LDMuMiwzOC4xbDI5LjgsMjkuOGM1LjYsNS42LDEzLDguNywyMC45LDguN2M2LjIsMCwxMi4xLTEuOSwxNy4xLTUuNVxcXG5cdFx0XHRsMjguMS0yMGMxMC4xLDUuMywyMC43LDkuNiwzMS42LDEzbDUuNiwzMy42YzIuNCwxNC4zLDE0LjcsMjQuNywyOS4yLDI0LjdoNDIuMmMxNC41LDAsMjYuOC0xMC40LDI5LjItMjQuN2w1LjctMzMuNlxcXG5cdFx0XHRjMTEuMy0zLjUsMjIuMi04LDMyLjYtMTMuNWwyNy43LDE5LjhjNSwzLjYsMTEsNS41LDE3LjIsNS41bDAsMGM3LjksMCwxNS4zLTMuMSwyMC45LTguN2wyOS44LTI5LjhjMTAuMi0xMC4yLDExLjYtMjYuMywzLjItMzguMVxcXG5cdFx0XHRsLTE5LjgtMjcuOGM1LjUtMTAuNSwxMC4xLTIxLjQsMTMuNS0zMi42bDMzLjYtNS42YzE0LjMtMi40LDI0LjctMTQuNywyNC43LTI5LjJ2LTQyLjFcXFxuXHRcdFx0QzQ3OC45LDIwMy44MDEsNDY4LjUsMTkxLjUwMSw0NTQuMiwxODkuMTAxeiBNNDUxLjksMjYwLjQwMWMwLDEuMy0wLjksMi40LTIuMiwyLjZsLTQyLDdjLTUuMywwLjktOS41LDQuOC0xMC44LDkuOVxcXG5cdFx0XHRjLTMuOCwxNC43LTkuNiwyOC44LTE3LjQsNDEuOWMtMi43LDQuNi0yLjUsMTAuMywwLjYsMTQuN2wyNC43LDM0LjhjMC43LDEsMC42LDIuNS0wLjMsMy40bC0yOS44LDI5LjhjLTAuNywwLjctMS40LDAuOC0xLjksMC44XFxcblx0XHRcdGMtMC42LDAtMS4xLTAuMi0xLjUtMC41bC0zNC43LTI0LjdjLTQuMy0zLjEtMTAuMS0zLjMtMTQuNy0wLjZjLTEzLjEsNy44LTI3LjIsMTMuNi00MS45LDE3LjRjLTUuMiwxLjMtOS4xLDUuNi05LjksMTAuOGwtNy4xLDQyXFxcblx0XHRcdGMtMC4yLDEuMy0xLjMsMi4yLTIuNiwyLjJoLTQyLjFjLTEuMywwLTIuNC0wLjktMi42LTIuMmwtNy00MmMtMC45LTUuMy00LjgtOS41LTkuOS0xMC44Yy0xNC4zLTMuNy0yOC4xLTkuNC00MS0xNi44XFxcblx0XHRcdGMtMi4xLTEuMi00LjUtMS44LTYuOC0xLjhjLTIuNywwLTUuNSwwLjgtNy44LDIuNWwtMzUsMjQuOWMtMC41LDAuMy0xLDAuNS0xLjUsMC41Yy0wLjQsMC0xLjItMC4xLTEuOS0wLjhsLTI5LjgtMjkuOFxcXG5cdFx0XHRjLTAuOS0wLjktMS0yLjMtMC4zLTMuNGwyNC42LTM0LjVjMy4xLTQuNCwzLjMtMTAuMiwwLjYtMTQuOGMtNy44LTEzLTEzLjgtMjcuMS0xNy42LTQxLjhjLTEuNC01LjEtNS42LTktMTAuOC05LjlsLTQyLjMtNy4yXFxcblx0XHRcdGMtMS4zLTAuMi0yLjItMS4zLTIuMi0yLjZ2LTQyLjFjMC0xLjMsMC45LTIuNCwyLjItMi42bDQxLjctN2M1LjMtMC45LDkuNi00LjgsMTAuOS0xMGMzLjctMTQuNyw5LjQtMjguOSwxNy4xLTQyXFxcblx0XHRcdGMyLjctNC42LDIuNC0xMC4zLTAuNy0xNC42bC0yNC45LTM1Yy0wLjctMS0wLjYtMi41LDAuMy0zLjRsMjkuOC0yOS44YzAuNy0wLjcsMS40LTAuOCwxLjktMC44YzAuNiwwLDEuMSwwLjIsMS41LDAuNWwzNC41LDI0LjZcXFxuXHRcdFx0YzQuNCwzLjEsMTAuMiwzLjMsMTQuOCwwLjZjMTMtNy44LDI3LjEtMTMuOCw0MS44LTE3LjZjNS4xLTEuNCw5LTUuNiw5LjktMTAuOGw3LjItNDIuM2MwLjItMS4zLDEuMy0yLjIsMi42LTIuMmg0Mi4xXFxcblx0XHRcdGMxLjMsMCwyLjQsMC45LDIuNiwyLjJsNyw0MS43YzAuOSw1LjMsNC44LDkuNiwxMCwxMC45YzE1LjEsMy44LDI5LjUsOS43LDQyLjksMTcuNmM0LjYsMi43LDEwLjMsMi41LDE0LjctMC42bDM0LjUtMjQuOFxcXG5cdFx0XHRjMC41LTAuMywxLTAuNSwxLjUtMC41YzAuNCwwLDEuMiwwLjEsMS45LDAuOGwyOS44LDI5LjhjMC45LDAuOSwxLDIuMywwLjMsMy40bC0yNC43LDM0LjdjLTMuMSw0LjMtMy4zLDEwLjEtMC42LDE0LjdcXFxuXHRcdFx0YzcuOCwxMy4xLDEzLjYsMjcuMiwxNy40LDQxLjljMS4zLDUuMiw1LjYsOS4xLDEwLjgsOS45bDQyLDcuMWMxLjMsMC4yLDIuMiwxLjMsMi4yLDIuNnY0Mi4xSDQ1MS45eidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhdGgyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3BhdGgnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcGF0aDIuc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAnZCcsXG4gICAgICAgICAgICAgICAgJ00yMzkuNCwxMzYuMDAxYy01NywwLTEwMy4zLDQ2LjMtMTAzLjMsMTAzLjNzNDYuMywxMDMuMywxMDMuMywxMDMuM3MxMDMuMy00Ni4zLDEwMy4zLTEwMy4zUzI5Ni40LDEzNi4wMDEsMjM5LjQsMTM2LjAwMXogTTIzOS40LDMxNS42MDFjLTQyLjEsMC03Ni4zLTM0LjItNzYuMy03Ni4zczM0LjItNzYuMyw3Ni4zLTc2LjNzNzYuMywzNC4yLDc2LjMsNzYuM1MyODEuNSwzMTUuNjAxLDIzOS40LDMxNS42MDF6J1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgc3ZnR3JvdXAuYXBwZW5kQ2hpbGQocGF0aDEpO1xuICAgICAgICAgICAgc3ZnR3JvdXAuYXBwZW5kQ2hpbGQocGF0aDIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXR0aW5nc0ljb247XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuLyoqXG4gKiBBIFVJIGNvbXBvbmVudCBjb250YWluaW5nIGFsbCB0aGUgc2V0dGluZ3MgZm9yIHRoZSBhcHBsaWNhdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIFNldHRpbmdzUGFuZWwge1xuICAgIF9yb290RWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgX3NldHRpbmdzQ2xvc2VCdXR0b246IEhUTUxFbGVtZW50O1xuICAgIF9zZXR0aW5nc0NvbnRlbnRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgUmV0dXJuIG9yIGNyZWF0ZXMgYSBIVE1MIGVsZW1lbnQgdGhhdCByZXByZXNlbnRzIHRoaXMgc2V0dGluZyBpbiB0aGUgRE9NLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuaWQgPSAnc2V0dGluZ3MtcGFuZWwnO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgncGFuZWwtd3JhcCcpO1xuXG4gICAgICAgICAgICBjb25zdCBwYW5lbEVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHBhbmVsRWxlbS5jbGFzc0xpc3QuYWRkKCdwYW5lbCcpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuYXBwZW5kQ2hpbGQocGFuZWxFbGVtKTtcblxuICAgICAgICAgICAgY29uc3Qgc2V0dGluZ3NIZWFkaW5nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBzZXR0aW5nc0hlYWRpbmcuaWQgPSAnc2V0dGluZ3NIZWFkaW5nJztcbiAgICAgICAgICAgIHNldHRpbmdzSGVhZGluZy50ZXh0Q29udGVudCA9ICdTZXR0aW5ncyc7XG4gICAgICAgICAgICBwYW5lbEVsZW0uYXBwZW5kQ2hpbGQoc2V0dGluZ3NIZWFkaW5nKTtcblxuICAgICAgICAgICAgcGFuZWxFbGVtLmFwcGVuZENoaWxkKHRoaXMuc2V0dGluZ3NDbG9zZUJ1dHRvbik7XG4gICAgICAgICAgICBwYW5lbEVsZW0uYXBwZW5kQ2hpbGQodGhpcy5zZXR0aW5nc0NvbnRlbnRFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzZXR0aW5nc0NvbnRlbnRFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5nc0NvbnRlbnRFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc0NvbnRlbnRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc0NvbnRlbnRFbGVtZW50LmlkID0gJ3NldHRpbmdzQ29udGVudCc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzQ29udGVudEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzZXR0aW5nc0Nsb3NlQnV0dG9uKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5nc0Nsb3NlQnV0dG9uKSB7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc0Nsb3NlQnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5nc0Nsb3NlQnV0dG9uLmlkID0gJ3NldHRpbmdzQ2xvc2UnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXR0aW5nc0Nsb3NlQnV0dG9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgc2V0dGluZ3MgcGFuZWwuXG4gICAgICovXG4gICAgcHVibGljIHNob3coKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ3BhbmVsLXdyYXAtdmlzaWJsZScpKSB7XG4gICAgICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3BhbmVsLXdyYXAtdmlzaWJsZScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVG9nZ2xlIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBzZXR0aW5ncyBwYW5lbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgdG9nZ2xlVmlzaWJpbGl0eSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKCdwYW5lbC13cmFwLXZpc2libGUnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIaWRlIHNldHRpbmdzIHBhbmVsLlxuICAgICAqL1xuICAgIHB1YmxpYyBoaWRlKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ3BhbmVsLXdyYXAtdmlzaWJsZScpKSB7XG4gICAgICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ3BhbmVsLXdyYXAtdmlzaWJsZScpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuLyoqXG4gKiBTdGF0cyBpY29uIHRoYXQgY2FuIGJlIGNsaWNrZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGF0c0ljb24ge1xuICAgIF9yb290RWxlbWVudDogSFRNTEJ1dHRvbkVsZW1lbnQ7XG4gICAgX3N0YXRzSWNvbjogU1ZHRWxlbWVudDtcbiAgICBfdG9vbHRpcFRleHQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aGUgYnV0dG9uIGNvbnRhaW5pbmcgdGhlIHN0YXRzIGljb24uXG4gICAgICovXG4gICAgcHVibGljIGdldCByb290RWxlbWVudCgpOiBIVE1MQnV0dG9uRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC50eXBlID0gJ2J1dHRvbic7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdVaVRvb2wnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmlkID0gJ3N0YXRzQnRuJztcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc3RhdHNJY29uKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudG9vbHRpcFRleHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHRvb2x0aXBUZXh0KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl90b29sdGlwVGV4dCkge1xuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcFRleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICAgICAgICB0aGlzLl90b29sdGlwVGV4dC5jbGFzc0xpc3QuYWRkKCd0b29sdGlwdGV4dCcpO1xuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcFRleHQuaW5uZXJIVE1MID0gJ0luZm9ybWF0aW9uJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fdG9vbHRpcFRleHQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzdGF0c0ljb24oKTogU1ZHRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fc3RhdHNJY29uKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0ljb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAnc3ZnJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRzSWNvbi5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnaWQnLCAnc3RhdHNJY29uJyk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0ljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ3gnLCAnMHB4Jyk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0ljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ3knLCAnMHB4Jyk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0ljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ3ZpZXdCb3gnLCAnMCAwIDMzMCAzMzAnKTtcblxuICAgICAgICAgICAgLy8gY3JlYXRlIHN2ZyBncm91cCBmb3IgdGhlIHBhdGhzXG4gICAgICAgICAgICBjb25zdCBzdmdHcm91cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdnJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmNsYXNzTGlzdC5hZGQoJ3N2Z0ljb24nKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRzSWNvbi5hcHBlbmRDaGlsZChzdmdHcm91cCk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBwYXRocyBmb3IgdGhlIGljb24gaXRzZWxmLCB0aGUgaW5uZXIgYW5kIG91dCBwYXRoIG9mIGEgY29nXG4gICAgICAgICAgICBjb25zdCBwYXRoMSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgxLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMTY1LDAuMDA4Qzc0LjAxOSwwLjAwOCwwLDc0LjAyNCwwLDE2NC45OTljMCw5MC45NzcsNzQuMDE5LDE2NC45OTIsMTY1LDE2NC45OTJzMTY1LTc0LjAxNSwxNjUtMTY0Ljk5MkMzMzAsNzQuMDI0LDI1NS45ODEsMC4wMDgsMTY1LDAuMDA4eiBNMTY1LDI5OS45OTJjLTc0LjQzOSwwLTEzNS02MC41NTctMTM1LTEzNC45OTJTOTAuNTYxLDMwLjAwOCwxNjUsMzAuMDA4czEzNSw2MC41NTcsMTM1LDEzNC45OTFDMzAwLDIzOS40MzYsMjM5LjQzOSwyOTkuOTkyLDE2NSwyOTkuOTkyeidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhdGgyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3BhdGgnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcGF0aDIuc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAnZCcsXG4gICAgICAgICAgICAgICAgJ00xNjUsMTMwLjAwOGMtOC4yODQsMC0xNSw2LjcxNi0xNSwxNXY5OS45ODNjMCw4LjI4NCw2LjcxNiwxNSwxNSwxNXMxNS02LjcxNiwxNS0xNXYtOTkuOTgzQzE4MCwxMzYuNzI1LDE3My4yODQsMTMwLjAwOCwxNjUsMTMwLjAwOHonXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBwYXRoMyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcbiAgICAgICAgICAgICAgICAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAgICAgICAgICAgICAgICdwYXRoJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHBhdGgzLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMTY1LDcwLjAxMWMtMy45NSwwLTcuODExLDEuNi0xMC42MSw0LjM5Yy0yLjc5LDIuNzktNC4zOSw2LjY2LTQuMzksMTAuNjFzMS42LDcuODEsNC4zOSwxMC42MWMyLjc5LDIuNzksNi42Niw0LjM5LDEwLjYxLDQuMzlzNy44MS0xLjYsMTAuNjA5LTQuMzljMi43OS0yLjgsNC4zOTEtNi42Niw0LjM5MS0xMC42MXMtMS42MDEtNy44Mi00LjM5MS0xMC42MUMxNzIuODEsNzEuNjEsMTY4Ljk1LDcwLjAxMSwxNjUsNzAuMDExeidcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgxKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgyKTtcbiAgICAgICAgICAgIHN2Z0dyb3VwLmFwcGVuZENoaWxkKHBhdGgzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdHNJY29uO1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmltcG9ydCB7IExhdGVuY3lUZXN0IH0gZnJvbSAnLi9MYXRlbmN5VGVzdCc7XG5pbXBvcnQge0luaXRpYWxTZXR0aW5ncywgTG9nZ2VyLCBQaXhlbFN0cmVhbWluZ30gZnJvbSAnQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMyc7XG5pbXBvcnQgeyBBZ2dyZWdhdGVkU3RhdHMgfSBmcm9tICdAZXBpY2dhbWVzLXBzL2xpYi1waXhlbHN0cmVhbWluZ2Zyb250ZW5kLXVlNS4zJztcbmltcG9ydCB7IE1hdGhVdGlscyB9IGZyb20gJy4uL1V0aWwvTWF0aFV0aWxzJztcbmltcG9ydCB7RGF0YUNoYW5uZWxMYXRlbmN5VGVzdH0gZnJvbSBcIi4vRGF0YUNoYW5uZWxMYXRlbmN5VGVzdFwiO1xuaW1wb3J0IHtQaXhlbFN0cmVhbWluZ1NldHRpbmdzfSBmcm9tIFwiQGVwaWNnYW1lcy1wcy9saWItcGl4ZWxzdHJlYW1pbmdmcm9udGVuZC11ZTUuMy90eXBlcy9EYXRhQ2hhbm5lbC9Jbml0aWFsU2V0dGluZ3NcIjtcblxuLyoqXG4gKiBBIHN0YXQgc3RydWN0dXJlLCBhbiBpZCwgdGhlIHN0YXQgc3RyaW5nLCBhbmQgdGhlIGVsZW1lbnQgd2hlcmUgaXQgaXMgcmVuZGVyZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGF0IHtcbiAgICBpZDogc3RyaW5nO1xuICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgc3RhdDogc3RyaW5nO1xuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xufVxuXG4vKipcbiAqIEEgVUkgY29tcG9uZW50IGNvbnRhaW5pbmcgYWxsIHRoZSBzdGF0cyBmb3IgdGhlIGFwcGxpY2F0aW9uLlxuICovXG5leHBvcnQgY2xhc3MgU3RhdHNQYW5lbCB7XG4gICAgX3Jvb3RFbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICBfc3RhdHNDbG9zZUJ1dHRvbjogSFRNTEVsZW1lbnQ7XG4gICAgX3N0YXRzQ29udGVudEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIF9zdGF0aXN0aWNzQ29udGFpbmVyOiBIVE1MRWxlbWVudDtcbiAgICBfc3RhdHNSZXN1bHQ6IEhUTUxFbGVtZW50O1xuXG4gICAgbGF0ZW5jeVRlc3Q6IExhdGVuY3lUZXN0O1xuICAgIGRhdGFDaGFubmVsTGF0ZW5jeVRlc3Q6IERhdGFDaGFubmVsTGF0ZW5jeVRlc3Q7XG5cbiAgICAvKiBBIG1hcCBzdGF0cyB3ZSBhcmUgc3RvcmluZy9yZW5kZXJpbmcgKi9cbiAgICBzdGF0c01hcCA9IG5ldyBNYXA8c3RyaW5nLCBTdGF0PigpO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMubGF0ZW5jeVRlc3QgPSBuZXcgTGF0ZW5jeVRlc3QoKTtcbiAgICAgICAgdGhpcy5kYXRhQ2hhbm5lbExhdGVuY3lUZXN0ID0gbmV3IERhdGFDaGFubmVsTGF0ZW5jeVRlc3QoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBSZXR1cm4gb3IgY3JlYXRlcyBhIEhUTUwgZWxlbWVudCB0aGF0IHJlcHJlc2VudHMgdGhpcyBzZXR0aW5nIGluIHRoZSBET00uXG4gICAgICovXG4gICAgcHVibGljIGdldCByb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5pZCA9ICdzdGF0cy1wYW5lbCc7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdwYW5lbC13cmFwJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhbmVsRWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgcGFuZWxFbGVtLmNsYXNzTGlzdC5hZGQoJ3BhbmVsJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZChwYW5lbEVsZW0pO1xuXG4gICAgICAgICAgICBjb25zdCBzdGF0c0hlYWRpbmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHN0YXRzSGVhZGluZy5pZCA9ICdzdGF0c0hlYWRpbmcnO1xuICAgICAgICAgICAgc3RhdHNIZWFkaW5nLnRleHRDb250ZW50ID0gJ0luZm9ybWF0aW9uJztcbiAgICAgICAgICAgIHBhbmVsRWxlbS5hcHBlbmRDaGlsZChzdGF0c0hlYWRpbmcpO1xuXG4gICAgICAgICAgICBwYW5lbEVsZW0uYXBwZW5kQ2hpbGQodGhpcy5zdGF0c0Nsb3NlQnV0dG9uKTtcbiAgICAgICAgICAgIHBhbmVsRWxlbS5hcHBlbmRDaGlsZCh0aGlzLnN0YXRzQ29udGVudEVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHN0YXRzQ29udGVudEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3N0YXRzQ29udGVudEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRzQ29udGVudEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRzQ29udGVudEVsZW1lbnQuaWQgPSAnc3RhdHNDb250ZW50JztcblxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtVG9vbFN0YXRzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBzdHJlYW1Ub29sU3RhdHMuaWQgPSAnc3RyZWFtVG9vbHNTdGF0cyc7XG4gICAgICAgICAgICBzdHJlYW1Ub29sU3RhdHMuY2xhc3NMaXN0LmFkZCgnY29udGFpbmVyJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbnRyb2xTdGF0cyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgY29udHJvbFN0YXRzLmlkID0gJ0NvbnRyb2xTdGF0cyc7XG4gICAgICAgICAgICBjb250cm9sU3RhdHMuY2xhc3NMaXN0LmFkZCgncm93Jyk7XG5cbiAgICAgICAgICAgIGNvbnN0IHN0YXRpc3RpY3MgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzZWN0aW9uJyk7XG4gICAgICAgICAgICBzdGF0aXN0aWNzLmlkID0gJ3N0YXRpc3RpY3MnO1xuICAgICAgICAgICAgc3RhdGlzdGljcy5jbGFzc0xpc3QuYWRkKCdzZXR0aW5nc0NvbnRhaW5lcicpO1xuXG4gICAgICAgICAgICBjb25zdCBzdGF0aXN0aWNzSGVhZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBzdGF0aXN0aWNzSGVhZGVyLmlkID0gJ3N0YXRpc3RpY3NIZWFkZXInO1xuICAgICAgICAgICAgc3RhdGlzdGljc0hlYWRlci5jbGFzc0xpc3QuYWRkKCdzZXR0aW5ncy10ZXh0Jyk7XG4gICAgICAgICAgICBzdGF0aXN0aWNzSGVhZGVyLmNsYXNzTGlzdC5hZGQoJ3NldHRpbmdzSGVhZGVyJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlc3Npb25TdGF0cyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgc2Vzc2lvblN0YXRzLmlubmVySFRNTCA9ICdTZXNzaW9uIFN0YXRzJztcblxuICAgICAgICAgICAgdGhpcy5fc3RhdHNDb250ZW50RWxlbWVudC5hcHBlbmRDaGlsZChzdHJlYW1Ub29sU3RhdHMpO1xuICAgICAgICAgICAgc3RyZWFtVG9vbFN0YXRzLmFwcGVuZENoaWxkKGNvbnRyb2xTdGF0cyk7XG4gICAgICAgICAgICBjb250cm9sU3RhdHMuYXBwZW5kQ2hpbGQoc3RhdGlzdGljcyk7XG4gICAgICAgICAgICBzdGF0aXN0aWNzLmFwcGVuZENoaWxkKHN0YXRpc3RpY3NIZWFkZXIpO1xuICAgICAgICAgICAgc3RhdGlzdGljc0hlYWRlci5hcHBlbmRDaGlsZChzZXNzaW9uU3RhdHMpO1xuICAgICAgICAgICAgc3RhdGlzdGljcy5hcHBlbmRDaGlsZCh0aGlzLnN0YXRpc3RpY3NDb250YWluZXIpO1xuXG4gICAgICAgICAgICBjb250cm9sU3RhdHMuYXBwZW5kQ2hpbGQodGhpcy5sYXRlbmN5VGVzdC5yb290RWxlbWVudCk7XG4gICAgICAgICAgICBjb250cm9sU3RhdHMuYXBwZW5kQ2hpbGQodGhpcy5kYXRhQ2hhbm5lbExhdGVuY3lUZXN0LnJvb3RFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdHNDb250ZW50RWxlbWVudDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHN0YXRpc3RpY3NDb250YWluZXIoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3N0YXRpc3RpY3NDb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRpc3RpY3NDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRpc3RpY3NDb250YWluZXIuaWQgPSAnc3RhdGlzdGljc0NvbnRhaW5lcic7XG4gICAgICAgICAgICB0aGlzLl9zdGF0aXN0aWNzQ29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ2Qtbm9uZScpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGlzdGljc0NvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLnN0YXRzUmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGlzdGljc0NvbnRhaW5lcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHN0YXRzUmVzdWx0KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zdGF0c1Jlc3VsdCkge1xuICAgICAgICAgICAgdGhpcy5fc3RhdHNSZXN1bHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRzUmVzdWx0LmlkID0gJ3N0YXRpc3RpY3NSZXN1bHQnO1xuICAgICAgICAgICAgdGhpcy5fc3RhdHNSZXN1bHQuY2xhc3NMaXN0LmFkZCgnU3RhdHNSZXN1bHQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdHNSZXN1bHQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCBzdGF0c0Nsb3NlQnV0dG9uKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zdGF0c0Nsb3NlQnV0dG9uKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0Nsb3NlQnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0c0Nsb3NlQnV0dG9uLmlkID0gJ3N0YXRzQ2xvc2UnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0c0Nsb3NlQnV0dG9uO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkRpc2Nvbm5lY3QoKTogdm9pZCB7XG4gICAgICAgIHRoaXMubGF0ZW5jeVRlc3QubGF0ZW5jeVRlc3RCdXR0b24ub25jbGljayA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRhdGFDaGFubmVsTGF0ZW5jeVRlc3QubGF0ZW5jeVRlc3RCdXR0b24ub25jbGljayA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vZG8gbm90aGluZ1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG9uVmlkZW9Jbml0aWFsaXplZChzdHJlYW06IFBpeGVsU3RyZWFtaW5nKTogdm9pZCB7XG4gICAgICAgIC8vIHN0YXJ0aW5nIGEgbGF0ZW5jeSBjaGVja1xuICAgICAgICB0aGlzLmxhdGVuY3lUZXN0LmxhdGVuY3lUZXN0QnV0dG9uLm9uY2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICBzdHJlYW0ucmVxdWVzdExhdGVuY3lUZXN0KCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZGF0YUNoYW5uZWxMYXRlbmN5VGVzdC5sYXRlbmN5VGVzdEJ1dHRvbi5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgbGV0IHN0YXJ0ZWQgPSBzdHJlYW0ucmVxdWVzdERhdGFDaGFubmVsTGF0ZW5jeVRlc3Qoe1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiAxMDAwLFxuICAgICAgICAgICAgICAgIHJwczogMTAsXG4gICAgICAgICAgICAgICAgcmVxdWVzdFNpemU6IDIwMCxcbiAgICAgICAgICAgICAgICByZXNwb25zZVNpemU6IDIwMFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoc3RhcnRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YUNoYW5uZWxMYXRlbmN5VGVzdC5oYW5kbGVUZXN0U3RhcnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29uZmlndXJlKHNldHRpbmdzOiBQaXhlbFN0cmVhbWluZ1NldHRpbmdzKTogdm9pZCB7XG4gICAgICAgIGlmIChzZXR0aW5ncy5EaXNhYmxlTGF0ZW5jeVRlc3QpIHtcbiAgICAgICAgICAgIHRoaXMubGF0ZW5jeVRlc3QubGF0ZW5jeVRlc3RCdXR0b24uZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5sYXRlbmN5VGVzdC5sYXRlbmN5VGVzdEJ1dHRvbi50aXRsZSA9XG4gICAgICAgICAgICAgICAgJ0Rpc2FibGVkIGJ5IC1QaXhlbFN0cmVhbWluZ0Rpc2FibGVMYXRlbmN5VGVzdGVyPXRydWUnO1xuICAgICAgICAgICAgdGhpcy5kYXRhQ2hhbm5lbExhdGVuY3lUZXN0LmxhdGVuY3lUZXN0QnV0dG9uLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuZGF0YUNoYW5uZWxMYXRlbmN5VGVzdC5sYXRlbmN5VGVzdEJ1dHRvbi50aXRsZSA9XG4gICAgICAgICAgICAgICAgJ0Rpc2FibGVkIGJ5IC1QaXhlbFN0cmVhbWluZ0Rpc2FibGVMYXRlbmN5VGVzdGVyPXRydWUnO1xuICAgICAgICAgICAgTG9nZ2VyLkluZm8oXG4gICAgICAgICAgICAgICAgTG9nZ2VyLkdldFN0YWNrVHJhY2UoKSxcbiAgICAgICAgICAgICAgICAnLVBpeGVsU3RyZWFtaW5nRGlzYWJsZUxhdGVuY3lUZXN0ZXI9dHJ1ZSwgcmVxdWVzdGluZyBsYXRlbmN5IHJlcG9ydCBmcm9tIHRoZSB0aGUgYnJvd3NlciB0byBVRSBpcyBkaXNhYmxlZC4nXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBzdGF0cyBwYW5lbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2hvdygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnJvb3RFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygncGFuZWwtd3JhcC12aXNpYmxlJykpIHtcbiAgICAgICAgICAgIHRoaXMucm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgncGFuZWwtd3JhcC12aXNpYmxlJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUb2dnbGUgdGhlIHZpc2liaWxpdHkgb2YgdGhlIHN0YXRzIHBhbmVsLlxuICAgICAqL1xuICAgIHB1YmxpYyB0b2dnbGVWaXNpYmlsaXR5KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoJ3BhbmVsLXdyYXAtdmlzaWJsZScpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhpZGUgdGhlIHN0YXRzIHBhbmVsLlxuICAgICAqL1xuICAgIHB1YmxpYyBoaWRlKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5yb290RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ3BhbmVsLXdyYXAtdmlzaWJsZScpKSB7XG4gICAgICAgICAgICB0aGlzLnJvb3RFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ3BhbmVsLXdyYXAtdmlzaWJsZScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGhhbmRsZVBsYXllckNvdW50KHBsYXllckNvdW50OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5hZGRPclVwZGF0ZVN0YXQoXG4gICAgICAgICAgICAnUGxheWVyQ291bnRTdGF0JyxcbiAgICAgICAgICAgICdQbGF5ZXJzJyxcbiAgICAgICAgICAgIHBsYXllckNvdW50LnRvU3RyaW5nKClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgc3RhdHMgY29taW5nIGluIGZyb20gYnJvd3Nlci9VRVxuICAgICAqIEBwYXJhbSBzdGF0cyB0aGUgc3RhdHMgc3RydWN0dXJlXG4gICAgICovXG4gICAgcHVibGljIGhhbmRsZVN0YXRzKHN0YXRzOiBBZ2dyZWdhdGVkU3RhdHMpIHtcbiAgICAgICAgLy8gZm9ybWF0IG51bWJlcmluZyBiYXNlZCBvbiB0aGUgYnJvd3NlciBsYW5ndWFnZVxuICAgICAgICBjb25zdCBudW1iZXJGb3JtYXQgPSBuZXcgSW50bC5OdW1iZXJGb3JtYXQod2luZG93Lm5hdmlnYXRvci5sYW5ndWFnZSwge1xuICAgICAgICAgICAgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiAwXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEluYm91bmQgZGF0YVxuICAgICAgICBjb25zdCBpbmJvdW5kRGF0YSA9IE1hdGhVdGlscy5mb3JtYXRCeXRlcyhcbiAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLmJ5dGVzUmVjZWl2ZWQsXG4gICAgICAgICAgICAyXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuYWRkT3JVcGRhdGVTdGF0KCdJbmJvdW5kRGF0YVN0YXQnLCAnUmVjZWl2ZWQnLCBpbmJvdW5kRGF0YSk7XG5cbiAgICAgICAgLy8gUGFja2V0cyBsb3N0XG4gICAgICAgIGNvbnN0IHBhY2tldHNMb3N0U3RhdCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcbiAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLFxuICAgICAgICAgICAgJ3BhY2tldHNMb3N0J1xuICAgICAgICApXG4gICAgICAgICAgICA/IG51bWJlckZvcm1hdC5mb3JtYXQoc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMucGFja2V0c0xvc3QpXG4gICAgICAgICAgICA6ICdDaHJvbWUgb25seSc7XG4gICAgICAgIHRoaXMuYWRkT3JVcGRhdGVTdGF0KFxuICAgICAgICAgICAgJ1BhY2tldHNMb3N0U3RhdCcsXG4gICAgICAgICAgICAnUGFja2V0cyBMb3N0JyxcbiAgICAgICAgICAgIHBhY2tldHNMb3N0U3RhdFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIEJpdHJhdGVcbiAgICAgICAgaWYgKHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLmJpdHJhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkT3JVcGRhdGVTdGF0KFxuICAgICAgICAgICAgICAgICdWaWRlb0JpdHJhdGVTdGF0JyxcbiAgICAgICAgICAgICAgICAnVmlkZW8gQml0cmF0ZSAoa2JwcyknLFxuICAgICAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLmJpdHJhdGUudG9TdHJpbmcoKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdGF0cy5pbmJvdW5kQXVkaW9TdGF0cy5iaXRyYXRlKSB7XG4gICAgICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICAgICAnQXVkaW9CaXRyYXRlU3RhdCcsXG4gICAgICAgICAgICAgICAgJ0F1ZGlvIEJpdHJhdGUgKGticHMpJyxcbiAgICAgICAgICAgICAgICBzdGF0cy5pbmJvdW5kQXVkaW9TdGF0cy5iaXRyYXRlLnRvU3RyaW5nKClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBWaWRlbyByZXNvbHV0aW9uXG4gICAgICAgIGNvbnN0IHJlc1N0YXQgPVxuICAgICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKFxuICAgICAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLFxuICAgICAgICAgICAgICAgICdmcmFtZVdpZHRoJ1xuICAgICAgICAgICAgKSAmJlxuICAgICAgICAgICAgc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMuZnJhbWVXaWR0aCAmJlxuICAgICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKFxuICAgICAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLFxuICAgICAgICAgICAgICAgICdmcmFtZUhlaWdodCdcbiAgICAgICAgICAgICkgJiZcbiAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLmZyYW1lSGVpZ2h0XG4gICAgICAgICAgICAgICAgPyBzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cy5mcmFtZVdpZHRoICtcbiAgICAgICAgICAgICAgICAgICd4JyArXG4gICAgICAgICAgICAgICAgICBzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cy5mcmFtZUhlaWdodFxuICAgICAgICAgICAgICAgIDogJ0Nocm9tZSBvbmx5JztcbiAgICAgICAgdGhpcy5hZGRPclVwZGF0ZVN0YXQoJ1ZpZGVvUmVzU3RhdCcsICdWaWRlbyByZXNvbHV0aW9uJywgcmVzU3RhdCk7XG5cbiAgICAgICAgLy8gRnJhbWVzIGRlY29kZWRcbiAgICAgICAgY29uc3QgZnJhbWVzRGVjb2RlZCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcbiAgICAgICAgICAgIHN0YXRzLmluYm91bmRWaWRlb1N0YXRzLFxuICAgICAgICAgICAgJ2ZyYW1lc0RlY29kZWQnXG4gICAgICAgIClcbiAgICAgICAgICAgID8gbnVtYmVyRm9ybWF0LmZvcm1hdChzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cy5mcmFtZXNEZWNvZGVkKVxuICAgICAgICAgICAgOiAnQ2hyb21lIG9ubHknO1xuICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICdGcmFtZXNEZWNvZGVkU3RhdCcsXG4gICAgICAgICAgICAnRnJhbWVzIERlY29kZWQnLFxuICAgICAgICAgICAgZnJhbWVzRGVjb2RlZFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIEZyYW1lcmF0ZVxuICAgICAgICBpZiAoc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMuZnJhbWVzUGVyU2Vjb25kKSB7XG4gICAgICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICAgICAnRnJhbWVyYXRlU3RhdCcsXG4gICAgICAgICAgICAgICAgJ0ZyYW1lcmF0ZScsXG4gICAgICAgICAgICAgICAgc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMuZnJhbWVzUGVyU2Vjb25kLnRvU3RyaW5nKClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGcmFtZXMgZHJvcHBlZFxuICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICdGcmFtZXNEcm9wcGVkU3RhdCcsXG4gICAgICAgICAgICAnRnJhbWVzIGRyb3BwZWQnLFxuICAgICAgICAgICAgc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMuZnJhbWVzRHJvcHBlZD8udG9TdHJpbmcoKVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChzdGF0cy5pbmJvdW5kVmlkZW9TdGF0cy5jb2RlY0lkKSB7XG4gICAgICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICAgICAnVmlkZW9Db2RlY1N0YXQnLFxuICAgICAgICAgICAgICAgICdWaWRlbyBjb2RlYycsXG4gICAgICAgICAgICAgICAgLy8gU3BsaXQgdGhlIGNvZGVjIHRvIHJlbW92ZSB0aGUgRm10cCBsaW5lXG4gICAgICAgICAgICAgICAgc3RhdHMuY29kZWNzXG4gICAgICAgICAgICAgICAgICAgIC5nZXQoc3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMuY29kZWNJZClcbiAgICAgICAgICAgICAgICAgICAgPy5zcGxpdCgnICcpWzBdID8/ICcnXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0YXRzLmluYm91bmRBdWRpb1N0YXRzLmNvZGVjSWQpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkT3JVcGRhdGVTdGF0KFxuICAgICAgICAgICAgICAgICdBdWRpb0NvZGVjU3RhdCcsXG4gICAgICAgICAgICAgICAgJ0F1ZGlvIGNvZGVjJyxcbiAgICAgICAgICAgICAgICAvLyBTcGxpdCB0aGUgY29kZWMgdG8gcmVtb3ZlIHRoZSBGbXRwIGxpbmVcbiAgICAgICAgICAgICAgICBzdGF0cy5jb2RlY3NcbiAgICAgICAgICAgICAgICAgICAgLmdldChzdGF0cy5pbmJvdW5kQXVkaW9TdGF0cy5jb2RlY0lkKVxuICAgICAgICAgICAgICAgICAgICA/LnNwbGl0KCcgJylbMF0gPz8gJydcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSVFRcbiAgICAgICAgY29uc3QgbmV0UlRUID1cbiAgICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcbiAgICAgICAgICAgICAgICBzdGF0cy5jYW5kaWRhdGVQYWlyLFxuICAgICAgICAgICAgICAgICdjdXJyZW50Um91bmRUcmlwVGltZSdcbiAgICAgICAgICAgICkgJiYgc3RhdHMuaXNOdW1iZXIoc3RhdHMuY2FuZGlkYXRlUGFpci5jdXJyZW50Um91bmRUcmlwVGltZSlcbiAgICAgICAgICAgICAgICA/IG51bWJlckZvcm1hdC5mb3JtYXQoXG4gICAgICAgICAgICAgICAgICAgICAgc3RhdHMuY2FuZGlkYXRlUGFpci5jdXJyZW50Um91bmRUcmlwVGltZSAqIDEwMDBcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICA6IFwiQ2FuJ3QgY2FsY3VsYXRlXCI7XG4gICAgICAgIHRoaXMuYWRkT3JVcGRhdGVTdGF0KCdSVFRTdGF0JywgJ05ldCBSVFQgKG1zKScsIG5ldFJUVCk7XG5cbiAgICAgICAgdGhpcy5hZGRPclVwZGF0ZVN0YXQoXG4gICAgICAgICAgICAnRHVyYXRpb25TdGF0JyxcbiAgICAgICAgICAgICdEdXJhdGlvbicsXG4gICAgICAgICAgICBzdGF0cy5zZXNzaW9uU3RhdHMucnVuVGltZVxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuYWRkT3JVcGRhdGVTdGF0KFxuICAgICAgICAgICAgJ0NvbnRyb2xzSW5wdXRTdGF0JyxcbiAgICAgICAgICAgICdDb250cm9scyBzdHJlYW0gaW5wdXQnLFxuICAgICAgICAgICAgc3RhdHMuc2Vzc2lvblN0YXRzLmNvbnRyb2xzU3RyZWFtSW5wdXRcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBRUFxuICAgICAgICB0aGlzLmFkZE9yVXBkYXRlU3RhdChcbiAgICAgICAgICAgICdRUFN0YXQnLFxuICAgICAgICAgICAgJ1ZpZGVvIHF1YW50aXphdGlvbiBwYXJhbWV0ZXInLFxuICAgICAgICAgICAgc3RhdHMuc2Vzc2lvblN0YXRzLnZpZGVvRW5jb2RlckF2Z1FQLnRvU3RyaW5nKClcbiAgICAgICAgKTtcblxuICAgICAgICAvLyB0b2RvOlxuICAgICAgICAvL3N0YXRzVGV4dCArPSBgPGRpdj5Ccm93c2VyIHJlY2VpdmUgdG8gY29tcG9zaXRlIChtcyk6ICR7c3RhdHMuaW5ib3VuZFZpZGVvU3RhdHMucmVjZWl2ZVRvQ29tcG9zaXRlTXN9PC9kaXY+YDtcblxuICAgICAgICBMb2dnZXIuTG9nKFxuICAgICAgICAgICAgTG9nZ2VyLkdldFN0YWNrVHJhY2UoKSxcbiAgICAgICAgICAgIGAtLS0tLS0tLS0gU3RhdHMgLS0tLS0tLS0tXFxuICR7c3RhdHN9XFxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tYCxcbiAgICAgICAgICAgIDZcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbmV3IHN0YXQgdG8gdGhlIHN0YXRzIHJlc3VsdHMgaW4gdGhlIERPTSBvciB1cGRhdGVzIGFuIGV4aXRpbmcgc3RhdC5cbiAgICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBzdGF0IHRvIGFkZC91cGRhdGUuXG4gICAgICogQHBhcmFtIHN0YXQgVGhlIGNvbnRlbnRzIG9mIHRoZSBzdGF0LlxuICAgICAqL1xuICAgIHB1YmxpYyBhZGRPclVwZGF0ZVN0YXQoaWQ6IHN0cmluZywgc3RhdExhYmVsOiBzdHJpbmcsIHN0YXQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBzdGF0SFRNTCA9IGAke3N0YXRMYWJlbH06ICR7c3RhdH1gO1xuXG4gICAgICAgIGlmICghdGhpcy5zdGF0c01hcC5oYXMoaWQpKSB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgdGhlIHN0YXRcbiAgICAgICAgICAgIGNvbnN0IG5ld1N0YXQgPSBuZXcgU3RhdCgpO1xuICAgICAgICAgICAgbmV3U3RhdC5pZCA9IGlkO1xuICAgICAgICAgICAgbmV3U3RhdC5zdGF0ID0gc3RhdDtcbiAgICAgICAgICAgIG5ld1N0YXQudGl0bGUgPSBzdGF0TGFiZWw7XG4gICAgICAgICAgICBuZXdTdGF0LmVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIG5ld1N0YXQuZWxlbWVudC5pbm5lckhUTUwgPSBzdGF0SFRNTDtcbiAgICAgICAgICAgIC8vIGFkZCB0aGUgc3RhdCB0byB0aGUgZG9tXG4gICAgICAgICAgICB0aGlzLnN0YXRzUmVzdWx0LmFwcGVuZENoaWxkKG5ld1N0YXQuZWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLnN0YXRzTWFwLnNldChpZCwgbmV3U3RhdCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdXBkYXRlIHRoZSBleGlzdGluZyBzdGF0XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLnN0YXRzTWFwLmdldChpZCk7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHZhbHVlLmVsZW1lbnQuaW5uZXJIVE1MID0gc3RhdEhUTUw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKiogV2hldGhlciBhIHN0cmVhbSBVSSBlbGVtZW50IGlzIGludGVybmFsbHkgbWFkZSwgZXh0ZXJuYWxseSBwcm92aWRlZCwgb3IgZGlzYWJsZWQuICovXG5leHBvcnQgZW51bSBVSUVsZW1lbnRDcmVhdGlvbk1vZGUge1xuICAgIENyZWF0ZURlZmF1bHRFbGVtZW50LFxuICAgIFVzZUN1c3RvbUVsZW1lbnQsXG4gICAgRGlzYWJsZVxufVxuXG4vKiogQSBjb25maWd1cmF0aW9uIGZvciBkaWZmZXJlbnQgVUkgZWxlbWVudHMgd2hpY2ggY29udHJvbC9kaXNwbGF5IGluZm8gcmVsYXRlZCB0byB0aGUgc3RyZWFtLiAqL1xuZXhwb3J0IHR5cGUgVUlFbGVtZW50Q29uZmlnID0ge1xuICAgIC8vIEluIHdoaWNoIHdheSBpcyB0aGlzIGVsZW1lbnQgY3JlYXRlZD9cbiAgICBjcmVhdGlvbk1vZGUgOiBVSUVsZW1lbnRDcmVhdGlvbk1vZGUsXG4gICAgLy8gKE9ubHkgcmVsZXZhbnQgaWYgd2hlbiBtb2RlIGlzIENyZWF0ZUN1c3RvbUVsZW1lbnQpIFZpc3VhbGl6aW5nIGVsZW1lbnRcbiAgICBjdXN0b21FbGVtZW50PyA6IEhUTUxFbGVtZW50XG59XG5cbi8qKlxuICogQ29uZmlndXJlcyBhIGdlbmVyYWwgc3RyZWFtLXJlbGF0ZWQgVUkgcGFuZWwuIFxuICogRm9yIGV4YW1wbGU6IGlzIGl0IGNyZWF0ZWQsIGFuZCBpZiBpdCBpcywgd2hhdCBraW5kIG9mIGJ1dHRvbiBpcyB1c2VkIHRvIHNob3cvaGlkZSBpdC5cbiAqIFRoaXMgY29uZmlndXJhdGlvbiBpcyB1c2VkIGZvciB0aGUgc2V0dGluZ3MgcGFuZWwgYW5kIHN0YXRzIHBhbmVsIGJ5IGRlZmF1bHQuXG4gKiBcbiAqIE5vdGU6IEZvciBjYXNlcyB3aGVyZSB0aGUgcGFuZWwgbmVlZHMgdG8gYmUgY3JlYXRlZCwgYnV0IGEgYnV0dG9uIGlzbid0IG5lZWRlZCwgXG4gKiB0aGUgcGFuZWwgZWxlbWVudCBjYW4gYmUgcGxhY2VkIGFueXdoZXJlIGluIHRoZSBET00gYXMgbmVlZGVkIChzZWUgQXBwbGljYXRpb24gY2xhc3MpLiBcbiAqL1xuZXhwb3J0IHR5cGUgUGFuZWxDb25maWd1cmF0aW9uID0ge1xuICAgIC8vIElmIHBhbmVsIGlzIGVuYWJsZWQsIEhUTUwgZWxlbWVudHMgZm9yIGl0IHdpbGwgYmUgY3JlYXRlZCwgYW5kIGZ1bnRpb25hbGl0eSBib3VuZFxuICAgIGlzRW5hYmxlZCA6IGJvb2xlYW4sXG4gICAgLy8gKE9ubHkgcmVsZXZhbnQgaWYgaXNFbmFibGVkKSBUaGUgdHlwZSBvZiB0aGUgYnV0dG9uIHRvIHNob3cvaGlkZSB0aGlzIHBhbmVsXG4gICAgdmlzaWJpbGl0eUJ1dHRvbkNvbmZpZz8gOiBVSUVsZW1lbnRDb25maWdcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUGFuZWxFbmFibGVkKGNvbmZpZyA6IFBhbmVsQ29uZmlndXJhdGlvbiB8IHVuZGVmaW5lZCkgOiBib29sZWFuIHtcbiAgICByZXR1cm4gIWNvbmZpZyB8fCAoISFjb25maWcgJiYgY29uZmlnLmlzRW5hYmxlZCk7XG59IiwiLy8gQ29weXJpZ2h0IEVwaWMgR2FtZXMsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblxuLyoqXG4gKiBBIFVJIGVsZW1lbnQgc2hvd2luZyB0aGUgUVAgKHF1YW50aXphdGlvbiBwYXJhbWV0ZXIpIG9mIHRoZSB2aWRlbyBzdHJlYW0gYXQgdGhlIGxhc3QgZW5jb2RlZCBmcmFtZSAod2VsbCwgbGFzdCB0cmFuc21pdHRlZCBRUCByZWFsbHkpLlxuICogQSBibG9ja2llciBlbmNvZGluZyB3aWxsIGhhdmUgYSBoaWdoZXIgUVAgYW5kIHRoaXMgd2lsbCBtYWtlIHRoZSBpbmRpY2F0b3IgdHVybiBtb3JlIHJlZC5cbiAqIEEgbm9uLWJsb2NreSBzdHJlYW0gd2lsbCBoYXZlIGEgbG93ZXIgUVAgYW5kIHRoaXMgd2lsbCBtYWtlIHRoZSBpbmRpY2F0b3IgdHVybiBtb3JlIGdyZWVuLlxuICogVGhlIFFQIGluZGljYXRvciBpcyByZXByZXNlbnRlZCB2aXN1YWxseSB1c2luZyBhIFdpRmkgaWNvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvUXBJbmRpY2F0b3Ige1xuICAgIHZpZGVvRW5jb2RlckF2Z1FQID0gLTE7XG5cbiAgICAvLyBub24gaHRtbCBlbGVtZW50c1xuICAgIHN0YXRzVGV4dCA9ICcnO1xuICAgIGNvbG9yID0gJyc7XG5cbiAgICAvLyBxcCBjb2xvcnNcbiAgICByZWFkb25seSBvcmFuZ2VRUCA9IDI2O1xuICAgIHJlYWRvbmx5IHJlZFFQID0gMzU7XG5cbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgIF9xdWFsaXR5VGV4dDogSFRNTEVsZW1lbnQ7XG4gICAgX3F1YWxpdHlTdGF0dXM6IFNWR0VsZW1lbnQ7XG4gICAgX2RvdDogU1ZHRWxlbWVudDtcbiAgICBfb3V0ZXI6IFNWR0VsZW1lbnQ7XG4gICAgX21pZGRsZTogU1ZHRWxlbWVudDtcbiAgICBfaW5uZXI6IFNWR0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHJvb3QgZWxlbWVudCBvZiB0aGUgUVAgaW5kaWNhdG9yLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICAvLyBtYWtlIHRoZSByb290IGVsZW1lbnQgdGhhdCBjb250YWlucyB0aGUgc3ZnIGZvciB0aGUgY29ubmVjdGlvblxuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmlkID0gJ2Nvbm5lY3Rpb24nO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnVWlUb29sJyk7XG5cbiAgICAgICAgICAgIC8vIGFkZCBzdmcgaWNvbiBmb3IgdGhlIGNvbm5lY3Rpb24gc3RyZW5ndGhcbiAgICAgICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMucXVhbGl0eVN0YXR1cyk7XG5cbiAgICAgICAgICAgIC8vIGFkZCB0aGUgdGV4dCB1bmRlcm5lYXRoIHRoZSBjb25uZWN0aW9uXG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnF1YWxpdHlUZXh0KTtcblxuICAgICAgICAgICAgLy8gc2V0IGNvbG9ycyB0byBub3QgY29ubmVjdGVkIGluaXRpYWxseVxuICAgICAgICAgICAgdGhpcy51cGRhdGVRcFRvb2x0aXAoLTEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yb290RWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRleHQgdGhhdCBkaXNwbGF5cyB1bmRlciB0aGUgaWNvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHF1YWxpdHlUZXh0KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9xdWFsaXR5VGV4dCkge1xuICAgICAgICAgICAgdGhpcy5fcXVhbGl0eVRleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICAgICAgICB0aGlzLl9xdWFsaXR5VGV4dC5pZCA9ICdxdWFsaXR5VGV4dCc7XG4gICAgICAgICAgICB0aGlzLl9xdWFsaXR5VGV4dC5jbGFzc0xpc3QuYWRkKCd0b29sdGlwdGV4dCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9xdWFsaXR5VGV4dDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGljb24uXG4gICAgICovXG4gICAgcHVibGljIGdldCBxdWFsaXR5U3RhdHVzKCk6IFNWR0VsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3F1YWxpdHlTdGF0dXMpIHtcbiAgICAgICAgICAgIHRoaXMuX3F1YWxpdHlTdGF0dXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAnc3ZnJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX3F1YWxpdHlTdGF0dXMuc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAnaWQnLFxuICAgICAgICAgICAgICAgICdjb25uZWN0aW9uU3RyZW5ndGgnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5fcXVhbGl0eVN0YXR1cy5zZXRBdHRyaWJ1dGVOUyhudWxsLCAneCcsICcwcHgnKTtcbiAgICAgICAgICAgIHRoaXMuX3F1YWxpdHlTdGF0dXMuc2V0QXR0cmlidXRlTlMobnVsbCwgJ3knLCAnMHB4Jyk7XG4gICAgICAgICAgICB0aGlzLl9xdWFsaXR5U3RhdHVzLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ3ZpZXdCb3gnLFxuICAgICAgICAgICAgICAgICcwIDAgNDk0LjQ1IDQ5NC40NSdcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIGJ1aWxkIHdpZmkgaWNvblxuICAgICAgICAgICAgdGhpcy5xdWFsaXR5U3RhdHVzLmFwcGVuZENoaWxkKHRoaXMuZG90KTtcbiAgICAgICAgICAgIHRoaXMucXVhbGl0eVN0YXR1cy5hcHBlbmRDaGlsZCh0aGlzLm1pZGRsZSk7XG4gICAgICAgICAgICB0aGlzLnF1YWxpdHlTdGF0dXMuYXBwZW5kQ2hpbGQodGhpcy5vdXRlcik7XG4gICAgICAgICAgICB0aGlzLnF1YWxpdHlTdGF0dXMuYXBwZW5kQ2hpbGQodGhpcy5pbm5lcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3F1YWxpdHlTdGF0dXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBkb3QgYXQgdGhlIGJvdHRvbSBvZiB0aGUgd2lmaSBpY29uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZG90KCk6IFNWR0VsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX2RvdCkge1xuICAgICAgICAgICAgdGhpcy5fZG90ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ2NpcmNsZSdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLl9kb3Quc2V0QXR0cmlidXRlTlMobnVsbCwgJ2lkJywgJ2RvdCcpO1xuICAgICAgICAgICAgdGhpcy5fZG90LnNldEF0dHJpYnV0ZU5TKG51bGwsICdjeCcsICcyNDcuMTI1Jyk7XG4gICAgICAgICAgICB0aGlzLl9kb3Quc2V0QXR0cmlidXRlTlMobnVsbCwgJ2N5JywgJzM5OC45MjUnKTtcbiAgICAgICAgICAgIHRoaXMuX2RvdC5zZXRBdHRyaWJ1dGVOUyhudWxsLCAncicsICczNS4zJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2RvdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIG91dGVyIGFyYyBvZiB0aGUgd2lmaSBpY29uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgb3V0ZXIoKTogU1ZHRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fb3V0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX291dGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3BhdGgnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5fb3V0ZXIuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2lkJywgJ291dGVyJyk7XG4gICAgICAgICAgICB0aGlzLl9vdXRlci5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTQ2Ny45MjUsMjA0LjYyNWMtNi44LDAtMTMuNS0yLjYtMTguNy03LjhjLTExMS41LTExMS40LTI5Mi43LTExMS40LTQwNC4xLDBjLTEwLjMsMTAuMy0yNy4xLDEwLjMtMzcuNCwwcy0xMC4zLTI3LjEsMC0zNy40YzY0LTY0LDE0OS05OS4yLDIzOS41LTk5LjJzMTc1LjUsMzUuMiwyMzkuNSw5OS4yYzEwLjMsMTAuMywxMC4zLDI3LjEsMCwzNy40QzQ4MS40MjUsMjAyLjAyNSw0NzQuNjI1LDIwNC42MjUsNDY3LjkyNSwyMDQuNjI1eidcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX291dGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgbWlkZGxlIGFyYyBvZiB0aGUgd2lmaSBpY29uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgbWlkZGxlKCk6IFNWR0VsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX21pZGRsZSkge1xuICAgICAgICAgICAgdGhpcy5fbWlkZGxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3BhdGgnXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5fbWlkZGxlLnNldEF0dHJpYnV0ZU5TKG51bGwsICdpZCcsICdtaWRkbGUnKTtcbiAgICAgICAgICAgIHRoaXMuX21pZGRsZS5zZXRBdHRyaWJ1dGVOUyhcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICdkJyxcbiAgICAgICAgICAgICAgICAnTTM5NS4yMjUsMjc3LjMyNWMtNi44LDAtMTMuNS0yLjYtMTguNy03LjhjLTcxLjQtNzEuMy0xODcuNC03MS4zLTI1OC44LDBjLTEwLjMsMTAuMy0yNy4xLDEwLjMtMzcuNCwwcy0xMC4zLTI3LjEsMC0zNy40YzkyLTkyLDI0MS42LTkyLDMzMy42LDBjMTAuMywxMC4zLDEwLjMsMjcuMSwwLDM3LjRDNDA4LjcyNSwyNzQuNzI1LDQwMS45MjUsMjc3LjMyNSwzOTUuMjI1LDI3Ny4zMjV6J1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fbWlkZGxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgaW5uZXIgYXJjIG9mIHRoZSB3aWZpIGljb24uXG4gICAgICovXG4gICAgcHVibGljIGdldCBpbm5lcigpOiBTVkdFbGVtZW50IHtcbiAgICAgICAgaWYgKCF0aGlzLl9pbm5lcikge1xuICAgICAgICAgICAgdGhpcy5faW5uZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLl9pbm5lci5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnaWQnLCAnaW5uZXInKTtcbiAgICAgICAgICAgIHRoaXMuX2lubmVyLnNldEF0dHJpYnV0ZU5TKFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgJ2QnLFxuICAgICAgICAgICAgICAgICdNMzIzLjYyNSwzNDguODI1Yy02LjgsMC0xMy41LTIuNi0xOC43LTcuOGMtMTUuNC0xNS40LTM2LTIzLjktNTcuOC0yMy45cy00Mi40LDguNS01Ny44LDIzLjljLTEwLjMsMTAuMy0yNy4xLDEwLjMtMzcuNCwwYy0xMC4zLTEwLjMtMTAuMy0yNy4xLDAtMzcuNGMyNS40LTI1LjQsNTkuMi0zOS40LDk1LjItMzkuNHM2OS44LDE0LDk1LjIsMzkuNWMxMC4zLDEwLjMsMTAuMywyNy4xLDAsMzcuNEMzMzcuMjI1LDM0Ni4yMjUsMzMwLjQyNSwzNDguODI1LDMyMy42MjUsMzQ4LjgyNXonXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9pbm5lcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIHRvIHNldCB0aGUgc3BlZWQgb2YgdGhlIHN0YXR1cyBsaWdodC5cbiAgICAgKiBAcGFyYW0gc3BlZWQgLSBTZXQgdGhlIHNwZWVkIG9mIHRoZSBibGluaywgaGlnaGVyIG51bWJlcnMgbWFrZSB0aGUgc3RhdHVzIGxpZ2h0IGJsaW5rIGZhc3Rlci5cbiAgICAgKi9cbiAgICBibGlua1ZpZGVvUXVhbGl0eVN0YXR1cyhzcGVlZDogbnVtYmVyKSB7XG4gICAgICAgIGxldCBpdGVyYXRpb24gPSBzcGVlZDtcbiAgICAgICAgbGV0IG9wYWNpdHkgPSAxO1xuICAgICAgICBjb25zdCB0aWNrSUQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICBvcGFjaXR5IC09IDAuMTtcbiAgICAgICAgICAgIHRoaXMucXVhbGl0eVRleHQuc3R5bGUub3BhY2l0eSA9IFN0cmluZyhcbiAgICAgICAgICAgICAgICBNYXRoLmFicygob3BhY2l0eSAtIDAuNSkgKiAyKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChvcGFjaXR5IDw9IDAuMSkge1xuICAgICAgICAgICAgICAgIGlmICgtLWl0ZXJhdGlvbiA9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGlja0lEKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBvcGFjaXR5ID0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIDEwMCAvIHNwZWVkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB1cGRhdGVzIHRoZSBRUCB0b29sdGlwIGJ5IGNvbnZlcnRpbmcgdGhlIFZpZGVvIEVuY29kZXIgUVAgdG8gYSBjb2xvciBsaWdodFxuICAgICAqIEBwYXJhbSBRUCAtIFRoZSB2aWRlbyBlbmNvZGVyIFFQIG51bWJlciBuZWVkZWQgdG8gZmluZCB0aGUgYXZlcmFnZVxuICAgICAqL1xuICAgIHVwZGF0ZVFwVG9vbHRpcChRUDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMudmlkZW9FbmNvZGVyQXZnUVAgPSBRUDtcbiAgICAgICAgaWYgKFFQID4gdGhpcy5yZWRRUCkge1xuICAgICAgICAgICAgdGhpcy5jb2xvciA9ICdyZWQnO1xuICAgICAgICAgICAgdGhpcy5ibGlua1ZpZGVvUXVhbGl0eVN0YXR1cygyKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNUZXh0ID0gYDxkaXYgc3R5bGU9XCJjb2xvcjogJHt0aGlzLmNvbG9yfVwiPlBvb3IgZW5jb2RpbmcgcXVhbGl0eTwvZGl2PmA7XG4gICAgICAgICAgICB0aGlzLm91dGVyLnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgJyMzYzNiNDAnKTtcbiAgICAgICAgICAgIHRoaXMubWlkZGxlLnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgJyMzYzNiNDAnKTtcbiAgICAgICAgICAgIHRoaXMuaW5uZXIuc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCB0aGlzLmNvbG9yKTtcbiAgICAgICAgICAgIHRoaXMuZG90LnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgdGhpcy5jb2xvcik7XG4gICAgICAgIH0gZWxzZSBpZiAoUVAgPiB0aGlzLm9yYW5nZVFQKSB7XG4gICAgICAgICAgICB0aGlzLmNvbG9yID0gJ29yYW5nZSc7XG4gICAgICAgICAgICB0aGlzLmJsaW5rVmlkZW9RdWFsaXR5U3RhdHVzKDEpO1xuICAgICAgICAgICAgdGhpcy5zdGF0c1RleHQgPSBgPGRpdiBzdHlsZT1cImNvbG9yOiAke3RoaXMuY29sb3J9XCI+QmxvY2t5IGVuY29kaW5nIHF1YWxpdHk8L2Rpdj5gO1xuICAgICAgICAgICAgdGhpcy5vdXRlci5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsICcjM2MzYjQwJyk7XG4gICAgICAgICAgICB0aGlzLm1pZGRsZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsIHRoaXMuY29sb3IpO1xuICAgICAgICAgICAgdGhpcy5pbm5lci5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsIHRoaXMuY29sb3IpO1xuICAgICAgICAgICAgdGhpcy5kb3Quc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCB0aGlzLmNvbG9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChRUCA8PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmNvbG9yID0gJyNiMGIwYjAnO1xuICAgICAgICAgICAgdGhpcy5vdXRlci5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsICcjM2MzYjQwJyk7XG4gICAgICAgICAgICB0aGlzLm1pZGRsZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsICcjM2MzYjQwJyk7XG4gICAgICAgICAgICB0aGlzLmlubmVyLnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgJyMzYzNiNDAnKTtcbiAgICAgICAgICAgIHRoaXMuZG90LnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgJyMzYzNiNDAnKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNUZXh0ID0gYDxkaXYgc3R5bGU9XCJjb2xvcjogJHt0aGlzLmNvbG9yfVwiPk5vdCBjb25uZWN0ZWQ8L2Rpdj5gO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jb2xvciA9ICdsaW1lJztcbiAgICAgICAgICAgIHRoaXMucXVhbGl0eVN0YXR1cy5zdHlsZS5vcGFjaXR5ID0gJzEnO1xuICAgICAgICAgICAgdGhpcy5zdGF0c1RleHQgPSBgPGRpdiBzdHlsZT1cImNvbG9yOiAke3RoaXMuY29sb3J9XCI+Q2xlYXIgZW5jb2RpbmcgcXVhbGl0eTwvZGl2PmA7XG4gICAgICAgICAgICB0aGlzLm91dGVyLnNldEF0dHJpYnV0ZU5TKG51bGwsICdmaWxsJywgdGhpcy5jb2xvcik7XG4gICAgICAgICAgICB0aGlzLm1pZGRsZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsIHRoaXMuY29sb3IpO1xuICAgICAgICAgICAgdGhpcy5pbm5lci5zZXRBdHRyaWJ1dGVOUyhudWxsLCAnZmlsbCcsIHRoaXMuY29sb3IpO1xuICAgICAgICAgICAgdGhpcy5kb3Quc2V0QXR0cmlidXRlTlMobnVsbCwgJ2ZpbGwnLCB0aGlzLmNvbG9yKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnF1YWxpdHlUZXh0LmlubmVySFRNTCA9IHRoaXMuc3RhdHNUZXh0O1xuICAgIH1cbn1cbiIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbi8qKlxuICogWFIgaWNvbiB0aGF0IGNhbiBiZSBjbGlja2VkLlxuICovXG5leHBvcnQgY2xhc3MgWFJJY29uIHtcbiAgICBfcm9vdEVsZW1lbnQ6IEhUTUxCdXR0b25FbGVtZW50O1xuICAgIF94ckljb246IFNWR0VsZW1lbnQ7XG4gICAgX3Rvb2x0aXBUZXh0OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGhlIGJ1dHRvbiBjb250YWluaW5nIHRoZSBYUiBpY29uLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgcm9vdEVsZW1lbnQoKTogSFRNTEJ1dHRvbkVsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQudHlwZSA9ICdidXR0b24nO1xuICAgICAgICAgICAgdGhpcy5fcm9vdEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnVWlUb29sJyk7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5pZCA9ICd4ckJ0bic7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnhySWNvbik7XG4gICAgICAgICAgICB0aGlzLl9yb290RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnRvb2x0aXBUZXh0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIGdldCB0b29sdGlwVGV4dCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIGlmICghdGhpcy5fdG9vbHRpcFRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcFRleHQuY2xhc3NMaXN0LmFkZCgndG9vbHRpcHRleHQnKTtcbiAgICAgICAgICAgIHRoaXMuX3Rvb2x0aXBUZXh0LmlubmVySFRNTCA9ICdYUic7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rvb2x0aXBUZXh0O1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgeHJJY29uKCk6IFNWR0VsZW1lbnQge1xuICAgICAgICBpZiAoIXRoaXMuX3hySWNvbikge1xuICAgICAgICAgICAgdGhpcy5feHJJY29uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFxuICAgICAgICAgICAgICAgICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgICAgICAgICAgICAgJ3N2ZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLl94ckljb24uc2V0QXR0cmlidXRlTlMobnVsbCwgJ2lkJywgJ3hySWNvbicpO1xuICAgICAgICAgICAgdGhpcy5feHJJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd4JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5feHJJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd5JywgJzBweCcpO1xuICAgICAgICAgICAgdGhpcy5feHJJY29uLnNldEF0dHJpYnV0ZU5TKG51bGwsICd2aWV3Qm94JywgJzAgMCAxMDAgMTAwJyk7XG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBzdmcgZ3JvdXAgZm9yIHRoZSBwYXRoc1xuICAgICAgICAgICAgY29uc3Qgc3ZnR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAnZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBzdmdHcm91cC5jbGFzc0xpc3QuYWRkKCdzdmdJY29uJyk7XG4gICAgICAgICAgICB0aGlzLl94ckljb24uYXBwZW5kQ2hpbGQoc3ZnR3JvdXApO1xuXG4gICAgICAgICAgICAvLyBjcmVhdGUgcGF0aHMgZm9yIHRoZSBpY29uIGl0c2VsZiwgdGhlIHBhdGggb2YgdGhlIHhyIGhlYWRzZXRcbiAgICAgICAgICAgIGNvbnN0IHBhdGggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXG4gICAgICAgICAgICAgICAgJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgICAgICAgICAgICAgICAncGF0aCdcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIHBhdGguc2V0QXR0cmlidXRlTlMoXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAnZCcsXG4gICAgICAgICAgICAgICAgJ00yOSA0MWMtNSAwLTkgNC05IDlzNCA5IDkgOSA5LTQgOS05LTQtOS05LTl6bTAgMTRjLTIuOCAwLTUtMi4yLTUtNXMyLjItNSA1LTUgNSAyLjIgNSA1LTIuMiA1LTUgNXptNDItMTRjLTUgMC05IDQtOSA5czQgOSA5IDkgOS00IDktOS00LTktOS05em0wIDE0Yy0yLjggMC01LTIuMi01LTVzMi4yLTUgNS01IDUgMi4yIDUgNS0yLjIgNS01IDV6bTEyLTMxSDE3Yy02LjYgMC0xMiA1LjQtMTIgMTJ2MjhjMCA2LjYgNS40IDEyIDEyIDEyaDE0LjVjMy41IDAgNi44LTEuNSA5LTQuMWwzLjUtNGMxLjUtMS43IDMuNy0yLjcgNi0yLjdzNC41IDEgNiAyLjdsMy41IDRjMi4zIDIuNiA1LjYgNC4xIDkgNC4xSDgzYzYuNiAwIDEyLTUuNCAxMi0xMlYzNmMwLTYuNi01LjQtMTItMTItMTJ6bTggNDBjMCA0LjQtMy42IDgtOCA4SDY4LjVjLTIuMyAwLTQuNS0xLTYtMi43bC0zLjUtNGMtMi4zLTIuNi01LjYtNC4xLTktNC4xLTMuNSAwLTYuOCAxLjUtOSA0LjFsLTMuNSA0QzM2IDcxIDMzLjggNzIgMzEuNSA3MkgxN2MtNC40IDAtOC0zLjYtOC04VjM2YzAtNC40IDMuNi04IDgtOGg2NmM0LjQgMCA4IDMuNiA4IDh2Mjh6J1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgc3ZnR3JvdXAuYXBwZW5kQ2hpbGQocGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3hySWNvbjtcbiAgICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgRXBpYyBHYW1lcywgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuXG5leHBvcnQgY2xhc3MgTWF0aFV0aWxzIHtcbiAgICAvKipcbiAgICAgKiBmb3JtYXRzIEJ5dGVzIGNvbWluZyBpbiBmb3IgdmlkZW8gc3RhdHNcbiAgICAgKiBAcGFyYW0gYnl0ZXMgbnVtYmVyIHRvIGNvbnZlcnRcbiAgICAgKiBAcGFyYW0gZGVjaW1hbHMgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzXG4gICAgICovXG4gICAgc3RhdGljIGZvcm1hdEJ5dGVzKGJ5dGVzOiBudW1iZXIsIGRlY2ltYWxzOiBudW1iZXIpOiBzdHJpbmcge1xuICAgICAgICBpZiAoYnl0ZXMgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiAnMCc7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmYWN0b3IgPSAxMDI0O1xuICAgICAgICBjb25zdCBkbSA9IGRlY2ltYWxzIDwgMCA/IDAgOiBkZWNpbWFscztcbiAgICAgICAgY29uc3Qgc2l6ZXMgPSBbXG4gICAgICAgICAgICAnQnl0ZXMnLFxuICAgICAgICAgICAgJ0tpQicsXG4gICAgICAgICAgICAnTWlCJyxcbiAgICAgICAgICAgICdHaUInLFxuICAgICAgICAgICAgJ1RpQicsXG4gICAgICAgICAgICAnUGlCJyxcbiAgICAgICAgICAgICdFaUInLFxuICAgICAgICAgICAgJ1ppQicsXG4gICAgICAgICAgICAnWWlCJ1xuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IGkgPSBNYXRoLmZsb29yKE1hdGgubG9nKGJ5dGVzKSAvIE1hdGgubG9nKGZhY3RvcikpO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBwYXJzZUZsb2F0KChieXRlcyAvIE1hdGgucG93KGZhY3RvciwgaSkpLnRvRml4ZWQoZG0pKSArXG4gICAgICAgICAgICAnICcgK1xuICAgICAgICAgICAgc2l6ZXNbaV1cbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfX2VwaWNnYW1lc19wc19saWJfcGl4ZWxzdHJlYW1pbmdmcm9udGVuZF91ZTVfM19fOyIsIm1vZHVsZS5leHBvcnRzID0gX19XRUJQQUNLX0VYVEVSTkFMX01PRFVMRV9qc3NfXzsiLCJtb2R1bGUuZXhwb3J0cyA9IF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfanNzX3BsdWdpbl9jYW1lbF9jYXNlX187IiwibW9kdWxlLmV4cG9ydHMgPSBfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFX2pzc19wbHVnaW5fZ2xvYmFsX187IiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXShtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSAobW9kdWxlKSA9PiB7XG5cdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuXHRcdCgpID0+IChtb2R1bGVbJ2RlZmF1bHQnXSkgOlxuXHRcdCgpID0+IChtb2R1bGUpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCB7IGE6IGdldHRlciB9KTtcblx0cmV0dXJuIGdldHRlcjtcbn07IiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyIsIi8vIENvcHlyaWdodCBFcGljIEdhbWVzLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG5cbmV4cG9ydCB7IEFwcGxpY2F0aW9uLCBVSU9wdGlvbnMsIFZpZGVvUVBJbmRpY2F0b3JDb25maWcgfSBmcm9tICcuL0FwcGxpY2F0aW9uL0FwcGxpY2F0aW9uJztcblxuZXhwb3J0IHsgUGl4ZWxTdHJlYW1pbmdBcHBsaWNhdGlvblN0eWxlIH0gZnJvbSAnLi9TdHlsZXMvUGl4ZWxTdHJlYW1pbmdBcHBsaWNhdGlvblN0eWxlcyc7XG5cbmV4cG9ydCB7IEFGS092ZXJsYXkgfSBmcm9tICcuL092ZXJsYXkvQUZLT3ZlcmxheSc7XG5leHBvcnQgeyBBY3Rpb25PdmVybGF5IH0gZnJvbSAnLi9PdmVybGF5L0FjdGlvbk92ZXJsYXknO1xuZXhwb3J0IHsgT3ZlcmxheUJhc2UgfSBmcm9tICcuL092ZXJsYXkvQmFzZU92ZXJsYXknO1xuZXhwb3J0IHsgQ29ubmVjdE92ZXJsYXkgfSBmcm9tICcuL092ZXJsYXkvQ29ubmVjdE92ZXJsYXknO1xuZXhwb3J0IHsgRGlzY29ubmVjdE92ZXJsYXkgfSBmcm9tICcuL092ZXJsYXkvRGlzY29ubmVjdE92ZXJsYXknO1xuZXhwb3J0IHsgRXJyb3JPdmVybGF5IH0gZnJvbSAnLi9PdmVybGF5L0Vycm9yT3ZlcmxheSc7XG5leHBvcnQgeyBJbmZvT3ZlcmxheSB9IGZyb20gJy4vT3ZlcmxheS9JbmZvT3ZlcmxheSc7XG5leHBvcnQgeyBQbGF5T3ZlcmxheSB9IGZyb20gJy4vT3ZlcmxheS9QbGF5T3ZlcmxheSc7XG5leHBvcnQgeyBUZXh0T3ZlcmxheSB9IGZyb20gJy4vT3ZlcmxheS9UZXh0T3ZlcmxheSc7XG5leHBvcnQgeyBDb25maWdVSSB9IGZyb20gJy4vQ29uZmlnL0NvbmZpZ1VJJztcbmV4cG9ydCB7IFNldHRpbmdVSUJhc2UgfSBmcm9tICcuL0NvbmZpZy9TZXR0aW5nVUlCYXNlJztcbmV4cG9ydCB7IFNldHRpbmdVSUZsYWcgfSBmcm9tICcuL0NvbmZpZy9TZXR0aW5nVUlGbGFnJztcbmV4cG9ydCB7IFNldHRpbmdVSU51bWJlciB9IGZyb20gJy4vQ29uZmlnL1NldHRpbmdVSU51bWJlcic7XG5leHBvcnQgeyBTZXR0aW5nVUlPcHRpb24gfSBmcm9tICcuL0NvbmZpZy9TZXR0aW5nVUlPcHRpb24nO1xuZXhwb3J0IHsgU2V0dGluZ1VJVGV4dCB9IGZyb20gJy4vQ29uZmlnL1NldHRpbmdVSVRleHQnO1xuZXhwb3J0IHsgUGFuZWxDb25maWd1cmF0aW9uLCBVSUVsZW1lbnRDb25maWcsIFVJRWxlbWVudENyZWF0aW9uTW9kZSB9IGZyb20gJy4vVUkvVUlDb25maWd1cmF0aW9uVHlwZXMnXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=