-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathMatrix.ps1
More file actions
362 lines (324 loc) · 67.5 KB
/
Copy pathMatrix.ps1
File metadata and controls
362 lines (324 loc) · 67.5 KB
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
<#
|====================================================================================>|
Matrix Animation [PwShell] by APoorv Verma [AP] on 8/21/2024
|====================================================================================>|
$) Multiple renderers (Windows, Unix): Default is Auto-Detect
$) Sparsity of the matrix effect (1 is fully dense, 0.1 is sparse)
$) Random Character Generation (+ Special Character Mode, like from the movie)
$) Object Oriented Model for Matrix Line (using Ticking logic)
$) Buffer / Cursor Position Saving (platform agnostic)
$) Dynamic Console Size Detection
$) Restore Console Properties upon Close
|====================================================================================>|
#>
using namespace System.Management.Automation.Host
param(
# Sparsity of the matrix effect (1 is fully dense, 0.1 is sparse)
[ValidateRange(0.0001, 1)][double]$Sparsity = 0.1,
# Sleep time in milliseconds between each frame
[ValidateRange(1, 10000)][int]$SleepTime = 50,
[ValidateSet("Windows", "Unix", "Auto-Detect")][string]$Renderer = "Auto-Detect",
[Switch]$SpecialChars,
[Switch]$Debug
)
# =======================================START=OF=COMPILER================================================================|
# The Following Code was added by AP-Compiler 1.6 (APC: 1.3) To Make this program independent of AP-Core Engine
# GitHub: https://github.com/avdaredevil/AP-Compiler
# ========================================================================================================================|
$Script:PSHell=$(if($PSHell){$PSHell}elseif($PSScriptRoot){$PSScriptRoot}else{"."});
if($AP_CONSOLE.mode -ne 'main' -or $AP_CONSOLE.customFlags.runAsCompiled) {
$Script:AP_CONSOLE = [PsCustomObject]@{version=[version]'1.3'; mode = 'shim'; customFlags = @{}}
function B64 {param([Parameter(ValueFromPipeline=$true)][String]$Text, [ValidateSet("UTF8","Unicode")][String]$Encoding = "UTF8") [System.Text.Encoding]::$Encoding.GetString([System.Convert]::FromBase64String($Text))}
# This syntax is to prevent AV's from misclassifying this as anything but innocuous
& (Get-Alias iex) (B64 "ZnVuY3Rpb24gQVAtUmVxdWlyZSB7cGFyYW0oW1BhcmFtZXRlcihNYW5kYXRvcnk9JFRydWUpXVtBbGlhcygiRnVuY3Rpb25hbGl0eSIsIkxpYnJhcnkiKV1bQXJndW1lbnRDb21wbGV0ZXIoew0KICAgIFtPdXRwdXRUeXBlKFtTeXN0ZW0uTWFuYWdlbWVudC5BdXRvbWF0aW9uLkNvbXBsZXRpb25SZXN1bHRdKV0NCiAgICBwYXJhbSgNCiAgICAgICAgW3N0cmluZ10gJENvbW1hbmROYW1lLA0KICAgICAgICBbc3RyaW5nXSAkUGFyYW1ldGVyTmFtZSwNCiAgICAgICAgW3N0cmluZ10gJFdvcmRUb0NvbXBsZXRlLA0KICAgICAgICBbU3lzdGVtLk1hbmFnZW1lbnQuQXV0b21hdGlvbi5MYW5ndWFnZS5Db21tYW5kQXN0XSAkQ29tbWFuZEFzdCwNCiAgICAgICAgW1N5c3RlbS5Db2xsZWN0aW9ucy5JRGljdGlvbmFyeV0gJEZha2VCb3VuZFBhcmFtZXRlcnMNCiAgICApDQogICAgJENvbXBsZXRpb25SZXN1bHRzID0gW1N5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RbU3lzdGVtLk1hbmFnZW1lbnQuQXV0b21hdGlvbi5Db21wbGV0aW9uUmVzdWx0XV06Om5ldygpDQogICAgJExpYiA9IEAoIkludGVybmV0Iiwib3M6d2luZG93cyIsIm9zOm1hYyIsIm9zOmxpbnV4Iiwib3M6dW5peCIsImFkbWluaXN0cmF0b3IiLCJyb290IiwiZGVwOiIsImxpYjoiLCJsaWJfdGVzdDoiLCJtb2R1bGU6IiwibW9kdWxlX3Rlc3Q6IiwiZnVuY3Rpb246Iiwic3RyaWN0X2Z1bmN0aW9uOiIsImFiaWxpdHk6ZXNjYXBlX2NvZGVzIiwiYWJpbGl0eTplbW9qaXMiLCJhYmlsaXR5Om5lcmRfZm9udCIsImFiaWxpdHk6bG9uZ19wYXRocyIsImFiaWxpdHk6Y29uc29sZV9tYW5pcHVsYXRpb24iKQ0KICAgICRqc09yID0ge2ZvcmVhY2ggKCRhIGluICRhcmdzKSB7JGEgPSAkKGlmKCRhIC1pcyBbc2NyaXB0YmxvY2tdKXsmJGF9ZWxzZXskYX0pO2lmICghJGEpe2NvbnRpbnVlfTtyZXR1cm4gJGF9O3JldHVybiAkYX0gIyBNYW51YWxseSBlbWJlZGRlZCBKUy1PUg0KICAgICYgJGpzT3IgeyRMaWIgfCA/IHskXyAtbGlrZSAiJFdvcmRUb0NvbXBsZXRlKiJ9fSB7JExpYiB8ID8geyRfIC1saWtlICIqJFdvcmRUb0NvbXBsZXRlKiJ9fSB8ICUgew0KICAgICAgICAkQ29tcGxldGlvblJlc3VsdHMuQWRkKFtTeXN0ZW0uTWFuYWdlbWVudC5BdXRvbWF0aW9uLkNvbXBsZXRpb25SZXN1bHRdOjpuZXcoJF8sICRfLCAnUGFyYW1ldGVyVmFsdWUnLCAkXykpDQogICAgfQ0KICAgIHJldHVybiAkQ29tcGxldGlvblJlc3VsdHMNCn0pXVtTdHJpbmddJExpYiwgW1NjcmlwdEJsb2NrXSRPbkZhaWwsIFtTd2l0Y2hdJFBhc3NUaHJ1KQ0KDQogICAgJExvYWRNb2R1bGUgPSB7DQogICAgICAgIHBhcmFtKCRGaWxlLFtib29sXSRJbXBvcnQpDQogICAgICAgIHRyeSB7SW1wb3J0LU1vZHVsZSAkRmlsZSAtZWEgc3RvcDtyZXR1cm4gMX0gY2F0Y2gge30NCiAgICAgICAgJExpYj1BUC1Db252ZXJ0UGF0aCAiPExJQj4iOyRMRiA9ICIkTGliXCRGaWxlIg0KICAgICAgICAkZiA9ICRMRiwiJExGLnBzbTEiLCIkTEYuZGxsIiB8ID8ge3Rlc3QtcGF0aCAtdCBsZWFmICRffSB8IHNlbGVjdCAtZiAxDQogICAgICAgIGlmICgkZiAtYW5kICRJbXBvcnQpIHsNCiAgICAgICAgICAgIEltcG9ydC1Nb2R1bGUgJGYNCiAgICAgICAgICAgIGlmICgkPykge3JldHVybiAkZn0gZWxzZSB7V3JpdGUtQVAgIiFGYWlsZWQgdG8gaW1wb3J0IFskRmlsZSAtPiAkRl0iO3JldHVybiAwfQ0KICAgICAgICB9DQogICAgICAgIHJldHVybiAkZg0KICAgIH0NCiAgICAkSW52b2tlT3JSZXR1cm4gPSB7cGFyYW0oJENtZCwgJGZhbGxiYWNrPTApIGlmICgkQ21kIC1pcyBbU2NyaXB0QmxvY2tdKSB7dHJ5eyYgJENtZH1jYXRjaHskZmFsbGJhY2t9fSBlbHNlIHskQ21kfX0NCiAgICBpZiAoISRPbkZhaWwpIHskUGFzc1RocnUgPSAkdHJ1ZX0NCiAgICAkU3RhdCA9ICQoc3dpdGNoIC1yZWdleCAoJExpYi50cmltKCkpIHsNCiAgICAgICAgIl5JbnRlcm5ldCQiICAgICAgICAgICAgICAgICAgICAgICB7dGVzdC1jb25uZWN0aW9uIGdvb2dsZS5jb20gLUNvdW50IDEgLVF1aWV0fQ0KICAgICAgICAiXmFkbWluKGlzdHJhdG9yKT8kfF5yb290JCIgICAgICAgIHtUZXN0LUFkbWluaXN0cmF0b3J9DQogICAgICAgICJeZGVwOiguKikkIiAgICAgICAgICAgICAgICAgICAgICAge0dldC1XaGVyZSAkTWF0Y2hlc1sxXX0NCiAgICAgICAgIl4obGlifG1vZHVsZSk6KC4qKSQiICAgICAgICAgICAgICB7JExvYWRNb2R1bGUuaW52b2tlKCRNYXRjaGVzWzJdLCAkdHJ1ZSl9DQogICAgICAgICJeKGxpYnxtb2R1bGUpX3Rlc3Q6KC4qKSQiICAgICAgICAgeyRMb2FkTW9kdWxlLmludm9rZSgkTWF0Y2hlc1syXSl9DQogICAgICAgICJeZnVuY3Rpb246KC4qKSQiICAgICAgICAgICAgICAgICAge2djbSAkTWF0Y2hlc1sxXSAtZWEgU2lsZW50bHlDb250aW51ZX0NCiAgICAgICAgIl5zdHJpY3RfZnVuY3Rpb246KC4qKSQiICAgICAgICAgICB7VGVzdC1QYXRoICJGdW5jdGlvbjpcJCgkTWF0Y2hlc1sxXSkifQ0KICAgICAgICAiXm9zOih3aW4oZG93cyk/fGxpbnV4fG1hY3x1bml4KSQiIHskbyA9IEdldC1PUzskSXNVbml4ID0gJFBTVmVyc2lvblRhYmxlLlBsYXRmb3JtIC1lcSAiVW5peCI7c3dpdGNoIC1yZWdleCAoJE1hdGNoZXNbMV0pIHsNCiAgICAgICAgICAgICJed2luIiAgIHtyZXR1cm4gJG8gLWVxICJXaW5kb3dzIn0NCiAgICAgICAgICAgICJsaW51eCIgIHtyZXR1cm4gJG8gLWVxICJMaW51eCJ9DQogICAgICAgICAgICAibWFjIiAgICB7cmV0dXJuICRvIC1lcSAiTWFjT1MifQ0KICAgICAgICAgICAgInVuaXgiICAge3JldHVybiAkSXNVbml4fQ0KICAgICAgICB9fQ0KICAgICAgICAiXmFiaWxpdHk6KC4rKSQiICAgICB7JG0gPSAkTWF0Y2hlc1sxXTtKUy1OQ1EgKCYgJEludm9rZU9yUmV0dXJuIChAew0KICAgICAgICAgICAgZXNjYXBlX2NvZGVzID0gJEhvc3QuVUkuU3VwcG9ydHNWaXJ0dWFsVGVybWluYWwNCiAgICAgICAgICAgIGVtb2ppcyA9ICRlbnY6V1RfU0VTU0lPTiAtb3IgJGVudjpXVF9QUk9GSUxFX0lEIC1vciAoJGVudjpURVJNX1BST0dSQU0gLW1hdGNoICd2c2NvZGV8aVRlcm0uYXBwfEFwcGxlX1Rlcm1pbmFsJykNCiAgICAgICAgICAgIG5lcmRfZm9udCA9IHskcD0kSG9zdC5VSS5SYXdVSS5DdXJzb3JQb3NpdGlvbjtXcml0ZS1Ib3N0IC1Ob05ld2xpbmUgKFtjaGFyXTo6Q29udmVydEZyb21VdGYzMigweEYwNTMxKSk7JG49JEhvc3QuVUkuUmF3VUkuQ3Vyc29yUG9zaXRpb247JEhvc3QuVUkuUmF3VUkuQ3Vyc29yUG9zaXRpb249JHA7V3JpdGUtSG9zdCAtTm9OZXdsaW5lICcgICc7JEhvc3QuVUkuUmF3VUkuQ3Vyc29yUG9zaXRpb249JHA7KCRuLlgtJHAuWCktZXEgMX0NCiAgICAgICAgICAgIGxvbmdfcGF0aHMgPSAkUFNWZXJzaW9uVGFibGUuUGxhdGZvcm0gLWVxICJVbml4IiAtb3IgKEdldC1JdGVtUHJvcGVydHkgLVBhdGggIkhLTE06XFNZU1RFTVxDdXJyZW50Q29udHJvbFNldFxDb250cm9sXEZpbGVTeXN0ZW0iIHwgJSBsb25ncGF0aHNlbmFibGVkKQ0KICAgICAgICAgICAgY29uc29sZV9tYW5pcHVsYXRpb24gPSAhW1N5c3RlbS5Db25zb2xlXTo6SXNPdXRwdXRSZWRpcmVjdGVkIC1hbmQgKCRIb3N0Lk5hbWUgLWVxICdDb25zb2xlSG9zdCcpDQogICAgICAgIH1bJG1dKSkge1dyaXRlLUFQICIhUmVxdWlyZWQgYWJpbGl0eSBbJG1dIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybS4iOyB0aHJvdyAnQkFEX1NFTEVDVE9SJ319DQogICAgICAgIGRlZmF1bHQge1dyaXRlLUFQICIhSW52YWxpZCBzZWxlY3RvciBwcm92aWRlZCBbJCgiJExpYiIuc3BsaXQoJzonKVswXSldIjt0aHJvdyAnQkFEX1NFTEVDVE9SJ30NCiAgICB9KQ0KICAgIGlmICghJFN0YXQgLWFuZCAkT25GYWlsKSB7JiAkT25GYWlsfQ0KICAgIGlmICgkUGFzc1RocnUgLW9yICEkT25GYWlsKSB7cmV0dXJuICRTdGF0fQ0KfQoKZnVuY3Rpb24gQWxpZ24tVGV4dCB7DQogICAgW0NtZGxldEJpbmRpbmcoKV0NCiAgICBbT3V0cHV0VHlwZShbU3RyaW5nXSwgW0hhc2h0YWJsZV0pXQ0KICAgIHBhcmFtKA0KICAgICAgICBbUGFyYW1ldGVyKE1hbmRhdG9yeT0xLCBWYWx1ZUZyb21QaXBlbGluZT0xKV1bQWxsb3dFbXB0eVN0cmluZygpXVtTdHJpbmdbXV0kVGV4dCwNCiAgICAgICAgW3N3aXRjaF0kQ29sb3JDb2Rlc0Rpc2NyZXRlUGVyTGluZSwNCiAgICAgICAgW3N3aXRjaF0kUG9yY2VsYWluLA0KICAgICAgICAjIFRoaXMgY2FuIGJlIFtpbnRdIG9yIFtzY3JpcHRibG9ja10NCiAgICAgICAgJENvbnN0cmFpblRvV2lkdGgsDQogICAgICAgIFtWYWxpZGF0ZVNldCgiQ2VudGVyIiwiUmlnaHQiLCJMZWZ0IildW1N0cmluZ10kQWxpZ249J0NlbnRlcicNCiAgICApDQogICAgYmVnaW4gew0KICAgICAgICAkaXNWZXJib3NlID0gJFBTQ21kbGV0Lk15SW52b2NhdGlvbi5Cb3VuZFBhcmFtZXRlcnMuVmVyYm9zZQ0KICAgICAgICAkRXNjYXBlQ29kZVNwbGl0dGVyID0gIiQoW3JlZ2V4XTo6ZXNjYXBlKCIkKEdldC1Fc2NhcGUpWyIpKVxkKyg/Olw7XGQrKSptIg0KICAgICAgICAkRGl2aWRlcnMgPSBAe2NodW5rID0gUHJvY2Vzcy1Vbmljb2RlICJgdXsxMTI4OH0iOyBzdHlsZSA9IFByb2Nlc3MtVW5pY29kZSAiYHV7MTIyODh9In0NCiAgICAgICAgJEZpbmFsRm9ybWF0dGVyID0gew0KICAgICAgICAgICAgcGFyYW0oJExpbmVzLCAkU3R5bGVzKQ0KICAgICAgICAgICAgaWYgKCEkUG9yY2VsYWluKSB7cmV0dXJuICRMaW5lc30NCiAgICAgICAgICAgIGlmICgkbnVsbCAtZXEgJFN0eWxlcykgeyRTdHlsZXMgPSBbUmVnZXhdOjpNYXRjaGVzKCgkTGluZXMgLWpvaW4gIiIpLCAkRXNjYXBlQ29kZVNwbGl0dGVyKS52YWx1ZX0NCiAgICAgICAgICAgIHJldHVybiBAe0xpbmVzID0gJExpbmVzOyBSdW5uaW5nU3R5bGVzID0gJFN0eWxlc30NCiAgICAgICAgfQ0KICAgIH0NCiAgICBwcm9jZXNzIHsNCiAgICAgICAgaWYgKCRBbGlnbiAtZXEgIkxlZnQiKSB7cmV0dXJuICYgJEZpbmFsRm9ybWF0dGVyICRUZXh0fQ0KICAgICAgICBpZiAoISIkVGV4dCIudHJpbSgpKSB7cmV0dXJuICRUZXh0fQ0KICAgICAgICAkV2luU2l6ZSA9ID86ICRDb25zdHJhaW5Ub1dpZHRoIHtJbnZva2UtT3JSZXR1cm4gJENvbnN0cmFpblRvV2lkdGh9IChbY29uc29sZV06OkJ1ZmZlcldpZHRoKQ0KICAgICAgICANCiAgICAgICAgJFRleHQgPSAkVGV4dCAtc3BsaXQgImByP2BuIg0KICAgICAgICBpZiAoJFRleHQuY291bnQgLWd0IDEpIHsNCiAgICAgICAgICAgICRMaW5lcyA9ICRUZXh0IHwgQWxpZ24tVGV4dCAtQWxpZ24gJEFsaWduIC1Db2xvckNvZGVzRGlzY3JldGVQZXJMaW5lOiRDb2xvckNvZGVzRGlzY3JldGVQZXJMaW5lIC1Qb3JjZWxhaW4NCiAgICAgICAgICAgIGlmICgkQ29sb3JDb2Rlc0Rpc2NyZXRlUGVyTGluZSkgew0KICAgICAgICAgICAgICAgIGZvciAoJGkgPSAxOyAkaSAtbHQgJExpbmVzLkNvdW50OyAkaSsrKSB7DQogICAgICAgICAgICAgICAgICAgICRMaW5lID0gJExpbmVzWyRpXQ0KICAgICAgICAgICAgICAgICAgICAkUHJldlN0eWxlcyArPSAkTGluZXNbJGkgLSAxXS5SdW5uaW5nU3R5bGVzDQogICAgICAgICAgICAgICAgICAgICRMaW5lLkxpbmVzID0gJExpbmUuTGluZXMgfCAlIHsiJFByZXZTdHlsZXMkXyJ9DQogICAgICAgICAgICAgICAgICAgICRMaW5lLlJ1bm5pbmdTdHlsZXMgPSAiJFByZXZTdHlsZXMkKCRMaW5lLlJ1bm5pbmdTdHlsZXMpIg0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiAmICRGaW5hbEZvcm1hdHRlciAoRmxhdHRlbiAkTGluZXMuTGluZXMpICgkTGluZXMuUnVubmluZ1N0eWxlcyAtam9pbiAiIikNCiAgICAgICAgfQ0KICAgICAgICAjIFNpbmdsZSBub24gYG4gbGluZSBwcm9jZXNzDQogICAgICAgICRDbGVhblRleHRTaXplID0gKFN0cmlwLUNvbG9yQ29kZXMgKCIiKyRUZXh0KSkuTGVuZ3RoDQoNCiAgICAgICAgIyA9PT09PT09PSBMaW5lIGlzIDwgJFdpblNpemUgPT09PT09PT09PT09PT18DQogICAgICAgIGlmICgkQ2xlYW5UZXh0U2l6ZSAtbGUgJFdpblNpemUpIHsNCiAgICAgICAgICAgIGlmICgkQWxpZ24gLWVxICJDZW50ZXIiKSB7DQogICAgICAgICAgICAgICAgcmV0dXJuICYgJEZpbmFsRm9ybWF0dGVyICgiICIqW21hdGhdOjp0cnVuY2F0ZSgoJFdpblNpemUtJENsZWFuVGV4dFNpemUpLzIpKyRUZXh0KQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgIyBSaWdodA0KICAgICAgICAgICAgcmV0dXJuICYgJEZpbmFsRm9ybWF0dGVyICgiICIqKCRXaW5TaXplLSRDbGVhblRleHRTaXplKSskVGV4dCkNCiAgICAgICAgfQ0KDQogICAgICAgICMgPT09PT09PT0gTGluZSBpcyA+PSAkV2luU2l6ZSA9PT09PT09PT09PT09PXwNCiAgICAgICAgIyBUcmFja2luZyBTdHlsZXMNCiAgICAgICAgJFJ1bm5pbmdTdHlsZXMgPSAiIg0KICAgICAgICAkQ3VycmxpbmUgPSBAew0KICAgICAgICAgICAgc3R5bGVkRGF0YSA9ICIiDQogICAgICAgICAgICBjb250ZW50U2l6ZSA9IDANCiAgICAgICAgICAgIGZpbmFsTGluZXMgPSBAKCkNCiAgICAgICAgICAgIG5leHQgPSB7DQogICAgICAgICAgICAgICAgIyBXcml0ZS1WZXJib3NlICIqJEludm9rIHwgTmV3IExpbmUgfCBMaW5lRGF0YTogJCgoJycrJEN1cnJsaW5lLnN0eWxlZERhdGEuTGVuZ3RoKS5QYWRMZWZ0KDMpKSINCiAgICAgICAgICAgICAgICAkQ3VycmxpbmUuZmluYWxMaW5lcyArPSAsJEN1cnJsaW5lLnN0eWxlZERhdGENCiAgICAgICAgICAgICAgICAkQ3VycmxpbmUuc3R5bGVkRGF0YSA9ICRSdW5uaW5nU3R5bGVzDQogICAgICAgICAgICAgICAgJEN1cnJsaW5lLmNvbnRlbnRTaXplID0gMA0KICAgICAgICAgICAgICAgICMgV3JpdGUtVmVyYm9zZSAiKiRJbnZvayB8IEN1cnIgVG90YWwgTGluZXM6ICQoJGN1cnJsaW5lLmZpbmFsTGluZXMuQ291bnQpIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICRBbGxDaHVua3MgPSAkVGV4dCAtcmVwbGFjZSAiKCR7RXNjYXBlQ29kZVNwbGl0dGVyfSkrKC4qPykoPz0ke0VzY2FwZUNvZGVTcGxpdHRlcn18JCkiLCIkKCREaXZpZGVycy5jaHVuaylgJDEkKCREaXZpZGVycy5zdHlsZSlgJDIiIC1zcGxpdCAkRGl2aWRlcnMuY2h1bmsNCiAgICAgICAgaWYgKCRBbGxDaHVua3NbMF0gLW5vdGNvbnRhaW5zICREaXZpZGVycy5zdHlsZSkgeyRBbGxDaHVua3NbMF0gPSAiJCgkRGl2aWRlcnMuc3R5bGUpJCgkQWxsQ2h1bmtzWzBdKSJ9ICMgVGhlIGZpcnN0IGNodW5rIGNvdWxkIGhhdmUgbm8gc3R5bGVzDQogICAgICAgIGZvcmVhY2ggKCRDdXJyQ2h1bmsgaW4gJEFsbENodW5rcykgew0KICAgICAgICAgICAgJFN0eWxlLCRUZXh0Q2h1bmsgPSAkQ3VyckNodW5rIC1zcGxpdCAkRGl2aWRlcnMuc3R5bGUNCiAgICAgICAgICAgICRSdW5uaW5nU3R5bGVzID0gPzogJENvbG9yQ29kZXNEaXNjcmV0ZVBlckxpbmUgIiRSdW5uaW5nU3R5bGVzJFN0eWxlIiAkU3R5bGUNCiAgICAgICAgICAgICMgV3JpdGUtSG9zdCAtZiAyICgiSW5jb21pbmdTdHlsZTogJFN0eWxlIHwgUnVubmluZ1N0eWxlczogJFJ1bm5pbmdTdHlsZXMiIC1yZXBsYWNlIChbcmVnZXhdOjpFc2NhcGUoJChHZXQtRXNjYXBlKSkpLCdcZScpDQogICAgICAgICAgICAjIFdyaXRlLUhvc3QgLWYgWWVsbG93ICJUZXh0Q2h1bms6ICRUZXh0Q2h1bmsiDQogICAgICAgICAgICAkQ3VycmxpbmUuc3R5bGVkRGF0YSArPSAkUnVubmluZ1N0eWxlcw0KICAgICAgICAgICAgJFRleHRDaHVua1N0ckluZGV4ID0gMA0KICAgICAgICAgICAgIyBXcml0ZS1WZXJib3NlICIqJEludm9rIHwgVGV4dENodW5rOiAkVGV4dENodW5rIHwgQWxsQ2h1bmtzU2l6ZTogJCgoJycrJEFsbENodW5rcy5MZW5ndGgpLlBhZExlZnQoMykpIg0KICAgICAgICAgICAgd2hpbGUoJFRleHRDaHVua1N0ckluZGV4IC1sdCAkVGV4dENodW5rLkxlbmd0aCkgew0KICAgICAgICAgICAgICAgIGlmICgkaXNWZXJib3NlKSB7UGxhY2UtQnVmZmVyZWRDb250ZW50ICgiJEludm9rIHwgTGluZURhdGE6ICQoKCcnKyRDdXJybGluZS5zdHlsZWREYXRhLkxlbmd0aCkuUGFkTGVmdCgzKSkgfCBDaHVua0lkeDogJCgoJycrJFRleHRDaHVua1N0ckluZGV4KS5QYWRMZWZ0KDMpKSB8IENodW5rTGVuOiAkKCRUZXh0Q2h1bmsuTGVuZ3RoKSB8IEZpbmFsTGluZXM6ICQoJEN1cnJsaW5lLmZpbmFsTGluZXMuQ291bnQpIikgLXggMCAteSAoW0NvbnNvbGVdOjpCdWZmZXJIZWlnaHQgLSAxKSBZZWxsb3cgRGFya0dyYXl9DQogICAgICAgICAgICAgICAgJENodW5rU2l6ZSA9ICRUZXh0Q2h1bmsuTGVuZ3RoIC0gJFRleHRDaHVua1N0ckluZGV4DQogICAgICAgICAgICAgICAgV3JpdGUtVmVyYm9zZSAiKkNodW5rU2l6ZTogJENodW5rU2l6ZSB8ICQoJEN1cnJsaW5lLmNvbnRlbnRTaXplKSB8ICRXaW5TaXplIg0KICAgICAgICAgICAgICAgIGlmICgoJEN1cnJsaW5lLmNvbnRlbnRTaXplKyRDaHVua1NpemUpIC1sdCAkV2luU2l6ZSkgew0KICAgICAgICAgICAgICAgICAgICAjIElmIHRoZSBjdXJyZW50IGNodW5rIGZpdHMgaW4gdGhlIGN1cnJlbnQgbGluZQ0KICAgICAgICAgICAgICAgICAgICAkQ3VycmxpbmUuc3R5bGVkRGF0YSArPSAkVGV4dENodW5rLlN1YnN0cmluZygkVGV4dENodW5rU3RySW5kZXgpDQogICAgICAgICAgICAgICAgICAgICRDdXJybGluZS5jb250ZW50U2l6ZSArPSAkQ2h1bmtTaXplDQogICAgICAgICAgICAgICAgICAgICRUZXh0Q2h1bmtTdHJJbmRleCArPSAkQ2h1bmtTaXplDQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICMgSWYgdGhlIGN1cnJlbnQgY2h1bmsgZG9lc24ndCBmaXQgaW4gdGhlIGN1cnJlbnQgbGluZQ0KICAgICAgICAgICAgICAgICRuZXdDb250ZW50ID0gJFRleHRDaHVuay5TdWJzdHJpbmcoJFRleHRDaHVua1N0ckluZGV4LCAkV2luU2l6ZS0kQ3VycmxpbmUuY29udGVudFNpemUpDQogICAgICAgICAgICAgICAgJEN1cnJsaW5lLnN0eWxlZERhdGEgKz0gJG5ld0NvbnRlbnQNCiAgICAgICAgICAgICAgICAkQ3VycmxpbmUuY29udGVudFNpemUgKz0gJG5ld0NvbnRlbnQubGVuZ3RoDQogICAgICAgICAgICAgICAgJFRleHRDaHVua1N0ckluZGV4ICs9ICRuZXdDb250ZW50Lmxlbmd0aA0KICAgICAgICAgICAgICAgICYgJEN1cnJsaW5lLm5leHQNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBpZiAoJEN1cnJsaW5lLmNvbnRlbnRTaXplIC1ndCAwKSB7DQogICAgICAgICAgICBpZiAoJEN1cnJsaW5lLmNvbnRlbnRTaXplKXsNCiAgICAgICAgICAgICAgICBBbGlnbi1UZXh0IC1BbGlnbiAkQWxpZ24gLVRleHQgJEN1cnJsaW5lLnN0eWxlZERhdGEgLUNvbG9yQ29kZXNEaXNjcmV0ZVBlckxpbmU6JENvbG9yQ29kZXNEaXNjcmV0ZVBlckxpbmUgfCA/IHskX30gfCAlIHsNCiAgICAgICAgICAgICAgICAgICAgJEN1cnJsaW5lLmZpbmFsTGluZXMgKz0gLCRfDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAkQ3VycmxpbmUuZmluYWxMaW5lc1stMV0gKz0gJEN1cnJsaW5lLnN0eWxlZERhdGENCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gJiAkRmluYWxGb3JtYXR0ZXIgJEN1cnJsaW5lLmZpbmFsTGluZXMgJFJ1bm5pbmdTdHlsZXMNCiAgICAgICAgcmV0dXJuICRDdXJybGluZS5maW5hbExpbmVzDQogICAgfQ0KfQoKZnVuY3Rpb24gS2V5VHJhbnNsYXRlIHtwYXJhbShbUGFyYW1ldGVyKE1hbmRhdG9yeT0kVHJ1ZSldW1N0cmluZ10kS2V5KQ0KDQogICAgJEhhc2hLZXkgPSBAew0KICAgICAgICAifn5DdHJsQ35+Ij02Nw0KICAgICAgICAifn5TcGFjZX5+Ij0zMg0KICAgICAgICAifn5FU0NBUEV+fiI9MjcNCiAgICAgICAgIn5+RW50ZXJ+fiI9MTMNCiAgICAgICAgIn5+U2hpZnR+fiI9MTYNCiAgICAgICAgIn5+Q29udHJvbH5+Ij0xNw0KICAgICAgICAifn5Db250cm9sTGVmdH5+Ij1Ae2NvZGUgPSAxNzsgZW5oYW5jZWQgPSAkZmFsc2V9DQogICAgICAgICJ+fkNvbnRyb2xSaWdodH5+Ij1Ae2NvZGUgPSAxNzsgZW5oYW5jZWQgPSAkdHJ1ZX0NCiAgICAgICAgIn5+QWx0fn4iPTE4DQogICAgICAgICJ+fkJhY2tTcGFjZX5+Ij04DQogICAgICAgICJ+fkRlbGV0ZX5+Ij00Ng0KICAgICAgICAifn5mMX5+Ij0xMTINCiAgICAgICAgIn5+ZjJ+fiI9MTEzDQogICAgICAgICJ+fmYzfn4iPTExNA0KICAgICAgICAifn5mNH5+Ij0xMTUNCiAgICAgICAgIn5+ZjV+fiI9MTE2DQogICAgICAgICJ+fmY2fn4iPTExNw0KICAgICAgICAifn5mN35+Ij0xMTgNCiAgICAgICAgIn5+Zjh+fiI9MTE5DQogICAgICAgICJ+fmY5fn4iPTEyMA0KICAgICAgICAifn5mMTB+fiI9MTIxDQogICAgICAgICJ+fmYxMX5+Ij0xMjINCiAgICAgICAgIn5+ZjEyfn4iPTEyMw0KICAgICAgICAifn5NdXRlfn4iPTE3Mw0KICAgICAgICAifn5JbnNlcnR+fiI9NDUNCiAgICAgICAgIn5+UGFnZVVwfn4iPTMzDQogICAgICAgICJ+flBhZ2VEb3dufn4iPTM0DQogICAgICAgICJ+fkVORH5+Ij0zNQ0KICAgICAgICAifn5IT01Ffn4iPTM2DQogICAgICAgICJ+fnRhYn5+Ij05DQogICAgICAgICJ+fkNhcHNMb2Nrfn4iPTIwDQogICAgICAgICJ+fk51bUxvY2t+fiI9MTQ0DQogICAgICAgICJ+flNjcm9sbExvY2t+fiI9MTQ1DQogICAgICAgICJ+fldpbmRvd3N+fiI9OTENCiAgICAgICAgIn5+TGVmdH5+Ij0zNw0KICAgICAgICAifn5VcH5+Ij0zOA0KICAgICAgICAifn5SaWdodH5+Ij0zOQ0KICAgICAgICAifn5Eb3dufn4iPTQwDQogICAgICAgICJ+fktQMH5+Ij05Ng0KICAgICAgICAifn5LUDF+fiI9OTcNCiAgICAgICAgIn5+S1Ayfn4iPTk4DQogICAgICAgICJ+fktQM35+Ij05OQ0KICAgICAgICAifn5LUDR+fiI9MTAwDQogICAgICAgICJ+fktQNX5+Ij0xMDENCiAgICAgICAgIn5+S1A2fn4iPTEwMg0KICAgICAgICAifn5LUDd+fiI9MTAzDQogICAgICAgICJ+fktQOH5+Ij0xMDQNCiAgICAgICAgIn5+S1A5fn4iPTEwNQ0KICAgICAgICAifn5LUCp+fiI9MTA2DQogICAgICAgICJ+fktQK35+Ij0xMDcNCiAgICAgICAgIn5+S1Atfn4iPTEwOQ0KICAgICAgICAifn5LUC5+fiI9MTEwDQogICAgICAgICJ+fktQL35+Ij0xMTENCiAgICAgICAgIn5+S1AtRU5URVJ+fiI9QHtjb2RlID0gMTM7IGVuaGFuY2VkID0gJHRydWV9DQogICAgfQ0KICAgIGlmICgkQ29udmVydCA9ICRIYXNoS2V5LiRLZXkpIHtyZXR1cm4gJENvbnZlcnR9DQogICAgVGhyb3cgIkludmFsaWQgU3BlY2lhbCBLZXkgQ29udmVyc2lvbiBbJEtleV0iDQp9CgpmdW5jdGlvbiBGbGF0dGVuIHtwYXJhbShbb2JqZWN0W11dJHgpDQoNCiAgICBpZiAoISgkWCAtaXMgW2FycmF5XSkpIHtyZXR1cm4gJHh9DQogICAgaWYgKCRYLmNvdW50IC1lcSAxKSB7DQogICAgICAgIHJldHVybiAkeCB8ICUgeyRffQ0KICAgIH0NCiAgICAkeCB8ICUge0ZsYXR0ZW4gJF99DQp9CgpmdW5jdGlvbiBKUy1OQ1Ege2ZvcmVhY2ggKCRhIGluICRhcmdzKSB7JHIgPSBJbnZva2UtT3JSZXR1cm4gJGE7aWYgKCRudWxsIC1uZSAkcikge3JldHVybiAkcn19O3JldHVybiAkcn0KCmZ1bmN0aW9uIFRlc3QtQWRtaW5pc3RyYXRvciB7DQogICAgaWYgKCRQU1ZlcnNpb25UYWJsZS5QbGF0Zm9ybSAtZXEgIlVuaXgiKSB7DQogICAgICAgIGlmICgkKHdob2FtaSkgLWVxICJyb290Iikgew0KICAgICAgICAgICAgcmV0dXJuICR0cnVlDQogICAgICAgIH0NCiAgICAgICAgZWxzZSB7DQogICAgICAgICAgICByZXR1cm4gJGZhbHNlDQogICAgICAgIH0NCiAgICB9DQogICAgIyBXaW5kb3dzDQogICAgKE5ldy1PYmplY3QgU2VjdXJpdHkuUHJpbmNpcGFsLldpbmRvd3NQcmluY2lwYWwgKFtTZWN1cml0eS5QcmluY2lwYWwuV2luZG93c0lkZW50aXR5XTo6R2V0Q3VycmVudCgpKSkuSXNJblJvbGUoW1NlY3VyaXR5LlByaW5jaXBhbC5XaW5kb3dzQnVpbHRpblJvbGVdOjpBZG1pbmlzdHJhdG9yKQ0KfQoKZnVuY3Rpb24gQVAtQ29udmVydFBhdGgge3BhcmFtKFtQYXJhbWV0ZXIoTWFuZGF0b3J5PSRUcnVlKV1bU3RyaW5nXSRQYXRoKQ0KDQogICAgJFBhdGhTZXAgPSBbSU8uUGF0aF06OkRpcmVjdG9yeVNlcGFyYXRvckNoYXINCiAgICByZXR1cm4gJFBhdGggLXJlcGxhY2UNCiAgICAgICAgIjxEZXA+IiwiPExpYj4ke1BhdGhTZXB9RGVwZW5kZW5jaWVzIiAtcmVwbGFjZQ0KICAgICAgICAiPExpYj4iLCI8SG9tZT4ke1BhdGhTZXB9QVAtTGlicmFyaWVzIiAtcmVwbGFjZQ0KICAgICAgICAiPENvbXAob25lbnRzKT8+IiwiPEhvbWU+JHtQYXRoU2VwfUFQLUNvbXBvbmVudHMiIC1yZXBsYWNlDQogICAgICAgICI8SG9tZT4iLCRQU0hlbGx9CgpmdW5jdGlvbiBJbnZva2UtT3JSZXR1cm4ge3BhcmFtKFtQYXJhbWV0ZXIoTWFuZGF0b3J5PSR0cnVlLCBWYWx1ZUZyb21QaXBlbGluZT0kdHJ1ZSwgUG9zaXRpb249MCldW0FsbG93TnVsbCgpXSRDb2RlLCBbUGFyYW1ldGVyKFZhbHVlRnJvbVJlbWFpbmluZ0FyZ3VtZW50cz0xKV0kX19SZXN0LCBbU3dpdGNoXSRBc1Byb2Nlc3NCbG9jaykNCg0KICAgIGlmICghKCRDb2RlIC1pcyBbU2NyaXB0QmxvY2tdKSkge3JldHVybiAkQ29kZX0NCiAgICBpZiAoISRBc1Byb2Nlc3NCbG9jaykge3JldHVybiAmICRDb2RlIEBfX1Jlc3R9DQogICAgcmV0dXJuICUgLXByb2Nlc3MgJENvZGUgLUlucHV0T2JqZWN0ICRfX1Jlc3QNCn0KCmZ1bmN0aW9uIEpTLU9SIHtmb3JlYWNoICgkYSBpbiAkYXJncykgeyRyID0gSW52b2tlLU9yUmV0dXJuICRhO2lmICghJHIpe2NvbnRpbnVlfTtyZXR1cm4gJHJ9O3JldHVybiAkcn0KCmZ1bmN0aW9uIFNldC1QYXRoIHsNCiAgICBbY21kbGV0YmluZGluZygpXQ0KICAgIHBhcmFtKA0KICAgICAgICBbUGFyYW1ldGVyKE1hbmRhdG9yeSA9ICR0cnVlLCBWYWx1ZUZyb21QaXBlbGluZSA9ICR0cnVlKV1bc3RyaW5nW11dJFBhdGgsDQogICAgICAgIFtzdHJpbmddJFBhdGhTZXAsDQogICAgICAgIFtzdHJpbmddJFBhdGhWYXIgPSAiUEFUSCINCiAgICApDQogICAgYmVnaW4gew0KICAgICAgICBbc3RyaW5nW11dJEZpbmFsUGF0aA0KICAgICAgICAkUGF0aFNlcCA9IEdldC1QYXRoVmFyU2VwICRQYXRoU2VwDQogICAgfQ0KICAgIHByb2Nlc3Mgew0KICAgICAgICAkUGF0aCB8ICUgew0KICAgICAgICAgICAgJEZpbmFsUGF0aCArPSAkXw0KICAgICAgICB9DQogICAgfQ0KICAgIGVuZCB7DQogICAgICAgICRQdGggPSAkRmluYWxQYXRoIC1qb2luICRQYXRoU2VwDQogICAgICAgICRQdGggPSAoJFB0aCAtcmVwbGFjZSgiJFBhdGhTZXArIiwgJFBhdGhTZXApIC1yZXBsYWNlKCJcXCRQYXRoU2VwfFxcJCIsICRQYXRoU2VwKSkudHJpbSgkUGF0aFNlcCkNCiAgICAgICAgJFB0aCA9ICgoJFB0aCkuc3BsaXQoJFBhdGhTZXApIHwgc2VsZWN0IC11bmlxdWUpIC1qb2luICRQYXRoU2VwDQogICAgICAgIFtFbnZpcm9ubWVudF06OlNldEVudmlyb25tZW50VmFyaWFibGUoJFBhdGhWYXIsICRQdGgpDQogICAgfQ0KfQoKZnVuY3Rpb24gU3RyaXAtQ29sb3JDb2RlcyB7DQogICAgW0NtZGxldEJpbmRpbmcoKV1wYXJhbShbUGFyYW1ldGVyKFZhbHVlRnJvbVBpcGVsaW5lPTEpXSRTdHIpDQogICAgcHJvY2VzcyB7JFN0ciB8ICUgeyRfIC1yZXBsYWNlICIkKFtyZWdleF06OmVzY2FwZSgiJChHZXQtRXNjYXBlKVsiKSlcZCsoXDtcZCspKm0iLCIifX0NCn0KCmZ1bmN0aW9uIEdldC1Fc2NhcGUgew0KICAgIGlmICgkbnVsbCAtZXEgJEFQX0NPTlNPTEUuY3VzdG9tRmxhZ3MuX19kZXRlY3RlZF9lc2NhcGVfY29kZXMpIHskQVBfQ09OU09MRS5jdXN0b21GbGFncy5fX2RldGVjdGVkX2VzY2FwZV9jb2RlcyA9IEFQLVJlcXVpcmUgImFiaWxpdHk6ZXNjYXBlX2NvZGVzIn0NCiAgICBpZiAoISRBUF9DT05TT0xFLmN1c3RvbUZsYWdzLl9fZGV0ZWN0ZWRfZXNjYXBlX2NvZGVzIC1hbmQgISRBUF9DT05TT0xFLmN1c3RvbUZsYWdzLmZvcmNlVW5peEVzY2FwZXMpIHt0aHJvdyAiW0FQQ29uc29sZTo6R2V0LUVzY2FwZV0gWW91ciBjb25zb2xlIGRvZXMgbm90IHN1cHBvcnQgQU5TSSBlc2NhcGUgY29kZXMuIFlvdSBjYW4gc2V0IGAkQVBfQ09OU09MRS5jdXN0b21GbGFncy5ub1VuaXhFc2NhcGVzID0gYCR0cnVlIHRvIGRpc2FibGUgdW5peCBlc2NhcGUgY29kZXMuIE9yLCB1c2U6IGAkQVBfQ09OU09MRS5jdXN0b21GbGFncy5mb3JjZVVuaXhFc2NhcGVzIHRvIGF0dGVtcHQgaXQgYW55d2F5cyJ9DQogICAgIyBXZSBkbyB0aGlzLCBiZWNhdXNlIFBvd2VyU2hlbGwgTmF0aXZlIGRvZXNuJ3Qga25vdyBgZQ0KICAgIHJldHVybiBbQ2hhcl0weDFiICMgYGUNCn0KCmZ1bmN0aW9uIFdyaXRlLUFQIHsNCiAgICBbQ21kbGV0QmluZGluZygpXQ0KICAgIHBhcmFtKFtQYXJhbWV0ZXIoVmFsdWVGcm9tUGlwZWxpbmU9MSwgTWFuZGF0b3J5PTEpXSRUZXh0LFtTd2l0Y2hdJE5vU2lnbixbU3dpdGNoXSRQbGFpblRleHQsW1ZhbGlkYXRlU2V0KCJDZW50ZXIiLCJSaWdodCIsIkxlZnQiKV1bU3RyaW5nXSRBbGlnbj0nTGVmdCcsW1N3aXRjaF0kUGFzc1RocnUpDQogICAgYmVnaW4geyRUVCA9IEAoKX0NCiAgICBQcm9jZXNzIHskVFQgKz0gLCRUZXh0fQ0KICAgIEVORCB7DQogICAgICAgICRCbHVlID0gJChpZiAoJEFQX0NPTlNPTEUuY3VzdG9tRmxhZ3MubGVnYWN5Q29sb3JzKXszfWVsc2V7J0JsdWUnfSkNCiAgICAgICAgaWYgKCRUVC5jb3VudCAtZXEgMSkgeyRUVCA9ICRUVFswXX07JFRleHQgPSAkVFQNCiAgICAgICAgaWYgKCR0ZXh0LmNvdW50IC1ndCAxIC1vciAkdGV4dC5HZXRUeXBlKCkuTmFtZSAtbWF0Y2ggIlxbXF0kIikgew0KICAgICAgICAgICAgcmV0dXJuICRUZXh0IHwgJSB7DQogICAgICAgICAgICAgICAgV3JpdGUtQVAgJF8gLU5vU2lnbjokTm9TaWduIC1QbGFpblRleHQ6JFBsYWluVGV4dCAtQWxpZ24gJEFsaWduIC1QYXNzVGhydTokUGFzc1RocnUNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBpZiAoISR0ZXh0IC1vciAkdGV4dCAtbm90bWF0Y2ggIig/c21pKV4oKD88Tk5MPngpfCg/PE5TPm5zPykpezAsMn0oPzx0Plw+KikoPzxzPltcK1wtXCFcKlwjXEBfXSkoPzx3Pi4qKSIpIHtyZXR1cm4gQWxpZ24tVGV4dCAkVGV4dCAtQWxpZ24gJEFsaWduIHwgV3JpdGUtSG9zdH0NCiAgICAgICAgJHRiICA9ICIgICAgIiokTWF0Y2hlcy50Lmxlbmd0aA0KICAgICAgICAkQ29sID0gQHsnKyc9JzInOyctJz0nMTInOychJz0nMTQnOycqJz0kQmx1ZTsnIyc9J0RhcmtHcmF5JzsnQCc9J0dyYXknOydfJz0nd2hpdGUnfVsoJFNpZ24gPSAkTWF0Y2hlcy5TKV0NCiAgICAgICAgaWYgKCEkQ29sKSB7VGhyb3cgIkluY29ycmVjdCBTaWduIFskU2lnbl0gUGFzc2VkISJ9DQogICAgICAgICRTaWduID0gJChpZiAoJE5vU2lnbiAtb3IgJE1hdGNoZXMuTlMpIHsiIn0gZWxzZSB7IlskU2lnbl0gIn0pDQogICAgICAgICREYXRhID0gIiR0YiRTaWduJCgkTWF0Y2hlcy5XKSI7aWYgKCEkRGF0YSkge3JldHVybiBXcml0ZS1Ib3N0ICIifQ0KICAgICAgICBpZiAoQVAtUmVxdWlyZSAiZnVuY3Rpb246QWxpZ24tVGV4dCIgLXBhKSB7DQogICAgICAgICAgICAkRGF0YSA9IEFsaWduLVRleHQgLUFsaWduICRBbGlnbiAiJHRiJFNpZ24kKCRNYXRjaGVzLlcpIg0KICAgICAgICB9DQogICAgICAgIGlmICgkUGxhaW5UZXh0KSB7cmV0dXJuICREYXRhfQ0KICAgICAgICAkRGF0YUxpbmVzID0gJERhdGEgLXNwbGl0ICJgbiINCiAgICAgICAgMS4uJERhdGFMaW5lcy5Db3VudCB8ICUgew0KICAgICAgICAgICAgJElkeCA9ICRfIC0gMQ0KICAgICAgICAgICAgJE5OTCA9ICEkaWR4IC1hbmQgJE1hdGNoZXMuTk5MDQogICAgICAgICAgICBXcml0ZS1Ib3N0IC1Ob05ld0xpbmU6JE5OTCAtZiAkQ29sICREYXRhTGluZXNbJElkeF0NCiAgICAgICAgICAgIGlmICgkUGFzc1RocnUpIHtyZXR1cm4gJERhdGF9DQogICAgICAgIH0NCiAgICB9DQp9CgpmdW5jdGlvbiBHZXQtV2hlcmUgew0KICAgIFtDbWRsZXRCaW5kaW5nKERlZmF1bHRQYXJhbWV0ZXJTZXROYW1lPSJOb3JtYWwiKV0NCiAgICBwYXJhbSgNCiAgICAgICAgW1BhcmFtZXRlcihNYW5kYXRvcnk9JHRydWUsIFBvc2l0aW9uPTApXVtzdHJpbmddJEZpbGUsDQogICAgICAgIFtTd2l0Y2hdJEFsbCwNCiAgICAgICAgW1BhcmFtZXRlcihQYXJhbWV0ZXJTZXROYW1lPSdOb3JtYWwnKV1bUGFyYW1ldGVyKFBhcmFtZXRlclNldE5hbWU9J1NjYW4nKV1bU3dpdGNoXSRNYW51YWxTY2FuLA0KICAgICAgICBbUGFyYW1ldGVyKFBhcmFtZXRlclNldE5hbWU9J1NjYW4nKV1bU3dpdGNoXSREYmcsDQogICAgICAgIFtQYXJhbWV0ZXIoUGFyYW1ldGVyU2V0TmFtZT0nU2NhbicpXVtzdHJpbmddJFBhdGhWYXIgPSAiUEFUSCINCiAgICApDQogICAgJElzVmVyYm9zZSA9ICREYmcgLW9yICRQU0NtZGxldC5NeUludm9jYXRpb24uQm91bmRQYXJhbWV0ZXJzLlZlcmJvc2UgLW9yICRQU0NtZGxldC5NeUludm9jYXRpb24uQm91bmRQYXJhbWV0ZXJzLkRlYnVnDQogICAgJFdoZXJlQmluRXhpc3RzID0gR2V0LUNvbW1hbmQgIndoZXJlIiAtZWEgU2lsZW50bHlDb250aW51ZQ0KICAgICRJc1VuaXggPSAkUFNWZXJzaW9uVGFibGUuUGxhdGZvcm0gLWVxICJVbml4Ig0KICAgIGlmICgkRmlsZSAtZXEgIndoZXJlIiAtb3IgJEZpbGUgLWVxICJ3aGVyZS5leGUiKSB7cmV0dXJuICRXaGVyZUJpbkV4aXN0c30NCiAgICBpZiAoJFdoZXJlQmluRXhpc3RzIC1hbmQgISRNYW51YWxTY2FuKSB7DQogICAgICAgICRPdXQ9JG51bGwNCiAgICAgICAgaWYgKCRJc1VuaXgpIHsNCiAgICAgICAgICAgICRPdXQgPSB3aGljaCAkZmlsZSAyPiRudWxsDQogICAgICAgIH0gZWxzZSB7JE91dCA9IHdoZXJlLmV4ZSAkZmlsZSAyPiRudWxsfQ0KDQogICAgICAgIGlmICghJE91dCkge3JldHVybn0NCiAgICAgICAgaWYgKCRBbGwpIHtyZXR1cm4gJE91dH0NCiAgICAgICAgcmV0dXJuIEAoJE91dClbMF0NCiAgICB9DQogICAgZm9yZWFjaCAoJEZvbGRlciBpbiAoR2V0LVBhdGggLVBhdGhWYXIgJFBhdGhWYXIpKSB7DQogICAgICAgIGlmICgkSXNVbml4KSB7DQogICAgICAgICAgICAkTG9va3VwID0gIiRGb2xkZXIvJEZpbGUiDQogICAgICAgICAgICBpZiAoJElzVmVyYm9zZSkge1dyaXRlLUFQICIqQ2hlY2tpbmcgWyRMb29rdXBdIn0NCiAgICAgICAgICAgIGlmICghKFRlc3QtUGF0aCAtUGF0aFR5cGUgTGVhZiAkTG9va3VwKSkge2NvbnRpbnVlfQ0KICAgICAgICAgICAgUmVzb2x2ZS1QYXRoICRMb29rdXAgfCAlIFBhdGgNCiAgICAgICAgICAgIGlmICghJEFsbCkge3JldHVybn0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGZvcmVhY2ggKCRFeHRlbnNpb24gaW4gKEdldC1QYXRoIC1QYXRoVmFyIFBBVEhFWFQpKSB7DQogICAgICAgICAgICAgICAgJExvb2t1cCA9ICIkRm9sZGVyLyRGaWxlJEV4dGVuc2lvbiINCiAgICAgICAgICAgICAgICBpZiAoJElzVmVyYm9zZSkge1dyaXRlLUFQICIqQ2hlY2tpbmcgWyRMb29rdXBdIn0NCiAgICAgICAgICAgICAgICBpZiAoIShUZXN0LVBhdGggLVBhdGhUeXBlIExlYWYgJExvb2t1cCkpIHtjb250aW51ZX0NCiAgICAgICAgICAgICAgICBSZXNvbHZlLVBhdGggJExvb2t1cCB8ICUgUGF0aA0KICAgICAgICAgICAgICAgIGlmICghJEFsbCkge3JldHVybn0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCn0KCmZ1bmN0aW9uIEdldC1Db2xvciB7DQogICAgPCMgIC5EZXNjcmlwdGlvbg0KICAgICAgICBGZXRjaGVzIGJhc2ljIGNvbG9ycyB1c2luZyB0aGUgVW5pY29kZSBFc2NhcGUgc2VxdWVuY2VzDQogICAgIz4NCiAgICBwYXJhbSAoDQogICAgICAgIFtWYWxpZGF0ZVNldCgNCiAgICAgICAgICAgICdyJywncmVzZXQnLCdyUycsJ3Jlc2V0U3R5bGVzJywnZCcsJ2RpbScsJ3MnLCdzdHJpa2UnLCd1JywndW5kZXJsaW5lJywnYicsJ2JvbGQnLCdpJywnaXRhbGljJywnYmwnLCdibGluaycsJ3JldmVyc2UnLCdoJywnaGlkZGVuJywNCiAgICAgICAgICAgICdCbGFjaycsJ0RhcmtCbHVlJywnRGFya0dyZWVuJywnRGFya0N5YW4nLCdEYXJrUmVkJywnRGFya01hZ2VudGEnLCdEYXJrWWVsbG93JywnR3JheScsJ0RhcmtHcmF5JywnQmx1ZScsJ0dyZWVuJywnQ3lhbicsJ1JlZCcsJ01hZ2VudGEnLCdZZWxsb3cnLCdXaGl0ZScsDQogICAgICAgICAgICAnYmcuQmxhY2snLCdiZy5EYXJrQmx1ZScsJ2JnLkRhcmtHcmVlbicsJ2JnLkRhcmtDeWFuJywnYmcuRGFya1JlZCcsJ2JnLkRhcmtNYWdlbnRhJywnYmcuRGFya1llbGxvdycsJ2JnLkdyYXknLCdiZy5EYXJrR3JheScsJ2JnLkJsdWUnLCdiZy5HcmVlbicsJ2JnLkN5YW4nLCdiZy5SZWQnLCdiZy5NYWdlbnRhJywnYmcuWWVsbG93JywnYmcuV2hpdGUnDQogICAgICAgICldW1N0cmluZ1tdXSRDb2RlLA0KICAgICAgICBbQWxpYXMoJ2JnJyldW1N3aXRjaF0kQmFja2dyb3VuZCwNCiAgICAgICAgW1N3aXRjaF0kQ29kZVN0cmluZw0KICAgICkNCiAgICBpZiAoJEFQX0NPTlNPTEUuY3VzdG9tRmxhZ3Mubm9Vbml4RXNjYXBlcykge3JldHVybn0NCiAgICAkQWxpYXNUYWJsZSA9IEB7dSA9ICd1bmRlcmxpbmUnO2IgPSAnYm9sZCc7aSA9ICdpdGFsaWMnO3IgPSAncmVzZXQnO3JTID0gJ3Jlc2V0U3R5bGVzJztzID0gJ3N0cmlrZSc7ZCA9ICdkaW0nO2JsID0gJ2JsaW5rJztoID0gJ2hpZGRlbid9DQogICAgaWYgKCEkR2xvYmFsOkFQX0NPTE9SX1RBQkxFKSB7DQogICAgICAgICRUQkwgPSAkR2xvYmFsOkFQX0NPTE9SX1RBQkxFID0gQHtyZXNldCA9IDA7Ym9sZCA9IDE7ZGltID0gMjtpdGFsaWMgPSAzO3VuZGVybGluZSA9IDQ7YmxpbmsgPSA1O3JldmVyc2UgPSA3O2hpZGRlbiA9IDg7c3RyaWtlID0gOTtyZXNldFN0eWxlcyA9ICcyMjsyMzsyNDsyNTsyNzsyODsyOSd9DQogICAgICAgIDAsMSB8ICUgew0KICAgICAgICAgICAgJEJnSW5kZXggPSAkXw0KICAgICAgICAgICAgMCwxIHwgJSB7DQogICAgICAgICAgICAgICAgJFNwY0luZGV4ID0gJF8NCiAgICAgICAgICAgICAgICAkaSA9IDANCiAgICAgICAgICAgICAgICAnQmxhY2suVHxSZWR8R3JlZW58WWVsbG93fEJsdWV8TWFnZW50YXxDeWFufFdoaXRlJy5zcGxpdCgnfCcpIHwgJSB7DQogICAgICAgICAgICAgICAgICAgICRJbmNyID0gJEJnSW5kZXggKiAxMA0KICAgICAgICAgICAgICAgICAgICAkQ29sTmFtZSA9ICgoJycsJ2JnLicpWyRCZ0luZGV4XSkrKCgnRGFyaycsJycpWyRTcGNJbmRleF0pKyRfDQogICAgICAgICAgICAgICAgICAgICRDb2xTcGFjZSA9ICgzMCwgOTApWyRTcGNJbmRleF0gKyAkSW5jcg0KICAgICAgICAgICAgICAgICAgICAkVEJMLiRDb2xOYW1lID0gJENvbFNwYWNlKygkaSsrKQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBAe0RhcmtHcmF5ID0gJ0JsYWNrLlQnO0JsYWNrID0gJ0RhcmtCbGFjay5UJztHcmF5ID0gJ0RhcmtXaGl0ZSd9LkdldEVudW1lcmF0b3IoKSB8ICUgew0KICAgICAgICAgICAgJFRCTC4oJF8uS2V5KSA9ICRUQkwuKCRfLlZhbHVlKQ0KICAgICAgICAgICAgJFRCTC4oJ2JnLicrJF8uS2V5KSA9ICRUQkwuKCdiZy4nKyRfLlZhbHVlKQ0KICAgICAgICAgICAgJFRCTC5yZW1vdmUoJF8uVmFsdWUpDQogICAgICAgICAgICAkVEJMLnJlbW92ZSgnYmcuJyskXy5WYWx1ZSkNCiAgICAgICAgfQ0KICAgIH0NCiAgICAkQ29kZXMgPSAoJENvZGUrJEFyZ3MgfCAlIHsNCiAgICAgICAgJEdsb2JhbDpBUF9DT0xPUl9UQUJMRS4oSlMtT1IgJEFsaWFzVGFibGUuJF8gJF8pDQogICAgfSkgLWpvaW4gJzsnDQogICAgaWYgKCRDb2RlU3RyaW5nKSB7cmV0dXJuICRDb2Rlc30NCiAgICByZXR1cm4gKEdldC1Fc2NhcGUpICsgJ1snICsgJENvZGVzICsgJ20nICMgVXNpbmcgc3RyaW5nIGNvbmNhdCBmb3IgZmFzdGVyIHByb2Nlc3NpbmcNCn0KCmZ1bmN0aW9uIEdldC1SR0Ige3BhcmFtKFtWYWxpZGF0ZVJhbmdlKDAsIDI1NSldJFJlZCwgW1ZhbGlkYXRlUmFuZ2UoMCwgMjU1KV1baW50XSRHcmVlbiwgW1ZhbGlkYXRlUmFuZ2UoMCwgMjU1KV1baW50XSRCbHVlLCBbQWxpYXMoJ2JnJyldW1N3aXRjaF0kQmFja2dyb3VuZCkNCg0KICAgIGlmICgkQVBfQ09OU09MRS5jdXN0b21GbGFncy5ub1VuaXhFc2NhcGVzKSB7cmV0dXJufQ0KICAgIGlmICgkUmVkIC1pcyBbQXJyYXldKSB7DQogICAgICAgIFtpbnRdJFJlZCwgJEdyZWVuLCAkQmx1ZSA9ICRSZWQNCiAgICB9DQogICAgJExvY2F0aW9uID0gJChpZigkQmFja2dyb3VuZCl7NDh9ZWxzZXszOH0pDQogICAgJHN0ciA9IChHZXQtRXNjYXBlKSArICdbJyArICRMb2NhdGlvbiArICc7MjsnICsgJFJlZCArICc7JyArICRHcmVlbiArICc7JyArICRCbHVlICsgJ20nICMgVXNpbmcgc3RyaW5nIGNvbmNhdCBmb3IgZmFzdGVyIHByb2Nlc3NpbmcNCiAgICByZXR1cm4gJHN0cg0KfQoKZnVuY3Rpb24gRG8tQ2xhbXAgew0KICAgIHBhcmFtKFtQYXJhbWV0ZXIoTWFuZGF0b3J5PTEsIFBvc2l0aW9uPTApXVtpbnRdJHZhbCwgW1BhcmFtZXRlcihNYW5kYXRvcnk9MSwgUG9zaXRpb249MSldW2ludF0kbWluLCBbUGFyYW1ldGVyKE1hbmRhdG9yeT0xLCBQb3NpdGlvbj0yKV1baW50XSRtYXgpDQogICAgaWYgKCR2YWwgLWx0ICRtaW4pIHskbWlufQ0KICAgIGVsc2VpZiAoJHZhbCAtZ3QgJG1heCkgeyRtYXh9DQogICAgZWxzZSB7JHZhbH0NCn0KCmZ1bmN0aW9uIFdyaXRlLUFQTCB7DQogICAgW0NtZGxldEJpbmRpbmcoKV0NCiAgICBwYXJhbSgNCiAgICAgICAgW1BhcmFtZXRlcihWYWx1ZUZyb21QaXBlbGluZT0kdHJ1ZSwgTWFuZGF0b3J5PSRUcnVlKV0kVGV4dCwNCiAgICAgICAgW0FsaWFzKCdOUycpXVtTd2l0Y2hdJE5vU2lnbiwNCiAgICAgICAgW0FsaWFzKCdOTkwnLCdOTCcpXVtTd2l0Y2hdJE5vTmV3TGluZSwNCiAgICAgICAgW1N3aXRjaF0kUGFzc1RocnUNCiAgICApDQogICAgYmVnaW4gew0KICAgICAgICAkU2lnblJneCA9ICJbXCtcLVwhXCpcI1xAX10iOyAkVFQgPSBAKCkNCiAgICAgICAgJElzVmVyYm9zZSA9ICRQU0NtZGxldC5NeUludm9jYXRpb24uQm91bmRQYXJhbWV0ZXJzLlZlcmJvc2UNCiAgICB9DQogICAgcHJvY2VzcyB7RmxhdHRlbiAkVGV4dCB8ICUgew0KICAgICAgICAkTGluZSA9ICRfIC1zcGxpdCAiYG4iDQogICAgICAgICRMaW5lU3ltYm9sID0gJChpZiAoJGxpbmVbMF0gLW1hdGNoICJebj94P24/KFw+KikoJFNpZ25SZ3gpLiokIikgeyRNYXRjaGVzWzJdfSBlbHNlIHsiIn0pDQogICAgICAgIGlmICgkSXNWZXJib3NlKSB7V3JpdGUtVmVyYm9zZSAiJChjb2wgaSlMaW5lU3ltYm9sOiAkTGluZVN5bWJvbCB8IExpbmU6ICRMaW5lJChjb2wgclMpIn0NCiAgICAgICAgMS4uJExpbmUuTGVuZ3RoIHwgJSB7DQogICAgICAgICAgICAkaWR4ID0gJF8gLSAxDQogICAgICAgICAgICBpZiAoJGlkeCkgeyRUVCArPSAiYG4iKyRMaW5lU3ltYm9sKyRMaW5lWyRpZHhdfQ0KICAgICAgICAgICAgZWxzZSB7JFRUICs9ICRMaW5lWyRpZHhdfQ0KICAgICAgICB9DQogICAgfX0NCiAgICBlbmQgew0KICAgICAgICBpZiAoJElzVmVyYm9zZSkge1dyaXRlLVZlcmJvc2UgIiQoY29sIGkpJChQcmludC1MaXN0ICRUVCkkKGNvbCByUykifQ0KICAgICAgICBmb3IgKCRpPTA7JGkgLWx0ICRUVC5jb3VudDskaSsrKSB7DQogICAgICAgICAgICBbc3RyaW5nXSRDaHVuayA9ICRUVFskaV0NCiAgICAgICAgICAgIGlmICgkQ2h1bmtbMF0gLWVxICJgbiIpIHskQ2h1bmsgPSAkQ2h1bmsuU3Vic3RyaW5nKDEpO1dyaXRlLUhvc3R9ICMgU3BlY2lhbCBjYXNlIGZvciBuZXcgbGluZSB2aWEgYG4NCiAgICAgICAgICAgICRDaHVuayA9ICRDaHVuayAtcmVwbGFjZSAiXm4/eD9uPyhcPiokU2lnblJneCkiLCckMScNCiAgICAgICAgICAgIGlmICgkQ2h1bmsgLW5vdG1hdGNoICJeXD4qJFNpZ25SZ3guKiIpIHskQ2h1bmsgPSAiXyRDaHVuayJ9ICMgVXNlIGRlZmF1bHQgYXMgd2hpdGUNCiAgICAgICAgICAgICRQcmVmaXhDb2RlID0gPzogKCRpIC1lcSAwKSB7IngkKD86ICROb1NpZ24geyduJ30geycnfSkifSB7PzogKCRpIC1uZSAoJFRULkNvdW50IC0gMSkpIHsibngifSAibiQoPzogJE5vTmV3TGluZSB7J3gnfSB7Jyd9KSJ9DQogICAgICAgICAgICBpZiAoJFRULkNvdW50IC1lcSAxKSB7JFByZWZpeENvZGUgPSAiJCg/OiAkTm9TaWduIHsnbid9IHsnJ30pJCg/OiAkTm9OZXdMaW5lIHsneCd9IHsnJ30pIn0NCiAgICAgICAgICAgIGlmICgkSXNWZXJib3NlKSB7V3JpdGUtVmVyYm9zZSAiJChjb2wgaSlQcmVmaXhDb2RlOiAkUHJlZml4Q29kZSB8IENodW5rOiAkQ2h1bmskKGNvbCByUykifQ0KICAgICAgICAgICAgV3JpdGUtQVAgIiRQcmVmaXhDb2RlJENodW5rIiAtUGFzc1RocnU6JFBhc3NUaHJ1DQogICAgICAgIH0NCiAgICB9DQp9CgpmdW5jdGlvbiBHZXQtUGF0aCB7cGFyYW0oJG1hdGNoLCBbc3RyaW5nXSRQYXRoVmFyID0gIlBBVEgiLCBbc3RyaW5nXSRQYXRoU2VwID0gIiIpDQoNCiAgICAkUHRoID0gW0Vudmlyb25tZW50XTo6R2V0RW52aXJvbm1lbnRWYXJpYWJsZSgkUGF0aFZhcikNCiAgICAkUGF0aFNlcCA9IEdldC1QYXRoVmFyU2VwICRQYXRoU2VwDQogICAgaWYgKCEkUHRoKSB7cmV0dXJuIEAoKX0NCiAgICBTZXQtUGF0aCAkUHRoIC1QYXRoVmFyICRQYXRoVmFyIC1QYXRoU2VwICRQYXRoU2VwDQogICAgJGQgPSAoJFB0aCkuc3BsaXQoJFBhdGhTZXApDQogICAgaWYgKCRtYXRjaCkgeyRkIC1tYXRjaCAkbWF0Y2h9IGVsc2UgeyRkfQ0KfQoKZnVuY3Rpb24gQ3Jvc3MtQ29uc29sZUFQSSB7DQogICAgcGFyYW0oDQogICAgICAgIFtQYXJhbWV0ZXIoTWFuZGF0b3J5PSR0cnVlLCBQb3NpdGlvbj0wKV0NCiAgICAgICAgW0FyZ3VtZW50Q29tcGxldGVyKHsNCiAgICAgICAgICAgIHBhcmFtKCRhLCRiLCRXb3JkVG9Db21wbGV0ZSkNCiAgICAgICAgICAgICRUYWJsZSA9IF9Dcm9zcy1Db25zb2xlLVRhYmxlDQogICAgICAgICAgICByZXR1cm4gJFRhYmxlLktleXMgfCA/IHskXyAtbGlrZSAiJFdvcmRUb0NvbXBsZXRlKiJ9DQogICAgICAgIH0pXQ0KICAgICAgICBbc3RyaW5nXSRDb21tYW5kLA0KICAgICAgICBbVmFsaWRhdGVTZXQoJ2F1dG8nLCd3aW4nLCd1bml4JyldW3N0cmluZ10kUmVuZGVyZXIgPSAnYXV0bycsDQogICAgICAgIFtQYXJhbWV0ZXIoTWFuZGF0b3J5PSRmYWxzZSwgUG9zaXRpb249MSwgVmFsdWVGcm9tUmVtYWluaW5nQXJndW1lbnRzPSR0cnVlKV1bQXJndW1lbnRDb21wbGV0ZXIoew0KICAgICAgICAgICAgJEZha2VCb3VuZFBhcmFtZXRlcnMgPSAkYXJnc1s0XQ0KICAgICAgICAgICAgJFJlc29sdmVkQ29tbWFuZCA9ICRGYWtlQm91bmRQYXJhbWV0ZXJzLkNvbW1hbmQNCiAgICAgICAgICAgIGlmICghJFJlc29sdmVkQ29tbWFuZCkge3JldHVybn0NCiAgICAgICAgICAgICRUYWJsZSA9IF9Dcm9zcy1Db25zb2xlLVRhYmxlDQogICAgICAgICAgICBpZiAoISRUYWJsZS4kUmVzb2x2ZWRDb21tYW5kKSB7DQogICAgICAgICAgICAgICAgV3JpdGUtQVBMICItSW52YWxpZCBjb21tYW5kOiAkUmVzb2x2ZWRDb21tYW5kIg0KICAgICAgICAgICAgICAgIHJldHVybiBAKCkNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgICRDb21tYW5kSW5mbyA9ICRUYWJsZVskUmVzb2x2ZWRDb21tYW5kXQ0KICAgICAgICAgICAgaWYgKCEkQ29tbWFuZEluZm8uYXV0b2NvbXBsZXRlcikge3JldHVybn0NCiAgICAgICAgICAgIHJldHVybiAmICRDb21tYW5kSW5mby5hdXRvY29tcGxldGVyIEBhcmdzDQogICAgICAgIH0pXSRfX3Jlc3QNCiAgICApDQogICAgaWYgKCRSZW5kZXJlciAtZXEgJ2F1dG8nKSB7DQogICAgICAgICMgRGV0ZWN0IGlmIHRoZSBjdXJyZW50IGNvbnNvbGUgY2FuIGhhbmRsZSBBTlNJIGVzY2FwZSBzZXF1ZW5jZXMuIElzIFVuaXgsIG9yIFdpbmRvd3MgVGVybWluYWwNCiAgICAgICAgJFVuaXhUZXJtaW5hbCA9ICRQU1ZlcnNpb25UYWJsZS5QbGF0Zm9ybSAtZXEgJ1VuaXgnDQogICAgICAgICRJbldpblRlcm0gPSAkZW52OldUX1NFU1NJT04gLW9yICRlbnY6V1RfUFJPRklMRV9JRA0KICAgICAgICAkVGVybSA9IChHZXQtUHJvY2VzcyAtaWQgJHBpZCkuU3RhcnRJbmZvLkVudmlyb25tZW50VmFyaWFibGUuVEVSTV9QUk9HUkFNDQogICAgICAgICRJc1ZzQ29kZSA9ICRUZXJtIC1lcSAnY29kZScNCiAgICAgICAgaWYgKCRUZXJtIC1hbmQgISRJc1ZzQ29kZSkgew0KICAgICAgICAgICAgV3JpdGUtQVBMICIhSW1wbGVtZW50IHRoaXMgbG9naWM6IChHZXQtUHJvY2VzcyAtaWQgJHBpZCkuU3RhcnRJbmZvLkVudmlyb25tZW50VmFyaWFibGUuVEVSTV9QUk9HUkFNID09ICRUZXJtIg0KICAgICAgICB9DQogICAgICAgIGlmICgkVW5peFRlcm1pbmFsIC1vciAkSW5XaW5UZXJtIC1vciAkSXNWc0NvZGUgLW9yIChBUC1SZXF1aXJlICJhYmlsaXR5OmVzY2FwZV9jb2RlcyIpKSB7DQogICAgICAgICAgICAkUmVuZGVyZXIgPSAndW5peCcNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICRSZW5kZXJlciA9ICd3aW4nDQogICAgICAgIH0NCiAgICB9DQogICAgJEhvb2tzID0gQHsNCiAgICAgICAgcHJvY2Vzc0Nvb3JkcyA9IHsNCiAgICAgICAgICAgIHBhcmFtKCRkZWZhdWx0cywgJHgsICR5KQ0KICAgICAgICAgICAgaWYgKCR4IC1pcyBbYXJyYXldKSB7DQogICAgICAgICAgICAgICAgaWYgKCR4Lkxlbmd0aCAtZ3QgMikge3Rocm93ICJJbnZhbGlkIGN1cnNvciBwb3NpdGlvbiAoc2VuZCB4LHkgb3IgPGNtZD4geCB5KSJ9DQogICAgICAgICAgICAgICAgJHgsJHkgPSAkeCB8IHNlbGVjdCAtZiAyDQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoJHggLWlzIFtzdHJpbmddIC1hbmQgJHggLW1hdGNoICdeKC0/XGQrKSgsKC0/XGQrKSk/JCcpIHsNCiAgICAgICAgICAgICAgICAkeCA9ICRNYXRjaGVzLjENCiAgICAgICAgICAgICAgICAkeSA9IGlmICgkTWF0Y2hlcy4zKSB7JE1hdGNoZXMuM30gZWxzZSB7JHl9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoJHgpIHtpZiAoJHggLWlzIFtpbnRdIC1vciAiJHgiIC1tYXRjaCAiXi0/XGQrJCIpIHskeCA9IFtpbnRdJHh9IGVsc2Uge3Rocm93ICJJbnZhbGlkIHggY29vcmRpbmF0ZTogJHggKG11c3QgYmUgYW4gaW50ZWdlcikifX0NCiAgICAgICAgICAgIGlmICgkeSkge2lmICgkeSAtaXMgW2ludF0gLW9yICIkeSIgLW1hdGNoICJeLT9cZCskIikgeyR5ID0gW2ludF0keX0gZWxzZSB7dGhyb3cgIkludmFsaWQgeSBjb29yZGluYXRlOiAkeSAobXVzdCBiZSBhbiBpbnRlZ2VyKSJ9fQ0KICAgICAgICAgICAgJHggPSBKUy1OQ1EgJHggJGRlZmF1bHRzWzBdDQogICAgICAgICAgICAkeSA9IEpTLU5DUSAkeSAkZGVmYXVsdHNbMV0NCiAgICAgICAgICAgIHJldHVybiAkeCwkeQ0KICAgICAgICB9DQogICAgICAgIHByb2Nlc3NDb29yZHNXaXRoV3JhcCA9IHsNCiAgICAgICAgICAgICR4LCAkeSA9ICYgJGhvb2tzLnByb2Nlc3NDb29yZHMgQGFyZ3MNCiAgICAgICAgICAgIGlmIChbQ29uc29sZV06OklzT3V0cHV0UmVkaXJlY3RlZCkge3JldHVybiAkeCwkeX0NCiAgICAgICAgICAgIGlmICgkeCAtbHQgMCkgeyR4ID0gKFtDb25zb2xlXTo6QnVmZmVyV2lkdGgpICsgJHh9DQogICAgICAgICAgICBpZiAoJHkgLWx0IDApIHskeSA9IChbQ29uc29sZV06OkJ1ZmZlckhlaWdodCkgKyAkeX0NCiAgICAgICAgICAgIHJldHVybiAkeCwkeQ0KICAgICAgICB9DQogICAgICAgIHByb2Nlc3NEaXJlY3Rpb25zID0gew0KICAgICAgICAgICAgcGFyYW0oJGRpciwgJG9mZnNldCkNCiAgICAgICAgICAgIGlmICgkZGlyIC1pcyBbYXJyYXldKSB7DQogICAgICAgICAgICAgICAgIyBDaGVjayBpZiB0aGUgZmlyc3QgZWxlbWVudCBpcyBhIG51bWJlciwgaWYgc28sIGl0J3MgYSBkaXJlY3Rpb24NCiAgICAgICAgICAgICAgICBpZiAoJGRpclswXSAtaXMgW2ludF0gLW9yICIkKCRkaXJbMF0pIiAtbWF0Y2ggIl4tP1xkKyQiKSB7cmV0dXJuICRkaXJ9DQogICAgICAgICAgICAgICAgaWYgKCRkaXIuTGVuZ3RoIC1ndCAyKSB7dGhyb3cgIkludmFsaWQgY3Vyc29yIHBvc2l0aW9uIChzZW5kIHgseSBvciA8Y21kPiB4IHkpIn0NCiAgICAgICAgICAgICAgICAkZGlyLCRvZmZzZXQgPSAkZGlyIHwgc2VsZWN0IC1mIDINCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmICgkZGlyIC1pcyBbaW50XSAtb3IgIiRkaXIiIC1tYXRjaCAiXi0/XGQrJCIpIHtyZXR1cm4gW2ludF0kZGlyLFtpbnRdJG9mZnNldH0NCiAgICAgICAgICAgIGlmICgkZGlyIC1ub3RtYXRjaCAnXih1cHxkb3dufGxlZnR8cmlnaHQpJCcpIHt0aHJvdyAiSW52YWxpZCBkaXJlY3Rpb246ICRkaXIsIGFjY2VwdGVkIHZhbHVlczogdXAsIGRvd24sIGxlZnQsIHJpZ2h0LiBPciB1c2UgeCx5In0NCiAgICAgICAgICAgIHRyeSB7W2ludF0kb2Zmc2V0ID0gSlMtTkNRICRvZmZzZXQgMX0gY2F0Y2gge3Rocm93ICJJbnZhbGlkIG9mZnNldDogJG9mZnNldCAobXVzdCBiZSBhbiBpbnRlZ2VyID49MSkifQ0KICAgICAgICAgICAgJHggPSAwOyAkeSA9IDANCiAgICAgICAgICAgIHN3aXRjaCAoJGRpcikgew0KICAgICAgICAgICAgICAgICJ1cCIgICAgeyR5ID0gLSRvZmZzZXR9DQogICAgICAgICAgICAgICAgImRvd24iICB7JHkgPSAkb2Zmc2V0fQ0KICAgICAgICAgICAgICAgICJsZWZ0IiAgeyR4ID0gLSRvZmZzZXR9DQogICAgICAgICAgICAgICAgInJpZ2h0IiB7JHggPSAkb2Zmc2V0fQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuICR4LCR5DQogICAgICAgIH0NCiAgICB9DQogICAgJFRhYmxlID0gX0Nyb3NzLUNvbnNvbGUtVGFibGUNCiAgICBpZiAoISRUYWJsZS4kQ29tbWFuZCkge3Rocm93ICJJbnZhbGlkIGNvbW1hbmQ6ICRDb21tYW5kIn0NCiAgICAmICRUYWJsZVskQ29tbWFuZF0uJFJlbmRlcmVyICRob29rcyBAX19yZXN0DQp9CgpmdW5jdGlvbiBfQ3Jvc3MtQ29uc29sZS1UYWJsZSB7ICMgSGFzIHRvIGJlIGEgZnVuY3Rpb24gc28gdGhhdCBBUC1Db25zb2xlIENvbXBpbGVyIGNhbiBwaWNrIGl0IHVwIHdoZW4gY29tcGlsaW5nDQogICAgJEN1cnNvckF1dG9jb21wbGV0ZXIgPSB7DQogICAgICAgIHBhcmFtKCRhLCRiLCRXb3JkVG9Db21wbGV0ZSwkQ29tbWFuZEFzdCwgJEZha2VCb3VuZFBhcmFtZXRlcnMpDQogICAgICAgIFBsYWNlLUJ1ZmZlcmVkQ29udGVudCAteCAwIC15IDAgIkJvdW5kIHBhcmFtZXRlcnM6ICQoUHJpbnQtTGlzdCAoJEZha2VCb3VuZFBhcmFtZXRlcnMgfCBHZXQtTWVtYmVyIC1NZW1iZXJUeXBlIE5vdGVQcm9wZXJ0eSB8ICUgeyRfLk5hbWV9KSkiIFllbGxvdw0KICAgICAgICByZXR1cm4gQCgiMCwwIiwiMCIpIHwgRG8tQXJnTWF0Y2ggLVdvcmRUb0NvbXBsZXRlICRXb3JkVG9Db21wbGV0ZQ0KICAgIH0NCiAgICByZXR1cm4gW29yZGVyZWRdQHsNCiAgICAgICAgImJhY2t1cC1jdXJzb3IiID0gQHsNCiAgICAgICAgICAgIHdpbiA9IHsNCiAgICAgICAgICAgICAgICBpZiAoISRHbG9iYWw6X19BUF9DT05TT0xFX0NVUlNPUl9QT1MpIHskR2xvYmFsOl9fQVBfQ09OU09MRV9DVVJTT1JfUE9TID0gW1N5c3RlbS5Db2xsZWN0aW9ucy5TdGFja106Om5ldygpfQ0KICAgICAgICAgICAgICAgICRHbG9iYWw6X19BUF9DT05TT0xFX0NVUlNPUl9QT1MuUHVzaChAKFtDb25zb2xlXTo6Q3Vyc29yTGVmdCwgW0NvbnNvbGVdOjpDdXJzb3JUb3ApKQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgdW5peCA9IHtXcml0ZS1Ib3N0IC1Ob05ld2xpbmUgIiQoR2V0LUVzY2FwZSlbcyJ9DQogICAgICAgIH0NCiAgICAgICAgInJlc3RvcmUtY3Vyc29yIiA9IEB7DQogICAgICAgICAgICB3aW4gPSB7DQogICAgICAgICAgICAgICAgJFBvcyA9ICRHbG9iYWw6X19BUF9DT05TT0xFX0NVUlNPUl9QT1MuUG9wKCkNCiAgICAgICAgICAgICAgICBpZiAoISRQb3MpIHtyZXR1cm59DQogICAgICAgICAgICAgICAgaWYgKFtDb25zb2xlXTo6SXNPdXRwdXRSZWRpcmVjdGVkKSB7cmV0dXJufQ0KICAgICAgICAgICAgICAgIFtDb25zb2xlXTo6U2V0Q3Vyc29yUG9zaXRpb24oJFBvc1swXSwgJFBvc1sxXSkNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHVuaXggPSB7V3JpdGUtSG9zdCAtTm9OZXdsaW5lICIkKEdldC1Fc2NhcGUpW3UifQ0KICAgICAgICB9DQogICAgICAgICJnZXQtY3Vyc29yIiA9IEB7DQogICAgICAgICAgICB3aW4gPSB7DQogICAgICAgICAgICAgICAgaWYgKFtDb25zb2xlXTo6SXNPdXRwdXRSZWRpcmVjdGVkKSB7cmV0dXJuICIwLDAifQ0KICAgICAgICAgICAgICAgIHJldHVybiAiezB9LHsxfSIgLWYgW0NvbnNvbGVdOjpDdXJzb3JMZWZ0LCBbQ29uc29sZV06OkN1cnNvclRvcA0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgdW5peCA9IHsNCiAgICAgICAgICAgICAgICAkQ0wgPSBbQ29uc29sZV06OkN1cnNvckxlZnQNCiAgICAgICAgICAgICAgICBXcml0ZS1Ib3N0IC1Ob05ld2xpbmUgIiQoR2V0LUVzY2FwZSlbNm4iDQogICAgICAgICAgICAgICAgJGl0ZXJzID0gMDt3aGlsZSAoISRIb3N0LlVJLlJhd1VJLktleUF2YWlsYWJsZSkge1N0YXJ0LVNsZWVwIC1tIDEwOyBpZiAoJGl0ZXJzKysgLWd0IDE1KSB7DQogICAgICAgICAgICAgICAgICAgIFdyaXRlLUFQICItW1VuaXggUmVuZGVyZXJdIEZhaWxlZCB0byBnZXQgdGhlIGN1cnNvciBwb3NpdGlvbiINCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuDQogICAgICAgICAgICAgICAgfX0NCiAgICAgICAgICAgICAgICAkRGV0ZWN0ZWRQb2ludCA9ICQod2hpbGUgKCRIb3N0LlVJLlJhd1VJLktleUF2YWlsYWJsZSkgew0KICAgICAgICAgICAgICAgICAgICAkSG9zdC5VSS5SYXdVSS5SZWFkS2V5KCJOb0VjaG8sSW5jbHVkZUtleURvd24sSW5jbHVkZUtleVVwIikNCiAgICAgICAgICAgICAgICAgICAgU3RhcnQtU2xlZXAgLW0gMTANCiAgICAgICAgICAgICAgICB9KS5DaGFyYWN0ZXIgLWpvaW4gIiINCg0KICAgICAgICAgICAgICAgIGlmICgkRGV0ZWN0ZWRQb2ludCAtZXEgIiIgLWFuZCBbQ29uc29sZV06OkN1cnNvckxlZnQgLW5lICRDTCkgew0KICAgICAgICAgICAgICAgICAgICAjIFNvbWV0aW1lcyB0aGUgdGVybWluYWwgZG9lc24ndCByZXNwb25kIHdpdGggdGhlIGN1cnNvciBwb3NpdGlvbiwgYW5kIGluc3RlYWQgcHJpbnRlZCBpdA0KICAgICAgICAgICAgICAgICAgICB3aGlsZShbQ29uc29sZV06OkN1cnNvckxlZnQgLWd0ICRDTCkge1dyaXRlLUhvc3QgLU5vTmV3bGluZSAiYGIifQ0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gInswfSx7MX0iIC1mIFtDb25zb2xlXTo6Q3Vyc29yTGVmdCwgW0NvbnNvbGVdOjpDdXJzb3JUb3ANCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBpZiAoISREZXRlY3RlZFBvaW50IC1vciAkRGV0ZWN0ZWRQb2ludCAtbm90bWF0Y2ggIl5ceDFiXFsoXGQrKTsoXGQrKVIkIikge3JldHVybiAiMCwwIn0NCiAgICAgICAgICAgICAgICByZXR1cm4gInswfSx7MX0iIC1mICgkTWF0Y2hlc1syXS0xKSwoJE1hdGNoZXNbMV0tMSkNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICAiY2xlYXItZnJvbS1jdXJzb3IiID0gQHsNCiAgICAgICAgICAgIGF1dG9jb21wbGV0ZXIgPSB7DQogICAgICAgICAgICAgICAgcGFyYW0oJGEsJGIsJFdvcmRUb0NvbXBsZXRlKQ0KICAgICAgICAgICAgICAgIHJldHVybiBAKCJsZWZ0IiwicmlnaHQiKSB8IERvLUFyZ01hdGNoIC1Xb3JkVG9Db21wbGV0ZSAkV29yZFRvQ29tcGxldGUNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHdpbiA9IHsNCiAgICAgICAgICAgICAgICBpZiAoW0NvbnNvbGVdOjpJc091dHB1dFJlZGlyZWN0ZWQpIHtyZXR1cm59DQogICAgICAgICAgICAgICAgJGhhc1JpZ2h0ID0gJGFyZ3MgLWNvbnRhaW5zICJyaWdodCINCiAgICAgICAgICAgICAgICAkaGFzTGVmdCA9ICRhcmdzIC1jb250YWlucyAibGVmdCIgLW9yICEkaGFzUmlnaHQNCiAgICAgICAgICAgICAgICBpZiAoJGhhc0xlZnQpIHtQbGFjZS1CdWZmZXJlZENvbnRlbnQgLXggMCAteSAoW0NvbnNvbGVdOjpDdXJzb3JUb3ApICgiICIgKiBbQ29uc29sZV06OkN1cnNvckxlZnQpfQ0KICAgICAgICAgICAgICAgIGlmICgkaGFzUmlnaHQpIHtQbGFjZS1CdWZmZXJlZENvbnRlbnQgLXggKFtDb25zb2xlXTo6Q3Vyc29yTGVmdCkgLXkgKFtDb25zb2xlXTo6Q3Vyc29yVG9wKSAgKCIgIiAqIChbQ29uc29sZV06OkJ1ZmZlcldpZHRoIC0gW0NvbnNvbGVdOjpDdXJzb3JMZWZ0KSl9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB1bml4ID0gew0KICAgICAgICAgICAgICAgICRoYXNMZWZ0ID0gJGFyZ3MgLWNvbnRhaW5zICJsZWZ0Ig0KICAgICAgICAgICAgICAgICRoYXNSaWdodCA9ICRhcmdzIC1jb250YWlucyAicmlnaHQiDQogICAgICAgICAgICAgICAgaWYgKCRoYXNMZWZ0IC1hbmQgJGhhc1JpZ2h0KSB7cmV0dXJuIFdyaXRlLUhvc3QgLU5vTmV3bGluZSAiJChHZXQtRXNjYXBlKVsySyJ9DQogICAgICAgICAgICAgICAgaWYgKCRoYXNMZWZ0KSB7V3JpdGUtSG9zdCAtTm9OZXdsaW5lICIkKEdldC1Fc2NhcGUpWzFLIn0NCiAgICAgICAgICAgICAgICBpZiAoJGhhc1JpZ2h0KSB7V3JpdGUtSG9zdCAtTm9OZXdsaW5lICIkKEdldC1Fc2NhcGUpWzBLIn0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICAiY2xlYXItbGluZSIgPSBAew0KICAgICAgICAgICAgd2luID0ge0NsZWFyLUxpbmV9DQogICAgICAgICAgICB1bml4ID0ge1dyaXRlLUhvc3QgLU5vTmV3bGluZSAiJChHZXQtRXNjYXBlKVsyS2ByIn0NCiAgICAgICAgfQ0KICAgICAgICAiY2xlYXItc2NyZWVuIiA9IEB7DQogICAgICAgICAgICB3aW4gPSB7Q2xlYXItSG9zdH0NCiAgICAgICAgICAgIHVuaXggPSB7TGludXgtQ2xzfQ0KICAgICAgICB9DQogICAgICAgICJzZXQtY3Vyc29yIiA9IEB7DQogICAgICAgICAgICBhdXRvY29tcGxldGVyID0gJEN1cnNvckF1dG9jb21wbGV0ZXINCiAgICAgICAgICAgIHdpbiA9IHsNCiAgICAgICAgICAgICAgICBwYXJhbSgkaG9va3MpDQogICAgICAgICAgICAgICAgaWYgKFtDb25zb2xlXTo6SXNPdXRwdXRSZWRpcmVjdGVkKSB7cmV0dXJufQ0KICAgICAgICAgICAgICAgICR4LCAkeSA9ICYgJGhvb2tzLnByb2Nlc3NDb29yZHNXaXRoV3JhcCAoW0NvbnNvbGVdOjpDdXJzb3JMZWZ0LFtDb25zb2xlXTo6Q3Vyc29yVG9wKSBAYXJncw0KICAgICAgICAgICAgICAgICR4ID0gRG8tQ2xhbXAgJHggMCAoW0NvbnNvbGVdOjpCdWZmZXJXaWR0aCAtIDEpDQogICAgICAgICAgICAgICAgJHkgPSBEby1DbGFtcCAkeSAwIChbQ29uc29sZV06OkJ1ZmZlckhlaWdodCAtIDEpDQogICAgICAgICAgICAgICAgW0NvbnNvbGVdOjpTZXRDdXJzb3JQb3NpdGlvbigkeCwgJHkpDQogICAgICAgICAgICB9DQogICAgICAgICAgICB1bml4ID0gew0KICAgICAgICAgICAgICAgIHBhcmFtKCRob29rcykNCiAgICAgICAgICAgICAgICAkeCwgJHkgPSAmICRob29rcy5wcm9jZXNzQ29vcmRzV2l0aFdyYXAgKFtDb25zb2xlXTo6Q3Vyc29yTGVmdCxbQ29uc29sZV06OkN1cnNvclRvcCkgQGFyZ3MNCiAgICAgICAgICAgICAgICBXcml0ZS1Ib3N0IC1Ob05ld2xpbmUgIiQoR2V0LUVzY2FwZSlbJCgkeSsxKTskKCgkeCsxKSlIIg0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICJtb3ZlLWN1cnNvciIgPSBAew0KICAgICAgICAgICAgYXV0b2NvbXBsZXRlciA9ICRDdXJzb3JBdXRvY29tcGxldGVyDQogICAgICAgICAgICB3aW4gPSB7DQogICAgICAgICAgICAgICAgcGFyYW0oJGhvb2tzKQ0KICAgICAgICAgICAgICAgICR4LCAkeSA9ICYgJGhvb2tzLnByb2Nlc3NEaXJlY3Rpb25zIEBhcmdzDQogICAgICAgICAgICAgICAgJHgsICR5ID0gJiAkaG9va3MucHJvY2Vzc0Nvb3JkcyAwLDAgJHgsJHkNCiAgICAgICAgICAgICAgICAjIFBsYWNlLUJ1ZmZlcmVkQ29udGVudCAteCAwIC15IDMgIngrJHggeSskeSB8ICQoUHJpbnQtTGlzdCAkYXJncykiDQogICAgICAgICAgICAgICAgJHggPSBEby1DbGFtcCAoW0NvbnNvbGVdOjpDdXJzb3JMZWZ0ICsgJFgpIDAgKFtDb25zb2xlXTo6QnVmZmVyV2lkdGggLSAxKQ0KICAgICAgICAgICAgICAgICR5ID0gRG8tQ2xhbXAgKFtDb25zb2xlXTo6Q3Vyc29yVG9wICsgJFkpIDAgKFtDb25zb2xlXTo6QnVmZmVySGVpZ2h0IC0gMSkNCiAgICAgICAgICAgICAgICBpZiAoW0NvbnNvbGVdOjpJc091dHB1dFJlZGlyZWN0ZWQpIHtyZXR1cm59DQogICAgICAgICAgICAgICAgW0NvbnNvbGVdOjpTZXRDdXJzb3JQb3NpdGlvbigkeCwgJHkpDQogICAgICAgICAgICB9DQogICAgICAgICAgICB1bml4ID0gew0KICAgICAgICAgICAgICAgIHBhcmFtKCRob29rcykNCiAgICAgICAgICAgICAgICAkeCwgJHkgPSAmICRob29rcy5wcm9jZXNzRGlyZWN0aW9ucyBAYXJncw0KICAgICAgICAgICAgICAgICR4LCAkeSA9ICYgJGhvb2tzLnByb2Nlc3NDb29yZHMgMCwwICR4LCR5DQogICAgICAgICAgICAgICAgJHhDb2RlID0gaWYgKCR4IC1sdCAwKSB7IiQoR2V0LUVzY2FwZSlbJCgtJHgpRCJ9IGVsc2VpZiAoJHggLWd0IDApIHsiJChHZXQtRXNjYXBlKVske3h9QyJ9IGVsc2UgeyIifQ0KICAgICAgICAgICAgICAgICR5Q29kZSA9IGlmICgkeSAtbHQgMCkgeyIkKEdldC1Fc2NhcGUpWyQoLSR5KUEifSBlbHNlaWYgKCR5IC1ndCAwKSB7IiQoR2V0LUVzY2FwZSlbJHt5fUIifSBlbHNlIHsiIn0NCiAgICAgICAgICAgICAgICBXcml0ZS1Ib3N0IC1Ob05ld2xpbmUgIiR4Q29kZSR5Q29kZSINCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCn0KCmZ1bmN0aW9uIFByaW50LUxpc3Qge3BhcmFtKCR4LCBbU3dpdGNoXSRJblJlY3Vyc2UpDQoNCiAgICBpZiAoJHguY291bnQgLWxlIDEpIHtyZXR1cm4gPzooJEluUmVjdXJzZSl7JHh9eyJbJHhdIn19IGVsc2Ugew0KICAgICAgICByZXR1cm4gIlskKCgkeCB8ICUge1ByaW50LUxpc3QgJF8gLUluUmVjdXJzZX0pIC1qb2luICcsICcpXSINCiAgICB9DQp9CgpmdW5jdGlvbiBHZXQtT1Mgew0KICAgIGlmICgkUFNWZXJzaW9uVGFibGUuUFNFZGl0aW9uIC1lcSAnQ29yZScpIHsNCiAgICAgICAgaWYgKCRJc1dpbmRvd3MpIHtyZXR1cm4gJ1dpbmRvd3MnfQ0KICAgICAgICBlbHNlaWYgKCRJc0xpbnV4KSB7cmV0dXJuICdMaW51eCd9DQogICAgICAgIGVsc2VpZiAoJElzTWFjT1MpIHtyZXR1cm4gJ01hY09TJ30NCiAgICB9IGVsc2Uge3JldHVybiAnV2luZG93cyd9DQp9CgpmdW5jdGlvbiBLZXlQcmVzc2VkQ29kZSB7cGFyYW0oW1BhcmFtZXRlcihNYW5kYXRvcnk9JFRydWUpXVtJbnRdJEtleSwgJFN0b3JlPSJeXl4iKQ0KDQogICAgaWYgKCEkSG9zdC5VSS5SYXdVSS5LZXlBdmFpbGFibGUgLWFuZCAkU3RvcmUgLWVxICJeXl4iKSB7UmV0dXJuICRGYWxzZX0NCiAgICBpZiAoJFN0b3JlIC1lcSAiXl5eIikgeyRTdG9yZSA9ICRIb3N0LlVJLlJhd1VJLlJlYWRLZXkoIkluY2x1ZGVLZXlVcCxOb0VjaG8iKX0NCiAgICByZXR1cm4gKCRLZXkgLWluICRTdG9yZS5WaXJ0dWFsS2V5Q29kZSkNCn0KCmZ1bmN0aW9uIEludm9rZS1UZXJuYXJ5IHtwYXJhbSgkZGVjaWRlciwgJGlmdHJ1ZSwgJGlmZmFsc2UgPSB7fSkNCg0KICAgICRJbnZva2VPclJldHVybiA9IHsNCiAgICAgICAgcGFyYW0oJENtZCkNCiAgICAgICAgaWYgKCRDbWQgLWlzIFtTY3JpcHRCbG9ja10pIHsmICRDbWR9IGVsc2UgeyRDbWR9DQogICAgfQ0KICAgIGlmICgkZGVjaWRlcikgeyYgJEludm9rZU9yUmV0dXJuICRpZnRydWV9IGVsc2UgeyYgJEludm9rZU9yUmV0dXJuICRpZmZhbHNlfQ0KfQoKZnVuY3Rpb24gUHJvY2Vzcy1Vbmljb2RlIHsNCiAgICAkRmluYWxBcmdzID0gRmxhdHRlbiAkYXJncw0KICAgICMgUG93ZXJTaGVsbCBDb3JlIHN5bnRheCB3aGVuIHByb2Nlc3NlZCBieSBQb3dlclNoZWxsIE5hdGl2ZQ0KICAgIGlmICgiJEZpbmFsQXJncyIgLW1hdGNoICJ1eyhcdyspfSIpIHsNCiAgICAgICAgcmV0dXJuIFtSZWdleF06OlVuZXNjYXBlKCgiJEZpbmFsQXJncyIgLXJlcGxhY2UgInV7KFx3Kyl9IiwnXHUkMScpKQ0KICAgIH0NCiAgICBpZiAoISgkRmluYWxBcmdzIHwgPyB7JF8gLWlzbm90IFtpbnRdfSkpIHsNCiAgICAgICAgcmV0dXJuIFtjaGFyW11dJEZpbmFsQXJncyAtam9pbiAnJw0KICAgIH0NCiAgICByZXR1cm4gJGFyZ3MNCn0KCmZ1bmN0aW9uIEdldC1QYXRoVmFyU2VwIHtwYXJhbShbc3RyaW5nXSRPdmVycmlkZSA9ICIiKQ0KDQogICAgJElzVW5peCA9ICRQU1ZlcnNpb25UYWJsZS5QbGF0Zm9ybSAtZXEgIlVuaXgiDQogICAgcmV0dXJuIEpTLU9SICRPdmVycmlkZSAoPzogJElzVW5peCAiOiIgIjsiKQ0KfQoKZnVuY3Rpb24gS2V5UHJlc3NlZCB7cGFyYW0oW1BhcmFtZXRlcihNYW5kYXRvcnk9JFRydWUpXVtTdHJpbmdbXV0kS2V5LCAkU3RvcmUgPSAiXl5eIikNCg0KICAgIGlmICgkU3RvcmUgLWVxICJeXl4iIC1hbmQgJEhvc3QuVUkuUmF3VUkuS2V5QXZhaWxhYmxlKSB7JFN0b3JlID0gJEhvc3QuVUkuUmF3VUkuUmVhZEtleSgiSW5jbHVkZUtleVVwLE5vRWNobyIpfSBlbHNlIHtpZiAoJFN0b3JlIC1lcSAiXl5eIikge3JldHVybiAkRmFsc2V9fQ0KICAgICRLZXkgfCAlIHsNCiAgICAgICAgJFNPVVJDRSA9ICRfDQogICAgICAgIEZvcmVhY2ggKCRLIGluICRTT1VSQ0UpIHsNCiAgICAgICAgICAgIFtTdHJpbmddJEsgPSAkSw0KICAgICAgICAgICAgaWYgKCRLIC1tYXRjaCAiXmMtKFxkKykkIikgew0KICAgICAgICAgICAgICAgIGlmIChLZXlQcmVzc2VkQ29kZSAkTWF0Y2hlc1sxXSAkU3RvcmUpIHtyZXR1cm4gJFRydWV9DQogICAgICAgICAgICB9IGVsc2VpZiAoJEsgLW1hdGNoICJefn4oLispfn4kIikgew0KICAgICAgICAgICAgICAgICRDb2RlID0gS2V5VHJhbnNsYXRlICRLDQogICAgICAgICAgICAgICAgaWYgKCRDb2RlIC1pcyBbaGFzaHRhYmxlXSkgew0KICAgICAgICAgICAgICAgICAgICAkSGFzRW5oYW5jZWQgPSAkU3RvcmUuQ29udHJvbEtleVN0YXRlLkhhc0ZsYWcoW1N5c3RlbS5NYW5hZ2VtZW50LkF1dG9tYXRpb24uSG9zdC5Db250cm9sS2V5U3RhdGVzXTo6RW5oYW5jZWRLZXkpDQogICAgICAgICAgICAgICAgICAgIGlmICgkQ29kZS5lbmhhbmNlZCAtbmUgJEhhc0VuaGFuY2VkKSB7Y29udGludWV9DQogICAgICAgICAgICAgICAgICAgICRDb2RlID0gJENvZGUuY29kZQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoS2V5UHJlc3NlZENvZGUgJENvZGUgJFN0b3JlKSB7cmV0dXJuICRUcnVlfQ0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBpZiAoJEsuY2hhcnMoMCkgLWluICRTdG9yZS5DaGFyYWN0ZXIpIHtyZXR1cm4gJFRydWV9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQogICAgcmV0dXJuICRGYWxzZQ0KfQoKZnVuY3Rpb24gR2V0LUxldmVuc2h0ZWluIHsNCiAgICBbQ21kbGV0QmluZGluZygpXQ0KICAgIHBhcmFtKA0KICAgICAgICBbUGFyYW1ldGVyKE1hbmRhdG9yeT0kdHJ1ZSwgUG9zaXRpb249MCldW3N0cmluZ10kU291cmNlLA0KICAgICAgICBbUGFyYW1ldGVyKE1hbmRhdG9yeT0kdHJ1ZSwgUG9zaXRpb249MSldW3N0cmluZ10kVGFyZ2V0LA0KICAgICAgICBbc3dpdGNoXSROb3JtYWxpemUNCiAgICApDQoNCiAgICAjIE9wdGltaXphdGlvbnMgZm9yIGVkZ2UgY2FzZXMNCiAgICBpZiAoJFNvdXJjZSAtZXEgJFRhcmdldCkge3JldHVybiAwfQ0KICAgIGlmIChbc3RyaW5nXTo6SXNOdWxsT3JFbXB0eSgkU291cmNlKSkge3JldHVybiAkVGFyZ2V0Lkxlbmd0aH0NCiAgICBpZiAoW3N0cmluZ106OklzTnVsbE9yRW1wdHkoJFRhcmdldCkpIHtyZXR1cm4gJFNvdXJjZS5MZW5ndGh9DQoNCiAgICAjIFN3YXAgZm9yIG9wdGltaXphdGlvbiBpZiBUYXJnZXQgaXMgc2hvcnRlciB0aGFuIFNvdXJjZQ0KICAgIGlmICgkVGFyZ2V0Lkxlbmd0aCAtbHQgJFNvdXJjZS5MZW5ndGgpIHsNCiAgICAgICAgJFRlbXAgPSAkU291cmNlDQogICAgICAgICRTb3VyY2UgPSAkVGFyZ2V0DQogICAgICAgICRUYXJnZXQgPSAkVGVtcA0KICAgIH0NCg0KICAgICMgSW5pdGlhbGl6ZSBkaXN0YW5jZSBhcnJheSAob25seSBzdG9yZSBjdXJyZW50IGFuZCBwcmV2aW91cyByb3dzKQ0KICAgICRQcmV2Um93ID0gTmV3LU9iamVjdCBpbnRbXSAoJFNvdXJjZS5MZW5ndGggKyAxKQ0KICAgICRDdXJyUm93ID0gTmV3LU9iamVjdCBpbnRbXSAoJFNvdXJjZS5MZW5ndGggKyAxKQ0KDQogICAgIyBJbml0aWFsaXplIHRoZSBmaXJzdCByb3cNCiAgICBmb3IgKCRpID0gMDsgJGkgLWxlICRTb3VyY2UuTGVuZ3RoOyAkaSsrKSB7DQogICAgICAgICRQcmV2Um93WyRpXSA9ICRpDQogICAgfQ0KDQogICAgIyBDYWxjdWxhdGUgdGhlIG1pbmltdW0gZWRpdCBkaXN0YW5jZQ0KICAgIGZvciAoJGkgPSAwOyAkaSAtbHQgJFRhcmdldC5MZW5ndGg7ICRpKyspIHsNCiAgICAgICAgJEN1cnJSb3dbMF0gPSAkaSArIDENCg0KICAgICAgICBmb3IgKCRqID0gMDsgJGogLWx0ICRTb3VyY2UuTGVuZ3RoOyAkaisrKSB7DQogICAgICAgICAgICAkQ29zdCA9IGlmICgkU291cmNlWyRqXSAtZXEgJFRhcmdldFskaV0pIHswfSBlbHNlIHsxfQ0KDQogICAgICAgICAgICAjIENhbGN1bGF0ZSBtaW5pbXVtIGNvc3QgZnJvbSB0aHJlZSBvcGVyYXRpb25zDQogICAgICAgICAgICAkQ3VyclJvd1skaiArIDFdID0gW01hdGhdOjpNaW4oDQogICAgICAgICAgICAgICAgKCRDdXJyUm93WyRqXSArIDEpLCAgICAgICAgICAgICAgICAgICAjIEluc2VydGlvbg0KICAgICAgICAgICAgICAgIFtNYXRoXTo6TWluKA0KICAgICAgICAgICAgICAgICAgICAoJFByZXZSb3dbJGogKyAxXSArIDEpLCAgICAgICAgICAgIyBEZWxldGlvbg0KICAgICAgICAgICAgICAgICAgICAoJFByZXZSb3dbJGpdICsgJENvc3QpICAgICAgICAgICAgIyBTdWJzdGl0dXRpb24NCiAgICAgICAgICAgICAgICApDQogICAgICAgICAgICApDQogICAgICAgIH0NCg0KICAgICAgICAjIFN3YXAgcm93cyBmb3IgbmV4dCBpdGVyYXRpb24NCiAgICAgICAgJFRlbXAgPSAkUHJldlJvdw0KICAgICAgICAkUHJldlJvdyA9ICRDdXJyUm93DQogICAgICAgICRDdXJyUm93ID0gJFRlbXANCiAgICB9DQoNCiAgICAkRGlzdGFuY2UgPSAkUHJldlJvd1skU291cmNlLkxlbmd0aF0NCg0KICAgICMgTm9ybWFsaXplIGlmIHJlcXVlc3RlZCAoMC0xIHNjYWxlIHdoZXJlIDEgbWVhbnMgaWRlbnRpY2FsKQ0KICAgIGlmICgkTm9ybWFsaXplKSB7DQogICAgICAgICRNYXhMZW5ndGggPSBbTWF0aF06Ok1heCgkU291cmNlLkxlbmd0aCwgJFRhcmdldC5MZW5ndGgpDQogICAgICAgIHJldHVybiA/OiAoJE1heExlbmd0aCAtZXEgMCkgMSAoMSAtICgkRGlzdGFuY2UgLyAkTWF4TGVuZ3RoKSkNCiAgICB9DQoNCiAgICByZXR1cm4gJERpc3RhbmNlDQp9CgpmdW5jdGlvbiBDbGVhci1MaW5lIHsNCiAgICAkTm0gPSBbQ29uc29sZV06OldpbmRvd1dpZHRoDQogICAgJHQgPSBbQ29uc29sZV06OkN1cnNvclRvcDtbQ29uc29sZV06OkN1cnNvckxlZnQ9MA0KICAgIFdyaXRlLUhvc3QgLU5vTmV3TGluZSAoIiAiKiROTSkNCiAgICBbQ29uc29sZV06OkN1cnNvclRvcD0kdDtbQ29uc29sZV06OkN1cnNvckxlZnQ9MA0KfQoKZnVuY3Rpb24gRG8tQXJnTWF0Y2ggew0KICAgIFtDbWRsZXRCaW5kaW5nKCldDQogICAgcGFyYW0oDQogICAgICAgIFtzdHJpbmddJFdvcmRUb0NvbXBsZXRlLA0KICAgICAgICBbc2NyaXB0YmxvY2tdJE1hdGNoT24sDQogICAgICAgIFtzY3JpcHRibG9ja10kQ29tcGxldGlvbkZvcm1hdHRlciwNCiAgICAgICAgW0FsaWFzKCdMaW1pdCcpXVtpbnRdJE1heFJlc3VsdHMgPSA1MCwNCiAgICAgICAgW0FsaWFzKCdGdXp6eScpXVtzd2l0Y2hdJFVzZUxldmVuc2h0ZWluLA0KICAgICAgICBbUGFyYW1ldGVyKFZhbHVlRnJvbVBpcGVsaW5lPSR0cnVlKV0kX2FyZ3MNCiAgICApDQogICAgYmVnaW4geyRjb2xsZWN0ZWRBcmdzID0gQCgpfQ0KICAgIHByb2Nlc3MgeyRjb2xsZWN0ZWRBcmdzICs9ICwkX2FyZ3N9DQogICAgZW5kIHsNCiAgICAgICAgJFRyeUdldFRleHQgPSB7DQogICAgICAgICAgICBwYXJhbSgkVGV4dCkNCiAgICAgICAgICAgIGlmICgkTWF0Y2hPbiAtaXMgW3NjcmlwdGJsb2NrXSkge3JldHVybiAkVGV4dCB8ICUgJE1hdGNoT259DQogICAgICAgICAgICBpZiAoJFRleHQgLWlzIFtTeXN0ZW0uTWFuYWdlbWVudC5BdXRvbWF0aW9uLkNvbXBsZXRpb25SZXN1bHRdKSB7cmV0dXJuICRUZXh0LkNvbXBsZXRpb25UZXh0fQ0KICAgICAgICAgICAgcmV0dXJuIFtzdHJpbmddJFRleHQNCiAgICAgICAgfQ0KICAgICAgICAkU2VsZWN0QXJncyA9ID86ICgkTWF4UmVzdWx0cyAtZ3QgMCkgQHtGaXJzdD0kTWF4UmVzdWx0c30gQHt9DQogICAgICAgICRGaWx0ZXJlcnMgPSBAKA0KICAgICAgICAgICAgeyRjb2xsZWN0ZWRBcmdzIHwgPyB7KCYgJFRyeUdldFRleHQgJF8pIC1saWtlICIkV29yZFRvQ29tcGxldGUqIn19DQogICAgICAgICAgICB7JGNvbGxlY3RlZEFyZ3MgfCA/IHsoJiAkVHJ5R2V0VGV4dCAkXykgLWxpa2UgIiokV29yZFRvQ29tcGxldGUqIn19DQogICAgICAgICAgICAkKGlmICgkVXNlTGV2ZW5zaHRlaW4pIHt7DQogICAgICAgICAgICAgICAgJGNvbGxlY3RlZEFyZ3MgfCAlIHsNCiAgICAgICAgICAgICAgICAgICAgJHRleHQgPSAmICRUcnlHZXRUZXh0ICRfDQogICAgICAgICAgICAgICAgICAgICRzaW1pbGFyaXR5ID0gR2V0LUxldmVuc2h0ZWluICRXb3JkVG9Db21wbGV0ZSAoJHRleHQuU3Vic3RyaW5nKDAsIFtNYXRoXTo6TWluKCRXb3JkVG9Db21wbGV0ZS5MZW5ndGgsICR0ZXh0Lkxlbmd0aCkpKSAtTm9ybWFsaXplDQogICAgICAgICAgICAgICAgICAgIGlmICgkc2ltaWxhcml0eSAtZ2UgLjcpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIFtQU0N1c3RvbU9iamVjdF1Ae0l0ZW09JF87U2ltaWxhcml0eT0kc2ltaWxhcml0eX0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0gfCBzb3J0IFNpbWlsYXJpdHkgLURlc2NlbmRpbmcgfCBzZWxlY3QgLUV4cGFuZFByb3BlcnR5IEl0ZW0NCiAgICAgICAgICAgIH19IGVsc2Uge3t9fSksDQogICAgICAgICAgICAkY29sbGVjdGVkQXJncw0KICAgICAgICApIHwgPyB7JF99DQogICAgICAgIHJldHVybiBKUy1PUiBARmlsdGVyZXJzIHwgc2VsZWN0IEBTZWxlY3RBcmdzIHwgJSB7DQogICAgICAgICAgICBpZiAoISRDb21wbGV0aW9uRm9ybWF0dGVyKSB7cmV0dXJuICRffQ0KICAgICAgICAgICAgJF8gfCAlICRDb21wbGV0aW9uRm9ybWF0dGVyDQogICAgICAgIH0gfCAlIHsNCiAgICAgICAgICAgICRuYW1lID0gSlMtT1IgJF8uTmFtZSAkXy5WYWx1ZSAkXy5LZXkgJF8uQ29tcGxldGlvblRleHQgJF8NCiAgICAgICAgICAgICRkaXNwbGF5VGV4dCA9IEpTLU9SICRfLkRpc3BsYXkgJF8uVmlzdWFsICRfLkxpc3RJdGVtVGV4dCAkbmFtZQ0KICAgICAgICAgICAgJGRlc2NyaXB0aW9uID0gSlMtT1IgJF8uRGVzY3JpcHRpb24gJF8uQ29tbWVudCAkXy5Tb3VyY2UgJF8uVG9vbFRpcCAkZGlzcGxheVRleHQgJG5hbWUNCiAgICAgICAgICAgICR0eXBlID0gSlMtT1IgJF8uUmVzdWx0VHlwZSAiUGFyYW1ldGVyVmFsdWUiDQogICAgICAgICAgICAkZmluYWxPcHRpb25hbGx5UXVvdGVkTmFtZSA9IGlmICgkbmFtZSAtbWF0Y2ggJ1xzJykgeyJgIiRuYW1lYCIifSBlbHNlIHskbmFtZX0NCiAgICAgICAgICAgIFtTeXN0ZW0uTWFuYWdlbWVudC5BdXRvbWF0aW9uLkNvbXBsZXRpb25SZXN1bHRdOjpuZXcoJGZpbmFsT3B0aW9uYWxseVF1b3RlZE5hbWUsICRkaXNwbGF5VGV4dCwgJHR5cGUsICRkZXNjcmlwdGlvbikNCiAgICAgICAgfQ0KICAgIH0NCn0KCmZ1bmN0aW9uIFBsYWNlLUJ1ZmZlcmVkQ29udGVudCB7cGFyYW0oJFRleHQsICR4LCAkeSwgW0NvbnNvbGVDb2xvcl0kRm9yZWdyb3VuZENvbG9yPVtDb25zb2xlXTo6Rm9yZWdyb3VuZENvbG9yLCBbQ29uc29sZUNvbG9yXSRCYWNrZ3JvdW5kQ29sb3I9W0NvbnNvbGVdOjpCYWNrZ3JvdW5kQ29sb3IpDQoNCiAgICBpZiAoISRUZXh0KSB7cmV0dXJufQ0KICAgICRjcmQgPSBbTWFuYWdlbWVudC5BdXRvbWF0aW9uLkhvc3QuQ29vcmRpbmF0ZXNdOjpuZXcoJHgsJHkpDQogICAgJGIgPSAkSG9zdC5VSS5SYXdVSQ0KICAgICRhcnIgPSAkYi5OZXdCdWZmZXJDZWxsQXJyYXkoQCgkVGV4dCksICRGb3JlZ3JvdW5kQ29sb3IsICRCYWNrZ3JvdW5kQ29sb3IpDQogICAgJHggPSBbQ29uc29sZV06OkJ1ZmZlcldpZHRoLTEtJFRleHQubGVuZ3RoDQogICAgJGIuU2V0QnVmZmVyQ29udGVudHMoJGNyZCwgJGFycikNCn0KCmZ1bmN0aW9uIExpbnV4LUNscyB7DQogICAgPCMNCiAgICAuU1lOT1BTSVMNCiAgICAgICAgQ2xlYXJzIHRoZSB0ZXJtaW5hbCAoY29uc29sZSkgc2NyZWVuIGFzIHdlbGwgYXMgdGhlIHNjcm9sbGJhY2sgYnVmZmVyLg0KICAgICM+DQogICAgW0NvbnNvbGVdOjpXcml0ZSgiJChHZXQtRXNjYXBlKVsySiQoR2V0LUVzY2FwZSlbM0okKEdldC1Fc2NhcGUpW0giKQ0KfQoKU2V0LUFsaWFzIHhjb24gQ3Jvc3MtQ29uc29sZUFQSQpTZXQtQWxpYXMgPzogSW52b2tlLVRlcm5hcnkKU2V0LUFsaWFzIHJnYiBHZXQtUkdCClNldC1BbGlhcyBjb2wgR2V0LUNvbG9yClNldC1BbGlhcyB3aGljaCBHZXQtV2hlcmU=")
} elseif($AP_CONSOLE.warnOnCompileRun) {& $AP_CONSOLE.warnOnCompileRun}
# ========================================END=OF=COMPILER=================================================================|
if ($Renderer -eq "Auto-Detect") {$Renderer = ?: (AP-Require ability:escape_codes) "Unix" "Windows"}
$e = Get-Escape
function Get-RandomChar {
if (!$SpecialChars) {return [char](Get-Random -Minimum 33 -Maximum 126)}
$charSets = @(
# Katakana characters
@(0x30A0..0x30FF),
# Latin letters (uppercase and lowercase)
@(0x0041..0x005A + 0x0061..0x007A),
# Digits
@(0x0030..0x0039),
# Some special characters
@(0x0021, 0x0023, 0x0024, 0x0025, 0x002B, 0x003D, 0x003F, 0x0040),
# Additional Matrix-like symbols
@(0x25A0, 0x25A1, 0x25B2, 0x25B3, 0x25BC, 0x25BD)
)
$weights = @(
70, # Weight for Katakana
20, # Weight for Latin letters
5, # Weight for digits
3, # Weight for special characters
2 # Weight for additional symbols
)
$totalWeight = ($weights | Measure-Object -Sum).Sum
$randomValue = Get-Random -Minimum 1 -Maximum ($totalWeight + 1)
$currentWeight = 0
$selectedSet = -1
for ($i = 0; $i -lt $weights.Count; $i++) {
$currentWeight += $weights[$i]
if ($randomValue -le $currentWeight) {
$selectedSet = $i
break
}
}
try {
$char = [char](Get-Random -InputObject $charSets[$selectedSet])
} catch {
Write-Host "Selected set: $selectedSet | Set count: $($charSets.Count)"
exit
}
return $char
}
class MatrixLine {
[char[]]$Line
[int]$xOffset
[int]$Speed = 1
[int]$Size = 1
[bool]$IsDead = $false
hidden [int]$yOffset = 0
MatrixLine([int]$xOffset) {
$this.xOffset = $xOffset
$this.initialize()
$this.Speed = Get-Random -Minimum 1 -Maximum ([Math]::Max(2, $this.Size * .3))
}
MatrixLine([int]$xOffset, [int]$Speed) {
$this.xOffset = $xOffset
$this.Speed = $Speed
$this.initialize()
}
Hidden initialize() {
$this.Line = @()
$ConsoleHeight = $global:Host.UI.RawUI.WindowSize.Height
# Randomize the length of the line between 9% and 40% of the console height
$this.Size = Get-Random -Minimum ([Math]::Max(1, $ConsoleHeight * .09)) -Maximum ([Math]::Min([Math]::Max(2, $ConsoleHeight * .70), 50))
}
[bool]ValidateIsInBounds() {
if ($this.IsDead) { return $false }
$ConsoleWidth = $global:Host.UI.RawUI.WindowSize.Width
$ConsoleHeight = $global:Host.UI.RawUI.WindowSize.Height
if (($this.yOffset - $this.Size - 1) -gt $ConsoleHeight) {
$this.Die()
return $false
}
if ($this.xOffset -lt 0 -or $this.xOffset -ge $ConsoleWidth) {
$this.Die()
return $false
}
return $true
}
Tick() {
# Write-AP "x*","n_Ticking ($($this.IsDead) | $($this.ValidateIsInBounds()) | $($this.Line.Length) | $($this.Size) | $($this.yOffset) | $($this.xOffset))"
if (!$this.ValidateIsInBounds()) { return }
if ($this.Line.Length -lt $this.Size) {
$this.Line += Get-RandomChar
}
$this.Draw()
$this.yOffset += $this.Speed
}
Draw() {
$ConsoleHeight = $global:Host.UI.RawUI.WindowSize.Height
for ($i = 0; $i -lt $this.Line.Length; $i++) {
if ($this.yOffset + $i -ge $ConsoleHeight) { break }
$char = Get-RandomChar
if ($Script:Debug) {try{Place-BufferedContent -x ([Console]::WindowWidth - 50) -y 0 -Text " i: $i | $char | $($this.Line.Length) | $($this.yOffset + $i) | $($this.Line.Length - 1) "}catch{}}
$RatioToFront = $(if ($i -eq ($this.Line.Length - 1) -and $this.yOffset) {1} else {$i / $this.Line.Length})
# WriteTo the Correct position
DrawTo -x $this.xOffset -y ($this.yOffset + $i) -RatioToFront $RatioToFront -text $char
}
# Erase the last character of the line
$LastYs = ($this.yOffset - $this.Line.Length)..($this.yOffset - $this.Line.Length - $this.Speed)
$LastYs | ? {$_ -ge 0 -and $_ -le $ConsoleHeight} | % {
DrawTo -x $this.xOffset -y $_ -RatioToFront -1 -text " "
}
}
Die() {
$this.IsDead = $true
}
}
function DrawTo([int]$x, [int]$y, [decimal]$RatioToFront, [string]$text) {
if ($Renderer -eq "Windows") {
if ($RatioToFront -eq -1) {
# Clear the position
Place-BufferedContent -x $x -y $y -Text " "
return
}
$Styles = @{
ForegroundColor = ""
BackgroundColor = [Console]::BackgroundColor
}
$Styles.ForegroundColor = $(if ($RatioToFront -eq 1) {"White"} elseif ($RatioToFront -ge 0.7) {"Green"} else {"DarkGreen"})
if ($RatioToFront -ge 0.7) {$Styles.BackgroundColor = "DarkGreen"}
Place-BufferedContent -x $x -y $y -Text "$text" @Styles
} elseif ($Renderer -eq "Unix") {
if ($RatioToFront -eq -1) {
# Clear the position
Write-Host -NoNewline "${e}[$y;${x}H "
return
}
# Base green color (dark green to bright green)
$baseGreen = [Math]::Max(0, [Math]::Min(255, [int](50 + (205 * $RatioToFront))))
# Enhanced glow effect for leading characters
if ($RatioToFront -gt 0.7) {
$glowIntensity = ($RatioToFront - 0.7) / 0.3 # Normalized to 0-1 range
$red = [Math]::Min(255, [int](200 * $glowIntensity))
$green = 255 # Max brightness for green
$blue = [Math]::Min(255, [int](100 * $glowIntensity))
$escapeSequence = "${e}[$y;${x}H${e}[38;2;$red;$green;$blue m"
} else {
$escapeSequence = "${e}[$y;${x}H${e}[38;2;0;$baseGreen;0m"
}
Write-Host -NoNewline "$escapeSequence$text${e}[0m"
}
}
function Setup-Console {
# Back up the current terminal buffer content
$Script:CurrBuffer = [Rectangle]::new(0, 0, $Host.UI.RawUI.BufferSize.Width, $Host.UI.RawUI.BufferSize.Height)
if ($Renderer -eq "Windows") {
try {
$Script:BufferContent = $Host.UI.RawUI.GetBufferContents($Script:CurrBuffer)
# Save the current cursor position
$Script:CursorPos = $Host.UI.RawUI.CursorPosition
# Hide the cursor
[Console]::CursorVisible = $false
} catch {
Write-AP "x*","n_Failed to get the current terminal buffer content: $_"
Start-Sleep 1
}
} elseif ($Renderer -eq "Unix") {
# Print ESC[?47h to save the current terminal buffer content
Write-Host -NoNewline "${e}[?47h"
# # Save the current cursor position with ESC[s
# Write-Host -NoNewline "${e}[s"
# Save Cursor Exact Position with ESC[6n
$global:cp = $Script:CursorPosUnix = xcon get-cursor -Renderer unix
# Hide the cursor with ESC[?25l
Write-Host -NoNewline "${e}[?25l"
}
Clear-Host
}
function Reset-Console {
if ($Renderer -eq "Windows") {
# Show the cursor
[Console]::CursorVisible = $true
# Clear the screen
Clear-Host
# Restore the original terminal buffer content
if ($Script:BufferContent) {
try {
Write-AP "x*","n_Restoring the original terminal buffer content"
$Coords = [Coordinates]::new(0, 0)
$Host.UI.RawUI.SetBufferContents($Coords, $Script:BufferContent)
} catch {
Write-Host -f Red "Failed to restore the original terminal buffer content: $_"
}
}
# Restore the original cursor position
if ($Script:CursorPos) {
try {
$Host.UI.RawUI.CursorPosition = $Script:CursorPos
} catch {
Write-Host -f Red "Failed to restore the original cursor position: $_"
}
}
} elseif ($Renderer -eq "Unix") {
# Print ESC[?47l to restore the original terminal buffer content
Write-Host "${e}[?47l"
# Show the cursor with ESC[?25h
Write-Host "${e}[?25h"
# Restore the cursor position with ESC[<row>;<column>R
xcon set-cursor $global:cp -Renderer unix
}
}
$Script:CurrMatrixLines = @()
function Get-GridColumns {
$ConsoleWidth = $global:Host.UI.RawUI.WindowSize.Width
return [Math]::Max(1, [Math]::Floor($ConsoleWidth * $Sparsity))
}
function Tick-MatrixAnimation {
$ConsoleWidth = $global:Host.UI.RawUI.WindowSize.Width
$TotalColumns = Get-GridColumns
# Make sure CurrMatrixLines is the same length as the console width
while ($Script:CurrMatrixLines.Length -lt $TotalColumns) {$Script:CurrMatrixLines += $null} # Add nulls until the length is correct
$Script:CurrMatrixLines = $Script:CurrMatrixLines[0..($TotalColumns - 1)] # Trim the array to the correct length
$EmptyLineIndeces = 0..($TotalColumns - 1) | ? { !$Script:CurrMatrixLines[$_] }
0..$Script:CurrMatrixLines.length | % {
if (!$Script:CurrMatrixLines[$_].IsDead) { return }
$Script:CurrMatrixLines[$_] = $null # Remove dead lines
}
if ($EmptyLineIndeces.Count -ne 0) {
$EmptyLineIndeces | Get-Random | % {
$ColumnWidth = $Script:ColumnWidths[$_]
$ColumnIdx = $_
$ColumnMin = ($Script:ColumnWidths[0..($ColumnIdx - 1)] | Measure-Object -Sum).Sum
$ColumnMax = [Math]::Max($ColumnMin + 1, $ColumnWidth * ($ColumnIdx + 1))
if ($Debug) {try{Place-BufferedContent -x ([Console]::WindowWidth - 50) -y 1 -Text " $ColumnIdx | $ColumnMin | $ColumnMax | $ColumnWidth | $ConsoleWidth/$TotalColumns "}catch{}}
$RandomX = [Math]::Floor((Get-Random -Minimum $ColumnMin -Maximum $ColumnMax))
$Script:CurrMatrixLines[$ColumnIdx] = [MatrixLine]::new($RandomX)
}
}
$CurrMatrixLines | ? {$_} | % { $_.Tick() }
}
function Recompute-ColumnWidths {
$ConsoleWidth = $global:Host.UI.RawUI.WindowSize.Width
$TotalColumns = Get-GridColumns
$AdjustableIndeces = @()
$ColumnWidth = [Math]::Max(1, [int]($ConsoleWidth / $TotalColumns))
$Script:ColumnWidths = JS-OR $Script:ColumnWidths {1..$TotalColumns | % { $ColumnWidth }}
if ($Script:ColumnWidths.Count -lt $TotalColumns) {
$AdjustableIndeces += $Script:ColumnWidths.Count..($TotalColumns - 1)
$Script:ColumnWidths += 1..($TotalColumns - $Script:ColumnWidths.Count) | % { $ColumnWidth }
} elseif ($Script:ColumnWidths.Count -gt $TotalColumns) {
$Script:ColumnWidths = $Script:ColumnWidths[0..($TotalColumns - 1)]
}
if ($AdjustableIndeces.Count -eq 0) { $AdjustableIndeces = 0..($TotalColumns - 1) }
$TotalAllocatedSize = $Script:ColumnWidths | Measure-Object -Sum | Select-Object -ExpandProperty Sum
for ($i = 0; $i -lt ($ConsoleWidth - $TotalAllocatedSize); $i++) { $Script:ColumnWidths[(Get-Random $AdjustableIndeces)]++ }
if ($Debug) {
xcon move-cursor 0 ([Console]::WindowHeight - 1)
Write-Host -NoNewLine ((1..$TotalColumns | % {
$ColumnIdx = $_ - 1
$ColumnWidth = $Script:ColumnWidths[$ColumnIdx]
Write-Host -NoNewline "$(rgb -bg (1..3 | % {get-random -min 0 -max 255}))$(" " * $ColumnWidth)"
}) -join "")
}
}
function Script-Tick {
# Detect Escape and reset the terminal
While ($Host.UI.RawUI.KeyAvailable) {
$Store = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,IncludeKeyUp")
if (KeyPressed "~~Escape~~" $Store) {
Reset-Console
exit
}
}
Tick-MatrixAnimation
Start-Sleep -Milliseconds $SleepTime
}
# Set up the console
Setup-Console
# Run the matrix effect
$Script:KnownDims = $Host.UI.RawUI.WindowSize
$SizeChanged = $false
Recompute-ColumnWidths
try {
while ($true) {
# Reset the console if the window size has changed
while (($Host.UI.RawUI.WindowSize.Width -ne $Script:KnownDims.Width) -or ($Host.UI.RawUI.WindowSize.Height -ne $Script:KnownDims.Height)) {
Clear-Host
$Script:KnownDims = $Host.UI.RawUI.WindowSize
Write-Host "Window size changed. Resetting console. | $($Host.UI.RawUI.WindowSize.Width) | $($Host.UI.RawUI.WindowSize.Height) | $($Script:KnownDims.Width) | $($Script:KnownDims.Height) | $(Get-Random)"
$SizeChanged = $true
Start-Sleep 1
}
if ($SizeChanged) {Clear-Host;$SizeChanged = $false;Recompute-ColumnWidths}
Script-Tick
}
} finally {
Reset-Console
}