w-cluster 1.0.1 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +1 -0
- package/.github/workflows/ci-test.yml +24 -0
- package/README.md +9 -4
- package/SECURITY.md +5 -0
- package/dist/w-cluster.umd.js +2 -2
- package/dist/w-cluster.umd.js.map +1 -1
- package/dist/w-cluster.wk.umd.js +1 -0
- package/docs/WCluster.mjs.html +1 -1
- package/docs/examples/ex-PCA.html +1 -1
- package/docs/examples/ex-cluster-k-means.html +14 -2
- package/docs/examples/ex-cluster-k-medoids.html +1 -1
- package/docs/examples/ex-cluster-webworker-k-medoids.html +1 -1
- package/docs/global.html +1 -1
- package/docs/index.html +1 -1
- package/examples/ex-cluster-k-means.html +13 -1
- package/examples/ex-cluster-webworker-k-medoids.html +1 -1
- package/g-PCA-nodeworker.mjs +32 -0
- package/g-PCA.mjs +0 -1
- package/g-cluster-nodeworker.mjs +106 -0
- package/g-cluster.mjs +0 -1
- package/package.json +3 -3
- package/src/WPCAMat.mjs +11 -0
- package/test/PCA.test.mjs +125 -0
- package/test/cluster.test.mjs +135 -0
- package/toolg/gDistRollup.mjs +6 -6
- package/toolg/gDocsExams.mjs +2 -2
- package/dist/w-cluster.ww.umd.js +0 -1
- package/test/createParseStream.test.mjs +0 -87
- package/test/createStringifyStream.test.mjs +0 -78
- package/test/parse.test.mjs +0 -135
- package/test/parseByStream.test.mjs +0 -135
- package/test/stringify.test.mjs +0 -135
- package/test/stringifyByStream.test.mjs +0 -135
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import assert from 'assert'
|
|
2
|
+
import WCluster from '../src/WCluster.mjs'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
describe(`PCA`, function() {
|
|
6
|
+
|
|
7
|
+
let mat = [
|
|
8
|
+
[40, 50, 60],
|
|
9
|
+
[50, 70, 60],
|
|
10
|
+
[80, 70, 90],
|
|
11
|
+
[50, 60, 80]
|
|
12
|
+
]
|
|
13
|
+
let clmat = [
|
|
14
|
+
[36.76572825085965, 50.81184119955175, 61.992939427698765],
|
|
15
|
+
[50.520478881706346, 69.86935352609807, 59.679283942385844],
|
|
16
|
+
[77.39502404588043, 70.65388036857387, 91.60517102143689],
|
|
17
|
+
[55.318768821553576, 58.66492490577632, 76.7226056084785]
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
it(`should return '${JSON.stringify(clmat)}' when input ${JSON.stringify(mat)}, { nCompNIPALS: 2 }`, async function() {
|
|
21
|
+
let r = await WCluster.PCA(mat, { nCompNIPALS: 2 })
|
|
22
|
+
assert.strict.deepStrictEqual(r, clmat)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it(`should return 'Error: data is not eff. array' when input 123`, async function() {
|
|
26
|
+
let r = ''
|
|
27
|
+
await WCluster.PCA(123)
|
|
28
|
+
.catch((err) => {
|
|
29
|
+
r = err.toString()
|
|
30
|
+
})
|
|
31
|
+
let rr = 'Error: data is not eff. array'
|
|
32
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it(`should return 'Error: data is not eff. array' when input 123.456`, async function() {
|
|
36
|
+
let r = ''
|
|
37
|
+
await WCluster.PCA(123.456)
|
|
38
|
+
.catch((err) => {
|
|
39
|
+
r = err.toString()
|
|
40
|
+
})
|
|
41
|
+
let rr = 'Error: data is not eff. array'
|
|
42
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it(`should return 'Error: data is not eff. array' when input '123'`, async function() {
|
|
46
|
+
let r = ''
|
|
47
|
+
await WCluster.PCA('123')
|
|
48
|
+
.catch((err) => {
|
|
49
|
+
r = err.toString()
|
|
50
|
+
})
|
|
51
|
+
let rr = 'Error: data is not eff. array'
|
|
52
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it(`should return 'Error: data is not eff. array' when input '123.456'`, async function() {
|
|
56
|
+
let r = ''
|
|
57
|
+
await WCluster.PCA('123.456')
|
|
58
|
+
.catch((err) => {
|
|
59
|
+
r = err.toString()
|
|
60
|
+
})
|
|
61
|
+
let rr = 'Error: data is not eff. array'
|
|
62
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it(`should return 'Error: data is not eff. array' when input true`, async function() {
|
|
66
|
+
let r = ''
|
|
67
|
+
await WCluster.PCA(true)
|
|
68
|
+
.catch((err) => {
|
|
69
|
+
r = err.toString()
|
|
70
|
+
})
|
|
71
|
+
let rr = 'Error: data is not eff. array'
|
|
72
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it(`should return 'Error: data is not eff. array' when input ''`, async function() {
|
|
76
|
+
let r = ''
|
|
77
|
+
await WCluster.PCA('')
|
|
78
|
+
.catch((err) => {
|
|
79
|
+
r = err.toString()
|
|
80
|
+
})
|
|
81
|
+
let rr = 'Error: data is not eff. array'
|
|
82
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it(`should return 'Error: data is not eff. array' when input []`, async function() {
|
|
86
|
+
let r = ''
|
|
87
|
+
await WCluster.PCA([])
|
|
88
|
+
.catch((err) => {
|
|
89
|
+
r = err.toString()
|
|
90
|
+
})
|
|
91
|
+
let rr = 'Error: data is not eff. array'
|
|
92
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it(`should return 'Error: data is not eff. array' when input {}`, async function() {
|
|
96
|
+
let r = ''
|
|
97
|
+
await WCluster.PCA({})
|
|
98
|
+
.catch((err) => {
|
|
99
|
+
r = err.toString()
|
|
100
|
+
})
|
|
101
|
+
let rr = 'Error: data is not eff. array'
|
|
102
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it(`should return 'Error: data is not eff. array' when input null`, async function() {
|
|
106
|
+
let r = ''
|
|
107
|
+
await WCluster.PCA(null)
|
|
108
|
+
.catch((err) => {
|
|
109
|
+
r = err.toString()
|
|
110
|
+
})
|
|
111
|
+
let rr = 'Error: data is not eff. array'
|
|
112
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it(`should return 'Error: data is not eff. array' when input undefined`, async function() {
|
|
116
|
+
let r = ''
|
|
117
|
+
await WCluster.PCA(undefined)
|
|
118
|
+
.catch((err) => {
|
|
119
|
+
r = err.toString()
|
|
120
|
+
})
|
|
121
|
+
let rr = 'Error: data is not eff. array'
|
|
122
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
})
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import assert from 'assert'
|
|
2
|
+
import WCluster from '../src/WCluster.mjs'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
describe(`cluster`, function() {
|
|
6
|
+
|
|
7
|
+
let mode = 'k-medoids'
|
|
8
|
+
|
|
9
|
+
let mat = [
|
|
10
|
+
[40, 50, 60],
|
|
11
|
+
[50, 70, 60],
|
|
12
|
+
[80, 70, 90],
|
|
13
|
+
[50, 60, 80]
|
|
14
|
+
]
|
|
15
|
+
let clmat = { 'keys': null, 'ginds': [[2], [0, 1, 3]], 'gltdt': [[[80, 70, 90]], [[40, 50, 60], [50, 70, 60], [50, 60, 80]]], 'gmat': [[[77.39502404588043, 70.65388036857387, 91.60517102143689]], [[36.76572825085965, 50.81184119955175, 61.992939427698765], [50.520478881706346, 69.86935352609807, 59.679283942385844], [55.318768821553576, 58.66492490577632, 76.7226056084785]]] }
|
|
16
|
+
|
|
17
|
+
it(`should return '${JSON.stringify(clmat)}' when input ${JSON.stringify(mat)}, { mode, kNumber: 2, nCompNIPALS: 2 }`, async function() {
|
|
18
|
+
let r = await WCluster.cluster(mat, { mode, kNumber: 2, nCompNIPALS: 2 })
|
|
19
|
+
assert.strict.deepStrictEqual(r, clmat)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
let ltdt = [
|
|
23
|
+
{ name: 'Cameron', a: 40, b: 50, c: 60 },
|
|
24
|
+
{ name: 'Buckley', a: 50, b: 70, c: 60 },
|
|
25
|
+
{ name: 'Paul', a: 80, b: 70, c: 90 },
|
|
26
|
+
{ name: 'Fawcett', a: 50, b: 60, c: 80 },
|
|
27
|
+
]
|
|
28
|
+
let clltdt = { 'keys': ['a', 'b', 'c'], 'ginds': [[2], [0, 1, 3]], 'gltdt': [[{ 'name': 'Paul', 'a': 80, 'b': 70, 'c': 90 }], [{ 'name': 'Cameron', 'a': 40, 'b': 50, 'c': 60 }, { 'name': 'Buckley', 'a': 50, 'b': 70, 'c': 60 }, { 'name': 'Fawcett', 'a': 50, 'b': 60, 'c': 80 }]], 'gmat': [[[77.39502404588043, 70.65388036857387, 91.60517102143689]], [[36.76572825085965, 50.81184119955175, 61.992939427698765], [50.520478881706346, 69.86935352609807, 59.679283942385844], [55.318768821553576, 58.66492490577632, 76.7226056084785]]] }
|
|
29
|
+
|
|
30
|
+
it(`should return '${JSON.stringify(clltdt)}' when input ${JSON.stringify(ltdt)}, { mode, kNumber: 2, nCompNIPALS: 2 }`, async function() {
|
|
31
|
+
let r = await WCluster.cluster(ltdt, { mode, kNumber: 2, nCompNIPALS: 2 })
|
|
32
|
+
assert.strict.deepStrictEqual(r, clltdt)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it(`should return 'Error: data is not eff. array' when input 123`, async function() {
|
|
36
|
+
let r = ''
|
|
37
|
+
await WCluster.cluster(123)
|
|
38
|
+
.catch((err) => {
|
|
39
|
+
r = err.toString()
|
|
40
|
+
})
|
|
41
|
+
let rr = 'Error: data is not eff. array'
|
|
42
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it(`should return 'Error: data is not eff. array' when input 123.456`, async function() {
|
|
46
|
+
let r = ''
|
|
47
|
+
await WCluster.cluster(123.456)
|
|
48
|
+
.catch((err) => {
|
|
49
|
+
r = err.toString()
|
|
50
|
+
})
|
|
51
|
+
let rr = 'Error: data is not eff. array'
|
|
52
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it(`should return 'Error: data is not eff. array' when input '123'`, async function() {
|
|
56
|
+
let r = ''
|
|
57
|
+
await WCluster.cluster('123')
|
|
58
|
+
.catch((err) => {
|
|
59
|
+
r = err.toString()
|
|
60
|
+
})
|
|
61
|
+
let rr = 'Error: data is not eff. array'
|
|
62
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it(`should return 'Error: data is not eff. array' when input '123.456'`, async function() {
|
|
66
|
+
let r = ''
|
|
67
|
+
await WCluster.cluster('123.456')
|
|
68
|
+
.catch((err) => {
|
|
69
|
+
r = err.toString()
|
|
70
|
+
})
|
|
71
|
+
let rr = 'Error: data is not eff. array'
|
|
72
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it(`should return 'Error: data is not eff. array' when input true`, async function() {
|
|
76
|
+
let r = ''
|
|
77
|
+
await WCluster.cluster(true)
|
|
78
|
+
.catch((err) => {
|
|
79
|
+
r = err.toString()
|
|
80
|
+
})
|
|
81
|
+
let rr = 'Error: data is not eff. array'
|
|
82
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it(`should return 'Error: data is not eff. array' when input ''`, async function() {
|
|
86
|
+
let r = ''
|
|
87
|
+
await WCluster.cluster('')
|
|
88
|
+
.catch((err) => {
|
|
89
|
+
r = err.toString()
|
|
90
|
+
})
|
|
91
|
+
let rr = 'Error: data is not eff. array'
|
|
92
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it(`should return 'Error: data is not eff. array' when input []`, async function() {
|
|
96
|
+
let r = ''
|
|
97
|
+
await WCluster.cluster([])
|
|
98
|
+
.catch((err) => {
|
|
99
|
+
r = err.toString()
|
|
100
|
+
})
|
|
101
|
+
let rr = 'Error: data is not eff. array'
|
|
102
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it(`should return 'Error: data is not eff. array' when input {}`, async function() {
|
|
106
|
+
let r = ''
|
|
107
|
+
await WCluster.cluster({})
|
|
108
|
+
.catch((err) => {
|
|
109
|
+
r = err.toString()
|
|
110
|
+
})
|
|
111
|
+
let rr = 'Error: data is not eff. array'
|
|
112
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it(`should return 'Error: data is not eff. array' when input null`, async function() {
|
|
116
|
+
let r = ''
|
|
117
|
+
await WCluster.cluster(null)
|
|
118
|
+
.catch((err) => {
|
|
119
|
+
r = err.toString()
|
|
120
|
+
})
|
|
121
|
+
let rr = 'Error: data is not eff. array'
|
|
122
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it(`should return 'Error: data is not eff. array' when input undefined`, async function() {
|
|
126
|
+
let r = ''
|
|
127
|
+
await WCluster.cluster(undefined)
|
|
128
|
+
.catch((err) => {
|
|
129
|
+
r = err.toString()
|
|
130
|
+
})
|
|
131
|
+
let rr = 'Error: data is not eff. array'
|
|
132
|
+
assert.strict.deepStrictEqual(r, rr)
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
})
|
package/toolg/gDistRollup.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import rollupFiles from 'w-package-tools/src/rollupFiles.mjs'
|
|
3
|
-
import
|
|
3
|
+
import rollupWorker from 'w-package-tools/src/rollupWorker.mjs'
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
let fdSrc = './src'
|
|
@@ -14,7 +14,7 @@ async function rp() {
|
|
|
14
14
|
fdSrc,
|
|
15
15
|
fdTar,
|
|
16
16
|
nameDistType: 'kebabCase',
|
|
17
|
-
bNodePolyfill: true,
|
|
17
|
+
// bNodePolyfill: true,
|
|
18
18
|
// bMinify: false,
|
|
19
19
|
globals: {
|
|
20
20
|
},
|
|
@@ -25,17 +25,17 @@ async function rp() {
|
|
|
25
25
|
console.log(err)
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
-
await
|
|
28
|
+
await rollupWorker({
|
|
29
29
|
name: 'WCluster', //原模組名稱, 將來會掛於winodw下
|
|
30
30
|
type: 'object', //原模組輸出為物件
|
|
31
|
-
funNames: ['PCA', 'cluster'],
|
|
31
|
+
funNames: ['PCA', 'cluster'],
|
|
32
32
|
// target: 'old', //不支援IE11
|
|
33
|
-
bNodePolyfill: true,
|
|
33
|
+
// bNodePolyfill: true,
|
|
34
34
|
// bMinify: false,
|
|
35
35
|
// bSourcemap: true, //rollupWebWorker不提供sourcemap
|
|
36
36
|
execObjectFunsByInstance: true, //各函式使用獨立實體執行
|
|
37
37
|
fpSrc: path.resolve(fdSrc, 'WCluster.mjs'), //原始檔案路徑
|
|
38
|
-
fpTar: path.resolve(fdTar, 'w-cluster.
|
|
38
|
+
fpTar: path.resolve(fdTar, 'w-cluster.wk.umd.js'), //檔案輸出路徑
|
|
39
39
|
hookNameDist: () => 'w-cluster',
|
|
40
40
|
// nameDistType: 'kebabCase',
|
|
41
41
|
formatOut: 'umd', //umd為瀏覽器端直接使用, es為供vue-cli或webpack使用
|
package/toolg/gDocsExams.mjs
CHANGED
|
@@ -16,7 +16,7 @@ function main() {
|
|
|
16
16
|
|
|
17
17
|
//url
|
|
18
18
|
let url = `https://cdn.jsdelivr.net/npm/w-cluster@${pks.version}/dist/w-cluster.umd.js`
|
|
19
|
-
let urlww = `https://cdn.jsdelivr.net/npm/w-cluster@${pks.version}/dist/w-cluster.
|
|
19
|
+
let urlww = `https://cdn.jsdelivr.net/npm/w-cluster@${pks.version}/dist/w-cluster.wk.umd.js`
|
|
20
20
|
|
|
21
21
|
//mkdirSync
|
|
22
22
|
if (!fs.existsSync(fdTar)) {
|
|
@@ -38,7 +38,7 @@ function main() {
|
|
|
38
38
|
let r
|
|
39
39
|
r = `../dist/w-cluster.umd.js`
|
|
40
40
|
c = c.replace(r, url)
|
|
41
|
-
r = `../dist/w-cluster.
|
|
41
|
+
r = `../dist/w-cluster.wk.umd.js`
|
|
42
42
|
c = c.replace(r, urlww)
|
|
43
43
|
|
|
44
44
|
//write
|
package/dist/w-cluster.ww.umd.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(d,l){"object"==typeof exports&&"undefined"!=typeof module?module.exports=l():"function"==typeof define&&define.amd?define(l):(d="undefined"!=typeof globalThis?globalThis:d||self)["w-cluster"]=l()}(this,(function(){"use strict";function d(d,l){(null==l||l>d.length)&&(l=d.length);for(var c=0,Z=new Array(l);c<l;c++)Z[c]=d[c];return Z}function l(l){return function(l){if(Array.isArray(l))return d(l)}(l)||function(d){if("undefined"!=typeof Symbol&&null!=d[Symbol.iterator]||null!=d["@@iterator"])return Array.from(d)}(l)||function(l,c){if(l){if("string"==typeof l)return d(l,c);var Z=Object.prototype.toString.call(l).slice(8,-1);return"Object"===Z&&l.constructor&&(Z=l.constructor.name),"Map"===Z||"Set"===Z?Array.from(l):"Arguments"===Z||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(Z)?d(l,c):void 0}}(l)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function c(d,l,c,Z,b,X,y){try{var G=d[X](y),m=G.value}catch(d){return void c(d)}G.done?l(m):Promise.resolve(m).then(Z,b)}function Z(d){return function(){var l=this,Z=arguments;return new Promise((function(b,X){var y=d.apply(l,Z);function G(d){c(y,b,X,G,m,"next",d)}function m(d){c(y,b,X,G,m,"throw",d)}G(void 0)}))}}function b(d){return(b="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(d){return typeof d}:function(d){return d&&"function"==typeof Symbol&&d.constructor===Symbol&&d!==Symbol.prototype?"symbol":typeof d})(d)}function X(d){var l={exports:{}};return d(l,l.exports),l.exports}var y=X((function(d){var l=function(d){var l,c=Object.prototype,Z=c.hasOwnProperty,X="function"==typeof Symbol?Symbol:{},y=X.iterator||"@@iterator",G=X.asyncIterator||"@@asyncIterator",m=X.toStringTag||"@@toStringTag";function K(d,l,c){return Object.defineProperty(d,l,{value:c,enumerable:!0,configurable:!0,writable:!0}),d[l]}try{K({},"")}catch(d){K=function(d,l,c){return d[l]=c}}function p(d,l,c,Z){var b=l&&l.prototype instanceof o?l:o,X=Object.create(b.prototype),y=new g(Z||[]);return X._invoke=function(d,l,c){var Z=i;return function(b,X){if(Z===u)throw new Error("Generator is already running");if(Z===W){if("throw"===b)throw X;return Q()}for(c.method=b,c.arg=X;;){var y=c.delegate;if(y){var G=S(y,c);if(G){if(G===h)continue;return G}}if("next"===c.method)c.sent=c._sent=c.arg;else if("throw"===c.method){if(Z===i)throw Z=W,c.arg;c.dispatchException(c.arg)}else"return"===c.method&&c.abrupt("return",c.arg);Z=u;var m=t(d,l,c);if("normal"===m.type){if(Z=c.done?W:I,m.arg===h)continue;return{value:m.arg,done:c.done}}"throw"===m.type&&(Z=W,c.method="throw",c.arg=m.arg)}}}(d,c,y),X}function t(d,l,c){try{return{type:"normal",arg:d.call(l,c)}}catch(d){return{type:"throw",arg:d}}}d.wrap=p;var i="suspendedStart",I="suspendedYield",u="executing",W="completed",h={};function o(){}function V(){}function s(){}var H={};H[y]=function(){return this};var L=Object.getPrototypeOf,a=L&&L(L(z([])));a&&a!==c&&Z.call(a,y)&&(H=a);var C=s.prototype=o.prototype=Object.create(H);function n(d){["next","throw","return"].forEach((function(l){K(d,l,(function(d){return this._invoke(l,d)}))}))}function x(d,l){function c(X,y,G,m){var K=t(d[X],d,y);if("throw"!==K.type){var p=K.arg,i=p.value;return i&&"object"===b(i)&&Z.call(i,"__await")?l.resolve(i.__await).then((function(d){c("next",d,G,m)}),(function(d){c("throw",d,G,m)})):l.resolve(i).then((function(d){p.value=d,G(p)}),(function(d){return c("throw",d,G,m)}))}m(K.arg)}var X;this._invoke=function(d,Z){function b(){return new l((function(l,b){c(d,Z,l,b)}))}return X=X?X.then(b,b):b()}}function S(d,c){var Z=d.iterator[c.method];if(Z===l){if(c.delegate=null,"throw"===c.method){if(d.iterator.return&&(c.method="return",c.arg=l,S(d,c),"throw"===c.method))return h;c.method="throw",c.arg=new TypeError("The iterator does not provide a 'throw' method")}return h}var b=t(Z,d.iterator,c.arg);if("throw"===b.type)return c.method="throw",c.arg=b.arg,c.delegate=null,h;var X=b.arg;return X?X.done?(c[d.resultName]=X.value,c.next=d.nextLoc,"return"!==c.method&&(c.method="next",c.arg=l),c.delegate=null,h):X:(c.method="throw",c.arg=new TypeError("iterator result is not an object"),c.delegate=null,h)}function Y(d){var l={tryLoc:d[0]};1 in d&&(l.catchLoc=d[1]),2 in d&&(l.finallyLoc=d[2],l.afterLoc=d[3]),this.tryEntries.push(l)}function R(d){var l=d.completion||{};l.type="normal",delete l.arg,d.completion=l}function g(d){this.tryEntries=[{tryLoc:"root"}],d.forEach(Y,this),this.reset(!0)}function z(d){if(d){var c=d[y];if(c)return c.call(d);if("function"==typeof d.next)return d;if(!isNaN(d.length)){var b=-1,X=function c(){for(;++b<d.length;)if(Z.call(d,b))return c.value=d[b],c.done=!1,c;return c.value=l,c.done=!0,c};return X.next=X}}return{next:Q}}function Q(){return{value:l,done:!0}}return V.prototype=C.constructor=s,s.constructor=V,V.displayName=K(s,m,"GeneratorFunction"),d.isGeneratorFunction=function(d){var l="function"==typeof d&&d.constructor;return!!l&&(l===V||"GeneratorFunction"===(l.displayName||l.name))},d.mark=function(d){return Object.setPrototypeOf?Object.setPrototypeOf(d,s):(d.__proto__=s,K(d,m,"GeneratorFunction")),d.prototype=Object.create(C),d},d.awrap=function(d){return{__await:d}},n(x.prototype),x.prototype[G]=function(){return this},d.AsyncIterator=x,d.async=function(l,c,Z,b,X){void 0===X&&(X=Promise);var y=new x(p(l,c,Z,b),X);return d.isGeneratorFunction(c)?y:y.next().then((function(d){return d.done?d.value:y.next()}))},n(C),K(C,m,"Generator"),C[y]=function(){return this},C.toString=function(){return"[object Generator]"},d.keys=function(d){var l=[];for(var c in d)l.push(c);return l.reverse(),function c(){for(;l.length;){var Z=l.pop();if(Z in d)return c.value=Z,c.done=!1,c}return c.done=!0,c}},d.values=z,g.prototype={constructor:g,reset:function(d){if(this.prev=0,this.next=0,this.sent=this._sent=l,this.done=!1,this.delegate=null,this.method="next",this.arg=l,this.tryEntries.forEach(R),!d)for(var c in this)"t"===c.charAt(0)&&Z.call(this,c)&&!isNaN(+c.slice(1))&&(this[c]=l)},stop:function(){this.done=!0;var d=this.tryEntries[0].completion;if("throw"===d.type)throw d.arg;return this.rval},dispatchException:function(d){if(this.done)throw d;var c=this;function b(Z,b){return G.type="throw",G.arg=d,c.next=Z,b&&(c.method="next",c.arg=l),!!b}for(var X=this.tryEntries.length-1;X>=0;--X){var y=this.tryEntries[X],G=y.completion;if("root"===y.tryLoc)return b("end");if(y.tryLoc<=this.prev){var m=Z.call(y,"catchLoc"),K=Z.call(y,"finallyLoc");if(m&&K){if(this.prev<y.catchLoc)return b(y.catchLoc,!0);if(this.prev<y.finallyLoc)return b(y.finallyLoc)}else if(m){if(this.prev<y.catchLoc)return b(y.catchLoc,!0)}else{if(!K)throw new Error("try statement without catch or finally");if(this.prev<y.finallyLoc)return b(y.finallyLoc)}}}},abrupt:function(d,l){for(var c=this.tryEntries.length-1;c>=0;--c){var b=this.tryEntries[c];if(b.tryLoc<=this.prev&&Z.call(b,"finallyLoc")&&this.prev<b.finallyLoc){var X=b;break}}X&&("break"===d||"continue"===d)&&X.tryLoc<=l&&l<=X.finallyLoc&&(X=null);var y=X?X.completion:{};return y.type=d,y.arg=l,X?(this.method="next",this.next=X.finallyLoc,h):this.complete(y)},complete:function(d,l){if("throw"===d.type)throw d.arg;return"break"===d.type||"continue"===d.type?this.next=d.arg:"return"===d.type?(this.rval=this.arg=d.arg,this.method="return",this.next="end"):"normal"===d.type&&l&&(this.next=l),h},finish:function(d){for(var l=this.tryEntries.length-1;l>=0;--l){var c=this.tryEntries[l];if(c.finallyLoc===d)return this.complete(c.completion,c.afterLoc),R(c),h}},catch:function(d){for(var l=this.tryEntries.length-1;l>=0;--l){var c=this.tryEntries[l];if(c.tryLoc===d){var Z=c.completion;if("throw"===Z.type){var b=Z.arg;R(c)}return b}}throw new Error("illegal catch attempt")},delegateYield:function(d,c,Z){return this.delegate={iterator:z(d),resultName:c,nextLoc:Z},"next"===this.method&&(this.arg=l),h}},d}(d.exports);try{regeneratorRuntime=l}catch(d){Function("r","regeneratorRuntime = r")(l)}})),G=X((function(d){var l=Object.prototype.hasOwnProperty,c="~";function Z(){}function b(d,l,c){this.fn=d,this.context=l,this.once=c||!1}function X(d,l,Z,X,y){if("function"!=typeof Z)throw new TypeError("The listener must be a function");var G=new b(Z,X||d,y),m=c?c+l:l;return d._events[m]?d._events[m].fn?d._events[m]=[d._events[m],G]:d._events[m].push(G):(d._events[m]=G,d._eventsCount++),d}function y(d,l){0==--d._eventsCount?d._events=new Z:delete d._events[l]}function G(){this._events=new Z,this._eventsCount=0}Object.create&&(Z.prototype=Object.create(null),(new Z).__proto__||(c=!1)),G.prototype.eventNames=function(){var d,Z,b=[];if(0===this._eventsCount)return b;for(Z in d=this._events)l.call(d,Z)&&b.push(c?Z.slice(1):Z);return Object.getOwnPropertySymbols?b.concat(Object.getOwnPropertySymbols(d)):b},G.prototype.listeners=function(d){var l=c?c+d:d,Z=this._events[l];if(!Z)return[];if(Z.fn)return[Z.fn];for(var b=0,X=Z.length,y=new Array(X);b<X;b++)y[b]=Z[b].fn;return y},G.prototype.listenerCount=function(d){var l=c?c+d:d,Z=this._events[l];return Z?Z.fn?1:Z.length:0},G.prototype.emit=function(d,l,Z,b,X,y){var G=c?c+d:d;if(!this._events[G])return!1;var m,K,p=this._events[G],t=arguments.length;if(p.fn){switch(p.once&&this.removeListener(d,p.fn,void 0,!0),t){case 1:return p.fn.call(p.context),!0;case 2:return p.fn.call(p.context,l),!0;case 3:return p.fn.call(p.context,l,Z),!0;case 4:return p.fn.call(p.context,l,Z,b),!0;case 5:return p.fn.call(p.context,l,Z,b,X),!0;case 6:return p.fn.call(p.context,l,Z,b,X,y),!0}for(K=1,m=new Array(t-1);K<t;K++)m[K-1]=arguments[K];p.fn.apply(p.context,m)}else{var i,I=p.length;for(K=0;K<I;K++)switch(p[K].once&&this.removeListener(d,p[K].fn,void 0,!0),t){case 1:p[K].fn.call(p[K].context);break;case 2:p[K].fn.call(p[K].context,l);break;case 3:p[K].fn.call(p[K].context,l,Z);break;case 4:p[K].fn.call(p[K].context,l,Z,b);break;default:if(!m)for(i=1,m=new Array(t-1);i<t;i++)m[i-1]=arguments[i];p[K].fn.apply(p[K].context,m)}}return!0},G.prototype.on=function(d,l,c){return X(this,d,l,c,!1)},G.prototype.once=function(d,l,c){return X(this,d,l,c,!0)},G.prototype.removeListener=function(d,l,Z,b){var X=c?c+d:d;if(!this._events[X])return this;if(!l)return y(this,X),this;var G=this._events[X];if(G.fn)G.fn!==l||b&&!G.once||Z&&G.context!==Z||y(this,X);else{for(var m=0,K=[],p=G.length;m<p;m++)(G[m].fn!==l||b&&!G[m].once||Z&&G[m].context!==Z)&&K.push(G[m]);K.length?this._events[X]=1===K.length?K[0]:K:y(this,X)}return this},G.prototype.removeAllListeners=function(d){var l;return d?(l=c?c+d:d,this._events[l]&&y(this,l)):(this._events=new Z,this._eventsCount=0),this},G.prototype.off=G.prototype.removeListener,G.prototype.addListener=G.prototype.on,G.prefixed=c,G.EventEmitter=G,d.exports=G}));function m(){return new G}function K(){var d,l,c=new Promise((function(){d=arguments[0],l=arguments[1]}));return c.resolve=d,c.reject=l,c}function p(){for(var d=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10,l=[],c="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),Z=c.length,b=0;b<d;b++)l[b]=c[0|Math.random()*Z];var X=l.join("");return X}var t=atob("Cgp2YXIgdD1BcnJheS5pc0FycmF5LGU9InVuZGVmaW5lZCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6InVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3c/d2luZG93OiJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsP2dsb2JhbDoidW5kZWZpbmVkIiE9dHlwZW9mIHNlbGY/c2VsZjp7fTtmdW5jdGlvbiByKHQpe3JldHVybiB0JiZ0Ll9fZXNNb2R1bGUmJk9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0LCJkZWZhdWx0Iik/dC5kZWZhdWx0OnR9ZnVuY3Rpb24gbyh0KXt2YXIgZT17ZXhwb3J0czp7fX07cmV0dXJuIHQoZSxlLmV4cG9ydHMpLGUuZXhwb3J0c312YXIgbj0ib2JqZWN0Ij09dHlwZW9mIGUmJmUmJmUuT2JqZWN0PT09T2JqZWN0JiZlLHM9Im9iamVjdCI9PXR5cGVvZiBzZWxmJiZzZWxmJiZzZWxmLk9iamVjdD09PU9iamVjdCYmc2VsZixpPW58fHN8fEZ1bmN0aW9uKCJyZXR1cm4gdGhpcyIpKCksdT1pLlN5bWJvbCxhPU9iamVjdC5wcm90b3R5cGUsaD1hLmhhc093blByb3BlcnR5LGw9YS50b1N0cmluZyxjPXU/dS50b1N0cmluZ1RhZzp2b2lkIDA7dmFyIGY9ZnVuY3Rpb24odCl7dmFyIGU9aC5jYWxsKHQsYykscj10W2NdO3RyeXt0W2NdPXZvaWQgMDt2YXIgbz0hMH1jYXRjaCh0KXt9dmFyIG49bC5jYWxsKHQpO3JldHVybiBvJiYoZT90W2NdPXI6ZGVsZXRlIHRbY10pLG59LG09T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzt2YXIgZz1mdW5jdGlvbih0KXtyZXR1cm4gbS5jYWxsKHQpfSxwPXU/dS50b1N0cmluZ1RhZzp2b2lkIDA7dmFyIHc9ZnVuY3Rpb24odCl7cmV0dXJuIG51bGw9PXQ/dm9pZCAwPT09dD8iW29iamVjdCBVbmRlZmluZWRdIjoiW29iamVjdCBOdWxsXSI6cCYmcCBpbiBPYmplY3QodCk/Zih0KTpnKHQpfTt2YXIgZD1mdW5jdGlvbih0KXtyZXR1cm4gbnVsbCE9dCYmIm9iamVjdCI9PXR5cGVvZiB0fTt2YXIgYj1mdW5jdGlvbih0KXtyZXR1cm4ic3ltYm9sIj09dHlwZW9mIHR8fGQodCkmJiJbb2JqZWN0IFN5bWJvbF0iPT13KHQpfSx5PS9cLnxcWyg/OlteW1xdXSp8KFsiJ10pKD86KD8hXDEpW15cXF18XFwuKSo/XDEpXF0vLHY9L15cdyokLzt2YXIgTT1mdW5jdGlvbihlLHIpe2lmKHQoZSkpcmV0dXJuITE7dmFyIG89dHlwZW9mIGU7cmV0dXJuISgibnVtYmVyIiE9byYmInN5bWJvbCIhPW8mJiJib29sZWFuIiE9byYmbnVsbCE9ZSYmIWIoZSkpfHwodi50ZXN0KGUpfHwheS50ZXN0KGUpfHxudWxsIT1yJiZlIGluIE9iamVjdChyKSl9O3ZhciB4PWZ1bmN0aW9uKHQpe3ZhciBlPXR5cGVvZiB0O3JldHVybiBudWxsIT10JiYoIm9iamVjdCI9PWV8fCJmdW5jdGlvbiI9PWUpfTt2YXIgRSxTPWZ1bmN0aW9uKHQpe2lmKCF4KHQpKXJldHVybiExO3ZhciBlPXcodCk7cmV0dXJuIltvYmplY3QgRnVuY3Rpb25dIj09ZXx8IltvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dIj09ZXx8IltvYmplY3QgQXN5bmNGdW5jdGlvbl0iPT1lfHwiW29iamVjdCBQcm94eV0iPT1lfSxqPWlbIl9fY29yZS1qc19zaGFyZWRfXyJdLF89KEU9L1teLl0rJC8uZXhlYyhqJiZqLmtleXMmJmoua2V5cy5JRV9QUk9UT3x8IiIpKT8iU3ltYm9sKHNyYylfMS4iK0U6IiI7dmFyIEE9ZnVuY3Rpb24odCl7cmV0dXJuISFfJiZfIGluIHR9LEM9RnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO3ZhciBSPWZ1bmN0aW9uKHQpe2lmKG51bGwhPXQpe3RyeXtyZXR1cm4gQy5jYWxsKHQpfWNhdGNoKHQpe310cnl7cmV0dXJuIHQrIiJ9Y2F0Y2godCl7fX1yZXR1cm4iIn0sST0vXlxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXF0kLyxrPUZ1bmN0aW9uLnByb3RvdHlwZSxOPU9iamVjdC5wcm90b3R5cGUsTz1rLnRvU3RyaW5nLEY9Ti5oYXNPd25Qcm9wZXJ0eSx6PVJlZ0V4cCgiXiIrTy5jYWxsKEYpLnJlcGxhY2UoL1tcXF4kLiorPygpW1xde318XS9nLCJcXCQmIikucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXCgpfCBmb3IgLis/KD89XFxcXSkvZywiJDEuKj8iKSsiJCIpO3ZhciBUPWZ1bmN0aW9uKHQpe3JldHVybiEoIXgodCl8fEEodCkpJiYoUyh0KT96OkkpLnRlc3QoUih0KSl9O3ZhciBWPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG51bGw9PXQ/dm9pZCAwOnRbZV19O3ZhciBQPWZ1bmN0aW9uKHQsZSl7dmFyIHI9Vih0LGUpO3JldHVybiBUKHIpP3I6dm9pZCAwfSxxPVAoT2JqZWN0LCJjcmVhdGUiKTt2YXIgJD1mdW5jdGlvbigpe3RoaXMuX19kYXRhX189cT9xKG51bGwpOnt9LHRoaXMuc2l6ZT0wfTt2YXIgRD1mdW5jdGlvbih0KXt2YXIgZT10aGlzLmhhcyh0KSYmZGVsZXRlIHRoaXMuX19kYXRhX19bdF07cmV0dXJuIHRoaXMuc2l6ZS09ZT8xOjAsZX0sVT1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O3ZhciBMPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuX19kYXRhX187aWYocSl7dmFyIHI9ZVt0XTtyZXR1cm4iX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyI9PT1yP3ZvaWQgMDpyfXJldHVybiBVLmNhbGwoZSx0KT9lW3RdOnZvaWQgMH0sQj1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O3ZhciBHPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuX19kYXRhX187cmV0dXJuIHE/dm9pZCAwIT09ZVt0XTpCLmNhbGwoZSx0KX07dmFyIEs9ZnVuY3Rpb24odCxlKXt2YXIgcj10aGlzLl9fZGF0YV9fO3JldHVybiB0aGlzLnNpemUrPXRoaXMuaGFzKHQpPzA6MSxyW3RdPXEmJnZvaWQgMD09PWU/Il9fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18iOmUsdGhpc307ZnVuY3Rpb24gVyh0KXt2YXIgZT0tMSxyPW51bGw9PXQ/MDp0Lmxlbmd0aDtmb3IodGhpcy5jbGVhcigpOysrZTxyOyl7dmFyIG89dFtlXTt0aGlzLnNldChvWzBdLG9bMV0pfX1XLnByb3RvdHlwZS5jbGVhcj0kLFcucHJvdG90eXBlLmRlbGV0ZT1ELFcucHJvdG90eXBlLmdldD1MLFcucHJvdG90eXBlLmhhcz1HLFcucHJvdG90eXBlLnNldD1LO3ZhciBYPVc7dmFyIEo9ZnVuY3Rpb24oKXt0aGlzLl9fZGF0YV9fPVtdLHRoaXMuc2l6ZT0wfTt2YXIgWT1mdW5jdGlvbih0LGUpe3JldHVybiB0PT09ZXx8dCE9dCYmZSE9ZX07dmFyIFo9ZnVuY3Rpb24odCxlKXtmb3IodmFyIHI9dC5sZW5ndGg7ci0tOylpZihZKHRbcl1bMF0sZSkpcmV0dXJuIHI7cmV0dXJuLTF9LEg9QXJyYXkucHJvdG90eXBlLnNwbGljZTt2YXIgUT1mdW5jdGlvbih0KXt2YXIgZT10aGlzLl9fZGF0YV9fLHI9WihlLHQpO3JldHVybiEocjwwKSYmKHI9PWUubGVuZ3RoLTE/ZS5wb3AoKTpILmNhbGwoZSxyLDEpLC0tdGhpcy5zaXplLCEwKX07dmFyIHR0PWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuX19kYXRhX18scj1aKGUsdCk7cmV0dXJuIHI8MD92b2lkIDA6ZVtyXVsxXX07dmFyIGV0PWZ1bmN0aW9uKHQpe3JldHVybiBaKHRoaXMuX19kYXRhX18sdCk+LTF9O3ZhciBydD1mdW5jdGlvbih0LGUpe3ZhciByPXRoaXMuX19kYXRhX18sbz1aKHIsdCk7cmV0dXJuIG88MD8oKyt0aGlzLnNpemUsci5wdXNoKFt0LGVdKSk6cltvXVsxXT1lLHRoaXN9O2Z1bmN0aW9uIG90KHQpe3ZhciBlPS0xLHI9bnVsbD09dD8wOnQubGVuZ3RoO2Zvcih0aGlzLmNsZWFyKCk7KytlPHI7KXt2YXIgbz10W2VdO3RoaXMuc2V0KG9bMF0sb1sxXSl9fW90LnByb3RvdHlwZS5jbGVhcj1KLG90LnByb3RvdHlwZS5kZWxldGU9USxvdC5wcm90b3R5cGUuZ2V0PXR0LG90LnByb3RvdHlwZS5oYXM9ZXQsb3QucHJvdG90eXBlLnNldD1ydDt2YXIgbnQ9b3Qsc3Q9UChpLCJNYXAiKTt2YXIgaXQ9ZnVuY3Rpb24oKXt0aGlzLnNpemU9MCx0aGlzLl9fZGF0YV9fPXtoYXNoOm5ldyBYLG1hcDpuZXcoc3R8fG50KSxzdHJpbmc6bmV3IFh9fTt2YXIgdXQ9ZnVuY3Rpb24odCl7dmFyIGU9dHlwZW9mIHQ7cmV0dXJuInN0cmluZyI9PWV8fCJudW1iZXIiPT1lfHwic3ltYm9sIj09ZXx8ImJvb2xlYW4iPT1lPyJfX3Byb3RvX18iIT09dDpudWxsPT09dH07dmFyIGF0PWZ1bmN0aW9uKHQsZSl7dmFyIHI9dC5fX2RhdGFfXztyZXR1cm4gdXQoZSk/clsic3RyaW5nIj09dHlwZW9mIGU/InN0cmluZyI6Imhhc2giXTpyLm1hcH07dmFyIGh0PWZ1bmN0aW9uKHQpe3ZhciBlPWF0KHRoaXMsdCkuZGVsZXRlKHQpO3JldHVybiB0aGlzLnNpemUtPWU/MTowLGV9O3ZhciBsdD1mdW5jdGlvbih0KXtyZXR1cm4gYXQodGhpcyx0KS5nZXQodCl9O3ZhciBjdD1mdW5jdGlvbih0KXtyZXR1cm4gYXQodGhpcyx0KS5oYXModCl9O3ZhciBmdD1mdW5jdGlvbih0LGUpe3ZhciByPWF0KHRoaXMsdCksbz1yLnNpemU7cmV0dXJuIHIuc2V0KHQsZSksdGhpcy5zaXplKz1yLnNpemU9PW8/MDoxLHRoaXN9O2Z1bmN0aW9uIG10KHQpe3ZhciBlPS0xLHI9bnVsbD09dD8wOnQubGVuZ3RoO2Zvcih0aGlzLmNsZWFyKCk7KytlPHI7KXt2YXIgbz10W2VdO3RoaXMuc2V0KG9bMF0sb1sxXSl9fW10LnByb3RvdHlwZS5jbGVhcj1pdCxtdC5wcm90b3R5cGUuZGVsZXRlPWh0LG10LnByb3RvdHlwZS5nZXQ9bHQsbXQucHJvdG90eXBlLmhhcz1jdCxtdC5wcm90b3R5cGUuc2V0PWZ0O3ZhciBndD1tdDtmdW5jdGlvbiBwdCh0LGUpe2lmKCJmdW5jdGlvbiIhPXR5cGVvZiB0fHxudWxsIT1lJiYiZnVuY3Rpb24iIT10eXBlb2YgZSl0aHJvdyBuZXcgVHlwZUVycm9yKCJFeHBlY3RlZCBhIGZ1bmN0aW9uIik7dmFyIHI9ZnVuY3Rpb24oKXt2YXIgbz1hcmd1bWVudHMsbj1lP2UuYXBwbHkodGhpcyxvKTpvWzBdLHM9ci5jYWNoZTtpZihzLmhhcyhuKSlyZXR1cm4gcy5nZXQobik7dmFyIGk9dC5hcHBseSh0aGlzLG8pO3JldHVybiByLmNhY2hlPXMuc2V0KG4saSl8fHMsaX07cmV0dXJuIHIuY2FjaGU9bmV3KHB0LkNhY2hlfHxndCkscn1wdC5DYWNoZT1ndDt2YXIgd3Q9cHQ7dmFyIGR0PS9bXi5bXF1dK3xcWyg/OigtP1xkKyg/OlwuXGQrKT8pfChbIiddKSgoPzooPyFcMilbXlxcXXxcXC4pKj8pXDIpXF18KD89KD86XC58XFtcXSkoPzpcLnxcW1xdfCQpKS9nLGJ0PS9cXChcXCk/L2cseXQ9ZnVuY3Rpb24odCl7dmFyIGU9d3QodCwoZnVuY3Rpb24odCl7cmV0dXJuIDUwMD09PXIuc2l6ZSYmci5jbGVhcigpLHR9KSkscj1lLmNhY2hlO3JldHVybiBlfSgoZnVuY3Rpb24odCl7dmFyIGU9W107cmV0dXJuIDQ2PT09dC5jaGFyQ29kZUF0KDApJiZlLnB1c2goIiIpLHQucmVwbGFjZShkdCwoZnVuY3Rpb24odCxyLG8sbil7ZS5wdXNoKG8/bi5yZXBsYWNlKGJ0LCIkMSIpOnJ8fHQpfSkpLGV9KSk7dmFyIHZ0PWZ1bmN0aW9uKHQsZSl7Zm9yKHZhciByPS0xLG89bnVsbD09dD8wOnQubGVuZ3RoLG49QXJyYXkobyk7KytyPG87KW5bcl09ZSh0W3JdLHIsdCk7cmV0dXJuIG59LE10PXU/dS5wcm90b3R5cGU6dm9pZCAwLHh0PU10P010LnRvU3RyaW5nOnZvaWQgMDt2YXIgRXQ9ZnVuY3Rpb24gZShyKXtpZigic3RyaW5nIj09dHlwZW9mIHIpcmV0dXJuIHI7aWYodChyKSlyZXR1cm4gdnQocixlKSsiIjtpZihiKHIpKXJldHVybiB4dD94dC5jYWxsKHIpOiIiO3ZhciBvPXIrIiI7cmV0dXJuIjAiPT1vJiYxL3I9PS1JbmZpbml0eT8iLTAiOm99O3ZhciBTdD1mdW5jdGlvbih0KXtyZXR1cm4gbnVsbD09dD8iIjpFdCh0KX07dmFyIGp0PWZ1bmN0aW9uKGUscil7cmV0dXJuIHQoZSk/ZTpNKGUscik/W2VdOnl0KFN0KGUpKX07dmFyIF90PWZ1bmN0aW9uKHQpe2lmKCJzdHJpbmciPT10eXBlb2YgdHx8Yih0KSlyZXR1cm4gdDt2YXIgZT10KyIiO3JldHVybiIwIj09ZSYmMS90PT0tSW5maW5pdHk/Ii0wIjplfTt2YXIgQXQ9ZnVuY3Rpb24odCxlKXtmb3IodmFyIHI9MCxvPShlPWp0KGUsdCkpLmxlbmd0aDtudWxsIT10JiZyPG87KXQ9dFtfdChlW3IrK10pXTtyZXR1cm4gciYmcj09bz90OnZvaWQgMH07dmFyIEN0PWZ1bmN0aW9uKHQsZSxyKXt2YXIgbz1udWxsPT10P3ZvaWQgMDpBdCh0LGUpO3JldHVybiB2b2lkIDA9PT1vP3I6b30sUnQ9T2JqZWN0LnByb3RvdHlwZTt2YXIgSXQ9ZnVuY3Rpb24odCl7dmFyIGU9dCYmdC5jb25zdHJ1Y3RvcjtyZXR1cm4gdD09PSgiZnVuY3Rpb24iPT10eXBlb2YgZSYmZS5wcm90b3R5cGV8fFJ0KX07dmFyIGt0PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHIpe3JldHVybiB0KGUocikpfX0oT2JqZWN0LmtleXMsT2JqZWN0KSxOdD1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O3ZhciBPdD1mdW5jdGlvbih0KXtpZighSXQodCkpcmV0dXJuIGt0KHQpO3ZhciBlPVtdO2Zvcih2YXIgciBpbiBPYmplY3QodCkpTnQuY2FsbCh0LHIpJiYiY29uc3RydWN0b3IiIT1yJiZlLnB1c2gocik7cmV0dXJuIGV9LEZ0PVAoaSwiRGF0YVZpZXciKSx6dD1QKGksIlByb21pc2UiKSxUdD1QKGksIlNldCIpLFZ0PVAoaSwiV2Vha01hcCIpLFB0PVIoRnQpLHF0PVIoc3QpLCR0PVIoenQpLER0PVIoVHQpLFV0PVIoVnQpLEx0PXc7KEZ0JiYiW29iamVjdCBEYXRhVmlld10iIT1MdChuZXcgRnQobmV3IEFycmF5QnVmZmVyKDEpKSl8fHN0JiYiW29iamVjdCBNYXBdIiE9THQobmV3IHN0KXx8enQmJiJbb2JqZWN0IFByb21pc2VdIiE9THQoenQucmVzb2x2ZSgpKXx8VHQmJiJbb2JqZWN0IFNldF0iIT1MdChuZXcgVHQpfHxWdCYmIltvYmplY3QgV2Vha01hcF0iIT1MdChuZXcgVnQpKSYmKEx0PWZ1bmN0aW9uKHQpe3ZhciBlPXcodCkscj0iW29iamVjdCBPYmplY3RdIj09ZT90LmNvbnN0cnVjdG9yOnZvaWQgMCxvPXI/UihyKToiIjtpZihvKXN3aXRjaChvKXtjYXNlIFB0OnJldHVybiJbb2JqZWN0IERhdGFWaWV3XSI7Y2FzZSBxdDpyZXR1cm4iW29iamVjdCBNYXBdIjtjYXNlICR0OnJldHVybiJbb2JqZWN0IFByb21pc2VdIjtjYXNlIER0OnJldHVybiJbb2JqZWN0IFNldF0iO2Nhc2UgVXQ6cmV0dXJuIltvYmplY3QgV2Vha01hcF0ifXJldHVybiBlfSk7dmFyIEJ0PUx0O3ZhciBHdD1mdW5jdGlvbih0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQmJnQ+LTEmJnQlMT09MCYmdDw9OTAwNzE5OTI1NDc0MDk5MX07dmFyIEt0PWZ1bmN0aW9uKHQpe3JldHVybiBudWxsIT10JiZHdCh0Lmxlbmd0aCkmJiFTKHQpfTt2YXIgV3Q9ZnVuY3Rpb24oZSl7cmV0dXJuInN0cmluZyI9PXR5cGVvZiBlfHwhdChlKSYmZChlKSYmIltvYmplY3QgU3RyaW5nXSI9PXcoZSl9O3ZhciBYdD1mdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIG51bGw9PWU/dm9pZCAwOmVbdF19fSxKdD1YdCgibGVuZ3RoIiksWXQ9UmVnRXhwKCJbXFx1MjAwZFxcdWQ4MDAtXFx1ZGZmZlxcdTAzMDAtXFx1MDM2ZlxcdWZlMjAtXFx1ZmUyZlxcdTIwZDAtXFx1MjBmZlxcdWZlMGVcXHVmZTBmXSIpO3ZhciBadD1mdW5jdGlvbih0KXtyZXR1cm4gWXQudGVzdCh0KX0sSHQ9IltcXHVkODAwLVxcdWRmZmZdIixRdD0iW1xcdTAzMDAtXFx1MDM2ZlxcdWZlMjAtXFx1ZmUyZlxcdTIwZDAtXFx1MjBmZl0iLHRlPSJcXHVkODNjW1xcdWRmZmItXFx1ZGZmZl0iLGVlPSJbXlxcdWQ4MDAtXFx1ZGZmZl0iLHJlPSIoPzpcXHVkODNjW1xcdWRkZTYtXFx1ZGRmZl0pezJ9IixvZT0iW1xcdWQ4MDAtXFx1ZGJmZl1bXFx1ZGMwMC1cXHVkZmZmXSIsbmU9Iig/OiIrUXQrInwiK3RlKyIpIisiPyIsc2U9IltcXHVmZTBlXFx1ZmUwZl0/IituZSsoIig/OlxcdTIwMGQoPzoiK1tlZSxyZSxvZV0uam9pbigifCIpKyIpW1xcdWZlMGVcXHVmZTBmXT8iK25lKyIpKiIpLGllPSIoPzoiK1tlZStRdCsiPyIsUXQscmUsb2UsSHRdLmpvaW4oInwiKSsiKSIsdWU9UmVnRXhwKHRlKyIoPz0iK3RlKyIpfCIraWUrc2UsImciKTt2YXIgYWU9ZnVuY3Rpb24odCl7Zm9yKHZhciBlPXVlLmxhc3RJbmRleD0wO3VlLnRlc3QodCk7KSsrZTtyZXR1cm4gZX07dmFyIGhlPWZ1bmN0aW9uKHQpe3JldHVybiBadCh0KT9hZSh0KTpKdCh0KX07dmFyIGxlPWZ1bmN0aW9uKHQpe2lmKG51bGw9PXQpcmV0dXJuIDA7aWYoS3QodCkpcmV0dXJuIFd0KHQpP2hlKHQpOnQubGVuZ3RoO3ZhciBlPUJ0KHQpO3JldHVybiJbb2JqZWN0IE1hcF0iPT1lfHwiW29iamVjdCBTZXRdIj09ZT90LnNpemU6T3QodCkubGVuZ3RofTt2YXIgY2U9ZnVuY3Rpb24odCl7cmV0dXJuIm51bWJlciI9PXR5cGVvZiB0fHxkKHQpJiYiW29iamVjdCBOdW1iZXJdIj09dyh0KX07dmFyIGZlPWZ1bmN0aW9uKHQpe3JldHVybiEwPT09dHx8ITE9PT10fHxkKHQpJiYiW29iamVjdCBCb29sZWFuXSI9PXcodCl9O2NvbnN0IG1lPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7ZnVuY3Rpb24gZ2UodCl7cmV0dXJuIG1lLmNhbGwodCkuZW5kc1dpdGgoIkFycmF5XSIpfWZ1bmN0aW9uIHBlKHQpe3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MSYmdm9pZCAwIT09YXJndW1lbnRzWzFdP2FyZ3VtZW50c1sxXTp7fTtpZighZ2UodCkpdGhyb3cgbmV3IFR5cGVFcnJvcigiaW5wdXQgbXVzdCBiZSBhbiBhcnJheSIpO2lmKDA9PT10Lmxlbmd0aCl0aHJvdyBuZXcgVHlwZUVycm9yKCJpbnB1dCBtdXN0IG5vdCBiZSBlbXB0eSIpO3ZhciByPWUuZnJvbUluZGV4LG89dm9pZCAwPT09cj8wOnIsbj1lLnRvSW5kZXgscz12b2lkIDA9PT1uP3QubGVuZ3RoOm47aWYobzwwfHxvPj10Lmxlbmd0aHx8IU51bWJlci5pc0ludGVnZXIobykpdGhyb3cgbmV3IEVycm9yKCJmcm9tSW5kZXggbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIgc21hbGxlciB0aGFuIGxlbmd0aCIpO2lmKHM8PW98fHM+dC5sZW5ndGh8fCFOdW1iZXIuaXNJbnRlZ2VyKHMpKXRocm93IG5ldyBFcnJvcigidG9JbmRleCBtdXN0IGJlIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIGZyb21JbmRleCBhbmQgYXQgbW9zdCBlcXVhbCB0byBsZW5ndGgiKTtmb3IodmFyIGk9dFtvXSx1PW8rMTt1PHM7dSsrKXRbdV0+aSYmKGk9dFt1XSk7cmV0dXJuIGl9ZnVuY3Rpb24gd2UodCl7dmFyIGU9YXJndW1lbnRzLmxlbmd0aD4xJiZ2b2lkIDAhPT1hcmd1bWVudHNbMV0/YXJndW1lbnRzWzFdOnt9O2lmKCFnZSh0KSl0aHJvdyBuZXcgVHlwZUVycm9yKCJpbnB1dCBtdXN0IGJlIGFuIGFycmF5Iik7aWYoMD09PXQubGVuZ3RoKXRocm93IG5ldyBUeXBlRXJyb3IoImlucHV0IG11c3Qgbm90IGJlIGVtcHR5Iik7dmFyIHI9ZS5mcm9tSW5kZXgsbz12b2lkIDA9PT1yPzA6cixuPWUudG9JbmRleCxzPXZvaWQgMD09PW4/dC5sZW5ndGg6bjtpZihvPDB8fG8+PXQubGVuZ3RofHwhTnVtYmVyLmlzSW50ZWdlcihvKSl0aHJvdyBuZXcgRXJyb3IoImZyb21JbmRleCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciBzbWFsbGVyIHRoYW4gbGVuZ3RoIik7aWYoczw9b3x8cz50Lmxlbmd0aHx8IU51bWJlci5pc0ludGVnZXIocykpdGhyb3cgbmV3IEVycm9yKCJ0b0luZGV4IG11c3QgYmUgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gZnJvbUluZGV4IGFuZCBhdCBtb3N0IGVxdWFsIHRvIGxlbmd0aCIpO2Zvcih2YXIgaT10W29dLHU9bysxO3U8czt1KyspdFt1XTxpJiYoaT10W3VdKTtyZXR1cm4gaX1mdW5jdGlvbiBkZSh0KXt2YXIgZSxyPWFyZ3VtZW50cy5sZW5ndGg+MSYmdm9pZCAwIT09YXJndW1lbnRzWzFdP2FyZ3VtZW50c1sxXTp7fTtpZighZ2UodCkpdGhyb3cgbmV3IFR5cGVFcnJvcigiaW5wdXQgbXVzdCBiZSBhbiBhcnJheSIpO2lmKDA9PT10Lmxlbmd0aCl0aHJvdyBuZXcgVHlwZUVycm9yKCJpbnB1dCBtdXN0IG5vdCBiZSBlbXB0eSIpO2lmKHZvaWQgMCE9PXIub3V0cHV0KXtpZighZ2Uoci5vdXRwdXQpKXRocm93IG5ldyBUeXBlRXJyb3IoIm91dHB1dCBvcHRpb24gbXVzdCBiZSBhbiBhcnJheSBpZiBzcGVjaWZpZWQiKTtlPXIub3V0cHV0fWVsc2UgZT1uZXcgQXJyYXkodC5sZW5ndGgpO3ZhciBvPXdlKHQpLG49cGUodCk7aWYobz09PW4pdGhyb3cgbmV3IFJhbmdlRXJyb3IoIm1pbmltdW0gYW5kIG1heGltdW0gaW5wdXQgdmFsdWVzIGFyZSBlcXVhbC4gQ2Fubm90IHJlc2NhbGUgYSBjb25zdGFudCBhcnJheSIpO3ZhciBzPXIubWluLGk9dm9pZCAwPT09cz9yLmF1dG9NaW5NYXg/bzowOnMsdT1yLm1heCxhPXZvaWQgMD09PXU/ci5hdXRvTWluTWF4P246MTp1O2lmKGk+PWEpdGhyb3cgbmV3IFJhbmdlRXJyb3IoIm1pbiBvcHRpb24gbXVzdCBiZSBzbWFsbGVyIHRoYW4gbWF4IG9wdGlvbiIpO2Zvcih2YXIgaD0oYS1pKS8obi1vKSxsPTA7bDx0Lmxlbmd0aDtsKyspZVtsXT0odFtsXS1vKSpoK2k7cmV0dXJuIGV9Y29uc3QgYmU9IiAiLnJlcGVhdCgyKSx5ZT0iICIucmVwZWF0KDQpO2Z1bmN0aW9uIHZlKHQsZT17fSl7Y29uc3R7bWF4Um93czpyPTE1LG1heENvbHVtbnM6bz0xMCxtYXhOdW1TaXplOm49OH09ZTtyZXR1cm5gJHt0LmNvbnN0cnVjdG9yLm5hbWV9IHtcbiR7YmV9W1xuJHt5ZX0ke2Z1bmN0aW9uKHQsZSxyLG8pe2NvbnN0e3Jvd3M6bixjb2x1bW5zOnN9PXQsaT1NYXRoLm1pbihuLGUpLHU9TWF0aC5taW4ocyxyKSxhPVtdO2ZvcihsZXQgZT0wO2U8aTtlKyspe2xldCByPVtdO2ZvcihsZXQgbj0wO248dTtuKyspci5wdXNoKE1lKHQuZ2V0KGUsbiksbykpO2EucHVzaChgJHtyLmpvaW4oIiAiKX1gKX11IT09cyYmKGFbYS5sZW5ndGgtMV0rPWAgLi4uICR7cy1yfSBtb3JlIGNvbHVtbnNgKTtpIT09biYmYS5wdXNoKGAuLi4gJHtuLWV9IG1vcmUgcm93c2ApO3JldHVybiBhLmpvaW4oYFxuJHt5ZX1gKX0odCxyLG8sbil9XG4ke2JlfV1cbiR7YmV9cm93czogJHt0LnJvd3N9XG4ke2JlfWNvbHVtbnM6ICR7dC5jb2x1bW5zfVxufWB9ZnVuY3Rpb24gTWUodCxlKXtjb25zdCByPVN0cmluZyh0KTtpZihyLmxlbmd0aDw9ZSlyZXR1cm4gci5wYWRFbmQoZSwiICIpO2NvbnN0IG89dC50b1ByZWNpc2lvbihlLTIpO2lmKG8ubGVuZ3RoPD1lKXJldHVybiBvO2NvbnN0IG49dC50b0V4cG9uZW50aWFsKGUtMikscz1uLmluZGV4T2YoImUiKSxpPW4uc2xpY2Uocyk7cmV0dXJuIG4uc2xpY2UoMCxlLWkubGVuZ3RoKStpfWZ1bmN0aW9uIHhlKHQsZSxyKXtsZXQgbz1yP3Qucm93czp0LnJvd3MtMTtpZihlPDB8fGU+byl0aHJvdyBuZXcgUmFuZ2VFcnJvcigiUm93IGluZGV4IG91dCBvZiByYW5nZSIpfWZ1bmN0aW9uIEVlKHQsZSxyKXtsZXQgbz1yP3QuY29sdW1uczp0LmNvbHVtbnMtMTtpZihlPDB8fGU+byl0aHJvdyBuZXcgUmFuZ2VFcnJvcigiQ29sdW1uIGluZGV4IG91dCBvZiByYW5nZSIpfWZ1bmN0aW9uIFNlKHQsZSl7aWYoZS50bzFEQXJyYXkmJihlPWUudG8xREFycmF5KCkpLGUubGVuZ3RoIT09dC5jb2x1bW5zKXRocm93IG5ldyBSYW5nZUVycm9yKCJ2ZWN0b3Igc2l6ZSBtdXN0IGJlIHRoZSBzYW1lIGFzIHRoZSBudW1iZXIgb2YgY29sdW1ucyIpO3JldHVybiBlfWZ1bmN0aW9uIGplKHQsZSl7aWYoZS50bzFEQXJyYXkmJihlPWUudG8xREFycmF5KCkpLGUubGVuZ3RoIT09dC5yb3dzKXRocm93IG5ldyBSYW5nZUVycm9yKCJ2ZWN0b3Igc2l6ZSBtdXN0IGJlIHRoZSBzYW1lIGFzIHRoZSBudW1iZXIgb2Ygcm93cyIpO3JldHVybiBlfWZ1bmN0aW9uIF9lKHQsZSl7aWYoIm9iamVjdCIhPXR5cGVvZiBlKXRocm93IG5ldyBUeXBlRXJyb3IoInVuZXhwZWN0ZWQgdHlwZSBmb3Igcm93IGluZGljZXMiKTtpZihlLnNvbWUoKGU9PmU8MHx8ZT49dC5yb3dzKSkpdGhyb3cgbmV3IFJhbmdlRXJyb3IoInJvdyBpbmRpY2VzIGFyZSBvdXQgb2YgcmFuZ2UiKTtyZXR1cm4gQXJyYXkuaXNBcnJheShlKXx8KGU9QXJyYXkuZnJvbShlKSksZX1mdW5jdGlvbiBBZSh0LGUpe2lmKCJvYmplY3QiIT10eXBlb2YgZSl0aHJvdyBuZXcgVHlwZUVycm9yKCJ1bmV4cGVjdGVkIHR5cGUgZm9yIGNvbHVtbiBpbmRpY2VzIik7aWYoZS5zb21lKChlPT5lPDB8fGU+PXQuY29sdW1ucykpKXRocm93IG5ldyBSYW5nZUVycm9yKCJjb2x1bW4gaW5kaWNlcyBhcmUgb3V0IG9mIHJhbmdlIik7cmV0dXJuIEFycmF5LmlzQXJyYXkoZSl8fChlPUFycmF5LmZyb20oZSkpLGV9ZnVuY3Rpb24gQ2UodCxlLHIsbyxuKXtpZig1IT09YXJndW1lbnRzLmxlbmd0aCl0aHJvdyBuZXcgUmFuZ2VFcnJvcigiZXhwZWN0ZWQgNCBhcmd1bWVudHMiKTtpZihJZSgic3RhcnRSb3ciLGUpLEllKCJlbmRSb3ciLHIpLEllKCJzdGFydENvbHVtbiIsbyksSWUoImVuZENvbHVtbiIsbiksZT5yfHxvPm58fGU8MHx8ZT49dC5yb3dzfHxyPDB8fHI+PXQucm93c3x8bzwwfHxvPj10LmNvbHVtbnN8fG48MHx8bj49dC5jb2x1bW5zKXRocm93IG5ldyBSYW5nZUVycm9yKCJTdWJtYXRyaXggaW5kaWNlcyBhcmUgb3V0IG9mIHJhbmdlIil9ZnVuY3Rpb24gUmUodCxlPTApe2xldCByPVtdO2ZvcihsZXQgbz0wO288dDtvKyspci5wdXNoKGUpO3JldHVybiByfWZ1bmN0aW9uIEllKHQsZSl7aWYoIm51bWJlciIhPXR5cGVvZiBlKXRocm93IG5ldyBUeXBlRXJyb3IoYCR7dH0gbXVzdCBiZSBhIG51bWJlcmApfWZ1bmN0aW9uIGtlKHQpe2lmKHQuaXNFbXB0eSgpKXRocm93IG5ldyBFcnJvcigiRW1wdHkgbWF0cml4IGhhcyBubyBlbGVtZW50cyB0byBpbmRleCIpfWNsYXNzIE5le3N0YXRpYyBmcm9tMURBcnJheSh0LGUscil7aWYodCplIT09ci5sZW5ndGgpdGhyb3cgbmV3IFJhbmdlRXJyb3IoImRhdGEgbGVuZ3RoIGRvZXMgbm90IG1hdGNoIGdpdmVuIGRpbWVuc2lvbnMiKTtsZXQgbz1uZXcgRmUodCxlKTtmb3IobGV0IG49MDtuPHQ7bisrKWZvcihsZXQgdD0wO3Q8ZTt0Kyspby5zZXQobix0LHJbbiplK3RdKTtyZXR1cm4gb31zdGF0aWMgcm93VmVjdG9yKHQpe2xldCBlPW5ldyBGZSgxLHQubGVuZ3RoKTtmb3IobGV0IHI9MDtyPHQubGVuZ3RoO3IrKyllLnNldCgwLHIsdFtyXSk7cmV0dXJuIGV9c3RhdGljIGNvbHVtblZlY3Rvcih0KXtsZXQgZT1uZXcgRmUodC5sZW5ndGgsMSk7Zm9yKGxldCByPTA7cjx0Lmxlbmd0aDtyKyspZS5zZXQociwwLHRbcl0pO3JldHVybiBlfXN0YXRpYyB6ZXJvcyh0LGUpe3JldHVybiBuZXcgRmUodCxlKX1zdGF0aWMgb25lcyh0LGUpe3JldHVybiBuZXcgRmUodCxlKS5maWxsKDEpfXN0YXRpYyByYW5kKHQsZSxyPXt9KXtpZigib2JqZWN0IiE9dHlwZW9mIHIpdGhyb3cgbmV3IFR5cGVFcnJvcigib3B0aW9ucyBtdXN0IGJlIGFuIG9iamVjdCIpO2NvbnN0e3JhbmRvbTpvPU1hdGgucmFuZG9tfT1yO2xldCBuPW5ldyBGZSh0LGUpO2ZvcihsZXQgcj0wO3I8dDtyKyspZm9yKGxldCB0PTA7dDxlO3QrKyluLnNldChyLHQsbygpKTtyZXR1cm4gbn1zdGF0aWMgcmFuZEludCh0LGUscj17fSl7aWYoIm9iamVjdCIhPXR5cGVvZiByKXRocm93IG5ldyBUeXBlRXJyb3IoIm9wdGlvbnMgbXVzdCBiZSBhbiBvYmplY3QiKTtjb25zdHttaW46bz0wLG1heDpuPTFlMyxyYW5kb206cz1NYXRoLnJhbmRvbX09cjtpZighTnVtYmVyLmlzSW50ZWdlcihvKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJtaW4gbXVzdCBiZSBhbiBpbnRlZ2VyIik7aWYoIU51bWJlci5pc0ludGVnZXIobikpdGhyb3cgbmV3IFR5cGVFcnJvcigibWF4IG11c3QgYmUgYW4gaW50ZWdlciIpO2lmKG8+PW4pdGhyb3cgbmV3IFJhbmdlRXJyb3IoIm1pbiBtdXN0IGJlIHNtYWxsZXIgdGhhbiBtYXgiKTtsZXQgaT1uLW8sdT1uZXcgRmUodCxlKTtmb3IobGV0IHI9MDtyPHQ7cisrKWZvcihsZXQgdD0wO3Q8ZTt0Kyspe2xldCBlPW8rTWF0aC5yb3VuZChzKCkqaSk7dS5zZXQocix0LGUpfXJldHVybiB1fXN0YXRpYyBleWUodCxlLHIpe3ZvaWQgMD09PWUmJihlPXQpLHZvaWQgMD09PXImJihyPTEpO2xldCBvPU1hdGgubWluKHQsZSksbj10aGlzLnplcm9zKHQsZSk7Zm9yKGxldCB0PTA7dDxvO3QrKyluLnNldCh0LHQscik7cmV0dXJuIG59c3RhdGljIGRpYWcodCxlLHIpe2xldCBvPXQubGVuZ3RoO3ZvaWQgMD09PWUmJihlPW8pLHZvaWQgMD09PXImJihyPWUpO2xldCBuPU1hdGgubWluKG8sZSxyKSxzPXRoaXMuemVyb3MoZSxyKTtmb3IobGV0IGU9MDtlPG47ZSsrKXMuc2V0KGUsZSx0W2VdKTtyZXR1cm4gc31zdGF0aWMgbWluKHQsZSl7dD10aGlzLmNoZWNrTWF0cml4KHQpLGU9dGhpcy5jaGVja01hdHJpeChlKTtsZXQgcj10LnJvd3Msbz10LmNvbHVtbnMsbj1uZXcgRmUocixvKTtmb3IobGV0IHM9MDtzPHI7cysrKWZvcihsZXQgcj0wO3I8bztyKyspbi5zZXQocyxyLE1hdGgubWluKHQuZ2V0KHMsciksZS5nZXQocyxyKSkpO3JldHVybiBufXN0YXRpYyBtYXgodCxlKXt0PXRoaXMuY2hlY2tNYXRyaXgodCksZT10aGlzLmNoZWNrTWF0cml4KGUpO2xldCByPXQucm93cyxvPXQuY29sdW1ucyxuPW5ldyB0aGlzKHIsbyk7Zm9yKGxldCBzPTA7czxyO3MrKylmb3IobGV0IHI9MDtyPG87cisrKW4uc2V0KHMscixNYXRoLm1heCh0LmdldChzLHIpLGUuZ2V0KHMscikpKTtyZXR1cm4gbn1zdGF0aWMgY2hlY2tNYXRyaXgodCl7cmV0dXJuIE5lLmlzTWF0cml4KHQpP3Q6bmV3IEZlKHQpfXN0YXRpYyBpc01hdHJpeCh0KXtyZXR1cm4gbnVsbCE9dCYmIk1hdHJpeCI9PT10LmtsYXNzfWdldCBzaXplKCl7cmV0dXJuIHRoaXMucm93cyp0aGlzLmNvbHVtbnN9YXBwbHkodCl7aWYoImZ1bmN0aW9uIiE9dHlwZW9mIHQpdGhyb3cgbmV3IFR5cGVFcnJvcigiY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uIik7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0LmNhbGwodGhpcyxlLHIpO3JldHVybiB0aGlzfXRvMURBcnJheSgpe2xldCB0PVtdO2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdC5wdXNoKHRoaXMuZ2V0KGUscikpO3JldHVybiB0fXRvMkRBcnJheSgpe2xldCB0PVtdO2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKyl7dC5wdXNoKFtdKTtmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdFtlXS5wdXNoKHRoaXMuZ2V0KGUscikpfXJldHVybiB0fXRvSlNPTigpe3JldHVybiB0aGlzLnRvMkRBcnJheSgpfWlzUm93VmVjdG9yKCl7cmV0dXJuIDE9PT10aGlzLnJvd3N9aXNDb2x1bW5WZWN0b3IoKXtyZXR1cm4gMT09PXRoaXMuY29sdW1uc31pc1ZlY3Rvcigpe3JldHVybiAxPT09dGhpcy5yb3dzfHwxPT09dGhpcy5jb2x1bW5zfWlzU3F1YXJlKCl7cmV0dXJuIHRoaXMucm93cz09PXRoaXMuY29sdW1uc31pc0VtcHR5KCl7cmV0dXJuIDA9PT10aGlzLnJvd3N8fDA9PT10aGlzLmNvbHVtbnN9aXNTeW1tZXRyaWMoKXtpZih0aGlzLmlzU3F1YXJlKCkpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPD10O2UrKylpZih0aGlzLmdldCh0LGUpIT09dGhpcy5nZXQoZSx0KSlyZXR1cm4hMTtyZXR1cm4hMH1yZXR1cm4hMX1pc0VjaGVsb25Gb3JtKCl7bGV0IHQ9MCxlPTAscj0tMSxvPSEwLG49ITE7Zm9yKDt0PHRoaXMucm93cyYmbzspe2ZvcihlPTAsbj0hMTtlPHRoaXMuY29sdW1ucyYmITE9PT1uOykwPT09dGhpcy5nZXQodCxlKT9lKys6MT09PXRoaXMuZ2V0KHQsZSkmJmU+cj8obj0hMCxyPWUpOihvPSExLG49ITApO3QrK31yZXR1cm4gb31pc1JlZHVjZWRFY2hlbG9uRm9ybSgpe2xldCB0PTAsZT0wLHI9LTEsbz0hMCxuPSExO2Zvcig7dDx0aGlzLnJvd3MmJm87KXtmb3IoZT0wLG49ITE7ZTx0aGlzLmNvbHVtbnMmJiExPT09bjspMD09PXRoaXMuZ2V0KHQsZSk/ZSsrOjE9PT10aGlzLmdldCh0LGUpJiZlPnI/KG49ITAscj1lKToobz0hMSxuPSEwKTtmb3IobGV0IHI9ZSsxO3I8dGhpcy5yb3dzO3IrKykwIT09dGhpcy5nZXQodCxyKSYmKG89ITEpO3QrK31yZXR1cm4gb31lY2hlbG9uRm9ybSgpe2xldCB0PXRoaXMuY2xvbmUoKSxlPTAscj0wO2Zvcig7ZTx0LnJvd3MmJnI8dC5jb2x1bW5zOyl7bGV0IG89ZTtmb3IobGV0IG49ZTtuPHQucm93cztuKyspdC5nZXQobixyKT50LmdldChvLHIpJiYobz1uKTtpZigwPT09dC5nZXQobyxyKSlyKys7ZWxzZXt0LnN3YXBSb3dzKGUsbyk7bGV0IG49dC5nZXQoZSxyKTtmb3IobGV0IG89cjtvPHQuY29sdW1ucztvKyspdC5zZXQoZSxvLHQuZ2V0KGUsbykvbik7Zm9yKGxldCBvPWUrMTtvPHQucm93cztvKyspe2xldCBuPXQuZ2V0KG8scikvdC5nZXQoZSxyKTt0LnNldChvLHIsMCk7Zm9yKGxldCBzPXIrMTtzPHQuY29sdW1ucztzKyspdC5zZXQobyxzLHQuZ2V0KG8scyktdC5nZXQoZSxzKSpuKX1lKysscisrfX1yZXR1cm4gdH1yZWR1Y2VkRWNoZWxvbkZvcm0oKXtsZXQgdD10aGlzLmVjaGVsb25Gb3JtKCksZT10LmNvbHVtbnMscj10LnJvd3Msbz1yLTE7Zm9yKDtvPj0wOylpZigwPT09dC5tYXhSb3cobykpby0tO2Vsc2V7bGV0IG49MCxzPSExO2Zvcig7bjxyJiYhMT09PXM7KTE9PT10LmdldChvLG4pP3M9ITA6bisrO2ZvcihsZXQgcj0wO3I8bztyKyspe2xldCBzPXQuZ2V0KHIsbik7Zm9yKGxldCBpPW47aTxlO2krKyl7bGV0IGU9dC5nZXQocixpKS1zKnQuZ2V0KG8saSk7dC5zZXQocixpLGUpfX1vLS19cmV0dXJuIHR9c2V0KCl7dGhyb3cgbmV3IEVycm9yKCJzZXQgbWV0aG9kIGlzIHVuaW1wbGVtZW50ZWQiKX1nZXQoKXt0aHJvdyBuZXcgRXJyb3IoImdldCBtZXRob2QgaXMgdW5pbXBsZW1lbnRlZCIpfXJlcGVhdCh0PXt9KXtpZigib2JqZWN0IiE9dHlwZW9mIHQpdGhyb3cgbmV3IFR5cGVFcnJvcigib3B0aW9ucyBtdXN0IGJlIGFuIG9iamVjdCIpO2NvbnN0e3Jvd3M6ZT0xLGNvbHVtbnM6cj0xfT10O2lmKCFOdW1iZXIuaXNJbnRlZ2VyKGUpfHxlPD0wKXRocm93IG5ldyBUeXBlRXJyb3IoInJvd3MgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIiKTtpZighTnVtYmVyLmlzSW50ZWdlcihyKXx8cjw9MCl0aHJvdyBuZXcgVHlwZUVycm9yKCJjb2x1bW5zIG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyIik7bGV0IG89bmV3IEZlKHRoaXMucm93cyplLHRoaXMuY29sdW1ucypyKTtmb3IobGV0IHQ9MDt0PGU7dCsrKWZvcihsZXQgZT0wO2U8cjtlKyspby5zZXRTdWJNYXRyaXgodGhpcyx0aGlzLnJvd3MqdCx0aGlzLmNvbHVtbnMqZSk7cmV0dXJuIG99ZmlsbCh0KXtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0KTtyZXR1cm4gdGhpc31uZWcoKXtyZXR1cm4gdGhpcy5tdWxTKC0xKX1nZXRSb3codCl7eGUodGhpcyx0KTtsZXQgZT1bXTtmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspZS5wdXNoKHRoaXMuZ2V0KHQscikpO3JldHVybiBlfWdldFJvd1ZlY3Rvcih0KXtyZXR1cm4gRmUucm93VmVjdG9yKHRoaXMuZ2V0Um93KHQpKX1zZXRSb3codCxlKXt4ZSh0aGlzLHQpLGU9U2UodGhpcyxlKTtmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQodCxyLGVbcl0pO3JldHVybiB0aGlzfXN3YXBSb3dzKHQsZSl7eGUodGhpcyx0KSx4ZSh0aGlzLGUpO2ZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl7bGV0IG89dGhpcy5nZXQodCxyKTt0aGlzLnNldCh0LHIsdGhpcy5nZXQoZSxyKSksdGhpcy5zZXQoZSxyLG8pfXJldHVybiB0aGlzfWdldENvbHVtbih0KXtFZSh0aGlzLHQpO2xldCBlPVtdO2ZvcihsZXQgcj0wO3I8dGhpcy5yb3dzO3IrKyllLnB1c2godGhpcy5nZXQocix0KSk7cmV0dXJuIGV9Z2V0Q29sdW1uVmVjdG9yKHQpe3JldHVybiBGZS5jb2x1bW5WZWN0b3IodGhpcy5nZXRDb2x1bW4odCkpfXNldENvbHVtbih0LGUpe0VlKHRoaXMsdCksZT1qZSh0aGlzLGUpO2ZvcihsZXQgcj0wO3I8dGhpcy5yb3dzO3IrKyl0aGlzLnNldChyLHQsZVtyXSk7cmV0dXJuIHRoaXN9c3dhcENvbHVtbnModCxlKXtFZSh0aGlzLHQpLEVlKHRoaXMsZSk7Zm9yKGxldCByPTA7cjx0aGlzLnJvd3M7cisrKXtsZXQgbz10aGlzLmdldChyLHQpO3RoaXMuc2V0KHIsdCx0aGlzLmdldChyLGUpKSx0aGlzLnNldChyLGUsbyl9cmV0dXJuIHRoaXN9YWRkUm93VmVjdG9yKHQpe3Q9U2UodGhpcyx0KTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpK3Rbcl0pO3JldHVybiB0aGlzfXN1YlJvd1ZlY3Rvcih0KXt0PVNlKHRoaXMsdCk7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldChlLHIsdGhpcy5nZXQoZSxyKS10W3JdKTtyZXR1cm4gdGhpc31tdWxSb3dWZWN0b3IodCl7dD1TZSh0aGlzLHQpO2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUscikqdFtyXSk7cmV0dXJuIHRoaXN9ZGl2Um93VmVjdG9yKHQpe3Q9U2UodGhpcyx0KTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpL3Rbcl0pO3JldHVybiB0aGlzfWFkZENvbHVtblZlY3Rvcih0KXt0PWplKHRoaXMsdCk7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldChlLHIsdGhpcy5nZXQoZSxyKSt0W2VdKTtyZXR1cm4gdGhpc31zdWJDb2x1bW5WZWN0b3IodCl7dD1qZSh0aGlzLHQpO2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUsciktdFtlXSk7cmV0dXJuIHRoaXN9bXVsQ29sdW1uVmVjdG9yKHQpe3Q9amUodGhpcyx0KTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpKnRbZV0pO3JldHVybiB0aGlzfWRpdkNvbHVtblZlY3Rvcih0KXt0PWplKHRoaXMsdCk7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldChlLHIsdGhpcy5nZXQoZSxyKS90W2VdKTtyZXR1cm4gdGhpc31tdWxSb3codCxlKXt4ZSh0aGlzLHQpO2ZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldCh0LHIsdGhpcy5nZXQodCxyKSplKTtyZXR1cm4gdGhpc31tdWxDb2x1bW4odCxlKXtFZSh0aGlzLHQpO2ZvcihsZXQgcj0wO3I8dGhpcy5yb3dzO3IrKyl0aGlzLnNldChyLHQsdGhpcy5nZXQocix0KSplKTtyZXR1cm4gdGhpc31tYXgoKXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm4gTmFOO2xldCB0PXRoaXMuZ2V0KDAsMCk7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLmdldChlLHIpPnQmJih0PXRoaXMuZ2V0KGUscikpO3JldHVybiB0fW1heEluZGV4KCl7a2UodGhpcyk7bGV0IHQ9dGhpcy5nZXQoMCwwKSxlPVswLDBdO2ZvcihsZXQgcj0wO3I8dGhpcy5yb3dzO3IrKylmb3IobGV0IG89MDtvPHRoaXMuY29sdW1ucztvKyspdGhpcy5nZXQocixvKT50JiYodD10aGlzLmdldChyLG8pLGVbMF09cixlWzFdPW8pO3JldHVybiBlfW1pbigpe2lmKHRoaXMuaXNFbXB0eSgpKXJldHVybiBOYU47bGV0IHQ9dGhpcy5nZXQoMCwwKTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuZ2V0KGUscik8dCYmKHQ9dGhpcy5nZXQoZSxyKSk7cmV0dXJuIHR9bWluSW5kZXgoKXtrZSh0aGlzKTtsZXQgdD10aGlzLmdldCgwLDApLGU9WzAsMF07Zm9yKGxldCByPTA7cjx0aGlzLnJvd3M7cisrKWZvcihsZXQgbz0wO288dGhpcy5jb2x1bW5zO28rKyl0aGlzLmdldChyLG8pPHQmJih0PXRoaXMuZ2V0KHIsbyksZVswXT1yLGVbMV09byk7cmV0dXJuIGV9bWF4Um93KHQpe2lmKHhlKHRoaXMsdCksdGhpcy5pc0VtcHR5KCkpcmV0dXJuIE5hTjtsZXQgZT10aGlzLmdldCh0LDApO2ZvcihsZXQgcj0xO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLmdldCh0LHIpPmUmJihlPXRoaXMuZ2V0KHQscikpO3JldHVybiBlfW1heFJvd0luZGV4KHQpe3hlKHRoaXMsdCksa2UodGhpcyk7bGV0IGU9dGhpcy5nZXQodCwwKSxyPVt0LDBdO2ZvcihsZXQgbz0xO288dGhpcy5jb2x1bW5zO28rKyl0aGlzLmdldCh0LG8pPmUmJihlPXRoaXMuZ2V0KHQsbyksclsxXT1vKTtyZXR1cm4gcn1taW5Sb3codCl7aWYoeGUodGhpcyx0KSx0aGlzLmlzRW1wdHkoKSlyZXR1cm4gTmFOO2xldCBlPXRoaXMuZ2V0KHQsMCk7Zm9yKGxldCByPTE7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuZ2V0KHQscik8ZSYmKGU9dGhpcy5nZXQodCxyKSk7cmV0dXJuIGV9bWluUm93SW5kZXgodCl7eGUodGhpcyx0KSxrZSh0aGlzKTtsZXQgZT10aGlzLmdldCh0LDApLHI9W3QsMF07Zm9yKGxldCBvPTE7bzx0aGlzLmNvbHVtbnM7bysrKXRoaXMuZ2V0KHQsbyk8ZSYmKGU9dGhpcy5nZXQodCxvKSxyWzFdPW8pO3JldHVybiByfW1heENvbHVtbih0KXtpZihFZSh0aGlzLHQpLHRoaXMuaXNFbXB0eSgpKXJldHVybiBOYU47bGV0IGU9dGhpcy5nZXQoMCx0KTtmb3IobGV0IHI9MTtyPHRoaXMucm93cztyKyspdGhpcy5nZXQocix0KT5lJiYoZT10aGlzLmdldChyLHQpKTtyZXR1cm4gZX1tYXhDb2x1bW5JbmRleCh0KXtFZSh0aGlzLHQpLGtlKHRoaXMpO2xldCBlPXRoaXMuZ2V0KDAsdCkscj1bMCx0XTtmb3IobGV0IG89MTtvPHRoaXMucm93cztvKyspdGhpcy5nZXQobyx0KT5lJiYoZT10aGlzLmdldChvLHQpLHJbMF09byk7cmV0dXJuIHJ9bWluQ29sdW1uKHQpe2lmKEVlKHRoaXMsdCksdGhpcy5pc0VtcHR5KCkpcmV0dXJuIE5hTjtsZXQgZT10aGlzLmdldCgwLHQpO2ZvcihsZXQgcj0xO3I8dGhpcy5yb3dzO3IrKyl0aGlzLmdldChyLHQpPGUmJihlPXRoaXMuZ2V0KHIsdCkpO3JldHVybiBlfW1pbkNvbHVtbkluZGV4KHQpe0VlKHRoaXMsdCksa2UodGhpcyk7bGV0IGU9dGhpcy5nZXQoMCx0KSxyPVswLHRdO2ZvcihsZXQgbz0xO288dGhpcy5yb3dzO28rKyl0aGlzLmdldChvLHQpPGUmJihlPXRoaXMuZ2V0KG8sdCksclswXT1vKTtyZXR1cm4gcn1kaWFnKCl7bGV0IHQ9TWF0aC5taW4odGhpcy5yb3dzLHRoaXMuY29sdW1ucyksZT1bXTtmb3IobGV0IHI9MDtyPHQ7cisrKWUucHVzaCh0aGlzLmdldChyLHIpKTtyZXR1cm4gZX1ub3JtKHQ9ImZyb2Jlbml1cyIpe2xldCBlPTA7aWYoIm1heCI9PT10KXJldHVybiB0aGlzLm1heCgpO2lmKCJmcm9iZW5pdXMiPT09dCl7Zm9yKGxldCB0PTA7dDx0aGlzLnJvd3M7dCsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyllKz10aGlzLmdldCh0LHIpKnRoaXMuZ2V0KHQscik7cmV0dXJuIE1hdGguc3FydChlKX10aHJvdyBuZXcgUmFuZ2VFcnJvcihgdW5rbm93biBub3JtIHR5cGU6ICR7dH1gKX1jdW11bGF0aXZlU3VtKCl7bGV0IHQ9MDtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXQrPXRoaXMuZ2V0KGUsciksdGhpcy5zZXQoZSxyLHQpO3JldHVybiB0aGlzfWRvdCh0KXtOZS5pc01hdHJpeCh0KSYmKHQ9dC50bzFEQXJyYXkoKSk7bGV0IGU9dGhpcy50bzFEQXJyYXkoKTtpZihlLmxlbmd0aCE9PXQubGVuZ3RoKXRocm93IG5ldyBSYW5nZUVycm9yKCJ2ZWN0b3JzIGRvIG5vdCBoYXZlIHRoZSBzYW1lIHNpemUiKTtsZXQgcj0wO2ZvcihsZXQgbz0wO288ZS5sZW5ndGg7bysrKXIrPWVbb10qdFtvXTtyZXR1cm4gcn1tbXVsKHQpe3Q9RmUuY2hlY2tNYXRyaXgodCk7bGV0IGU9dGhpcy5yb3dzLHI9dGhpcy5jb2x1bW5zLG89dC5jb2x1bW5zLG49bmV3IEZlKGUsbykscz1uZXcgRmxvYXQ2NEFycmF5KHIpO2ZvcihsZXQgaT0wO2k8bztpKyspe2ZvcihsZXQgZT0wO2U8cjtlKyspc1tlXT10LmdldChlLGkpO2ZvcihsZXQgdD0wO3Q8ZTt0Kyspe2xldCBlPTA7Zm9yKGxldCBvPTA7bzxyO28rKyllKz10aGlzLmdldCh0LG8pKnNbb107bi5zZXQodCxpLGUpfX1yZXR1cm4gbn1zdHJhc3NlbjJ4Mih0KXt0PUZlLmNoZWNrTWF0cml4KHQpO2xldCBlPW5ldyBGZSgyLDIpO2NvbnN0IHI9dGhpcy5nZXQoMCwwKSxvPXQuZ2V0KDAsMCksbj10aGlzLmdldCgwLDEpLHM9dC5nZXQoMCwxKSxpPXRoaXMuZ2V0KDEsMCksdT10LmdldCgxLDApLGE9dGhpcy5nZXQoMSwxKSxoPXQuZ2V0KDEsMSksbD0ocithKSoobytoKSxjPShpK2EpKm8sZj1yKihzLWgpLG09YSoodS1vKSxnPShyK24pKmgscD1sK20tZysobi1hKSoodStoKSx3PWYrZyxkPWMrbSxiPWwtYytmKyhpLXIpKihvK3MpO3JldHVybiBlLnNldCgwLDAscCksZS5zZXQoMCwxLHcpLGUuc2V0KDEsMCxkKSxlLnNldCgxLDEsYiksZX1zdHJhc3NlbjN4Myh0KXt0PUZlLmNoZWNrTWF0cml4KHQpO2xldCBlPW5ldyBGZSgzLDMpO2NvbnN0IHI9dGhpcy5nZXQoMCwwKSxvPXRoaXMuZ2V0KDAsMSksbj10aGlzLmdldCgwLDIpLHM9dGhpcy5nZXQoMSwwKSxpPXRoaXMuZ2V0KDEsMSksdT10aGlzLmdldCgxLDIpLGE9dGhpcy5nZXQoMiwwKSxoPXRoaXMuZ2V0KDIsMSksbD10aGlzLmdldCgyLDIpLGM9dC5nZXQoMCwwKSxmPXQuZ2V0KDAsMSksbT10LmdldCgwLDIpLGc9dC5nZXQoMSwwKSxwPXQuZ2V0KDEsMSksdz10LmdldCgxLDIpLGQ9dC5nZXQoMiwwKSxiPXQuZ2V0KDIsMSkseT10LmdldCgyLDIpLHY9KHItcykqKC1mK3ApLE09KC1yK3MraSkqKGMtZitwKSx4PShzK2kpKigtYytmKSxFPXIqYyxTPSgtcithK2gpKihjLW0rdyksaj0oLXIrYSkqKG0tdyksXz0oYStoKSooLWMrbSksQT0oLW4raCtsKSoocCtkLWIpLEM9KG4tbCkqKHAtYiksUj1uKmQsST0oaCtsKSooLWQrYiksaz0oLW4raSt1KSoodytkLXkpLE49KG4tdSkqKHcteSksTz0oaSt1KSooLWQreSksRj1FK1IrbypnLHo9KHIrbytuLXMtaS1oLWwpKnArTSt4K0UrQStSK0ksVD1FK1MrXysocitvK24taS11LWEtaCkqdytSK2srTyxWPXYraSooLWMrZitnLXAtdy1kK3kpK00rRStSK2srTixQPXYrTSt4K0UrdSpiLHE9UitrK04rTytzKm0sJD1FK1MraitoKigtYyttK2ctcC13LWQrYikrQStDK1IsRD1BK0MrUitJK2EqZixVPUUrUytqK18rbCp5O3JldHVybiBlLnNldCgwLDAsRiksZS5zZXQoMCwxLHopLGUuc2V0KDAsMixUKSxlLnNldCgxLDAsViksZS5zZXQoMSwxLFApLGUuc2V0KDEsMixxKSxlLnNldCgyLDAsJCksZS5zZXQoMiwxLEQpLGUuc2V0KDIsMixVKSxlfW1tdWxTdHJhc3Nlbih0KXt0PUZlLmNoZWNrTWF0cml4KHQpO2xldCBlPXRoaXMuY2xvbmUoKSxyPWUucm93cyxvPWUuY29sdW1ucyxuPXQucm93cyxzPXQuY29sdW1ucztmdW5jdGlvbiBpKHQsZSxyKXtsZXQgbz10LnJvd3Msbj10LmNvbHVtbnM7aWYobz09PWUmJm49PT1yKXJldHVybiB0O3tsZXQgbz1OZS56ZXJvcyhlLHIpO3JldHVybiBvPW8uc2V0U3ViTWF0cml4KHQsMCwwKSxvfX1vIT09biYmY29uc29sZS53YXJuKGBNdWx0aXBseWluZyAke3J9IHggJHtvfSBhbmQgJHtufSB4ICR7c30gbWF0cml4OiBkaW1lbnNpb25zIGRvIG5vdCBtYXRjaC5gKTtsZXQgdT1NYXRoLm1heChyLG4pLGE9TWF0aC5tYXgobyxzKTtyZXR1cm4gZT1pKGUsdSxhKSxmdW5jdGlvbiB0KGUscixvLG4pe2lmKG88PTUxMnx8bjw9NTEyKXJldHVybiBlLm1tdWwocik7byUyPT0xJiZuJTI9PTE/KGU9aShlLG8rMSxuKzEpLHI9aShyLG8rMSxuKzEpKTpvJTI9PTE/KGU9aShlLG8rMSxuKSxyPWkocixvKzEsbikpOm4lMj09MSYmKGU9aShlLG8sbisxKSxyPWkocixvLG4rMSkpO2xldCBzPXBhcnNlSW50KGUucm93cy8yLDEwKSx1PXBhcnNlSW50KGUuY29sdW1ucy8yLDEwKSxhPWUuc3ViTWF0cml4KDAscy0xLDAsdS0xKSxoPXIuc3ViTWF0cml4KDAscy0xLDAsdS0xKSxsPWUuc3ViTWF0cml4KDAscy0xLHUsZS5jb2x1bW5zLTEpLGM9ci5zdWJNYXRyaXgoMCxzLTEsdSxyLmNvbHVtbnMtMSksZj1lLnN1Yk1hdHJpeChzLGUucm93cy0xLDAsdS0xKSxtPXIuc3ViTWF0cml4KHMsci5yb3dzLTEsMCx1LTEpLGc9ZS5zdWJNYXRyaXgocyxlLnJvd3MtMSx1LGUuY29sdW1ucy0xKSxwPXIuc3ViTWF0cml4KHMsci5yb3dzLTEsdSxyLmNvbHVtbnMtMSksdz10KE5lLmFkZChhLGcpLE5lLmFkZChoLHApLHMsdSksZD10KE5lLmFkZChmLGcpLGgscyx1KSxiPXQoYSxOZS5zdWIoYyxwKSxzLHUpLHk9dChnLE5lLnN1YihtLGgpLHMsdSksdj10KE5lLmFkZChhLGwpLHAscyx1KSxNPXQoTmUuc3ViKGYsYSksTmUuYWRkKGgsYykscyx1KSx4PXQoTmUuc3ViKGwsZyksTmUuYWRkKG0scCkscyx1KSxFPU5lLmFkZCh3LHkpO0Uuc3ViKHYpLEUuYWRkKHgpO2xldCBTPU5lLmFkZChiLHYpLGo9TmUuYWRkKGQseSksXz1OZS5zdWIodyxkKTtfLmFkZChiKSxfLmFkZChNKTtsZXQgQT1OZS56ZXJvcygyKkUucm93cywyKkUuY29sdW1ucyk7cmV0dXJuIEE9QS5zZXRTdWJNYXRyaXgoRSwwLDApLEE9QS5zZXRTdWJNYXRyaXgoUyxFLnJvd3MsMCksQT1BLnNldFN1Yk1hdHJpeChqLDAsRS5jb2x1bW5zKSxBPUEuc2V0U3ViTWF0cml4KF8sRS5yb3dzLEUuY29sdW1ucyksQS5zdWJNYXRyaXgoMCxvLTEsMCxuLTEpfShlLHQ9aSh0LHUsYSksdSxhKX1zY2FsZVJvd3ModD17fSl7aWYoIm9iamVjdCIhPXR5cGVvZiB0KXRocm93IG5ldyBUeXBlRXJyb3IoIm9wdGlvbnMgbXVzdCBiZSBhbiBvYmplY3QiKTtjb25zdHttaW46ZT0wLG1heDpyPTF9PXQ7aWYoIU51bWJlci5pc0Zpbml0ZShlKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJtaW4gbXVzdCBiZSBhIG51bWJlciIpO2lmKCFOdW1iZXIuaXNGaW5pdGUocikpdGhyb3cgbmV3IFR5cGVFcnJvcigibWF4IG11c3QgYmUgYSBudW1iZXIiKTtpZihlPj1yKXRocm93IG5ldyBSYW5nZUVycm9yKCJtaW4gbXVzdCBiZSBzbWFsbGVyIHRoYW4gbWF4Iik7bGV0IG89bmV3IEZlKHRoaXMucm93cyx0aGlzLmNvbHVtbnMpO2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKyl7Y29uc3Qgbj10aGlzLmdldFJvdyh0KTtuLmxlbmd0aD4wJiZkZShuLHttaW46ZSxtYXg6cixvdXRwdXQ6bn0pLG8uc2V0Um93KHQsbil9cmV0dXJuIG99c2NhbGVDb2x1bW5zKHQ9e30pe2lmKCJvYmplY3QiIT10eXBlb2YgdCl0aHJvdyBuZXcgVHlwZUVycm9yKCJvcHRpb25zIG11c3QgYmUgYW4gb2JqZWN0Iik7Y29uc3R7bWluOmU9MCxtYXg6cj0xfT10O2lmKCFOdW1iZXIuaXNGaW5pdGUoZSkpdGhyb3cgbmV3IFR5cGVFcnJvcigibWluIG11c3QgYmUgYSBudW1iZXIiKTtpZighTnVtYmVyLmlzRmluaXRlKHIpKXRocm93IG5ldyBUeXBlRXJyb3IoIm1heCBtdXN0IGJlIGEgbnVtYmVyIik7aWYoZT49cil0aHJvdyBuZXcgUmFuZ2VFcnJvcigibWluIG11c3QgYmUgc21hbGxlciB0aGFuIG1heCIpO2xldCBvPW5ldyBGZSh0aGlzLnJvd3MsdGhpcy5jb2x1bW5zKTtmb3IobGV0IHQ9MDt0PHRoaXMuY29sdW1uczt0Kyspe2NvbnN0IG49dGhpcy5nZXRDb2x1bW4odCk7bi5sZW5ndGgmJmRlKG4se21pbjplLG1heDpyLG91dHB1dDpufSksby5zZXRDb2x1bW4odCxuKX1yZXR1cm4gb31mbGlwUm93cygpe2NvbnN0IHQ9TWF0aC5jZWlsKHRoaXMuY29sdW1ucy8yKTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0O3IrKyl7bGV0IHQ9dGhpcy5nZXQoZSxyKSxvPXRoaXMuZ2V0KGUsdGhpcy5jb2x1bW5zLTEtcik7dGhpcy5zZXQoZSxyLG8pLHRoaXMuc2V0KGUsdGhpcy5jb2x1bW5zLTEtcix0KX1yZXR1cm4gdGhpc31mbGlwQ29sdW1ucygpe2NvbnN0IHQ9TWF0aC5jZWlsKHRoaXMucm93cy8yKTtmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspZm9yKGxldCByPTA7cjx0O3IrKyl7bGV0IHQ9dGhpcy5nZXQocixlKSxvPXRoaXMuZ2V0KHRoaXMucm93cy0xLXIsZSk7dGhpcy5zZXQocixlLG8pLHRoaXMuc2V0KHRoaXMucm93cy0xLXIsZSx0KX1yZXR1cm4gdGhpc31rcm9uZWNrZXJQcm9kdWN0KHQpe3Q9RmUuY2hlY2tNYXRyaXgodCk7bGV0IGU9dGhpcy5yb3dzLHI9dGhpcy5jb2x1bW5zLG89dC5yb3dzLG49dC5jb2x1bW5zLHM9bmV3IEZlKGUqbyxyKm4pO2ZvcihsZXQgaT0wO2k8ZTtpKyspZm9yKGxldCBlPTA7ZTxyO2UrKylmb3IobGV0IHI9MDtyPG87cisrKWZvcihsZXQgdT0wO3U8bjt1Kyspcy5zZXQobyppK3IsbiplK3UsdGhpcy5nZXQoaSxlKSp0LmdldChyLHUpKTtyZXR1cm4gc31rcm9uZWNrZXJTdW0odCl7aWYodD1GZS5jaGVja01hdHJpeCh0KSwhdGhpcy5pc1NxdWFyZSgpfHwhdC5pc1NxdWFyZSgpKXRocm93IG5ldyBFcnJvcigiS3JvbmVja2VyIFN1bSBuZWVkcyB0d28gU3F1YXJlIE1hdHJpY2VzIik7bGV0IGU9dGhpcy5yb3dzLHI9dC5yb3dzLG89dGhpcy5rcm9uZWNrZXJQcm9kdWN0KEZlLmV5ZShyLHIpKSxuPUZlLmV5ZShlLGUpLmtyb25lY2tlclByb2R1Y3QodCk7cmV0dXJuIG8uYWRkKG4pfXRyYW5zcG9zZSgpe2xldCB0PW5ldyBGZSh0aGlzLmNvbHVtbnMsdGhpcy5yb3dzKTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXQuc2V0KHIsZSx0aGlzLmdldChlLHIpKTtyZXR1cm4gdH1zb3J0Um93cyh0PU9lKXtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspdGhpcy5zZXRSb3coZSx0aGlzLmdldFJvdyhlKS5zb3J0KHQpKTtyZXR1cm4gdGhpc31zb3J0Q29sdW1ucyh0PU9lKXtmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXRDb2x1bW4oZSx0aGlzLmdldENvbHVtbihlKS5zb3J0KHQpKTtyZXR1cm4gdGhpc31zdWJNYXRyaXgodCxlLHIsbyl7Q2UodGhpcyx0LGUscixvKTtsZXQgbj1uZXcgRmUoZS10KzEsby1yKzEpO2ZvcihsZXQgcz10O3M8PWU7cysrKWZvcihsZXQgZT1yO2U8PW87ZSsrKW4uc2V0KHMtdCxlLXIsdGhpcy5nZXQocyxlKSk7cmV0dXJuIG59c3ViTWF0cml4Um93KHQsZSxyKXtpZih2b2lkIDA9PT1lJiYoZT0wKSx2b2lkIDA9PT1yJiYocj10aGlzLmNvbHVtbnMtMSksZT5yfHxlPDB8fGU+PXRoaXMuY29sdW1uc3x8cjwwfHxyPj10aGlzLmNvbHVtbnMpdGhyb3cgbmV3IFJhbmdlRXJyb3IoIkFyZ3VtZW50IG91dCBvZiByYW5nZSIpO2xldCBvPW5ldyBGZSh0Lmxlbmd0aCxyLWUrMSk7Zm9yKGxldCBuPTA7bjx0Lmxlbmd0aDtuKyspZm9yKGxldCBzPWU7czw9cjtzKyspe2lmKHRbbl08MHx8dFtuXT49dGhpcy5yb3dzKXRocm93IG5ldyBSYW5nZUVycm9yKGBSb3cgaW5kZXggb3V0IG9mIHJhbmdlOiAke3Rbbl19YCk7by5zZXQobixzLWUsdGhpcy5nZXQodFtuXSxzKSl9cmV0dXJuIG99c3ViTWF0cml4Q29sdW1uKHQsZSxyKXtpZih2b2lkIDA9PT1lJiYoZT0wKSx2b2lkIDA9PT1yJiYocj10aGlzLnJvd3MtMSksZT5yfHxlPDB8fGU+PXRoaXMucm93c3x8cjwwfHxyPj10aGlzLnJvd3MpdGhyb3cgbmV3IFJhbmdlRXJyb3IoIkFyZ3VtZW50IG91dCBvZiByYW5nZSIpO2xldCBvPW5ldyBGZShyLWUrMSx0Lmxlbmd0aCk7Zm9yKGxldCBuPTA7bjx0Lmxlbmd0aDtuKyspZm9yKGxldCBzPWU7czw9cjtzKyspe2lmKHRbbl08MHx8dFtuXT49dGhpcy5jb2x1bW5zKXRocm93IG5ldyBSYW5nZUVycm9yKGBDb2x1bW4gaW5kZXggb3V0IG9mIHJhbmdlOiAke3Rbbl19YCk7by5zZXQocy1lLG4sdGhpcy5nZXQocyx0W25dKSl9cmV0dXJuIG99c2V0U3ViTWF0cml4KHQsZSxyKXtpZigodD1GZS5jaGVja01hdHJpeCh0KSkuaXNFbXB0eSgpKXJldHVybiB0aGlzO0NlKHRoaXMsZSxlK3Qucm93cy0xLHIscit0LmNvbHVtbnMtMSk7Zm9yKGxldCBvPTA7bzx0LnJvd3M7bysrKWZvcihsZXQgbj0wO248dC5jb2x1bW5zO24rKyl0aGlzLnNldChlK28scituLHQuZ2V0KG8sbikpO3JldHVybiB0aGlzfXNlbGVjdGlvbih0LGUpe2xldCByPWZ1bmN0aW9uKHQsZSxyKXtyZXR1cm57cm93Ol9lKHQsZSksY29sdW1uOkFlKHQscil9fSh0aGlzLHQsZSksbz1uZXcgRmUodC5sZW5ndGgsZS5sZW5ndGgpO2ZvcihsZXQgdD0wO3Q8ci5yb3cubGVuZ3RoO3QrKyl7bGV0IGU9ci5yb3dbdF07Zm9yKGxldCBuPTA7bjxyLmNvbHVtbi5sZW5ndGg7bisrKXtsZXQgcz1yLmNvbHVtbltuXTtvLnNldCh0LG4sdGhpcy5nZXQoZSxzKSl9fXJldHVybiBvfXRyYWNlKCl7bGV0IHQ9TWF0aC5taW4odGhpcy5yb3dzLHRoaXMuY29sdW1ucyksZT0wO2ZvcihsZXQgcj0wO3I8dDtyKyspZSs9dGhpcy5nZXQocixyKTtyZXR1cm4gZX1jbG9uZSgpe2xldCB0PW5ldyBGZSh0aGlzLnJvd3MsdGhpcy5jb2x1bW5zKTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXQuc2V0KGUscix0aGlzLmdldChlLHIpKTtyZXR1cm4gdH1zdW0odCl7c3dpdGNoKHQpe2Nhc2Uicm93IjpyZXR1cm4gZnVuY3Rpb24odCl7bGV0IGU9UmUodC5yb3dzKTtmb3IobGV0IHI9MDtyPHQucm93czsrK3IpZm9yKGxldCBvPTA7bzx0LmNvbHVtbnM7KytvKWVbcl0rPXQuZ2V0KHIsbyk7cmV0dXJuIGV9KHRoaXMpO2Nhc2UiY29sdW1uIjpyZXR1cm4gZnVuY3Rpb24odCl7bGV0IGU9UmUodC5jb2x1bW5zKTtmb3IobGV0IHI9MDtyPHQucm93czsrK3IpZm9yKGxldCBvPTA7bzx0LmNvbHVtbnM7KytvKWVbb10rPXQuZ2V0KHIsbyk7cmV0dXJuIGV9KHRoaXMpO2Nhc2Ugdm9pZCAwOnJldHVybiBmdW5jdGlvbih0KXtsZXQgZT0wO2ZvcihsZXQgcj0wO3I8dC5yb3dzO3IrKylmb3IobGV0IG89MDtvPHQuY29sdW1ucztvKyspZSs9dC5nZXQocixvKTtyZXR1cm4gZX0odGhpcyk7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgb3B0aW9uOiAke3R9YCl9fXByb2R1Y3QodCl7c3dpdGNoKHQpe2Nhc2Uicm93IjpyZXR1cm4gZnVuY3Rpb24odCl7bGV0IGU9UmUodC5yb3dzLDEpO2ZvcihsZXQgcj0wO3I8dC5yb3dzOysrcilmb3IobGV0IG89MDtvPHQuY29sdW1uczsrK28pZVtyXSo9dC5nZXQocixvKTtyZXR1cm4gZX0odGhpcyk7Y2FzZSJjb2x1bW4iOnJldHVybiBmdW5jdGlvbih0KXtsZXQgZT1SZSh0LmNvbHVtbnMsMSk7Zm9yKGxldCByPTA7cjx0LnJvd3M7KytyKWZvcihsZXQgbz0wO288dC5jb2x1bW5zOysrbyllW29dKj10LmdldChyLG8pO3JldHVybiBlfSh0aGlzKTtjYXNlIHZvaWQgMDpyZXR1cm4gZnVuY3Rpb24odCl7bGV0IGU9MTtmb3IobGV0IHI9MDtyPHQucm93cztyKyspZm9yKGxldCBvPTA7bzx0LmNvbHVtbnM7bysrKWUqPXQuZ2V0KHIsbyk7cmV0dXJuIGV9KHRoaXMpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIG9wdGlvbjogJHt0fWApfX1tZWFuKHQpe2NvbnN0IGU9dGhpcy5zdW0odCk7c3dpdGNoKHQpe2Nhc2Uicm93Ijpmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZVt0XS89dGhpcy5jb2x1bW5zO3JldHVybiBlO2Nhc2UiY29sdW1uIjpmb3IobGV0IHQ9MDt0PHRoaXMuY29sdW1uczt0KyspZVt0XS89dGhpcy5yb3dzO3JldHVybiBlO2Nhc2Ugdm9pZCAwOnJldHVybiBlL3RoaXMuc2l6ZTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgaW52YWxpZCBvcHRpb246ICR7dH1gKX19dmFyaWFuY2UodCxlPXt9KXtpZigib2JqZWN0Ij09dHlwZW9mIHQmJihlPXQsdD12b2lkIDApLCJvYmplY3QiIT10eXBlb2YgZSl0aHJvdyBuZXcgVHlwZUVycm9yKCJvcHRpb25zIG11c3QgYmUgYW4gb2JqZWN0Iik7Y29uc3R7dW5iaWFzZWQ6cj0hMCxtZWFuOm89dGhpcy5tZWFuKHQpfT1lO2lmKCJib29sZWFuIiE9dHlwZW9mIHIpdGhyb3cgbmV3IFR5cGVFcnJvcigidW5iaWFzZWQgbXVzdCBiZSBhIGJvb2xlYW4iKTtzd2l0Y2godCl7Y2FzZSJyb3ciOmlmKCFBcnJheS5pc0FycmF5KG8pKXRocm93IG5ldyBUeXBlRXJyb3IoIm1lYW4gbXVzdCBiZSBhbiBhcnJheSIpO3JldHVybiBmdW5jdGlvbih0LGUscil7Y29uc3Qgbz10LnJvd3Msbj10LmNvbHVtbnMscz1bXTtmb3IobGV0IGk9MDtpPG87aSsrKXtsZXQgbz0wLHU9MCxhPTA7Zm9yKGxldCBlPTA7ZTxuO2UrKylhPXQuZ2V0KGksZSktcltpXSxvKz1hLHUrPWEqYTtlP3MucHVzaCgodS1vKm8vbikvKG4tMSkpOnMucHVzaCgodS1vKm8vbikvbil9cmV0dXJuIHN9KHRoaXMscixvKTtjYXNlImNvbHVtbiI6aWYoIUFycmF5LmlzQXJyYXkobykpdGhyb3cgbmV3IFR5cGVFcnJvcigibWVhbiBtdXN0IGJlIGFuIGFycmF5Iik7cmV0dXJuIGZ1bmN0aW9uKHQsZSxyKXtjb25zdCBvPXQucm93cyxuPXQuY29sdW1ucyxzPVtdO2ZvcihsZXQgaT0wO2k8bjtpKyspe2xldCBuPTAsdT0wLGE9MDtmb3IobGV0IGU9MDtlPG87ZSsrKWE9dC5nZXQoZSxpKS1yW2ldLG4rPWEsdSs9YSphO2U/cy5wdXNoKCh1LW4qbi9vKS8oby0xKSk6cy5wdXNoKCh1LW4qbi9vKS9vKX1yZXR1cm4gc30odGhpcyxyLG8pO2Nhc2Ugdm9pZCAwOmlmKCJudW1iZXIiIT10eXBlb2Ygbyl0aHJvdyBuZXcgVHlwZUVycm9yKCJtZWFuIG11c3QgYmUgYSBudW1iZXIiKTtyZXR1cm4gZnVuY3Rpb24odCxlLHIpe2NvbnN0IG89dC5yb3dzLG49dC5jb2x1bW5zLHM9bypuO2xldCBpPTAsdT0wLGE9MDtmb3IobGV0IGU9MDtlPG87ZSsrKWZvcihsZXQgbz0wO288bjtvKyspYT10LmdldChlLG8pLXIsaSs9YSx1Kz1hKmE7cmV0dXJuIGU/KHUtaSppL3MpLyhzLTEpOih1LWkqaS9zKS9zfSh0aGlzLHIsbyk7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgb3B0aW9uOiAke3R9YCl9fXN0YW5kYXJkRGV2aWF0aW9uKHQsZSl7Im9iamVjdCI9PXR5cGVvZiB0JiYoZT10LHQ9dm9pZCAwKTtjb25zdCByPXRoaXMudmFyaWFuY2UodCxlKTtpZih2b2lkIDA9PT10KXJldHVybiBNYXRoLnNxcnQocik7Zm9yKGxldCB0PTA7dDxyLmxlbmd0aDt0Kyspclt0XT1NYXRoLnNxcnQoclt0XSk7cmV0dXJuIHJ9Y2VudGVyKHQsZT17fSl7aWYoIm9iamVjdCI9PXR5cGVvZiB0JiYoZT10LHQ9dm9pZCAwKSwib2JqZWN0IiE9dHlwZW9mIGUpdGhyb3cgbmV3IFR5cGVFcnJvcigib3B0aW9ucyBtdXN0IGJlIGFuIG9iamVjdCIpO2NvbnN0e2NlbnRlcjpyPXRoaXMubWVhbih0KX09ZTtzd2l0Y2godCl7Y2FzZSJyb3ciOmlmKCFBcnJheS5pc0FycmF5KHIpKXRocm93IG5ldyBUeXBlRXJyb3IoImNlbnRlciBtdXN0IGJlIGFuIGFycmF5Iik7cmV0dXJuIGZ1bmN0aW9uKHQsZSl7Zm9yKGxldCByPTA7cjx0LnJvd3M7cisrKWZvcihsZXQgbz0wO288dC5jb2x1bW5zO28rKyl0LnNldChyLG8sdC5nZXQocixvKS1lW3JdKX0odGhpcyxyKSx0aGlzO2Nhc2UiY29sdW1uIjppZighQXJyYXkuaXNBcnJheShyKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJjZW50ZXIgbXVzdCBiZSBhbiBhcnJheSIpO3JldHVybiBmdW5jdGlvbih0LGUpe2ZvcihsZXQgcj0wO3I8dC5yb3dzO3IrKylmb3IobGV0IG89MDtvPHQuY29sdW1ucztvKyspdC5zZXQocixvLHQuZ2V0KHIsbyktZVtvXSl9KHRoaXMsciksdGhpcztjYXNlIHZvaWQgMDppZigibnVtYmVyIiE9dHlwZW9mIHIpdGhyb3cgbmV3IFR5cGVFcnJvcigiY2VudGVyIG11c3QgYmUgYSBudW1iZXIiKTtyZXR1cm4gZnVuY3Rpb24odCxlKXtmb3IobGV0IHI9MDtyPHQucm93cztyKyspZm9yKGxldCBvPTA7bzx0LmNvbHVtbnM7bysrKXQuc2V0KHIsbyx0LmdldChyLG8pLWUpfSh0aGlzLHIpLHRoaXM7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgb3B0aW9uOiAke3R9YCl9fXNjYWxlKHQsZT17fSl7aWYoIm9iamVjdCI9PXR5cGVvZiB0JiYoZT10LHQ9dm9pZCAwKSwib2JqZWN0IiE9dHlwZW9mIGUpdGhyb3cgbmV3IFR5cGVFcnJvcigib3B0aW9ucyBtdXN0IGJlIGFuIG9iamVjdCIpO2xldCByPWUuc2NhbGU7c3dpdGNoKHQpe2Nhc2Uicm93IjppZih2b2lkIDA9PT1yKXI9ZnVuY3Rpb24odCl7Y29uc3QgZT1bXTtmb3IobGV0IHI9MDtyPHQucm93cztyKyspe2xldCBvPTA7Zm9yKGxldCBlPTA7ZTx0LmNvbHVtbnM7ZSsrKW8rPU1hdGgucG93KHQuZ2V0KHIsZSksMikvKHQuY29sdW1ucy0xKTtlLnB1c2goTWF0aC5zcXJ0KG8pKX1yZXR1cm4gZX0odGhpcyk7ZWxzZSBpZighQXJyYXkuaXNBcnJheShyKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJzY2FsZSBtdXN0IGJlIGFuIGFycmF5Iik7cmV0dXJuIGZ1bmN0aW9uKHQsZSl7Zm9yKGxldCByPTA7cjx0LnJvd3M7cisrKWZvcihsZXQgbz0wO288dC5jb2x1bW5zO28rKyl0LnNldChyLG8sdC5nZXQocixvKS9lW3JdKX0odGhpcyxyKSx0aGlzO2Nhc2UiY29sdW1uIjppZih2b2lkIDA9PT1yKXI9ZnVuY3Rpb24odCl7Y29uc3QgZT1bXTtmb3IobGV0IHI9MDtyPHQuY29sdW1ucztyKyspe2xldCBvPTA7Zm9yKGxldCBlPTA7ZTx0LnJvd3M7ZSsrKW8rPU1hdGgucG93KHQuZ2V0KGUsciksMikvKHQucm93cy0xKTtlLnB1c2goTWF0aC5zcXJ0KG8pKX1yZXR1cm4gZX0odGhpcyk7ZWxzZSBpZighQXJyYXkuaXNBcnJheShyKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJzY2FsZSBtdXN0IGJlIGFuIGFycmF5Iik7cmV0dXJuIGZ1bmN0aW9uKHQsZSl7Zm9yKGxldCByPTA7cjx0LnJvd3M7cisrKWZvcihsZXQgbz0wO288dC5jb2x1bW5zO28rKyl0LnNldChyLG8sdC5nZXQocixvKS9lW29dKX0odGhpcyxyKSx0aGlzO2Nhc2Ugdm9pZCAwOmlmKHZvaWQgMD09PXIpcj1mdW5jdGlvbih0KXtjb25zdCBlPXQuc2l6ZS0xO2xldCByPTA7Zm9yKGxldCBvPTA7bzx0LmNvbHVtbnM7bysrKWZvcihsZXQgbj0wO248dC5yb3dzO24rKylyKz1NYXRoLnBvdyh0LmdldChuLG8pLDIpL2U7cmV0dXJuIE1hdGguc3FydChyKX0odGhpcyk7ZWxzZSBpZigibnVtYmVyIiE9dHlwZW9mIHIpdGhyb3cgbmV3IFR5cGVFcnJvcigic2NhbGUgbXVzdCBiZSBhIG51bWJlciIpO3JldHVybiBmdW5jdGlvbih0LGUpe2ZvcihsZXQgcj0wO3I8dC5yb3dzO3IrKylmb3IobGV0IG89MDtvPHQuY29sdW1ucztvKyspdC5zZXQocixvLHQuZ2V0KHIsbykvZSl9KHRoaXMsciksdGhpcztkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgaW52YWxpZCBvcHRpb246ICR7dH1gKX19dG9TdHJpbmcodCl7cmV0dXJuIHZlKHRoaXMsdCl9fWZ1bmN0aW9uIE9lKHQsZSl7cmV0dXJuIHQtZX1OZS5wcm90b3R5cGUua2xhc3M9Ik1hdHJpeCIsInVuZGVmaW5lZCIhPXR5cGVvZiBTeW1ib2wmJihOZS5wcm90b3R5cGVbU3ltYm9sLmZvcigibm9kZWpzLnV0aWwuaW5zcGVjdC5jdXN0b20iKV09ZnVuY3Rpb24oKXtyZXR1cm4gdmUodGhpcyl9KSxOZS5yYW5kb209TmUucmFuZCxOZS5yYW5kb21JbnQ9TmUucmFuZEludCxOZS5kaWFnb25hbD1OZS5kaWFnLE5lLnByb3RvdHlwZS5kaWFnb25hbD1OZS5wcm90b3R5cGUuZGlhZyxOZS5pZGVudGl0eT1OZS5leWUsTmUucHJvdG90eXBlLm5lZ2F0ZT1OZS5wcm90b3R5cGUubmVnLE5lLnByb3RvdHlwZS50ZW5zb3JQcm9kdWN0PU5lLnByb3RvdHlwZS5rcm9uZWNrZXJQcm9kdWN0O2NsYXNzIEZlIGV4dGVuZHMgTmV7Y29uc3RydWN0b3IodCxlKXtpZihzdXBlcigpLEZlLmlzTWF0cml4KHQpKXJldHVybiB0LmNsb25lKCk7aWYoTnVtYmVyLmlzSW50ZWdlcih0KSYmdD49MCl7aWYodGhpcy5kYXRhPVtdLCEoTnVtYmVyLmlzSW50ZWdlcihlKSYmZT49MCkpdGhyb3cgbmV3IFR5cGVFcnJvcigibkNvbHVtbnMgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIiKTtmb3IobGV0IHI9MDtyPHQ7cisrKXRoaXMuZGF0YS5wdXNoKG5ldyBGbG9hdDY0QXJyYXkoZSkpfWVsc2V7aWYoIUFycmF5LmlzQXJyYXkodCkpdGhyb3cgbmV3IFR5cGVFcnJvcigiRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlciBvciBhbiBhcnJheSIpO3tjb25zdCByPXQ7aWYoIm51bWJlciIhPXR5cGVvZihlPSh0PXIubGVuZ3RoKT9yWzBdLmxlbmd0aDowKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJEYXRhIG11c3QgYmUgYSAyRCBhcnJheSB3aXRoIGF0IGxlYXN0IG9uZSBlbGVtZW50Iik7dGhpcy5kYXRhPVtdO2ZvcihsZXQgbz0wO288dDtvKyspe2lmKHJbb10ubGVuZ3RoIT09ZSl0aHJvdyBuZXcgUmFuZ2VFcnJvcigiSW5jb25zaXN0ZW50IGFycmF5IGRpbWVuc2lvbnMiKTt0aGlzLmRhdGEucHVzaChGbG9hdDY0QXJyYXkuZnJvbShyW29dKSl9fX10aGlzLnJvd3M9dCx0aGlzLmNvbHVtbnM9ZX1zZXQodCxlLHIpe3JldHVybiB0aGlzLmRhdGFbdF1bZV09cix0aGlzfWdldCh0LGUpe3JldHVybiB0aGlzLmRhdGFbdF1bZV19cmVtb3ZlUm93KHQpe3JldHVybiB4ZSh0aGlzLHQpLHRoaXMuZGF0YS5zcGxpY2UodCwxKSx0aGlzLnJvd3MtPTEsdGhpc31hZGRSb3codCxlKXtyZXR1cm4gdm9pZCAwPT09ZSYmKGU9dCx0PXRoaXMucm93cykseGUodGhpcyx0LCEwKSxlPUZsb2F0NjRBcnJheS5mcm9tKFNlKHRoaXMsZSkpLHRoaXMuZGF0YS5zcGxpY2UodCwwLGUpLHRoaXMucm93cys9MSx0aGlzfXJlbW92ZUNvbHVtbih0KXtFZSh0aGlzLHQpO2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKyl7Y29uc3Qgcj1uZXcgRmxvYXQ2NEFycmF5KHRoaXMuY29sdW1ucy0xKTtmb3IobGV0IG89MDtvPHQ7bysrKXJbb109dGhpcy5kYXRhW2VdW29dO2ZvcihsZXQgbz10KzE7bzx0aGlzLmNvbHVtbnM7bysrKXJbby0xXT10aGlzLmRhdGFbZV1bb107dGhpcy5kYXRhW2VdPXJ9cmV0dXJuIHRoaXMuY29sdW1ucy09MSx0aGlzfWFkZENvbHVtbih0LGUpe3ZvaWQgMD09PWUmJihlPXQsdD10aGlzLmNvbHVtbnMpLEVlKHRoaXMsdCwhMCksZT1qZSh0aGlzLGUpO2ZvcihsZXQgcj0wO3I8dGhpcy5yb3dzO3IrKyl7Y29uc3Qgbz1uZXcgRmxvYXQ2NEFycmF5KHRoaXMuY29sdW1ucysxKTtsZXQgbj0wO2Zvcig7bjx0O24rKylvW25dPXRoaXMuZGF0YVtyXVtuXTtmb3Iob1tuKytdPWVbcl07bjx0aGlzLmNvbHVtbnMrMTtuKyspb1tuXT10aGlzLmRhdGFbcl1bbi0xXTt0aGlzLmRhdGFbcl09b31yZXR1cm4gdGhpcy5jb2x1bW5zKz0xLHRoaXN9fSFmdW5jdGlvbih0LGUpe3QucHJvdG90eXBlLmFkZD1mdW5jdGlvbih0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/dGhpcy5hZGRTKHQpOnRoaXMuYWRkTSh0KX0sdC5wcm90b3R5cGUuYWRkUz1mdW5jdGlvbih0KXtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpK3QpO3JldHVybiB0aGlzfSx0LnByb3RvdHlwZS5hZGRNPWZ1bmN0aW9uKHQpe2lmKHQ9ZS5jaGVja01hdHJpeCh0KSx0aGlzLnJvd3MhPT10LnJvd3N8fHRoaXMuY29sdW1ucyE9PXQuY29sdW1ucyl0aHJvdyBuZXcgUmFuZ2VFcnJvcigiTWF0cmljZXMgZGltZW5zaW9ucyBtdXN0IGJlIGVxdWFsIik7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldChlLHIsdGhpcy5nZXQoZSxyKSt0LmdldChlLHIpKTtyZXR1cm4gdGhpc30sdC5hZGQ9ZnVuY3Rpb24odCxyKXtyZXR1cm4gbmV3IGUodCkuYWRkKHIpfSx0LnByb3RvdHlwZS5zdWI9ZnVuY3Rpb24odCl7cmV0dXJuIm51bWJlciI9PXR5cGVvZiB0P3RoaXMuc3ViUyh0KTp0aGlzLnN1Yk0odCl9LHQucHJvdG90eXBlLnN1YlM9ZnVuY3Rpb24odCl7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldChlLHIsdGhpcy5nZXQoZSxyKS10KTtyZXR1cm4gdGhpc30sdC5wcm90b3R5cGUuc3ViTT1mdW5jdGlvbih0KXtpZih0PWUuY2hlY2tNYXRyaXgodCksdGhpcy5yb3dzIT09dC5yb3dzfHx0aGlzLmNvbHVtbnMhPT10LmNvbHVtbnMpdGhyb3cgbmV3IFJhbmdlRXJyb3IoIk1hdHJpY2VzIGRpbWVuc2lvbnMgbXVzdCBiZSBlcXVhbCIpO2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUsciktdC5nZXQoZSxyKSk7cmV0dXJuIHRoaXN9LHQuc3ViPWZ1bmN0aW9uKHQscil7cmV0dXJuIG5ldyBlKHQpLnN1YihyKX0sdC5wcm90b3R5cGUuc3VidHJhY3Q9dC5wcm90b3R5cGUuc3ViLHQucHJvdG90eXBlLnN1YnRyYWN0Uz10LnByb3RvdHlwZS5zdWJTLHQucHJvdG90eXBlLnN1YnRyYWN0TT10LnByb3RvdHlwZS5zdWJNLHQuc3VidHJhY3Q9dC5zdWIsdC5wcm90b3R5cGUubXVsPWZ1bmN0aW9uKHQpe3JldHVybiJudW1iZXIiPT10eXBlb2YgdD90aGlzLm11bFModCk6dGhpcy5tdWxNKHQpfSx0LnByb3RvdHlwZS5tdWxTPWZ1bmN0aW9uKHQpe2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUscikqdCk7cmV0dXJuIHRoaXN9LHQucHJvdG90eXBlLm11bE09ZnVuY3Rpb24odCl7aWYodD1lLmNoZWNrTWF0cml4KHQpLHRoaXMucm93cyE9PXQucm93c3x8dGhpcy5jb2x1bW5zIT09dC5jb2x1bW5zKXRocm93IG5ldyBSYW5nZUVycm9yKCJNYXRyaWNlcyBkaW1lbnNpb25zIG11c3QgYmUgZXF1YWwiKTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpKnQuZ2V0KGUscikpO3JldHVybiB0aGlzfSx0Lm11bD1mdW5jdGlvbih0LHIpe3JldHVybiBuZXcgZSh0KS5tdWwocil9LHQucHJvdG90eXBlLm11bHRpcGx5PXQucHJvdG90eXBlLm11bCx0LnByb3RvdHlwZS5tdWx0aXBseVM9dC5wcm90b3R5cGUubXVsUyx0LnByb3RvdHlwZS5tdWx0aXBseU09dC5wcm90b3R5cGUubXVsTSx0Lm11bHRpcGx5PXQubXVsLHQucHJvdG90eXBlLmRpdj1mdW5jdGlvbih0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/dGhpcy5kaXZTKHQpOnRoaXMuZGl2TSh0KX0sdC5wcm90b3R5cGUuZGl2Uz1mdW5jdGlvbih0KXtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpL3QpO3JldHVybiB0aGlzfSx0LnByb3RvdHlwZS5kaXZNPWZ1bmN0aW9uKHQpe2lmKHQ9ZS5jaGVja01hdHJpeCh0KSx0aGlzLnJvd3MhPT10LnJvd3N8fHRoaXMuY29sdW1ucyE9PXQuY29sdW1ucyl0aHJvdyBuZXcgUmFuZ2VFcnJvcigiTWF0cmljZXMgZGltZW5zaW9ucyBtdXN0IGJlIGVxdWFsIik7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldChlLHIsdGhpcy5nZXQoZSxyKS90LmdldChlLHIpKTtyZXR1cm4gdGhpc30sdC5kaXY9ZnVuY3Rpb24odCxyKXtyZXR1cm4gbmV3IGUodCkuZGl2KHIpfSx0LnByb3RvdHlwZS5kaXZpZGU9dC5wcm90b3R5cGUuZGl2LHQucHJvdG90eXBlLmRpdmlkZVM9dC5wcm90b3R5cGUuZGl2Uyx0LnByb3RvdHlwZS5kaXZpZGVNPXQucHJvdG90eXBlLmRpdk0sdC5kaXZpZGU9dC5kaXYsdC5wcm90b3R5cGUubW9kPWZ1bmN0aW9uKHQpe3JldHVybiJudW1iZXIiPT10eXBlb2YgdD90aGlzLm1vZFModCk6dGhpcy5tb2RNKHQpfSx0LnByb3RvdHlwZS5tb2RTPWZ1bmN0aW9uKHQpe2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUscikldCk7cmV0dXJuIHRoaXN9LHQucHJvdG90eXBlLm1vZE09ZnVuY3Rpb24odCl7aWYodD1lLmNoZWNrTWF0cml4KHQpLHRoaXMucm93cyE9PXQucm93c3x8dGhpcy5jb2x1bW5zIT09dC5jb2x1bW5zKXRocm93IG5ldyBSYW5nZUVycm9yKCJNYXRyaWNlcyBkaW1lbnNpb25zIG11c3QgYmUgZXF1YWwiKTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpJXQuZ2V0KGUscikpO3JldHVybiB0aGlzfSx0Lm1vZD1mdW5jdGlvbih0LHIpe3JldHVybiBuZXcgZSh0KS5tb2Qocil9LHQucHJvdG90eXBlLm1vZHVsdXM9dC5wcm90b3R5cGUubW9kLHQucHJvdG90eXBlLm1vZHVsdXNTPXQucHJvdG90eXBlLm1vZFMsdC5wcm90b3R5cGUubW9kdWx1c009dC5wcm90b3R5cGUubW9kTSx0Lm1vZHVsdXM9dC5tb2QsdC5wcm90b3R5cGUuYW5kPWZ1bmN0aW9uKHQpe3JldHVybiJudW1iZXIiPT10eXBlb2YgdD90aGlzLmFuZFModCk6dGhpcy5hbmRNKHQpfSx0LnByb3RvdHlwZS5hbmRTPWZ1bmN0aW9uKHQpe2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUscikmdCk7cmV0dXJuIHRoaXN9LHQucHJvdG90eXBlLmFuZE09ZnVuY3Rpb24odCl7aWYodD1lLmNoZWNrTWF0cml4KHQpLHRoaXMucm93cyE9PXQucm93c3x8dGhpcy5jb2x1bW5zIT09dC5jb2x1bW5zKXRocm93IG5ldyBSYW5nZUVycm9yKCJNYXRyaWNlcyBkaW1lbnNpb25zIG11c3QgYmUgZXF1YWwiKTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpJnQuZ2V0KGUscikpO3JldHVybiB0aGlzfSx0LmFuZD1mdW5jdGlvbih0LHIpe3JldHVybiBuZXcgZSh0KS5hbmQocil9LHQucHJvdG90eXBlLm9yPWZ1bmN0aW9uKHQpe3JldHVybiJudW1iZXIiPT10eXBlb2YgdD90aGlzLm9yUyh0KTp0aGlzLm9yTSh0KX0sdC5wcm90b3R5cGUub3JTPWZ1bmN0aW9uKHQpe2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUscil8dCk7cmV0dXJuIHRoaXN9LHQucHJvdG90eXBlLm9yTT1mdW5jdGlvbih0KXtpZih0PWUuY2hlY2tNYXRyaXgodCksdGhpcy5yb3dzIT09dC5yb3dzfHx0aGlzLmNvbHVtbnMhPT10LmNvbHVtbnMpdGhyb3cgbmV3IFJhbmdlRXJyb3IoIk1hdHJpY2VzIGRpbWVuc2lvbnMgbXVzdCBiZSBlcXVhbCIpO2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUscil8dC5nZXQoZSxyKSk7cmV0dXJuIHRoaXN9LHQub3I9ZnVuY3Rpb24odCxyKXtyZXR1cm4gbmV3IGUodCkub3Iocil9LHQucHJvdG90eXBlLnhvcj1mdW5jdGlvbih0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/dGhpcy54b3JTKHQpOnRoaXMueG9yTSh0KX0sdC5wcm90b3R5cGUueG9yUz1mdW5jdGlvbih0KXtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpXnQpO3JldHVybiB0aGlzfSx0LnByb3RvdHlwZS54b3JNPWZ1bmN0aW9uKHQpe2lmKHQ9ZS5jaGVja01hdHJpeCh0KSx0aGlzLnJvd3MhPT10LnJvd3N8fHRoaXMuY29sdW1ucyE9PXQuY29sdW1ucyl0aHJvdyBuZXcgUmFuZ2VFcnJvcigiTWF0cmljZXMgZGltZW5zaW9ucyBtdXN0IGJlIGVxdWFsIik7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldChlLHIsdGhpcy5nZXQoZSxyKV50LmdldChlLHIpKTtyZXR1cm4gdGhpc30sdC54b3I9ZnVuY3Rpb24odCxyKXtyZXR1cm4gbmV3IGUodCkueG9yKHIpfSx0LnByb3RvdHlwZS5sZWZ0U2hpZnQ9ZnVuY3Rpb24odCl7cmV0dXJuIm51bWJlciI9PXR5cGVvZiB0P3RoaXMubGVmdFNoaWZ0Uyh0KTp0aGlzLmxlZnRTaGlmdE0odCl9LHQucHJvdG90eXBlLmxlZnRTaGlmdFM9ZnVuY3Rpb24odCl7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldChlLHIsdGhpcy5nZXQoZSxyKTw8dCk7cmV0dXJuIHRoaXN9LHQucHJvdG90eXBlLmxlZnRTaGlmdE09ZnVuY3Rpb24odCl7aWYodD1lLmNoZWNrTWF0cml4KHQpLHRoaXMucm93cyE9PXQucm93c3x8dGhpcy5jb2x1bW5zIT09dC5jb2x1bW5zKXRocm93IG5ldyBSYW5nZUVycm9yKCJNYXRyaWNlcyBkaW1lbnNpb25zIG11c3QgYmUgZXF1YWwiKTtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpPDx0LmdldChlLHIpKTtyZXR1cm4gdGhpc30sdC5sZWZ0U2hpZnQ9ZnVuY3Rpb24odCxyKXtyZXR1cm4gbmV3IGUodCkubGVmdFNoaWZ0KHIpfSx0LnByb3RvdHlwZS5zaWduUHJvcGFnYXRpbmdSaWdodFNoaWZ0PWZ1bmN0aW9uKHQpe3JldHVybiJudW1iZXIiPT10eXBlb2YgdD90aGlzLnNpZ25Qcm9wYWdhdGluZ1JpZ2h0U2hpZnRTKHQpOnRoaXMuc2lnblByb3BhZ2F0aW5nUmlnaHRTaGlmdE0odCl9LHQucHJvdG90eXBlLnNpZ25Qcm9wYWdhdGluZ1JpZ2h0U2hpZnRTPWZ1bmN0aW9uKHQpe2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUscik+PnQpO3JldHVybiB0aGlzfSx0LnByb3RvdHlwZS5zaWduUHJvcGFnYXRpbmdSaWdodFNoaWZ0TT1mdW5jdGlvbih0KXtpZih0PWUuY2hlY2tNYXRyaXgodCksdGhpcy5yb3dzIT09dC5yb3dzfHx0aGlzLmNvbHVtbnMhPT10LmNvbHVtbnMpdGhyb3cgbmV3IFJhbmdlRXJyb3IoIk1hdHJpY2VzIGRpbWVuc2lvbnMgbXVzdCBiZSBlcXVhbCIpO2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLHRoaXMuZ2V0KGUscik+PnQuZ2V0KGUscikpO3JldHVybiB0aGlzfSx0LnNpZ25Qcm9wYWdhdGluZ1JpZ2h0U2hpZnQ9ZnVuY3Rpb24odCxyKXtyZXR1cm4gbmV3IGUodCkuc2lnblByb3BhZ2F0aW5nUmlnaHRTaGlmdChyKX0sdC5wcm90b3R5cGUucmlnaHRTaGlmdD1mdW5jdGlvbih0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/dGhpcy5yaWdodFNoaWZ0Uyh0KTp0aGlzLnJpZ2h0U2hpZnRNKHQpfSx0LnByb3RvdHlwZS5yaWdodFNoaWZ0Uz1mdW5jdGlvbih0KXtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscix0aGlzLmdldChlLHIpPj4+dCk7cmV0dXJuIHRoaXN9LHQucHJvdG90eXBlLnJpZ2h0U2hpZnRNPWZ1bmN0aW9uKHQpe2lmKHQ9ZS5jaGVja01hdHJpeCh0KSx0aGlzLnJvd3MhPT10LnJvd3N8fHRoaXMuY29sdW1ucyE9PXQuY29sdW1ucyl0aHJvdyBuZXcgUmFuZ2VFcnJvcigiTWF0cmljZXMgZGltZW5zaW9ucyBtdXN0IGJlIGVxdWFsIik7Zm9yKGxldCBlPTA7ZTx0aGlzLnJvd3M7ZSsrKWZvcihsZXQgcj0wO3I8dGhpcy5jb2x1bW5zO3IrKyl0aGlzLnNldChlLHIsdGhpcy5nZXQoZSxyKT4+PnQuZ2V0KGUscikpO3JldHVybiB0aGlzfSx0LnJpZ2h0U2hpZnQ9ZnVuY3Rpb24odCxyKXtyZXR1cm4gbmV3IGUodCkucmlnaHRTaGlmdChyKX0sdC5wcm90b3R5cGUuemVyb0ZpbGxSaWdodFNoaWZ0PXQucHJvdG90eXBlLnJpZ2h0U2hpZnQsdC5wcm90b3R5cGUuemVyb0ZpbGxSaWdodFNoaWZ0Uz10LnByb3RvdHlwZS5yaWdodFNoaWZ0Uyx0LnByb3RvdHlwZS56ZXJvRmlsbFJpZ2h0U2hpZnRNPXQucHJvdG90eXBlLnJpZ2h0U2hpZnRNLHQuemVyb0ZpbGxSaWdodFNoaWZ0PXQucmlnaHRTaGlmdCx0LnByb3RvdHlwZS5ub3Q9ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSx+dGhpcy5nZXQodCxlKSk7cmV0dXJuIHRoaXN9LHQubm90PWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS5ub3QoKX0sdC5wcm90b3R5cGUuYWJzPWZ1bmN0aW9uKCl7Zm9yKGxldCB0PTA7dDx0aGlzLnJvd3M7dCsrKWZvcihsZXQgZT0wO2U8dGhpcy5jb2x1bW5zO2UrKyl0aGlzLnNldCh0LGUsTWF0aC5hYnModGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LmFicz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuYWJzKCl9LHQucHJvdG90eXBlLmFjb3M9ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLmFjb3ModGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LmFjb3M9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBlKHQpLmFjb3MoKX0sdC5wcm90b3R5cGUuYWNvc2g9ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLmFjb3NoKHRoaXMuZ2V0KHQsZSkpKTtyZXR1cm4gdGhpc30sdC5hY29zaD1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuYWNvc2goKX0sdC5wcm90b3R5cGUuYXNpbj1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGguYXNpbih0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQuYXNpbj1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuYXNpbigpfSx0LnByb3RvdHlwZS5hc2luaD1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGguYXNpbmgodGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LmFzaW5oPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS5hc2luaCgpfSx0LnByb3RvdHlwZS5hdGFuPWZ1bmN0aW9uKCl7Zm9yKGxldCB0PTA7dDx0aGlzLnJvd3M7dCsrKWZvcihsZXQgZT0wO2U8dGhpcy5jb2x1bW5zO2UrKyl0aGlzLnNldCh0LGUsTWF0aC5hdGFuKHRoaXMuZ2V0KHQsZSkpKTtyZXR1cm4gdGhpc30sdC5hdGFuPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS5hdGFuKCl9LHQucHJvdG90eXBlLmF0YW5oPWZ1bmN0aW9uKCl7Zm9yKGxldCB0PTA7dDx0aGlzLnJvd3M7dCsrKWZvcihsZXQgZT0wO2U8dGhpcy5jb2x1bW5zO2UrKyl0aGlzLnNldCh0LGUsTWF0aC5hdGFuaCh0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQuYXRhbmg9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBlKHQpLmF0YW5oKCl9LHQucHJvdG90eXBlLmNicnQ9ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLmNicnQodGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LmNicnQ9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBlKHQpLmNicnQoKX0sdC5wcm90b3R5cGUuY2VpbD1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGguY2VpbCh0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQuY2VpbD1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuY2VpbCgpfSx0LnByb3RvdHlwZS5jbHozMj1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGguY2x6MzIodGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LmNsejMyPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS5jbHozMigpfSx0LnByb3RvdHlwZS5jb3M9ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLmNvcyh0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQuY29zPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS5jb3MoKX0sdC5wcm90b3R5cGUuY29zaD1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGguY29zaCh0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQuY29zaD1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuY29zaCgpfSx0LnByb3RvdHlwZS5leHA9ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLmV4cCh0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQuZXhwPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS5leHAoKX0sdC5wcm90b3R5cGUuZXhwbTE9ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLmV4cG0xKHRoaXMuZ2V0KHQsZSkpKTtyZXR1cm4gdGhpc30sdC5leHBtMT1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuZXhwbTEoKX0sdC5wcm90b3R5cGUuZmxvb3I9ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLmZsb29yKHRoaXMuZ2V0KHQsZSkpKTtyZXR1cm4gdGhpc30sdC5mbG9vcj1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuZmxvb3IoKX0sdC5wcm90b3R5cGUuZnJvdW5kPWZ1bmN0aW9uKCl7Zm9yKGxldCB0PTA7dDx0aGlzLnJvd3M7dCsrKWZvcihsZXQgZT0wO2U8dGhpcy5jb2x1bW5zO2UrKyl0aGlzLnNldCh0LGUsTWF0aC5mcm91bmQodGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LmZyb3VuZD1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuZnJvdW5kKCl9LHQucHJvdG90eXBlLmxvZz1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGgubG9nKHRoaXMuZ2V0KHQsZSkpKTtyZXR1cm4gdGhpc30sdC5sb2c9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBlKHQpLmxvZygpfSx0LnByb3RvdHlwZS5sb2cxcD1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGgubG9nMXAodGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LmxvZzFwPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS5sb2cxcCgpfSx0LnByb3RvdHlwZS5sb2cxMD1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGgubG9nMTAodGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LmxvZzEwPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS5sb2cxMCgpfSx0LnByb3RvdHlwZS5sb2cyPWZ1bmN0aW9uKCl7Zm9yKGxldCB0PTA7dDx0aGlzLnJvd3M7dCsrKWZvcihsZXQgZT0wO2U8dGhpcy5jb2x1bW5zO2UrKyl0aGlzLnNldCh0LGUsTWF0aC5sb2cyKHRoaXMuZ2V0KHQsZSkpKTtyZXR1cm4gdGhpc30sdC5sb2cyPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS5sb2cyKCl9LHQucHJvdG90eXBlLnJvdW5kPWZ1bmN0aW9uKCl7Zm9yKGxldCB0PTA7dDx0aGlzLnJvd3M7dCsrKWZvcihsZXQgZT0wO2U8dGhpcy5jb2x1bW5zO2UrKyl0aGlzLnNldCh0LGUsTWF0aC5yb3VuZCh0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQucm91bmQ9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBlKHQpLnJvdW5kKCl9LHQucHJvdG90eXBlLnNpZ249ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLnNpZ24odGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LnNpZ249ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBlKHQpLnNpZ24oKX0sdC5wcm90b3R5cGUuc2luPWZ1bmN0aW9uKCl7Zm9yKGxldCB0PTA7dDx0aGlzLnJvd3M7dCsrKWZvcihsZXQgZT0wO2U8dGhpcy5jb2x1bW5zO2UrKyl0aGlzLnNldCh0LGUsTWF0aC5zaW4odGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LnNpbj1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuc2luKCl9LHQucHJvdG90eXBlLnNpbmg9ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLnNpbmgodGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LnNpbmg9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBlKHQpLnNpbmgoKX0sdC5wcm90b3R5cGUuc3FydD1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGguc3FydCh0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQuc3FydD1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkuc3FydCgpfSx0LnByb3RvdHlwZS50YW49ZnVuY3Rpb24oKXtmb3IobGV0IHQ9MDt0PHRoaXMucm93czt0KyspZm9yKGxldCBlPTA7ZTx0aGlzLmNvbHVtbnM7ZSsrKXRoaXMuc2V0KHQsZSxNYXRoLnRhbih0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQudGFuPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS50YW4oKX0sdC5wcm90b3R5cGUudGFuaD1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGgudGFuaCh0aGlzLmdldCh0LGUpKSk7cmV0dXJuIHRoaXN9LHQudGFuaD1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IGUodCkudGFuaCgpfSx0LnByb3RvdHlwZS50cnVuYz1mdW5jdGlvbigpe2ZvcihsZXQgdD0wO3Q8dGhpcy5yb3dzO3QrKylmb3IobGV0IGU9MDtlPHRoaXMuY29sdW1ucztlKyspdGhpcy5zZXQodCxlLE1hdGgudHJ1bmModGhpcy5nZXQodCxlKSkpO3JldHVybiB0aGlzfSx0LnRydW5jPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgZSh0KS50cnVuYygpfSx0LnBvdz1mdW5jdGlvbih0LHIpe3JldHVybiBuZXcgZSh0KS5wb3cocil9LHQucHJvdG90eXBlLnBvdz1mdW5jdGlvbih0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/dGhpcy5wb3dTKHQpOnRoaXMucG93TSh0KX0sdC5wcm90b3R5cGUucG93Uz1mdW5jdGlvbih0KXtmb3IobGV0IGU9MDtlPHRoaXMucm93cztlKyspZm9yKGxldCByPTA7cjx0aGlzLmNvbHVtbnM7cisrKXRoaXMuc2V0KGUscixNYXRoLnBvdyh0aGlzLmdldChlLHIpLHQpKTtyZXR1cm4gdGhpc30sdC5wcm90b3R5cGUucG93TT1mdW5jdGlvbih0KXtpZih0PWUuY2hlY2tNYXRyaXgodCksdGhpcy5yb3dzIT09dC5yb3dzfHx0aGlzLmNvbHVtbnMhPT10LmNvbHVtbnMpdGhyb3cgbmV3IFJhbmdlRXJyb3IoIk1hdHJpY2VzIGRpbWVuc2lvbnMgbXVzdCBiZSBlcXVhbCIpO2ZvcihsZXQgZT0wO2U8dGhpcy5yb3dzO2UrKylmb3IobGV0IHI9MDtyPHRoaXMuY29sdW1ucztyKyspdGhpcy5zZXQoZSxyLE1hdGgucG93KHRoaXMuZ2V0KGUsciksdC5nZXQoZSxyKSkpO3JldHVybiB0aGlzfX0oTmUsRmUpO2NsYXNzIHplIGV4dGVuZHMgTmV7Y29uc3RydWN0b3IodCxlLHIpe3N1cGVyKCksdGhpcy5tYXRyaXg9dCx0aGlzLnJvd3M9ZSx0aGlzLmNvbHVtbnM9cn19Y2xhc3MgVGUgZXh0ZW5kcyB6ZXtjb25zdHJ1Y3Rvcih0KXtzdXBlcih0LHQuY29sdW1ucyx0LnJvd3MpfXNldCh0LGUscil7cmV0dXJuIHRoaXMubWF0cml4LnNldChlLHQsciksdGhpc31nZXQodCxlKXtyZXR1cm4gdGhpcy5tYXRyaXguZ2V0KGUsdCl9fWNsYXNzIFZlIGV4dGVuZHMgTmV7Y29uc3RydWN0b3IodCl7c3VwZXIoKSx0aGlzLmRhdGE9dCx0aGlzLnJvd3M9dC5sZW5ndGgsdGhpcy5jb2x1bW5zPXRbMF0ubGVuZ3RofXNldCh0LGUscil7cmV0dXJuIHRoaXMuZGF0YVt0XVtlXT1yLHRoaXN9Z2V0KHQsZSl7cmV0dXJuIHRoaXMuZGF0YVt0XVtlXX19ZnVuY3Rpb24gUGUodCxlKXtsZXQgcj0wO3JldHVybiBNYXRoLmFicyh0KT5NYXRoLmFicyhlKT8ocj1lL3QsTWF0aC5hYnModCkqTWF0aC5zcXJ0KDErcipyKSk6MCE9PWU/KHI9dC9lLE1hdGguYWJzKGUpKk1hdGguc3FydCgxK3IqcikpOjB9Y2xhc3MgcWV7Y29uc3RydWN0b3IodCxlPXt9KXtpZigodD1WZS5jaGVja01hdHJpeCh0KSkuaXNFbXB0eSgpKXRocm93IG5ldyBFcnJvcigiTWF0cml4IG11c3QgYmUgbm9uLWVtcHR5Iik7bGV0IHI9dC5yb3dzLG89dC5jb2x1bW5zO2NvbnN0e2NvbXB1dGVMZWZ0U2luZ3VsYXJWZWN0b3JzOm49ITAsY29tcHV0ZVJpZ2h0U2luZ3VsYXJWZWN0b3JzOnM9ITAsYXV0b1RyYW5zcG9zZTppPSExfT1lO2xldCB1LGE9Qm9vbGVhbihuKSxoPUJvb2xlYW4ocyksbD0hMTtpZihyPG8paWYoaSl7dT10LnRyYW5zcG9zZSgpLHI9dS5yb3dzLG89dS5jb2x1bW5zLGw9ITA7bGV0IGU9YTthPWgsaD1lfWVsc2UgdT10LmNsb25lKCksY29uc29sZS53YXJuKCJDb21wdXRpbmcgU1ZEIG9uIGEgbWF0cml4IHdpdGggbW9yZSBjb2x1bW5zIHRoYW4gcm93cy4gQ29uc2lkZXIgZW5hYmxpbmcgYXV0b1RyYW5zcG9zZSIpO2Vsc2UgdT10LmNsb25lKCk7bGV0IGM9TWF0aC5taW4ocixvKSxmPU1hdGgubWluKHIrMSxvKSxtPW5ldyBGbG9hdDY0QXJyYXkoZiksZz1uZXcgRmUocixjKSxwPW5ldyBGZShvLG8pLHc9bmV3IEZsb2F0NjRBcnJheShvKSxkPW5ldyBGbG9hdDY0QXJyYXkociksYj1uZXcgRmxvYXQ2NEFycmF5KGYpO2ZvcihsZXQgdD0wO3Q8Zjt0KyspYlt0XT10O2xldCB5PU1hdGgubWluKHItMSxvKSx2PU1hdGgubWF4KDAsTWF0aC5taW4oby0yLHIpKSxNPU1hdGgubWF4KHksdik7Zm9yKGxldCB0PTA7dDxNO3QrKyl7aWYodDx5KXttW3RdPTA7Zm9yKGxldCBlPXQ7ZTxyO2UrKyltW3RdPVBlKG1bdF0sdS5nZXQoZSx0KSk7aWYoMCE9PW1bdF0pe3UuZ2V0KHQsdCk8MCYmKG1bdF09LW1bdF0pO2ZvcihsZXQgZT10O2U8cjtlKyspdS5zZXQoZSx0LHUuZ2V0KGUsdCkvbVt0XSk7dS5zZXQodCx0LHUuZ2V0KHQsdCkrMSl9bVt0XT0tbVt0XX1mb3IobGV0IGU9dCsxO2U8bztlKyspe2lmKHQ8eSYmMCE9PW1bdF0pe2xldCBvPTA7Zm9yKGxldCBuPXQ7bjxyO24rKylvKz11LmdldChuLHQpKnUuZ2V0KG4sZSk7bz0tby91LmdldCh0LHQpO2ZvcihsZXQgbj10O248cjtuKyspdS5zZXQobixlLHUuZ2V0KG4sZSkrbyp1LmdldChuLHQpKX13W2VdPXUuZ2V0KHQsZSl9aWYoYSYmdDx5KWZvcihsZXQgZT10O2U8cjtlKyspZy5zZXQoZSx0LHUuZ2V0KGUsdCkpO2lmKHQ8dil7d1t0XT0wO2ZvcihsZXQgZT10KzE7ZTxvO2UrKyl3W3RdPVBlKHdbdF0sd1tlXSk7aWYoMCE9PXdbdF0pe3dbdCsxXTwwJiYod1t0XT0wLXdbdF0pO2ZvcihsZXQgZT10KzE7ZTxvO2UrKyl3W2VdLz13W3RdO3dbdCsxXSs9MX1pZih3W3RdPS13W3RdLHQrMTxyJiYwIT09d1t0XSl7Zm9yKGxldCBlPXQrMTtlPHI7ZSsrKWRbZV09MDtmb3IobGV0IGU9dCsxO2U8cjtlKyspZm9yKGxldCByPXQrMTtyPG87cisrKWRbZV0rPXdbcl0qdS5nZXQoZSxyKTtmb3IobGV0IGU9dCsxO2U8bztlKyspe2xldCBvPS13W2VdL3dbdCsxXTtmb3IobGV0IG49dCsxO248cjtuKyspdS5zZXQobixlLHUuZ2V0KG4sZSkrbypkW25dKX19aWYoaClmb3IobGV0IGU9dCsxO2U8bztlKyspcC5zZXQoZSx0LHdbZV0pfX1sZXQgeD1NYXRoLm1pbihvLHIrMSk7aWYoeTxvJiYobVt5XT11LmdldCh5LHkpKSxyPHgmJihtW3gtMV09MCksdisxPHgmJih3W3ZdPXUuZ2V0KHYseC0xKSksd1t4LTFdPTAsYSl7Zm9yKGxldCB0PXk7dDxjO3QrKyl7Zm9yKGxldCBlPTA7ZTxyO2UrKylnLnNldChlLHQsMCk7Zy5zZXQodCx0LDEpfWZvcihsZXQgdD15LTE7dD49MDt0LS0paWYoMCE9PW1bdF0pe2ZvcihsZXQgZT10KzE7ZTxjO2UrKyl7bGV0IG89MDtmb3IobGV0IG49dDtuPHI7bisrKW8rPWcuZ2V0KG4sdCkqZy5nZXQobixlKTtvPS1vL2cuZ2V0KHQsdCk7Zm9yKGxldCBuPXQ7bjxyO24rKylnLnNldChuLGUsZy5nZXQobixlKStvKmcuZ2V0KG4sdCkpfWZvcihsZXQgZT10O2U8cjtlKyspZy5zZXQoZSx0LC1nLmdldChlLHQpKTtnLnNldCh0LHQsMStnLmdldCh0LHQpKTtmb3IobGV0IGU9MDtlPHQtMTtlKyspZy5zZXQoZSx0LDApfWVsc2V7Zm9yKGxldCBlPTA7ZTxyO2UrKylnLnNldChlLHQsMCk7Zy5zZXQodCx0LDEpfX1pZihoKWZvcihsZXQgdD1vLTE7dD49MDt0LS0pe2lmKHQ8diYmMCE9PXdbdF0pZm9yKGxldCBlPXQrMTtlPG87ZSsrKXtsZXQgcj0wO2ZvcihsZXQgbj10KzE7bjxvO24rKylyKz1wLmdldChuLHQpKnAuZ2V0KG4sZSk7cj0tci9wLmdldCh0KzEsdCk7Zm9yKGxldCBuPXQrMTtuPG87bisrKXAuc2V0KG4sZSxwLmdldChuLGUpK3IqcC5nZXQobix0KSl9Zm9yKGxldCBlPTA7ZTxvO2UrKylwLnNldChlLHQsMCk7cC5zZXQodCx0LDEpfWxldCBFPXgtMSxTPU51bWJlci5FUFNJTE9OO2Zvcig7eD4wOyl7bGV0IHQsZTtmb3IodD14LTI7dD49LTEmJi0xIT09dDt0LS0pe2NvbnN0IGU9TnVtYmVyLk1JTl9WQUxVRStTKk1hdGguYWJzKG1bdF0rTWF0aC5hYnMobVt0KzFdKSk7aWYoTWF0aC5hYnMod1t0XSk8PWV8fE51bWJlci5pc05hTih3W3RdKSl7d1t0XT0wO2JyZWFrfX1pZih0PT09eC0yKWU9NDtlbHNle2xldCByO2ZvcihyPXgtMTtyPj10JiZyIT09dDtyLS0pe2xldCBlPShyIT09eD9NYXRoLmFicyh3W3JdKTowKSsociE9PXQrMT9NYXRoLmFicyh3W3ItMV0pOjApO2lmKE1hdGguYWJzKG1bcl0pPD1TKmUpe21bcl09MDticmVha319cj09PXQ/ZT0zOnI9PT14LTE/ZT0xOihlPTIsdD1yKX1zd2l0Y2godCsrLGUpe2Nhc2UgMTp7bGV0IGU9d1t4LTJdO3dbeC0yXT0wO2ZvcihsZXQgcj14LTI7cj49dDtyLS0pe2xldCBuPVBlKG1bcl0sZSkscz1tW3JdL24saT1lL247aWYobVtyXT1uLHIhPT10JiYoZT0taSp3W3ItMV0sd1tyLTFdPXMqd1tyLTFdKSxoKWZvcihsZXQgdD0wO3Q8bzt0Kyspbj1zKnAuZ2V0KHQscikraSpwLmdldCh0LHgtMSkscC5zZXQodCx4LTEsLWkqcC5nZXQodCxyKStzKnAuZ2V0KHQseC0xKSkscC5zZXQodCxyLG4pfWJyZWFrfWNhc2UgMjp7bGV0IGU9d1t0LTFdO3dbdC0xXT0wO2ZvcihsZXQgbz10O288eDtvKyspe2xldCBuPVBlKG1bb10sZSkscz1tW29dL24saT1lL247aWYobVtvXT1uLGU9LWkqd1tvXSx3W29dPXMqd1tvXSxhKWZvcihsZXQgZT0wO2U8cjtlKyspbj1zKmcuZ2V0KGUsbykraSpnLmdldChlLHQtMSksZy5zZXQoZSx0LTEsLWkqZy5nZXQoZSxvKStzKmcuZ2V0KGUsdC0xKSksZy5zZXQoZSxvLG4pfWJyZWFrfWNhc2UgMzp7Y29uc3QgZT1NYXRoLm1heChNYXRoLmFicyhtW3gtMV0pLE1hdGguYWJzKG1beC0yXSksTWF0aC5hYnMod1t4LTJdKSxNYXRoLmFicyhtW3RdKSxNYXRoLmFicyh3W3RdKSksbj1tW3gtMV0vZSxzPW1beC0yXS9lLGk9d1t4LTJdL2UsdT1tW3RdL2UsbD13W3RdL2UsYz0oKHMrbikqKHMtbikraSppKS8yLGY9bippKihuKmkpO2xldCBkPTA7MD09PWMmJjA9PT1mfHwoZD1jPDA/MC1NYXRoLnNxcnQoYypjK2YpOk1hdGguc3FydChjKmMrZiksZD1mLyhjK2QpKTtsZXQgYj0odStuKSoodS1uKStkLHk9dSpsO2ZvcihsZXQgZT10O2U8eC0xO2UrKyl7bGV0IG49UGUoYix5KTswPT09biYmKG49TnVtYmVyLk1JTl9WQUxVRSk7bGV0IHM9Yi9uLGk9eS9uO2lmKGUhPT10JiYod1tlLTFdPW4pLGI9cyptW2VdK2kqd1tlXSx3W2VdPXMqd1tlXS1pKm1bZV0seT1pKm1bZSsxXSxtW2UrMV09cyptW2UrMV0saClmb3IobGV0IHQ9MDt0PG87dCsrKW49cypwLmdldCh0LGUpK2kqcC5nZXQodCxlKzEpLHAuc2V0KHQsZSsxLC1pKnAuZ2V0KHQsZSkrcypwLmdldCh0LGUrMSkpLHAuc2V0KHQsZSxuKTtpZihuPVBlKGIseSksMD09PW4mJihuPU51bWJlci5NSU5fVkFMVUUpLHM9Yi9uLGk9eS9uLG1bZV09bixiPXMqd1tlXStpKm1bZSsxXSxtW2UrMV09LWkqd1tlXStzKm1bZSsxXSx5PWkqd1tlKzFdLHdbZSsxXT1zKndbZSsxXSxhJiZlPHItMSlmb3IobGV0IHQ9MDt0PHI7dCsrKW49cypnLmdldCh0LGUpK2kqZy5nZXQodCxlKzEpLGcuc2V0KHQsZSsxLC1pKmcuZ2V0KHQsZSkrcypnLmdldCh0LGUrMSkpLGcuc2V0KHQsZSxuKX13W3gtMl09YjticmVha31jYXNlIDQ6aWYobVt0XTw9MCYmKG1bdF09bVt0XTwwPy1tW3RdOjAsaCkpZm9yKGxldCBlPTA7ZTw9RTtlKyspcC5zZXQoZSx0LC1wLmdldChlLHQpKTtmb3IoO3Q8RSYmIShtW3RdPj1tW3QrMV0pOyl7bGV0IGU9bVt0XTtpZihtW3RdPW1bdCsxXSxtW3QrMV09ZSxoJiZ0PG8tMSlmb3IobGV0IHI9MDtyPG87cisrKWU9cC5nZXQocix0KzEpLHAuc2V0KHIsdCsxLHAuZ2V0KHIsdCkpLHAuc2V0KHIsdCxlKTtpZihhJiZ0PHItMSlmb3IobGV0IG89MDtvPHI7bysrKWU9Zy5nZXQobyx0KzEpLGcuc2V0KG8sdCsxLGcuZ2V0KG8sdCkpLGcuc2V0KG8sdCxlKTt0Kyt9eC0tfX1pZihsKXtsZXQgdD1wO3A9ZyxnPXR9dGhpcy5tPXIsdGhpcy5uPW8sdGhpcy5zPW0sdGhpcy5VPWcsdGhpcy5WPXB9c29sdmUodCl7bGV0IGU9dCxyPXRoaXMudGhyZXNob2xkLG89dGhpcy5zLmxlbmd0aCxuPUZlLnplcm9zKG8sbyk7Zm9yKGxldCB0PTA7dDxvO3QrKylNYXRoLmFicyh0aGlzLnNbdF0pPD1yP24uc2V0KHQsdCwwKTpuLnNldCh0LHQsMS90aGlzLnNbdF0pO2xldCBzPXRoaXMuVSxpPXRoaXMucmlnaHRTaW5ndWxhclZlY3RvcnMsdT1pLm1tdWwobiksYT1pLnJvd3MsaD1zLnJvd3MsbD1GZS56ZXJvcyhhLGgpO2ZvcihsZXQgdD0wO3Q8YTt0KyspZm9yKGxldCBlPTA7ZTxoO2UrKyl7bGV0IHI9MDtmb3IobGV0IG49MDtuPG87bisrKXIrPXUuZ2V0KHQsbikqcy5nZXQoZSxuKTtsLnNldCh0LGUscil9cmV0dXJuIGwubW11bChlKX1zb2x2ZUZvckRpYWdvbmFsKHQpe3JldHVybiB0aGlzLnNvbHZlKEZlLmRpYWcodCkpfWludmVyc2UoKXtsZXQgdD10aGlzLlYsZT10aGlzLnRocmVzaG9sZCxyPXQucm93cyxvPXQuY29sdW1ucyxuPW5ldyBGZShyLHRoaXMucy5sZW5ndGgpO2ZvcihsZXQgcz0wO3M8cjtzKyspZm9yKGxldCByPTA7cjxvO3IrKylNYXRoLmFicyh0aGlzLnNbcl0pPmUmJm4uc2V0KHMscix0LmdldChzLHIpL3RoaXMuc1tyXSk7bGV0IHM9dGhpcy5VLGk9cy5yb3dzLHU9cy5jb2x1bW5zLGE9bmV3IEZlKHIsaSk7Zm9yKGxldCB0PTA7dDxyO3QrKylmb3IobGV0IGU9MDtlPGk7ZSsrKXtsZXQgcj0wO2ZvcihsZXQgbz0wO288dTtvKyspcis9bi5nZXQodCxvKSpzLmdldChlLG8pO2Euc2V0KHQsZSxyKX1yZXR1cm4gYX1nZXQgY29uZGl0aW9uKCl7cmV0dXJuIHRoaXMuc1swXS90aGlzLnNbTWF0aC5taW4odGhpcy5tLHRoaXMubiktMV19Z2V0IG5vcm0yKCl7cmV0dXJuIHRoaXMuc1swXX1nZXQgcmFuaygpe2xldCB0PU1hdGgubWF4KHRoaXMubSx0aGlzLm4pKnRoaXMuc1swXSpOdW1iZXIuRVBTSUxPTixlPTAscj10aGlzLnM7Zm9yKGxldCBvPTAsbj1yLmxlbmd0aDtvPG47bysrKXJbb10+dCYmZSsrO3JldHVybiBlfWdldCBkaWFnb25hbCgpe3JldHVybiBBcnJheS5mcm9tKHRoaXMucyl9Z2V0IHRocmVzaG9sZCgpe3JldHVybiBOdW1iZXIuRVBTSUxPTi8yKk1hdGgubWF4KHRoaXMubSx0aGlzLm4pKnRoaXMuc1swXX1nZXQgbGVmdFNpbmd1bGFyVmVjdG9ycygpe3JldHVybiB0aGlzLlV9Z2V0IHJpZ2h0U2luZ3VsYXJWZWN0b3JzKCl7cmV0dXJuIHRoaXMuVn1nZXQgZGlhZ29uYWxNYXRyaXgoKXtyZXR1cm4gRmUuZGlhZyh0aGlzLnMpfX1jbGFzcyAkZXtjb25zdHJ1Y3Rvcih0LGU9e30pe2NvbnN0e2Fzc3VtZVN5bW1ldHJpYzpyPSExfT1lO2lmKCEodD1WZS5jaGVja01hdHJpeCh0KSkuaXNTcXVhcmUoKSl0aHJvdyBuZXcgRXJyb3IoIk1hdHJpeCBpcyBub3QgYSBzcXVhcmUgbWF0cml4Iik7aWYodC5pc0VtcHR5KCkpdGhyb3cgbmV3IEVycm9yKCJNYXRyaXggbXVzdCBiZSBub24tZW1wdHkiKTtsZXQgbyxuLHM9dC5jb2x1bW5zLGk9bmV3IEZlKHMscyksdT1uZXcgRmxvYXQ2NEFycmF5KHMpLGE9bmV3IEZsb2F0NjRBcnJheShzKSxoPXQsbD0hMTtpZihsPSEhcnx8dC5pc1N5bW1ldHJpYygpLGwpe2ZvcihvPTA7bzxzO28rKylmb3Iobj0wO248cztuKyspaS5zZXQobyxuLGguZ2V0KG8sbikpOyFmdW5jdGlvbih0LGUscixvKXtsZXQgbixzLGksdSxhLGgsbCxjO2ZvcihhPTA7YTx0O2ErKylyW2FdPW8uZ2V0KHQtMSxhKTtmb3IodT10LTE7dT4wO3UtLSl7Zm9yKGM9MCxpPTAsaD0wO2g8dTtoKyspYys9TWF0aC5hYnMocltoXSk7aWYoMD09PWMpZm9yKGVbdV09clt1LTFdLGE9MDthPHU7YSsrKXJbYV09by5nZXQodS0xLGEpLG8uc2V0KHUsYSwwKSxvLnNldChhLHUsMCk7ZWxzZXtmb3IoaD0wO2g8dTtoKyspcltoXS89YyxpKz1yW2hdKnJbaF07Zm9yKG49clt1LTFdLHM9TWF0aC5zcXJ0KGkpLG4+MCYmKHM9LXMpLGVbdV09YypzLGktPW4qcyxyW3UtMV09bi1zLGE9MDthPHU7YSsrKWVbYV09MDtmb3IoYT0wO2E8dTthKyspe2ZvcihuPXJbYV0sby5zZXQoYSx1LG4pLHM9ZVthXStvLmdldChhLGEpKm4saD1hKzE7aDw9dS0xO2grKylzKz1vLmdldChoLGEpKnJbaF0sZVtoXSs9by5nZXQoaCxhKSpuO2VbYV09c31mb3Iobj0wLGE9MDthPHU7YSsrKWVbYV0vPWksbis9ZVthXSpyW2FdO2ZvcihsPW4vKGkraSksYT0wO2E8dTthKyspZVthXS09bCpyW2FdO2ZvcihhPTA7YTx1O2ErKyl7Zm9yKG49clthXSxzPWVbYV0saD1hO2g8PXUtMTtoKyspby5zZXQoaCxhLG8uZ2V0KGgsYSktKG4qZVtoXStzKnJbaF0pKTtyW2FdPW8uZ2V0KHUtMSxhKSxvLnNldCh1LGEsMCl9fXJbdV09aX1mb3IodT0wO3U8dC0xO3UrKyl7aWYoby5zZXQodC0xLHUsby5nZXQodSx1KSksby5zZXQodSx1LDEpLGk9clt1KzFdLDAhPT1pKXtmb3IoaD0wO2g8PXU7aCsrKXJbaF09by5nZXQoaCx1KzEpL2k7Zm9yKGE9MDthPD11O2ErKyl7Zm9yKHM9MCxoPTA7aDw9dTtoKyspcys9by5nZXQoaCx1KzEpKm8uZ2V0KGgsYSk7Zm9yKGg9MDtoPD11O2grKylvLnNldChoLGEsby5nZXQoaCxhKS1zKnJbaF0pfX1mb3IoaD0wO2g8PXU7aCsrKW8uc2V0KGgsdSsxLDApfWZvcihhPTA7YTx0O2ErKylyW2FdPW8uZ2V0KHQtMSxhKSxvLnNldCh0LTEsYSwwKTtvLnNldCh0LTEsdC0xLDEpLGVbMF09MH0ocyxhLHUsaSksZnVuY3Rpb24odCxlLHIsbyl7bGV0IG4scyxpLHUsYSxoLGwsYyxmLG0sZyxwLHcsZCxiLHk7Zm9yKGk9MTtpPHQ7aSsrKWVbaS0xXT1lW2ldO2VbdC0xXT0wO2xldCB2PTAsTT0wLHg9TnVtYmVyLkVQU0lMT047Zm9yKGg9MDtoPHQ7aCsrKXtmb3IoTT1NYXRoLm1heChNLE1hdGguYWJzKHJbaF0pK01hdGguYWJzKGVbaF0pKSxsPWg7bDx0JiYhKE1hdGguYWJzKGVbbF0pPD14Kk0pOylsKys7aWYobD5oKWRve2ZvcihuPXJbaF0sYz0ocltoKzFdLW4pLygyKmVbaF0pLGY9UGUoYywxKSxjPDAmJihmPS1mKSxyW2hdPWVbaF0vKGMrZikscltoKzFdPWVbaF0qKGMrZiksbT1yW2grMV0scz1uLXJbaF0saT1oKzI7aTx0O2krKylyW2ldLT1zO2Zvcih2Kz1zLGM9cltsXSxnPTEscD1nLHc9ZyxkPWVbaCsxXSxiPTAseT0wLGk9bC0xO2k+PWg7aS0tKWZvcih3PXAscD1nLHk9YixuPWcqZVtpXSxzPWcqYyxmPVBlKGMsZVtpXSksZVtpKzFdPWIqZixiPWVbaV0vZixnPWMvZixjPWcqcltpXS1iKm4scltpKzFdPXMrYiooZypuK2IqcltpXSksYT0wO2E8dDthKyspcz1vLmdldChhLGkrMSksby5zZXQoYSxpKzEsYipvLmdldChhLGkpK2cqcyksby5zZXQoYSxpLGcqby5nZXQoYSxpKS1iKnMpO2M9LWIqeSp3KmQqZVtoXS9tLGVbaF09YipjLHJbaF09ZypjfXdoaWxlKE1hdGguYWJzKGVbaF0pPngqTSk7cltoXT1yW2hdK3YsZVtoXT0wfWZvcihpPTA7aTx0LTE7aSsrKXtmb3IoYT1pLGM9cltpXSx1PWkrMTt1PHQ7dSsrKXJbdV08YyYmKGE9dSxjPXJbdV0pO2lmKGEhPT1pKWZvcihyW2FdPXJbaV0scltpXT1jLHU9MDt1PHQ7dSsrKWM9by5nZXQodSxpKSxvLnNldCh1LGksby5nZXQodSxhKSksby5zZXQodSxhLGMpfX0ocyxhLHUsaSl9ZWxzZXtsZXQgdD1uZXcgRmUocyxzKSxlPW5ldyBGbG9hdDY0QXJyYXkocyk7Zm9yKG49MDtuPHM7bisrKWZvcihvPTA7bzxzO28rKyl0LnNldChvLG4saC5nZXQobyxuKSk7IWZ1bmN0aW9uKHQsZSxyLG8pe2xldCBuLHMsaSx1LGEsaCxsLGM9MCxmPXQtMTtmb3IoaD1jKzE7aDw9Zi0xO2grKyl7Zm9yKGw9MCx1PWg7dTw9Zjt1KyspbCs9TWF0aC5hYnMoZS5nZXQodSxoLTEpKTtpZigwIT09bCl7Zm9yKGk9MCx1PWY7dT49aDt1LS0pclt1XT1lLmdldCh1LGgtMSkvbCxpKz1yW3VdKnJbdV07Zm9yKHM9TWF0aC5zcXJ0KGkpLHJbaF0+MCYmKHM9LXMpLGktPXJbaF0qcyxyW2hdPXJbaF0tcyxhPWg7YTx0O2ErKyl7Zm9yKG49MCx1PWY7dT49aDt1LS0pbis9clt1XSplLmdldCh1LGEpO2ZvcihuLz1pLHU9aDt1PD1mO3UrKyllLnNldCh1LGEsZS5nZXQodSxhKS1uKnJbdV0pfWZvcih1PTA7dTw9Zjt1Kyspe2ZvcihuPTAsYT1mO2E+PWg7YS0tKW4rPXJbYV0qZS5nZXQodSxhKTtmb3Iobi89aSxhPWg7YTw9ZjthKyspZS5zZXQodSxhLGUuZ2V0KHUsYSktbipyW2FdKX1yW2hdPWwqcltoXSxlLnNldChoLGgtMSxsKnMpfX1mb3IodT0wO3U8dDt1KyspZm9yKGE9MDthPHQ7YSsrKW8uc2V0KHUsYSx1PT09YT8xOjApO2ZvcihoPWYtMTtoPj1jKzE7aC0tKWlmKDAhPT1lLmdldChoLGgtMSkpe2Zvcih1PWgrMTt1PD1mO3UrKylyW3VdPWUuZ2V0KHUsaC0xKTtmb3IoYT1oO2E8PWY7YSsrKXtmb3Iocz0wLHU9aDt1PD1mO3UrKylzKz1yW3VdKm8uZ2V0KHUsYSk7Zm9yKHM9cy9yW2hdL2UuZ2V0KGgsaC0xKSx1PWg7dTw9Zjt1Kyspby5zZXQodSxhLG8uZ2V0KHUsYSkrcypyW3VdKX19fShzLHQsZSxpKSxmdW5jdGlvbih0LGUscixvLG4pe2xldCBzLGksdSxhLGgsbCxjLGYsbSxnLHAsdyxkLGIseSx2PXQtMSxNPTAseD10LTEsRT1OdW1iZXIuRVBTSUxPTixTPTAsaj0wLF89MCxBPTAsQz0wLFI9MCxJPTAsaz0wO2ZvcihzPTA7czx0O3MrKylmb3IoKHM8TXx8cz54KSYmKHJbc109bi5nZXQocyxzKSxlW3NdPTApLGk9TWF0aC5tYXgocy0xLDApO2k8dDtpKyspais9TWF0aC5hYnMobi5nZXQocyxpKSk7Zm9yKDt2Pj1NOyl7Zm9yKGE9djthPk0mJihSPU1hdGguYWJzKG4uZ2V0KGEtMSxhLTEpKStNYXRoLmFicyhuLmdldChhLGEpKSwwPT09UiYmKFI9aiksIShNYXRoLmFicyhuLmdldChhLGEtMSkpPEUqUikpOylhLS07aWYoYT09PXYpbi5zZXQodix2LG4uZ2V0KHYsdikrUyksclt2XT1uLmdldCh2LHYpLGVbdl09MCx2LS0saz0wO2Vsc2UgaWYoYT09PXYtMSl7aWYoYz1uLmdldCh2LHYtMSkqbi5nZXQodi0xLHYpLF89KG4uZ2V0KHYtMSx2LTEpLW4uZ2V0KHYsdikpLzIsQT1fKl8rYyxJPU1hdGguc3FydChNYXRoLmFicyhBKSksbi5zZXQodix2LG4uZ2V0KHYsdikrUyksbi5zZXQodi0xLHYtMSxuLmdldCh2LTEsdi0xKStTKSxmPW4uZ2V0KHYsdiksQT49MCl7Zm9yKEk9Xz49MD9fK0k6Xy1JLHJbdi0xXT1mK0ksclt2XT1yW3YtMV0sMCE9PUkmJihyW3ZdPWYtYy9JKSxlW3YtMV09MCxlW3ZdPTAsZj1uLmdldCh2LHYtMSksUj1NYXRoLmFicyhmKStNYXRoLmFicyhJKSxfPWYvUixBPUkvUixDPU1hdGguc3FydChfKl8rQSpBKSxfLz1DLEEvPUMsaT12LTE7aTx0O2krKylJPW4uZ2V0KHYtMSxpKSxuLnNldCh2LTEsaSxBKkkrXypuLmdldCh2LGkpKSxuLnNldCh2LGksQSpuLmdldCh2LGkpLV8qSSk7Zm9yKHM9MDtzPD12O3MrKylJPW4uZ2V0KHMsdi0xKSxuLnNldChzLHYtMSxBKkkrXypuLmdldChzLHYpKSxuLnNldChzLHYsQSpuLmdldChzLHYpLV8qSSk7Zm9yKHM9TTtzPD14O3MrKylJPW8uZ2V0KHMsdi0xKSxvLnNldChzLHYtMSxBKkkrXypvLmdldChzLHYpKSxvLnNldChzLHYsQSpvLmdldChzLHYpLV8qSSl9ZWxzZSByW3YtMV09ZitfLHJbdl09ZitfLGVbdi0xXT1JLGVbdl09LUk7di09MixrPTB9ZWxzZXtpZihmPW4uZ2V0KHYsdiksbT0wLGM9MCxhPHYmJihtPW4uZ2V0KHYtMSx2LTEpLGM9bi5nZXQodix2LTEpKm4uZ2V0KHYtMSx2KSksMTA9PT1rKXtmb3IoUys9ZixzPU07czw9djtzKyspbi5zZXQocyxzLG4uZ2V0KHMscyktZik7Uj1NYXRoLmFicyhuLmdldCh2LHYtMSkpK01hdGguYWJzKG4uZ2V0KHYtMSx2LTIpKSxmPW09Ljc1KlIsYz0tLjQzNzUqUipSfWlmKDMwPT09ayYmKFI9KG0tZikvMixSPVIqUitjLFI+MCkpe2ZvcihSPU1hdGguc3FydChSKSxtPGYmJihSPS1SKSxSPWYtYy8oKG0tZikvMitSKSxzPU07czw9djtzKyspbi5zZXQocyxzLG4uZ2V0KHMscyktUik7Uys9UixmPW09Yz0uOTY0fWZvcihrKz0xLGg9di0yO2g+PWEmJihJPW4uZ2V0KGgsaCksQz1mLUksUj1tLUksXz0oQypSLWMpL24uZ2V0KGgrMSxoKStuLmdldChoLGgrMSksQT1uLmdldChoKzEsaCsxKS1JLUMtUixDPW4uZ2V0KGgrMixoKzEpLFI9TWF0aC5hYnMoXykrTWF0aC5hYnMoQSkrTWF0aC5hYnMoQyksXy89UixBLz1SLEMvPVIsaCE9PWEpJiYhKE1hdGguYWJzKG4uZ2V0KGgsaC0xKSkqKE1hdGguYWJzKEEpK01hdGguYWJzKEMpKTxFKihNYXRoLmFicyhfKSooTWF0aC5hYnMobi5nZXQoaC0xLGgtMSkpK01hdGguYWJzKEkpK01hdGguYWJzKG4uZ2V0KGgrMSxoKzEpKSkpKTspaC0tO2ZvcihzPWgrMjtzPD12O3MrKyluLnNldChzLHMtMiwwKSxzPmgrMiYmbi5zZXQocyxzLTMsMCk7Zm9yKHU9aDt1PD12LTEmJihiPXUhPT12LTEsdSE9PWgmJihfPW4uZ2V0KHUsdS0xKSxBPW4uZ2V0KHUrMSx1LTEpLEM9Yj9uLmdldCh1KzIsdS0xKTowLGY9TWF0aC5hYnMoXykrTWF0aC5hYnMoQSkrTWF0aC5hYnMoQyksMCE9PWYmJihfLz1mLEEvPWYsQy89ZikpLDAhPT1mKTt1KyspaWYoUj1NYXRoLnNxcnQoXypfK0EqQStDKkMpLF88MCYmKFI9LVIpLDAhPT1SKXtmb3IodSE9PWg/bi5zZXQodSx1LTEsLVIqZik6YSE9PWgmJm4uc2V0KHUsdS0xLC1uLmdldCh1LHUtMSkpLF8rPVIsZj1fL1IsbT1BL1IsST1DL1IsQS89XyxDLz1fLGk9dTtpPHQ7aSsrKV89bi5nZXQodSxpKStBKm4uZ2V0KHUrMSxpKSxiJiYoXys9QypuLmdldCh1KzIsaSksbi5zZXQodSsyLGksbi5nZXQodSsyLGkpLV8qSSkpLG4uc2V0KHUsaSxuLmdldCh1LGkpLV8qZiksbi5zZXQodSsxLGksbi5nZXQodSsxLGkpLV8qbSk7Zm9yKHM9MDtzPD1NYXRoLm1pbih2LHUrMyk7cysrKV89ZipuLmdldChzLHUpK20qbi5nZXQocyx1KzEpLGImJihfKz1JKm4uZ2V0KHMsdSsyKSxuLnNldChzLHUrMixuLmdldChzLHUrMiktXypDKSksbi5zZXQocyx1LG4uZ2V0KHMsdSktXyksbi5zZXQocyx1KzEsbi5nZXQocyx1KzEpLV8qQSk7Zm9yKHM9TTtzPD14O3MrKylfPWYqby5nZXQocyx1KSttKm8uZ2V0KHMsdSsxKSxiJiYoXys9SSpvLmdldChzLHUrMiksby5zZXQocyx1KzIsby5nZXQocyx1KzIpLV8qQykpLG8uc2V0KHMsdSxvLmdldChzLHUpLV8pLG8uc2V0KHMsdSsxLG8uZ2V0KHMsdSsxKS1fKkEpfX19aWYoMD09PWopcmV0dXJuO2Zvcih2PXQtMTt2Pj0wO3YtLSlpZihfPXJbdl0sQT1lW3ZdLDA9PT1BKWZvcihhPXYsbi5zZXQodix2LDEpLHM9di0xO3M+PTA7cy0tKXtmb3IoYz1uLmdldChzLHMpLV8sQz0wLGk9YTtpPD12O2krKylDKz1uLmdldChzLGkpKm4uZ2V0KGksdik7aWYoZVtzXTwwKUk9YyxSPUM7ZWxzZSBpZihhPXMsMD09PWVbc10/bi5zZXQocyx2LDAhPT1jPy1DL2M6LUMvKEUqaikpOihmPW4uZ2V0KHMscysxKSxtPW4uZ2V0KHMrMSxzKSxBPShyW3NdLV8pKihyW3NdLV8pK2Vbc10qZVtzXSxsPShmKlItSSpDKS9BLG4uc2V0KHMsdixsKSxuLnNldChzKzEsdixNYXRoLmFicyhmKT5NYXRoLmFicyhJKT8oLUMtYypsKS9mOigtUi1tKmwpL0kpKSxsPU1hdGguYWJzKG4uZ2V0KHMsdikpLEUqbCpsPjEpZm9yKGk9cztpPD12O2krKyluLnNldChpLHYsbi5nZXQoaSx2KS9sKX1lbHNlIGlmKEE8MClmb3IoYT12LTEsTWF0aC5hYnMobi5nZXQodix2LTEpKT5NYXRoLmFicyhuLmdldCh2LTEsdikpPyhuLnNldCh2LTEsdi0xLEEvbi5nZXQodix2LTEpKSxuLnNldCh2LTEsdiwtKG4uZ2V0KHYsdiktXykvbi5nZXQodix2LTEpKSk6KHk9RGUoMCwtbi5nZXQodi0xLHYpLG4uZ2V0KHYtMSx2LTEpLV8sQSksbi5zZXQodi0xLHYtMSx5WzBdKSxuLnNldCh2LTEsdix5WzFdKSksbi5zZXQodix2LTEsMCksbi5zZXQodix2LDEpLHM9di0yO3M+PTA7cy0tKXtmb3IoZz0wLHA9MCxpPWE7aTw9djtpKyspZys9bi5nZXQocyxpKSpuLmdldChpLHYtMSkscCs9bi5nZXQocyxpKSpuLmdldChpLHYpO2lmKGM9bi5nZXQocyxzKS1fLGVbc108MClJPWMsQz1nLFI9cDtlbHNlIGlmKGE9cywwPT09ZVtzXT8oeT1EZSgtZywtcCxjLEEpLG4uc2V0KHMsdi0xLHlbMF0pLG4uc2V0KHMsdix5WzFdKSk6KGY9bi5nZXQocyxzKzEpLG09bi5nZXQocysxLHMpLHc9KHJbc10tXykqKHJbc10tXykrZVtzXSplW3NdLUEqQSxkPTIqKHJbc10tXykqQSwwPT09dyYmMD09PWQmJih3PUUqaiooTWF0aC5hYnMoYykrTWF0aC5hYnMoQSkrTWF0aC5hYnMoZikrTWF0aC5hYnMobSkrTWF0aC5hYnMoSSkpKSx5PURlKGYqQy1JKmcrQSpwLGYqUi1JKnAtQSpnLHcsZCksbi5zZXQocyx2LTEseVswXSksbi5zZXQocyx2LHlbMV0pLE1hdGguYWJzKGYpPk1hdGguYWJzKEkpK01hdGguYWJzKEEpPyhuLnNldChzKzEsdi0xLCgtZy1jKm4uZ2V0KHMsdi0xKStBKm4uZ2V0KHMsdikpL2YpLG4uc2V0KHMrMSx2LCgtcC1jKm4uZ2V0KHMsdiktQSpuLmdldChzLHYtMSkpL2YpKTooeT1EZSgtQy1tKm4uZ2V0KHMsdi0xKSwtUi1tKm4uZ2V0KHMsdiksSSxBKSxuLnNldChzKzEsdi0xLHlbMF0pLG4uc2V0KHMrMSx2LHlbMV0pKSksbD1NYXRoLm1heChNYXRoLmFicyhuLmdldChzLHYtMSkpLE1hdGguYWJzKG4uZ2V0KHMsdikpKSxFKmwqbD4xKWZvcihpPXM7aTw9djtpKyspbi5zZXQoaSx2LTEsbi5nZXQoaSx2LTEpL2wpLG4uc2V0KGksdixuLmdldChpLHYpL2wpfWZvcihzPTA7czx0O3MrKylpZihzPE18fHM+eClmb3IoaT1zO2k8dDtpKyspby5zZXQocyxpLG4uZ2V0KHMsaSkpO2ZvcihpPXQtMTtpPj1NO2ktLSlmb3Iocz1NO3M8PXg7cysrKXtmb3IoST0wLHU9TTt1PD1NYXRoLm1pbihpLHgpO3UrKylJKz1vLmdldChzLHUpKm4uZ2V0KHUsaSk7by5zZXQocyxpLEkpfX0ocyxhLHUsaSx0KX10aGlzLm49cyx0aGlzLmU9YSx0aGlzLmQ9dSx0aGlzLlY9aX1nZXQgcmVhbEVpZ2VudmFsdWVzKCl7cmV0dXJuIEFycmF5LmZyb20odGhpcy5kKX1nZXQgaW1hZ2luYXJ5RWlnZW52YWx1ZXMoKXtyZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmUpfWdldCBlaWdlbnZlY3Rvck1hdHJpeCgpe3JldHVybiB0aGlzLlZ9Z2V0IGRpYWdvbmFsTWF0cml4KCl7bGV0IHQsZSxyPXRoaXMubixvPXRoaXMuZSxuPXRoaXMuZCxzPW5ldyBGZShyLHIpO2Zvcih0PTA7dDxyO3QrKyl7Zm9yKGU9MDtlPHI7ZSsrKXMuc2V0KHQsZSwwKTtzLnNldCh0LHQsblt0XSksb1t0XT4wP3Muc2V0KHQsdCsxLG9bdF0pOm9bdF08MCYmcy5zZXQodCx0LTEsb1t0XSl9cmV0dXJuIHN9fWZ1bmN0aW9uIERlKHQsZSxyLG8pe2xldCBuLHM7cmV0dXJuIE1hdGguYWJzKHIpPk1hdGguYWJzKG8pPyhuPW8vcixzPXIrbipvLFsodCtuKmUpL3MsKGUtbip0KS9zXSk6KG49ci9vLHM9bytuKnIsWyhuKnQrZSkvcywobiplLXQpL3NdKX1jbGFzcyBVZXtjb25zdHJ1Y3Rvcih0LGU9e30pe3Q9VmUuY2hlY2tNYXRyaXgodCk7bGV0e1k6cn09ZTtjb25zdHtzY2FsZVNjb3JlczpvPSExLG1heEl0ZXJhdGlvbnM6bj0xZTMsdGVybWluYXRpb25Dcml0ZXJpYTpzPTFlLTEwfT1lO2xldCBpO2lmKHIpe2lmKHI9QXJyYXkuaXNBcnJheShyKSYmIm51bWJlciI9PXR5cGVvZiByWzBdP0ZlLmNvbHVtblZlY3RvcihyKTpWZS5jaGVja01hdHJpeChyKSxyLnJvd3MhPT10LnJvd3MpdGhyb3cgbmV3IEVycm9yKCJZIHNob3VsZCBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiByb3dzIGFzIFgiKTtpPXIuZ2V0Q29sdW1uVmVjdG9yKDApfWVsc2UgaT10LmdldENvbHVtblZlY3RvcigwKTtsZXQgdSxhLGgsbCxjPTE7Zm9yKGxldCBlPTA7ZTxuJiZjPnM7ZSsrKWg9dC50cmFuc3Bvc2UoKS5tbXVsKGkpLmRpdihpLnRyYW5zcG9zZSgpLm1tdWwoaSkuZ2V0KDAsMCkpLGg9aC5kaXYoaC5ub3JtKCkpLHU9dC5tbXVsKGgpLmRpdihoLnRyYW5zcG9zZSgpLm1tdWwoaCkuZ2V0KDAsMCkpLGU+MCYmKGM9dS5jbG9uZSgpLnN1YihsKS5wb3coMikuc3VtKCkpLGw9dS5jbG9uZSgpLHI/KGE9ci50cmFuc3Bvc2UoKS5tbXVsKHUpLmRpdih1LnRyYW5zcG9zZSgpLm1tdWwodSkuZ2V0KDAsMCkpLGE9YS5kaXYoYS5ub3JtKCkpLGk9ci5tbXVsKGEpLmRpdihhLnRyYW5zcG9zZSgpLm1tdWwoYSkuZ2V0KDAsMCkpKTppPXU7aWYocil7bGV0IGU9dC50cmFuc3Bvc2UoKS5tbXVsKHUpLmRpdih1LnRyYW5zcG9zZSgpLm1tdWwodSkuZ2V0KDAsMCkpO2U9ZS5kaXYoZS5ub3JtKCkpO2xldCBvPXQuY2xvbmUoKS5zdWIodS5jbG9uZSgpLm1tdWwoZS50cmFuc3Bvc2UoKSkpLG49aS50cmFuc3Bvc2UoKS5tbXVsKHUpLmRpdih1LnRyYW5zcG9zZSgpLm1tdWwodSkuZ2V0KDAsMCkpLHM9ci5jbG9uZSgpLnN1Yih1LmNsb25lKCkubXVsUyhuLmdldCgwLDApKS5tbXVsKGEudHJhbnNwb3NlKCkpKTt0aGlzLnQ9dSx0aGlzLnA9ZS50cmFuc3Bvc2UoKSx0aGlzLnc9aC50cmFuc3Bvc2UoKSx0aGlzLnE9YSx0aGlzLnU9aSx0aGlzLnM9dS50cmFuc3Bvc2UoKS5tbXVsKHUpLHRoaXMueFJlc2lkdWFsPW8sdGhpcy55UmVzaWR1YWw9cyx0aGlzLmJldGFzPW59ZWxzZSB0aGlzLnc9aC50cmFuc3Bvc2UoKSx0aGlzLnM9dS50cmFuc3Bvc2UoKS5tbXVsKHUpLnNxcnQoKSx0aGlzLnQ9bz91LmNsb25lKCkuZGl2KHRoaXMucy5nZXQoMCwwKSk6dSx0aGlzLnhSZXNpZHVhbD10LnN1Yih1Lm1tdWwoaC50cmFuc3Bvc2UoKSkpfX1jbGFzcyBMZXtjb25zdHJ1Y3Rvcih0LGU9e30pe2lmKCEwPT09dCl7Y29uc3QgdD1lO3JldHVybiB0aGlzLmNlbnRlcj10LmNlbnRlcix0aGlzLnNjYWxlPXQuc2NhbGUsdGhpcy5tZWFucz10Lm1lYW5zLHRoaXMuc3RkZXZzPXQuc3RkZXZzLHRoaXMuVT1GZS5jaGVja01hdHJpeCh0LlUpLHRoaXMuUz10LlMsdGhpcy5SPXQuUix2b2lkKHRoaXMuZXhjbHVkZWRGZWF0dXJlcz10LmV4Y2x1ZGVkRmVhdHVyZXN8fFtdKX10PW5ldyBGZSh0KTtjb25zdHtpc0NvdmFyaWFuY2VNYXRyaXg6cj0hMSxtZXRob2Q6bz0iU1ZEIixuQ29tcE5JUEFMUzpuPTIsY2VudGVyOnM9ITAsc2NhbGU6aT0hMSxpZ25vcmVaZXJvVmFyaWFuY2U6dT0hMX09ZTtpZih0aGlzLmNlbnRlcj1zLHRoaXMuc2NhbGU9aSx0aGlzLm1lYW5zPW51bGwsdGhpcy5zdGRldnM9bnVsbCx0aGlzLmV4Y2x1ZGVkRmVhdHVyZXM9W10scil0aGlzLl9jb21wdXRlRnJvbUNvdmFyaWFuY2VNYXRyaXgodCk7ZWxzZSBzd2l0Y2godGhpcy5fYWRqdXN0KHQsdSksbyl7Y2FzZSJjb3ZhcmlhbmNlTWF0cml4Ijp7Y29uc3QgZT1uZXcgVGUodCkubW11bCh0KS5kaXYodC5yb3dzLTEpO3RoaXMuX2NvbXB1dGVGcm9tQ292YXJpYW5jZU1hdHJpeChlKTticmVha31jYXNlIk5JUEFMUyI6dGhpcy5fY29tcHV0ZVdpdGhOSVBBTFModCxuKTticmVhaztjYXNlIlNWRCI6e2NvbnN0IGU9bmV3IHFlKHQse2NvbXB1dGVMZWZ0U2luZ3VsYXJWZWN0b3JzOiExLGNvbXB1dGVSaWdodFNpbmd1bGFyVmVjdG9yczohMCxhdXRvVHJhbnNwb3NlOiEwfSk7dGhpcy5VPWUucmlnaHRTaW5ndWxhclZlY3RvcnM7Y29uc3Qgcj1lLmRpYWdvbmFsLG89W107Zm9yKGNvbnN0IGUgb2YgcilvLnB1c2goZSplLyh0LnJvd3MtMSkpO3RoaXMuUz1vO2JyZWFrfWRlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGB1bmtub3duIG1ldGhvZDogJHtvfWApfX1zdGF0aWMgbG9hZCh0KXtpZigic3RyaW5nIiE9dHlwZW9mIHQubmFtZSl0aHJvdyBuZXcgVHlwZUVycm9yKCJtb2RlbCBtdXN0IGhhdmUgYSBuYW1lIHByb3BlcnR5Iik7aWYoIlBDQSIhPT10Lm5hbWUpdGhyb3cgbmV3IFJhbmdlRXJyb3IoYGludmFsaWQgbW9kZWw6ICR7dC5uYW1lfWApO3JldHVybiBuZXcgTGUoITAsdCl9cHJlZGljdCh0LGU9e30pe2NvbnN0e25Db21wb25lbnRzOnI9dGhpcy5VLmNvbHVtbnN9PWU7aWYodD1uZXcgRmUodCksdGhpcy5jZW50ZXImJih0LnN1YlJvd1ZlY3Rvcih0aGlzLm1lYW5zKSx0aGlzLnNjYWxlKSl7Zm9yKGxldCBlIG9mIHRoaXMuZXhjbHVkZWRGZWF0dXJlcyl0LnJlbW92ZUNvbHVtbihlKTt0LmRpdlJvd1ZlY3Rvcih0aGlzLnN0ZGV2cyl9bGV0IG89dC5tbXVsKHRoaXMuVSk7cmV0dXJuIG8uc3ViTWF0cml4KDAsby5yb3dzLTEsMCxyLTEpfWludmVydCh0KXtsZXQgZT0odD1GZS5jaGVja01hdHJpeCh0KSkubW11bCh0aGlzLlUudHJhbnNwb3NlKCkpO3JldHVybiB0aGlzLmNlbnRlciYmKHRoaXMuc2NhbGUmJmUubXVsUm93VmVjdG9yKHRoaXMuc3RkZXZzKSxlLmFkZFJvd1ZlY3Rvcih0aGlzLm1lYW5zKSksZX1nZXRFeHBsYWluZWRWYXJpYW5jZSgpe2xldCB0PTA7Zm9yKGNvbnN0IGUgb2YgdGhpcy5TKXQrPWU7cmV0dXJuIHRoaXMuUy5tYXAoKGU9PmUvdCkpfWdldEN1bXVsYXRpdmVWYXJpYW5jZSgpe2xldCB0PXRoaXMuZ2V0RXhwbGFpbmVkVmFyaWFuY2UoKTtmb3IobGV0IGU9MTtlPHQubGVuZ3RoO2UrKyl0W2VdKz10W2UtMV07cmV0dXJuIHR9Z2V0RWlnZW52ZWN0b3JzKCl7cmV0dXJuIHRoaXMuVX1nZXRFaWdlbnZhbHVlcygpe3JldHVybiB0aGlzLlN9Z2V0U3RhbmRhcmREZXZpYXRpb25zKCl7cmV0dXJuIHRoaXMuUy5tYXAoKHQ9Pk1hdGguc3FydCh0KSkpfWdldExvYWRpbmdzKCl7cmV0dXJuIHRoaXMuVS50cmFuc3Bvc2UoKX10b0pTT04oKXtyZXR1cm57bmFtZToiUENBIixjZW50ZXI6dGhpcy5jZW50ZXIsc2NhbGU6dGhpcy5zY2FsZSxtZWFuczp0aGlzLm1lYW5zLHN0ZGV2czp0aGlzLnN0ZGV2cyxVOnRoaXMuVSxTOnRoaXMuUyxleGNsdWRlZEZlYXR1cmVzOnRoaXMuZXhjbHVkZWRGZWF0dXJlc319X2FkanVzdCh0LGUpe2lmKHRoaXMuY2VudGVyKXtjb25zdCByPXQubWVhbigiY29sdW1uIiksbz10aGlzLnNjYWxlP3Quc3RhbmRhcmREZXZpYXRpb24oImNvbHVtbiIse21lYW46cn0pOm51bGw7aWYodGhpcy5tZWFucz1yLHQuc3ViUm93VmVjdG9yKHIpLHRoaXMuc2NhbGUpe2ZvcihsZXQgcj0wO3I8by5sZW5ndGg7cisrKWlmKDA9PT1vW3JdKXtpZighZSl0aHJvdyBuZXcgUmFuZ2VFcnJvcihgQ2Fubm90IHNjYWxlIHRoZSBkYXRhc2V0IChzdGFuZGFyZCBkZXZpYXRpb24gaXMgemVybyBhdCBpbmRleCAke3J9YCk7dC5yZW1vdmVDb2x1bW4ociksby5zcGxpY2UociwxKSx0aGlzLmV4Y2x1ZGVkRmVhdHVyZXMucHVzaChyKSxyLS19dGhpcy5zdGRldnM9byx0LmRpdlJvd1ZlY3RvcihvKX19fV9jb21wdXRlRnJvbUNvdmFyaWFuY2VNYXRyaXgodCl7Y29uc3QgZT1uZXcgJGUodCx7YXNzdW1lU3ltbWV0cmljOiEwfSk7dGhpcy5VPWUuZWlnZW52ZWN0b3JNYXRyaXgsdGhpcy5VLmZsaXBSb3dzKCksdGhpcy5TPWUucmVhbEVpZ2VudmFsdWVzLHRoaXMuUy5yZXZlcnNlKCl9X2NvbXB1dGVXaXRoTklQQUxTKHQsZSl7dGhpcy5VPW5ldyBGZShlLHQuY29sdW1ucyksdGhpcy5TPVtdO2xldCByPXQ7Zm9yKGxldCB0PTA7dDxlO3QrKyl7bGV0IGU9bmV3IFVlKHIpO3RoaXMuVS5zZXRSb3codCxlLncudHJhbnNwb3NlKCkpLHRoaXMuUy5wdXNoKE1hdGgucG93KGUucy5nZXQoMCwwKSwyKSkscj1lLnhSZXNpZHVhbH10aGlzLlU9dGhpcy5VLnRyYW5zcG9zZSgpfX1mdW5jdGlvbiBCZSh0LGU9e30pe2xldCByPUN0KGUsInNjYWxlIik7ZmUocil8fChyPSEwKTtsZXQgbz1DdChlLCJuQ29tcE5JUEFMUyIpO2lmKGNlKG8pfHwobz0yKSxvPmxlKEN0KHQsMCxbXSkpKXRocm93IG5ldyBFcnJvcigibkNvbXBOSVBBTFMgaXMgbW9yZSB0aGFuIHRoZSBkaW1lbnNpb24gb2YgZGF0YSIpO2xldCBuPW5ldyBMZSh0LHttZXRob2Q6Ik5JUEFMUyIsc2NhbGU6cixuQ29tcE5JUEFMUzpvfSkscz1uLnByZWRpY3QodCk7cmV0dXJuIG4uaW52ZXJ0KHMpLnRvSlNPTigpfXZhciBHZT1mdW5jdGlvbih0LGUpe2Zvcih2YXIgcj0tMSxvPW51bGw9PXQ/MDp0Lmxlbmd0aDsrK3I8byYmITEhPT1lKHRbcl0scix0KTspO3JldHVybiB0fTt2YXIgS2U9ZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKGUscixvKXtmb3IodmFyIG49LTEscz1PYmplY3QoZSksaT1vKGUpLHU9aS5sZW5ndGg7dS0tOyl7dmFyIGE9aVt0P3U6KytuXTtpZighMT09PXIoc1thXSxhLHMpKWJyZWFrfXJldHVybiBlfX0oKTt2YXIgV2U9ZnVuY3Rpb24odCxlKXtmb3IodmFyIHI9LTEsbz1BcnJheSh0KTsrK3I8dDspb1tyXT1lKHIpO3JldHVybiBvfTt2YXIgWGU9ZnVuY3Rpb24odCl7cmV0dXJuIGQodCkmJiJbb2JqZWN0IEFyZ3VtZW50c10iPT13KHQpfSxKZT1PYmplY3QucHJvdG90eXBlLFllPUplLmhhc093blByb3BlcnR5LFplPUplLnByb3BlcnR5SXNFbnVtZXJhYmxlLEhlPVhlKGZ1bmN0aW9uKCl7cmV0dXJuIGFyZ3VtZW50c30oKSk/WGU6ZnVuY3Rpb24odCl7cmV0dXJuIGQodCkmJlllLmNhbGwodCwiY2FsbGVlIikmJiFaZS5jYWxsKHQsImNhbGxlZSIpfTt2YXIgUWU9ZnVuY3Rpb24oKXtyZXR1cm4hMX0sdHI9bygoZnVuY3Rpb24odCxlKXt2YXIgcj1lJiYhZS5ub2RlVHlwZSYmZSxvPXImJnQmJiF0Lm5vZGVUeXBlJiZ0LG49byYmby5leHBvcnRzPT09cj9pLkJ1ZmZlcjp2b2lkIDAscz0obj9uLmlzQnVmZmVyOnZvaWQgMCl8fFFlO3QuZXhwb3J0cz1zfSkpLGVyPS9eKD86MHxbMS05XVxkKikkLzt2YXIgcnI9ZnVuY3Rpb24odCxlKXt2YXIgcj10eXBlb2YgdDtyZXR1cm4hIShlPW51bGw9PWU/OTAwNzE5OTI1NDc0MDk5MTplKSYmKCJudW1iZXIiPT1yfHwic3ltYm9sIiE9ciYmZXIudGVzdCh0KSkmJnQ+LTEmJnQlMT09MCYmdDxlfSxvcj17fTtvclsiW29iamVjdCBGbG9hdDMyQXJyYXldIl09b3JbIltvYmplY3QgRmxvYXQ2NEFycmF5XSJdPW9yWyJbb2JqZWN0IEludDhBcnJheV0iXT1vclsiW29iamVjdCBJbnQxNkFycmF5XSJdPW9yWyJbb2JqZWN0IEludDMyQXJyYXldIl09b3JbIltvYmplY3QgVWludDhBcnJheV0iXT1vclsiW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0iXT1vclsiW29iamVjdCBVaW50MTZBcnJheV0iXT1vclsiW29iamVjdCBVaW50MzJBcnJheV0iXT0hMCxvclsiW29iamVjdCBBcmd1bWVudHNdIl09b3JbIltvYmplY3QgQXJyYXldIl09b3JbIltvYmplY3QgQXJyYXlCdWZmZXJdIl09b3JbIltvYmplY3QgQm9vbGVhbl0iXT1vclsiW29iamVjdCBEYXRhVmlld10iXT1vclsiW29iamVjdCBEYXRlXSJdPW9yWyJbb2JqZWN0IEVycm9yXSJdPW9yWyJbb2JqZWN0IEZ1bmN0aW9uXSJdPW9yWyJbb2JqZWN0IE1hcF0iXT1vclsiW29iamVjdCBOdW1iZXJdIl09b3JbIltvYmplY3QgT2JqZWN0XSJdPW9yWyJbb2JqZWN0IFJlZ0V4cF0iXT1vclsiW29iamVjdCBTZXRdIl09b3JbIltvYmplY3QgU3RyaW5nXSJdPW9yWyJbb2JqZWN0IFdlYWtNYXBdIl09ITE7dmFyIG5yPWZ1bmN0aW9uKHQpe3JldHVybiBkKHQpJiZHdCh0Lmxlbmd0aCkmJiEhb3Jbdyh0KV19O3ZhciBzcj1mdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIHQoZSl9fSxpcj1vKChmdW5jdGlvbih0LGUpe3ZhciByPWUmJiFlLm5vZGVUeXBlJiZlLG89ciYmdCYmIXQubm9kZVR5cGUmJnQscz1vJiZvLmV4cG9ydHM9PT1yJiZuLnByb2Nlc3MsaT1mdW5jdGlvbigpe3RyeXt2YXIgdD1vJiZvLnJlcXVpcmUmJm8ucmVxdWlyZSgidXRpbCIpLnR5cGVzO3JldHVybiB0fHxzJiZzLmJpbmRpbmcmJnMuYmluZGluZygidXRpbCIpfWNhdGNoKHQpe319KCk7dC5leHBvcnRzPWl9KSksdXI9aXImJmlyLmlzVHlwZWRBcnJheSxhcj11cj9zcih1cik6bnIsaHI9T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTt2YXIgbHI9ZnVuY3Rpb24oZSxyKXt2YXIgbz10KGUpLG49IW8mJkhlKGUpLHM9IW8mJiFuJiZ0cihlKSxpPSFvJiYhbiYmIXMmJmFyKGUpLHU9b3x8bnx8c3x8aSxhPXU/V2UoZS5sZW5ndGgsU3RyaW5nKTpbXSxoPWEubGVuZ3RoO2Zvcih2YXIgbCBpbiBlKSFyJiYhaHIuY2FsbChlLGwpfHx1JiYoImxlbmd0aCI9PWx8fHMmJigib2Zmc2V0Ij09bHx8InBhcmVudCI9PWwpfHxpJiYoImJ1ZmZlciI9PWx8fCJieXRlTGVuZ3RoIj09bHx8ImJ5dGVPZmZzZXQiPT1sKXx8cnIobCxoKSl8fGEucHVzaChsKTtyZXR1cm4gYX07dmFyIGNyPWZ1bmN0aW9uKHQpe3JldHVybiBLdCh0KT9scih0KTpPdCh0KX07dmFyIGZyPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKHIsbyl7aWYobnVsbD09cilyZXR1cm4gcjtpZighS3QocikpcmV0dXJuIHQocixvKTtmb3IodmFyIG49ci5sZW5ndGgscz1lP246LTEsaT1PYmplY3Qocik7KGU/cy0tOisrczxuKSYmITEhPT1vKGlbc10scyxpKTspO3JldHVybiByfX0oKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQmJktlKHQsZSxjcil9KSk7dmFyIG1yPWZ1bmN0aW9uKHQpe3JldHVybiB0fTt2YXIgZ3I9ZnVuY3Rpb24odCl7cmV0dXJuImZ1bmN0aW9uIj09dHlwZW9mIHQ/dDptcn07dmFyIHByPWZ1bmN0aW9uKGUscil7cmV0dXJuKHQoZSk/R2U6ZnIpKGUsZ3IocikpfTt2YXIgd3I9ZnVuY3Rpb24oKXt0aGlzLl9fZGF0YV9fPW5ldyBudCx0aGlzLnNpemU9MH07dmFyIGRyPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuX19kYXRhX18scj1lLmRlbGV0ZSh0KTtyZXR1cm4gdGhpcy5zaXplPWUuc2l6ZSxyfTt2YXIgYnI9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuX19kYXRhX18uZ2V0KHQpfTt2YXIgeXI9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuX19kYXRhX18uaGFzKHQpfTt2YXIgdnI9ZnVuY3Rpb24odCxlKXt2YXIgcj10aGlzLl9fZGF0YV9fO2lmKHIgaW5zdGFuY2VvZiBudCl7dmFyIG89ci5fX2RhdGFfXztpZighc3R8fG8ubGVuZ3RoPDE5OSlyZXR1cm4gby5wdXNoKFt0LGVdKSx0aGlzLnNpemU9KytyLnNpemUsdGhpcztyPXRoaXMuX19kYXRhX189bmV3IGd0KG8pfXJldHVybiByLnNldCh0LGUpLHRoaXMuc2l6ZT1yLnNpemUsdGhpc307ZnVuY3Rpb24gTXIodCl7dmFyIGU9dGhpcy5fX2RhdGFfXz1uZXcgbnQodCk7dGhpcy5zaXplPWUuc2l6ZX1Nci5wcm90b3R5cGUuY2xlYXI9d3IsTXIucHJvdG90eXBlLmRlbGV0ZT1kcixNci5wcm90b3R5cGUuZ2V0PWJyLE1yLnByb3RvdHlwZS5oYXM9eXIsTXIucHJvdG90eXBlLnNldD12cjt2YXIgeHI9TXI7dmFyIEVyPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLl9fZGF0YV9fLnNldCh0LCJfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fIiksdGhpc307dmFyIFNyPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLl9fZGF0YV9fLmhhcyh0KX07ZnVuY3Rpb24ganIodCl7dmFyIGU9LTEscj1udWxsPT10PzA6dC5sZW5ndGg7Zm9yKHRoaXMuX19kYXRhX189bmV3IGd0OysrZTxyOyl0aGlzLmFkZCh0W2VdKX1qci5wcm90b3R5cGUuYWRkPWpyLnByb3RvdHlwZS5wdXNoPUVyLGpyLnByb3RvdHlwZS5oYXM9U3I7dmFyIF9yPWpyO3ZhciBBcj1mdW5jdGlvbih0LGUpe2Zvcih2YXIgcj0tMSxvPW51bGw9PXQ/MDp0Lmxlbmd0aDsrK3I8bzspaWYoZSh0W3JdLHIsdCkpcmV0dXJuITA7cmV0dXJuITF9O3ZhciBDcj1mdW5jdGlvbih0LGUpe3JldHVybiB0LmhhcyhlKX07dmFyIFJyPWZ1bmN0aW9uKHQsZSxyLG8sbixzKXt2YXIgaT0xJnIsdT10Lmxlbmd0aCxhPWUubGVuZ3RoO2lmKHUhPWEmJiEoaSYmYT51KSlyZXR1cm4hMTt2YXIgaD1zLmdldCh0KSxsPXMuZ2V0KGUpO2lmKGgmJmwpcmV0dXJuIGg9PWUmJmw9PXQ7dmFyIGM9LTEsZj0hMCxtPTImcj9uZXcgX3I6dm9pZCAwO2ZvcihzLnNldCh0LGUpLHMuc2V0KGUsdCk7KytjPHU7KXt2YXIgZz10W2NdLHA9ZVtjXTtpZihvKXZhciB3PWk/byhwLGcsYyxlLHQscyk6byhnLHAsYyx0LGUscyk7aWYodm9pZCAwIT09dyl7aWYodyljb250aW51ZTtmPSExO2JyZWFrfWlmKG0pe2lmKCFBcihlLChmdW5jdGlvbih0LGUpe2lmKCFDcihtLGUpJiYoZz09PXR8fG4oZyx0LHIsbyxzKSkpcmV0dXJuIG0ucHVzaChlKX0pKSl7Zj0hMTticmVha319ZWxzZSBpZihnIT09cCYmIW4oZyxwLHIsbyxzKSl7Zj0hMTticmVha319cmV0dXJuIHMuZGVsZXRlKHQpLHMuZGVsZXRlKGUpLGZ9LElyPWkuVWludDhBcnJheTt2YXIga3I9ZnVuY3Rpb24odCl7dmFyIGU9LTEscj1BcnJheSh0LnNpemUpO3JldHVybiB0LmZvckVhY2goKGZ1bmN0aW9uKHQsbyl7clsrK2VdPVtvLHRdfSkpLHJ9O3ZhciBOcj1mdW5jdGlvbih0KXt2YXIgZT0tMSxyPUFycmF5KHQuc2l6ZSk7cmV0dXJuIHQuZm9yRWFjaCgoZnVuY3Rpb24odCl7clsrK2VdPXR9KSkscn0sT3I9dT91LnByb3RvdHlwZTp2b2lkIDAsRnI9T3I/T3IudmFsdWVPZjp2b2lkIDA7dmFyIHpyPWZ1bmN0aW9uKHQsZSxyLG8sbixzLGkpe3N3aXRjaChyKXtjYXNlIltvYmplY3QgRGF0YVZpZXddIjppZih0LmJ5dGVMZW5ndGghPWUuYnl0ZUxlbmd0aHx8dC5ieXRlT2Zmc2V0IT1lLmJ5dGVPZmZzZXQpcmV0dXJuITE7dD10LmJ1ZmZlcixlPWUuYnVmZmVyO2Nhc2UiW29iamVjdCBBcnJheUJ1ZmZlcl0iOnJldHVybiEodC5ieXRlTGVuZ3RoIT1lLmJ5dGVMZW5ndGh8fCFzKG5ldyBJcih0KSxuZXcgSXIoZSkpKTtjYXNlIltvYmplY3QgQm9vbGVhbl0iOmNhc2UiW29iamVjdCBEYXRlXSI6Y2FzZSJbb2JqZWN0IE51bWJlcl0iOnJldHVybiBZKCt0LCtlKTtjYXNlIltvYmplY3QgRXJyb3JdIjpyZXR1cm4gdC5uYW1lPT1lLm5hbWUmJnQubWVzc2FnZT09ZS5tZXNzYWdlO2Nhc2UiW29iamVjdCBSZWdFeHBdIjpjYXNlIltvYmplY3QgU3RyaW5nXSI6cmV0dXJuIHQ9PWUrIiI7Y2FzZSJbb2JqZWN0IE1hcF0iOnZhciB1PWtyO2Nhc2UiW29iamVjdCBTZXRdIjp2YXIgYT0xJm87aWYodXx8KHU9TnIpLHQuc2l6ZSE9ZS5zaXplJiYhYSlyZXR1cm4hMTt2YXIgaD1pLmdldCh0KTtpZihoKXJldHVybiBoPT1lO298PTIsaS5zZXQodCxlKTt2YXIgbD1Scih1KHQpLHUoZSksbyxuLHMsaSk7cmV0dXJuIGkuZGVsZXRlKHQpLGw7Y2FzZSJbb2JqZWN0IFN5bWJvbF0iOmlmKEZyKXJldHVybiBGci5jYWxsKHQpPT1Gci5jYWxsKGUpfXJldHVybiExfTt2YXIgVHI9ZnVuY3Rpb24odCxlKXtmb3IodmFyIHI9LTEsbz1lLmxlbmd0aCxuPXQubGVuZ3RoOysrcjxvOyl0W24rcl09ZVtyXTtyZXR1cm4gdH07dmFyIFZyPWZ1bmN0aW9uKGUscixvKXt2YXIgbj1yKGUpO3JldHVybiB0KGUpP246VHIobixvKGUpKX07dmFyIFByPWZ1bmN0aW9uKHQsZSl7Zm9yKHZhciByPS0xLG89bnVsbD09dD8wOnQubGVuZ3RoLG49MCxzPVtdOysrcjxvOyl7dmFyIGk9dFtyXTtlKGkscix0KSYmKHNbbisrXT1pKX1yZXR1cm4gc307dmFyIHFyPWZ1bmN0aW9uKCl7cmV0dXJuW119LCRyPU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUsRHI9T2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyxVcj1Ecj9mdW5jdGlvbih0KXtyZXR1cm4gbnVsbD09dD9bXToodD1PYmplY3QodCksUHIoRHIodCksKGZ1bmN0aW9uKGUpe3JldHVybiAkci5jYWxsKHQsZSl9KSkpfTpxcjt2YXIgTHI9ZnVuY3Rpb24odCl7cmV0dXJuIFZyKHQsY3IsVXIpfSxCcj1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O3ZhciBHcj1mdW5jdGlvbih0LGUscixvLG4scyl7dmFyIGk9MSZyLHU9THIodCksYT11Lmxlbmd0aDtpZihhIT1McihlKS5sZW5ndGgmJiFpKXJldHVybiExO2Zvcih2YXIgaD1hO2gtLTspe3ZhciBsPXVbaF07aWYoIShpP2wgaW4gZTpCci5jYWxsKGUsbCkpKXJldHVybiExfXZhciBjPXMuZ2V0KHQpLGY9cy5nZXQoZSk7aWYoYyYmZilyZXR1cm4gYz09ZSYmZj09dDt2YXIgbT0hMDtzLnNldCh0LGUpLHMuc2V0KGUsdCk7Zm9yKHZhciBnPWk7KytoPGE7KXt2YXIgcD10W2w9dVtoXV0sdz1lW2xdO2lmKG8pdmFyIGQ9aT9vKHcscCxsLGUsdCxzKTpvKHAsdyxsLHQsZSxzKTtpZighKHZvaWQgMD09PWQ/cD09PXd8fG4ocCx3LHIsbyxzKTpkKSl7bT0hMTticmVha31nfHwoZz0iY29uc3RydWN0b3IiPT1sKX1pZihtJiYhZyl7dmFyIGI9dC5jb25zdHJ1Y3Rvcix5PWUuY29uc3RydWN0b3I7Yj09eXx8ISgiY29uc3RydWN0b3IiaW4gdCl8fCEoImNvbnN0cnVjdG9yImluIGUpfHwiZnVuY3Rpb24iPT10eXBlb2YgYiYmYiBpbnN0YW5jZW9mIGImJiJmdW5jdGlvbiI9PXR5cGVvZiB5JiZ5IGluc3RhbmNlb2YgeXx8KG09ITEpfXJldHVybiBzLmRlbGV0ZSh0KSxzLmRlbGV0ZShlKSxtfSxLcj0iW29iamVjdCBPYmplY3RdIixXcj1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O3ZhciBYcj1mdW5jdGlvbihlLHIsbyxuLHMsaSl7dmFyIHU9dChlKSxhPXQociksaD11PyJbb2JqZWN0IEFycmF5XSI6QnQoZSksbD1hPyJbb2JqZWN0IEFycmF5XSI6QnQociksYz0oaD0iW29iamVjdCBBcmd1bWVudHNdIj09aD9LcjpoKT09S3IsZj0obD0iW29iamVjdCBBcmd1bWVudHNdIj09bD9LcjpsKT09S3IsbT1oPT1sO2lmKG0mJnRyKGUpKXtpZighdHIocikpcmV0dXJuITE7dT0hMCxjPSExfWlmKG0mJiFjKXJldHVybiBpfHwoaT1uZXcgeHIpLHV8fGFyKGUpP1JyKGUscixvLG4scyxpKTp6cihlLHIsaCxvLG4scyxpKTtpZighKDEmbykpe3ZhciBnPWMmJldyLmNhbGwoZSwiX193cmFwcGVkX18iKSxwPWYmJldyLmNhbGwociwiX193cmFwcGVkX18iKTtpZihnfHxwKXt2YXIgdz1nP2UudmFsdWUoKTplLGQ9cD9yLnZhbHVlKCk6cjtyZXR1cm4gaXx8KGk9bmV3IHhyKSxzKHcsZCxvLG4saSl9fXJldHVybiEhbSYmKGl8fChpPW5ldyB4ciksR3IoZSxyLG8sbixzLGkpKX07dmFyIEpyPWZ1bmN0aW9uIHQoZSxyLG8sbixzKXtyZXR1cm4gZT09PXJ8fChudWxsPT1lfHxudWxsPT1yfHwhZChlKSYmIWQocik/ZSE9ZSYmciE9cjpYcihlLHIsbyxuLHQscykpfTt2YXIgWXI9ZnVuY3Rpb24odCxlLHIsbyl7dmFyIG49ci5sZW5ndGgscz1uLGk9IW87aWYobnVsbD09dClyZXR1cm4hcztmb3IodD1PYmplY3QodCk7bi0tOyl7dmFyIHU9cltuXTtpZihpJiZ1WzJdP3VbMV0hPT10W3VbMF1dOiEodVswXWluIHQpKXJldHVybiExfWZvcig7KytuPHM7KXt2YXIgYT0odT1yW25dKVswXSxoPXRbYV0sbD11WzFdO2lmKGkmJnVbMl0pe2lmKHZvaWQgMD09PWgmJiEoYSBpbiB0KSlyZXR1cm4hMX1lbHNle3ZhciBjPW5ldyB4cjtpZihvKXZhciBmPW8oaCxsLGEsdCxlLGMpO2lmKCEodm9pZCAwPT09Zj9KcihsLGgsMyxvLGMpOmYpKXJldHVybiExfX1yZXR1cm4hMH07dmFyIFpyPWZ1bmN0aW9uKHQpe3JldHVybiB0PT10JiYheCh0KX07dmFyIEhyPWZ1bmN0aW9uKHQpe2Zvcih2YXIgZT1jcih0KSxyPWUubGVuZ3RoO3ItLTspe3ZhciBvPWVbcl0sbj10W29dO2Vbcl09W28sbixacihuKV19cmV0dXJuIGV9O3ZhciBRcj1mdW5jdGlvbih0LGUpe3JldHVybiBmdW5jdGlvbihyKXtyZXR1cm4gbnVsbCE9ciYmKHJbdF09PT1lJiYodm9pZCAwIT09ZXx8dCBpbiBPYmplY3QocikpKX19O3ZhciB0bz1mdW5jdGlvbih0KXt2YXIgZT1Icih0KTtyZXR1cm4gMT09ZS5sZW5ndGgmJmVbMF1bMl0/UXIoZVswXVswXSxlWzBdWzFdKTpmdW5jdGlvbihyKXtyZXR1cm4gcj09PXR8fFlyKHIsdCxlKX19O3ZhciBlbz1mdW5jdGlvbih0LGUpe3JldHVybiBudWxsIT10JiZlIGluIE9iamVjdCh0KX07dmFyIHJvPWZ1bmN0aW9uKGUscixvKXtmb3IodmFyIG49LTEscz0ocj1qdChyLGUpKS5sZW5ndGgsaT0hMTsrK248czspe3ZhciB1PV90KHJbbl0pO2lmKCEoaT1udWxsIT1lJiZvKGUsdSkpKWJyZWFrO2U9ZVt1XX1yZXR1cm4gaXx8KytuIT1zP2k6ISEocz1udWxsPT1lPzA6ZS5sZW5ndGgpJiZHdChzKSYmcnIodSxzKSYmKHQoZSl8fEhlKGUpKX07dmFyIG9vPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG51bGwhPXQmJnJvKHQsZSxlbyl9O3ZhciBubz1mdW5jdGlvbih0LGUpe3JldHVybiBNKHQpJiZacihlKT9RcihfdCh0KSxlKTpmdW5jdGlvbihyKXt2YXIgbz1DdChyLHQpO3JldHVybiB2b2lkIDA9PT1vJiZvPT09ZT9vbyhyLHQpOkpyKGUsbywzKX19O3ZhciBzbz1mdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIEF0KGUsdCl9fTt2YXIgaW89ZnVuY3Rpb24odCl7cmV0dXJuIE0odCk/WHQoX3QodCkpOnNvKHQpfTt2YXIgdW89ZnVuY3Rpb24oZSl7cmV0dXJuImZ1bmN0aW9uIj09dHlwZW9mIGU/ZTpudWxsPT1lP21yOiJvYmplY3QiPT10eXBlb2YgZT90KGUpP25vKGVbMF0sZVsxXSk6dG8oZSk6aW8oZSl9O3ZhciBhbz1mdW5jdGlvbih0LGUpe3ZhciByPS0xLG89S3QodCk/QXJyYXkodC5sZW5ndGgpOltdO3JldHVybiBmcih0LChmdW5jdGlvbih0LG4scyl7b1srK3JdPWUodCxuLHMpfSkpLG99O3ZhciBobz1mdW5jdGlvbihlLHIpe3JldHVybih0KGUpP3Z0OmFvKShlLHVvKHIpKX07dmFyIGxvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHZ0KGUsKGZ1bmN0aW9uKGUpe3JldHVybiB0W2VdfSkpfTt2YXIgY289ZnVuY3Rpb24odCl7cmV0dXJuIG51bGw9PXQ/W106bG8odCxjcih0KSl9O2Z1bmN0aW9uIGZvKHQpe3JldHVybiJbb2JqZWN0IE9iamVjdF0iPT09T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpfWZ1bmN0aW9uIG1vKHQpe3JldHVybiJbb2JqZWN0IEFycmF5XSI9PT1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCl9ZnVuY3Rpb24gZ28odCl7cmV0dXJuIltvYmplY3QgU3RyaW5nXSI9PT1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCl9ZnVuY3Rpb24gcG8odCl7cmV0dXJuISFmdW5jdGlvbih0KXtyZXR1cm4iW29iamVjdCBVbmRlZmluZWRdIj09PU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KX0odCl8fCghIWZ1bmN0aW9uKHQpe3JldHVybiJbb2JqZWN0IE51bGxdIj09PU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KX0odCl8fCghIWZ1bmN0aW9uKHQpe2lmKGZvKHQpKXtmb3IobGV0IGUgaW4gdClyZXR1cm4hMTtyZXR1cm4hMH1yZXR1cm4hMX0odCl8fCghIWZ1bmN0aW9uKHQpe3JldHVybiEoIWdvKHQpfHwiIiE9PXQpfSh0KXx8ISFmdW5jdGlvbih0KXtyZXR1cm4hIW1vKHQpJiYwPT09dC5sZW5ndGh9KHQpKSkpfWZ1bmN0aW9uIHdvKHQpe3JldHVybiEhbW8odCkmJigwIT09dC5sZW5ndGgmJigxIT09dC5sZW5ndGh8fCFwbyh0WzBdKSkpfWZ1bmN0aW9uIGJvKHQpe3JldHVybiEoIWdvKHQpfHwiIj09PXQpfWZ1bmN0aW9uIHlvKHQsZSl7aWYoIWZvKHQpKXJldHVybnt9O2lmKCF3byhlKSlyZXR1cm57fTtsZXQgcj17fTtyZXR1cm4gcHIoZSwoZnVuY3Rpb24oZSl7KGZ1bmN0aW9uKHQsZSl7cmV0dXJuISFmbyh0KSYmISFibyhlKSYmZSBpbiB0fSkodCxlKSYmKHJbZV09Q3QodCxlKSl9KSkscn1mdW5jdGlvbiB2byh0KXtsZXQgZT0hMTtyZXR1cm4gYm8odCk/ZT0haXNOYU4oTnVtYmVyKHQpKTpmdW5jdGlvbih0KXtyZXR1cm4iW29iamVjdCBOdW1iZXJdIj09PU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KX0odCkmJihlPSEwKSxlfXZhciBNbz0vXHMvO3ZhciB4bz1mdW5jdGlvbih0KXtmb3IodmFyIGU9dC5sZW5ndGg7ZS0tJiZNby50ZXN0KHQuY2hhckF0KGUpKTspO3JldHVybiBlfSxFbz0vXlxzKy87dmFyIFNvPWZ1bmN0aW9uKHQpe3JldHVybiB0P3Quc2xpY2UoMCx4byh0KSsxKS5yZXBsYWNlKEVvLCIiKTp0fSxqbz0vXlstK10weFswLTlhLWZdKyQvaSxfbz0vXjBiWzAxXSskL2ksQW89L14wb1swLTddKyQvaSxDbz1wYXJzZUludDt2YXIgUm89ZnVuY3Rpb24odCl7aWYoIm51bWJlciI9PXR5cGVvZiB0KXJldHVybiB0O2lmKGIodCkpcmV0dXJuIE5hTjtpZih4KHQpKXt2YXIgZT0iZnVuY3Rpb24iPT10eXBlb2YgdC52YWx1ZU9mP3QudmFsdWVPZigpOnQ7dD14KGUpP2UrIiI6ZX1pZigic3RyaW5nIiE9dHlwZW9mIHQpcmV0dXJuIDA9PT10P3Q6K3Q7dD1Tbyh0KTt2YXIgcj1fby50ZXN0KHQpO3JldHVybiByfHxBby50ZXN0KHQpP0NvKHQuc2xpY2UoMikscj8yOjgpOmpvLnRlc3QodCk/TmFOOit0fTt2YXIgSW89ZnVuY3Rpb24odCl7cmV0dXJuIHQ/SW5maW5pdHk9PT0odD1Sbyh0KSl8fC1JbmZpbml0eT09PXQ/MTc5NzY5MzEzNDg2MjMxNTdlMjkyKih0PDA/LTE6MSk6dD09dD90OjA6MD09PXQ/dDowfTt2YXIga289ZnVuY3Rpb24odCl7dmFyIGU9SW8odCkscj1lJTE7cmV0dXJuIGU9PWU/cj9lLXI6ZTowfSxObz1pLmlzRmluaXRlLE9vPU1hdGgubWluO3ZhciBGbz1mdW5jdGlvbih0KXt2YXIgZT1NYXRoW3RdO3JldHVybiBmdW5jdGlvbih0LHIpe2lmKHQ9Um8odCksKHI9bnVsbD09cj8wOk9vKGtvKHIpLDI5MikpJiZObyh0KSl7dmFyIG89KFN0KHQpKyJlIikuc3BsaXQoImUiKSxuPWUob1swXSsiZSIrKCtvWzFdK3IpKTtyZXR1cm4rKChvPShTdChuKSsiZSIpLnNwbGl0KCJlIikpWzBdKyJlIisoK29bMV0tcikpfXJldHVybiBlKHQpfX0oInJvdW5kIik7ZnVuY3Rpb24gem8odCl7aWYoIXZvKHQpKXJldHVybiAwO3Q9ZnVuY3Rpb24odCl7cmV0dXJuIHZvKHQpP0lvKHQpOjB9KHQpO2xldCBlPUZvKHQpO3JldHVybiIwIj09PVN0cmluZyhlKT8wOmV9dmFyIFRvPUFycmF5LnByb3RvdHlwZS5qb2luO3ZhciBWbz1mdW5jdGlvbih0LGUpe3JldHVybiBudWxsPT10PyIiOlRvLmNhbGwodCxlKX07Y2xhc3MgUG97Y29uc3RydWN0b3IodCl7dGhpcy5nZXRDb3N0PSgpPT50aGlzLkVsZW1lbnRzLm1hcCgodD0+dC5EaXN0YW5jZUZyb21NZWRvaWQpKS5yZWR1Y2UoKCh0LGUpPT50K2UpLDApLHRoaXMuZmluZEJlc3RNZWRvaWRJZHg9dD0+dGhpcy5FbGVtZW50cy5tYXAoKGU9PnRoaXMuY2FsY0Nvc3RGb3JHaXZlbkVsZW1lbnRBc01lZG9pZChlLHQpKSkucmVkdWNlKCgodCxlLHIsbyk9PmUuQ29zdElmTWFkZU1lZG9pZDxvW3RdLkNvc3RJZk1hZGVNZWRvaWQ/cjp0KSwwKSx0aGlzLmNhbGNDb3N0Rm9yR2l2ZW5FbGVtZW50QXNNZWRvaWQ9KHQsZSk9Pih7Q29zdElmTWFkZU1lZG9pZDpuZXcgUG8oe0VsZW1lbnRzOnRoaXMuRWxlbWVudHMubWFwKChyPT4oe0Rpc3RhbmNlRnJvbU1lZG9pZDplKHIuRWxlbWVudCx0LkVsZW1lbnQpLEVsZW1lbnQ6ci5FbGVtZW50fSkpKSxNZWRvaWQ6dC5FbGVtZW50fSkuZ2V0Q29zdCgpLEVsZW1lbnQ6dH0pLHRoaXMuRWxlbWVudHM9dC5FbGVtZW50cyx0aGlzLk1lZG9pZD10Lk1lZG9pZH19dmFyIHFvPVBvLCRvPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7Q2x1c3Rlcjpxb30sIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLERvPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7ZGlzdGFuY2U6KHQsZSk9PntpZih0Lmxlbmd0aCE9PWUubGVuZ3RoKXRocm93IG5ldyBFcnJvcigidGhlIGlucHV0cyBtdXN0IGhhdmUgdGhlIHNhbWUgZGltZW5zaW9uIik7Y29uc3Qgcj1BcnJheS5mcm9tKHQua2V5cygpKS5tYXAoKHI9Pk1hdGgucG93KE1hdGguYWJzKHRbcl0tZVtyXSksMikpKS5yZWR1Y2UoKCh0LGUpPT50K2UpLDApO3JldHVybiBNYXRoLnNxcnQocil9fSwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSksVW89T2JqZWN0LmRlZmluZVByb3BlcnR5KHtrR3RFbGVtZW50QXJyTGVuZ3RoOiJrIG11c3QgYmUgbGVzcyB0aGFuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGlucHV0IGFycmF5In0sIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pO2NsYXNzIExve2NvbnN0cnVjdG9yKHQsZSxyKXt0aGlzLkVsZW1lbnRzPXQsdGhpcy5LPWUsdGhpcy5EaXN0YW5jZUZuPXIsdGhpcy5PcHRpbWlzYXRpb25Db21wbGV0ZWQ9ITEsdGhpcy5pdGVyYXRlPSgpPT57dGhpcy5JdGVyYXRpb25Db3VudCsrLHRoaXMuQ2x1c3RlcnN8fHRoaXMuYWxsb2NhdGVUb0NsdXN0ZXJzQXJvdW5kQ3VycmVudE1lZG9pZHMoKTtjb25zdCB0PXRoaXMuTWVkb2lkcyxlPXRoaXMuQ2x1c3RlcnMscj10aGlzLmNhbGN1bGF0ZUN1cnJlbnRDb3N0KCk7bGV0IG89cjtmb3IobGV0IHQ9MDt0PHRoaXMuTWVkb2lkcy5sZW5ndGg7dCsrKXtjb25zdCBlPXQ9PjA9PT10aGlzLk1lZG9pZHMuZmlsdGVyKChlPT4wPT09dGhpcy5EaXN0YW5jZUZuKHQsZSkpKS5sZW5ndGg7Zm9yKGNvbnN0IHIgb2YgdGhpcy5FbGVtZW50cy5maWx0ZXIoZSkpe2NvbnN0IGU9dGhpcy5NZWRvaWRzLnNsaWNlKCk7ZVt0XT1yO2NvbnN0IG49bmV3IExvKHRoaXMuRWxlbWVudHMuc2xpY2UoKSx0aGlzLkssdGhpcy5EaXN0YW5jZUZuKTtuLk1lZG9pZHM9ZSxuLmFsbG9jYXRlVG9DbHVzdGVyc0Fyb3VuZEN1cnJlbnRNZWRvaWRzKCk7Y29uc3Qgcz1uLmNhbGN1bGF0ZUN1cnJlbnRDb3N0KCk7czxvJiYobz1zLHRoaXMuQ2x1c3RlcnM9bi5DbHVzdGVycyx0aGlzLk1lZG9pZHM9ZSl9fXJldHVybiB0aGlzLmNhbGN1bGF0ZUN1cnJlbnRDb3N0KCk8cnx8KHRoaXMuQ2x1c3RlcnM9ZSx0aGlzLk1lZG9pZHM9dCx0aGlzLk9wdGltaXNhdGlvbkNvbXBsZXRlZD0hMCwhMSl9LHRoaXMuZ2V0Q2x1c3RlcmVkRGF0YT0oKT0+KHRoaXMuT3B0aW1pc2F0aW9uQ29tcGxldGVkfHx0aGlzLnJ1blRvQ29tcGxldGlvbigpLHRoaXMuQ2x1c3RlcnMubWFwKCh0PT50LkVsZW1lbnRzLm1hcCgodD0+dC5FbGVtZW50KSkpKSksdGhpcy5ydW5Ub0NvbXBsZXRpb249KCk9Pntmb3IoO3RoaXMuaXRlcmF0ZSgpOyk7fSx0aGlzLmFsbG9jYXRlVG9DbHVzdGVyc0Fyb3VuZEN1cnJlbnRNZWRvaWRzPSgpPT57dGhpcy5DbHVzdGVycz1uZXcgQXJyYXksdGhpcy5NZWRvaWRzLmZvckVhY2goKHQ9Pnt0aGlzLkNsdXN0ZXJzLnB1c2gobmV3ICRvLkNsdXN0ZXIoe0VsZW1lbnRzOltdLE1lZG9pZDp0fSkpfSkpLHRoaXMuRWxlbWVudHMuZm9yRWFjaCgoKHQsZSk9Pntjb25zdCByPXRoaXMuZmluZERpc3RhbmNlcyh0aGlzLkNsdXN0ZXJzLm1hcCgodD0+dC5NZWRvaWQpKSx0KSxvPXIucmVkdWNlKCgodCxlLHIsbyk9PmU8b1t0XT9yOnQpLDApO3RoaXMuQ2x1c3RlcnNbb10uRWxlbWVudHMucHVzaCh7RGlzdGFuY2VGcm9tTWVkb2lkOnJbb10sRWxlbWVudDp0fSl9KSl9LHRoaXMuY2FsY3VsYXRlQ3VycmVudENvc3Q9KCk9PnRoaXMuQ2x1c3RlcnMubWFwKCh0PT50LmdldENvc3QoKSkpLnJlZHVjZSgoKHQsZSk9PnQrZSksMCksdGhpcy5maW5kRGlzdGFuY2VzPSh0LGUpPT50Lm1hcCgodD0+dGhpcy5EaXN0YW5jZUZuKHQsZSkpKSx0aGlzLnNlbGVjdEluaXRpYWxNZWRvaWRzPSgpPT57aWYodGhpcy5LPj10aGlzLkVsZW1lbnRzLmxlbmd0aCl0aHJvdyBVby5rR3RFbGVtZW50QXJyTGVuZ3RoO2NvbnN0IHQ9W10sZT0odCxlKT0+e2Zvcihjb25zdCByIG9mIGUpaWYoMD09PXRoaXMuRGlzdGFuY2VGbihyLHQpKXJldHVybiExO3JldHVybiEwfTtsZXQgcj0wO2Zvcig7cjx0aGlzLkVsZW1lbnRzLmxlbmd0aCYmdC5sZW5ndGg8dGhpcy5LOyllKHRoaXMuRWxlbWVudHNbcl0sdCkmJnQucHVzaCh0aGlzLkVsZW1lbnRzW3JdKSxyKys7cmV0dXJuIHR9LHRoaXMuRGlzdGFuY2VGbj10aGlzLkRpc3RhbmNlRm58fERvLmRpc3RhbmNlLHRoaXMuTWVkb2lkcz10aGlzLnNlbGVjdEluaXRpYWxNZWRvaWRzKCksdGhpcy5JdGVyYXRpb25Db3VudD0wfWdldCBPcHRpbWlzYXRpb25TdGFydGVkKCl7cmV0dXJuIHRoaXMuSXRlcmF0aW9uQ291bnQ+MH19TG8uY2x1c3RlckVsZW1lbnRzPSh0LGUscik9PntMby5nZXRJbnN0YW5jZSh0LGUscik7cmV0dXJuIG5ldyBBcnJheX0sTG8uZ2V0SW5zdGFuY2U9KHQsZSxyKT0+bmV3IExvKHQsZSxyKTt2YXIgQm89TG8sR289T2JqZWN0LmRlZmluZVByb3BlcnR5KHtDbHVzdGVyZXI6Qm99LCJfX2VzTW9kdWxlIix7dmFsdWU6ITB9KSxLbz1yKG8oKGZ1bmN0aW9uKHQsZSl7ZnVuY3Rpb24gcih0KXtmb3IodmFyIHIgaW4gdCllLmhhc093blByb3BlcnR5KHIpfHwoZVtyXT10W3JdKX1PYmplY3QuZGVmaW5lUHJvcGVydHkoZSwiX19lc01vZHVsZSIse3ZhbHVlOiEwfSkscigkbykscihHbyl9KSkpO2Z1bmN0aW9uIFdvKHQsZSl7bGV0IHI9MDtmb3IobGV0IG89MDtvPHQubGVuZ3RoO28rKylyKz0odFtvXS1lW29dKSoodFtvXS1lW29dKTtyZXR1cm4gcn1jb25zdCBYbz17ZGlzdGFuY2VGdW5jdGlvbjpXb307ZnVuY3Rpb24gSm8odCxlLHI9WG8pe2NvbnN0IG89ci5kaXN0YW5jZUZ1bmN0aW9ufHxYby5kaXN0YW5jZUZ1bmN0aW9uLG49ci5zaW1pbGFyaXR5RnVuY3Rpb258fFhvLnNpbWlsYXJpdHlGdW5jdGlvbjtsZXQgcz0tMTtpZigiZnVuY3Rpb24iPT10eXBlb2Ygbil7bGV0IHI9TnVtYmVyLk1JTl9WQUxVRTtmb3IobGV0IG89MDtvPHQubGVuZ3RoO28rKyl7Y29uc3QgaT1uKGUsdFtvXSk7aT5yJiYocj1pLHM9byl9fWVsc2V7aWYoImZ1bmN0aW9uIiE9dHlwZW9mIG8pdGhyb3cgbmV3IEVycm9yKCJBIHNpbWlsYXJpdHkgb3IgZGlzdGFuY2UgZnVuY3Rpb24gaXQncyByZXF1aXJlZCIpO3tsZXQgcj1OdW1iZXIuTUFYX1ZBTFVFO2ZvcihsZXQgbj0wO248dC5sZW5ndGg7bisrKXtjb25zdCBpPW8oZSx0W25dKTtpPHImJihyPWkscz1uKX19fXJldHVybiBzfWZ1bmN0aW9uIFlvKHQsZSxyLG8pe2Zvcih2YXIgbj0wO248dC5sZW5ndGg7bisrKXJbbl09Sm8oZSx0W25dLHtkaXN0YW5jZUZ1bmN0aW9uOm99KTtyZXR1cm4gcn1mdW5jdGlvbiBabyh0LGUpe2NvbnN0IHI9NjU1MzUmKHQ+Pj49MCk7cmV0dXJuKCh0LXIpKihlPj4+PTApPj4+MCkrciplPj4+MH1jbGFzcyBIb3tjb25zdHJ1Y3Rvcih0PURhdGUubm93KCkpe3RoaXMuc3RhdGU9bmV3IFVpbnQzMkFycmF5KDQpLHRoaXMuaW5pdCh0KSx0aGlzLnJhbmRvbT10aGlzLmdldEZsb2F0LmJpbmQodGhpcyl9Z2V0VWludDMyKCl7cmV0dXJuIHRoaXMubmV4dFN0YXRlKCksdGhpcy5zdGF0ZVszXSt0aGlzLnN0YXRlWzJdPj4+MH1nZXRGbG9hdCgpe3JldHVybiA1Ljk2MDQ2NDQ3NzUzOTA2M2UtOCoodGhpcy5nZXRVaW50MzIoKT4+PjgpfWluaXQodCl7aWYoIU51bWJlci5pc0ludGVnZXIodCkpdGhyb3cgbmV3IFR5cGVFcnJvcigic2VlZCBtdXN0IGJlIGFuIGludGVnZXIiKTt0aGlzLnN0YXRlWzBdPXQsdGhpcy5zdGF0ZVsxXT0wLHRoaXMuc3RhdGVbMl09MCx0aGlzLnN0YXRlWzNdPTA7Zm9yKGxldCB0PTE7dDw4O3QrKyl0aGlzLnN0YXRlWzMmdF1ePXQrWm8oMTgxMjQzMzI1Myx0aGlzLnN0YXRlW3QtMSYzXV50aGlzLnN0YXRlW3QtMSYzXT4+PjMwPj4+MCk+Pj4wO3RoaXMucGVyaW9kQ2VydGlmaWNhdGlvbigpO2ZvcihsZXQgdD0wO3Q8ODt0KyspdGhpcy5uZXh0U3RhdGUoKX1wZXJpb2RDZXJ0aWZpY2F0aW9uKCl7MD09PXRoaXMuc3RhdGVbMF0mJjA9PT10aGlzLnN0YXRlWzFdJiYwPT09dGhpcy5zdGF0ZVsyXSYmMD09PXRoaXMuc3RhdGVbM10mJih0aGlzLnN0YXRlWzBdPTg4LHRoaXMuc3RhdGVbMV09ODMsdGhpcy5zdGF0ZVsyXT02NSx0aGlzLnN0YXRlWzNdPTY4KX1uZXh0U3RhdGUoKXtsZXQgdD10aGlzLnN0YXRlWzBdO3RePXQ8PDE1LHRePXQ+Pj4xOCx0Xj10aGlzLnN0YXRlWzNdPDwxMSx0aGlzLnN0YXRlWzBdPXRoaXMuc3RhdGVbMV0sdGhpcy5zdGF0ZVsxXT10aGlzLnN0YXRlWzJdLHRoaXMuc3RhdGVbMl09dGhpcy5zdGF0ZVszXSx0aGlzLnN0YXRlWzNdPXR9fWZ1bmN0aW9uIFFvKHQsZT17fSxyPU1hdGgucmFuZG9tKXtjb25zdHtzaXplOm89MSxyZXBsYWNlOm49ITEscHJvYmFiaWxpdGllczpzfT1lO2xldCBpLHU7aWYoaT0ibnVtYmVyIj09dHlwZW9mIHQ/ZnVuY3Rpb24odCl7Y29uc3QgZT1bXTtmb3IobGV0IHI9MDtyPHQ7cisrKWUucHVzaChyKTtyZXR1cm4gZX0odCk6dC5zbGljZSgpLHMpe2lmKCFuKXRocm93IG5ldyBFcnJvcigiY2hvaWNlIHdpdGggcHJvYmFiaWxpdGllcyBhbmQgbm8gcmVwbGFjZW1lbnQgaXMgbm90IGltcGxlbWVudGVkIik7aWYocy5sZW5ndGghPT1pLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoInRoZSBsZW5ndGggb2YgcHJvYmFiaWxpdGllcyBvcHRpb24gc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgY2hvaWNlcyIpO3U9W3NbMF1dO2ZvcihsZXQgdD0xO3Q8cy5sZW5ndGg7dCsrKXVbdF09dVt0LTFdK3NbdF07aWYoTWF0aC5hYnMoMS11W3UubGVuZ3RoLTFdKT4xZS04KXRocm93IG5ldyBFcnJvcihgcHJvYmFiaWxpdGllcyBzaG91bGQgc3VtIHRvIDEsIGJ1dCBpbnN0ZWFkIHN1bXMgdG8gJHt1W3UubGVuZ3RoLTFdfWApfWlmKCExPT09biYmbz5pLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoInNpemUgb3B0aW9uIGlzIHRvbyBsYXJnZSIpO2NvbnN0IGE9W107Zm9yKGxldCB0PTA7dDxvO3QrKyl7Y29uc3QgdD10bihpLmxlbmd0aCxyLHUpO2EucHVzaChpW3RdKSxufHxpLnNwbGljZSh0LDEpfXJldHVybiBhfWZ1bmN0aW9uIHRuKHQsZSxyKXtjb25zdCBvPWUoKTtpZihyKXtsZXQgdD0wO2Zvcig7bz5yW3RdOyl0Kys7cmV0dXJuIHR9cmV0dXJuIE1hdGguZmxvb3Iobyp0KX1jbGFzcyBlbntjb25zdHJ1Y3Rvcih0PU1hdGgucmFuZG9tKXtpZigibnVtYmVyIj09dHlwZW9mIHQpe2NvbnN0IGU9bmV3IEhvKHQpO3RoaXMucmFuZG9tR2VuZXJhdG9yPWUucmFuZG9tfWVsc2UgdGhpcy5yYW5kb21HZW5lcmF0b3I9dH1jaG9pY2UodCxlKXtyZXR1cm4gUW8odCxlLHRoaXMucmFuZG9tR2VuZXJhdG9yKX1yYW5kb20oKXtyZXR1cm4gdGhpcy5yYW5kb21HZW5lcmF0b3IoKX1yYW5kSW50KHQsZSl7cmV0dXJuIHZvaWQgMD09PWUmJihlPXQsdD0wKSx0K01hdGguZmxvb3IodGhpcy5yYW5kb21HZW5lcmF0b3IoKSooZS10KSl9cmFuZG9tU2FtcGxlKHQpe2NvbnN0IGU9W107Zm9yKGxldCByPTA7cjx0O3IrKyllLnB1c2godGhpcy5yYW5kb20oKSk7cmV0dXJuIGV9fWZ1bmN0aW9uIHJuKHQsZSl7Y29uc3Qgcj1uZXcgRmUodC5yb3dzLGUucm93cyk7Zm9yKGxldCBvPTA7bzx0LnJvd3M7bysrKWZvcihsZXQgbj0wO248ZS5yb3dzO24rKylyLnNldChvLG4sV28odC5nZXRSb3cobyksZS5nZXRSb3cobikpKTtyZXR1cm4gcn1mdW5jdGlvbiBvbih0KXtsZXQgZT1bXTtmb3IobGV0IHI9MDtyPHQ7cisrKWUucHVzaChyKTtyZXR1cm4gZX1mdW5jdGlvbiBubih0KXtsZXQgZT1bdFswXV07Zm9yKGxldCByPTE7cjx0Lmxlbmd0aDtyKyspZVtyXT1lW3ItMV0rdFtyXTtyZXR1cm4gZX1jb25zdCBzbj1TeW1ib2woImRpc3RhbmNlIik7Y2xhc3MgdW57Y29uc3RydWN0b3IodCxlLHIsbyxuKXt0aGlzLmNsdXN0ZXJzPXQsdGhpcy5jZW50cm9pZHM9ZSx0aGlzLmNvbnZlcmdlZD1yLHRoaXMuaXRlcmF0aW9ucz1vLHRoaXNbc25dPW59bmVhcmVzdCh0KXtjb25zdCBlPW5ldyBBcnJheSh0Lmxlbmd0aCk7cmV0dXJuIFlvKHQsdGhpcy5jZW50cm9pZHMubWFwKChmdW5jdGlvbih0KXtyZXR1cm4gdC5jZW50cm9pZH0pKSxlLHRoaXNbc25dKX1jb21wdXRlSW5mb3JtYXRpb24odCl7Zm9yKHZhciBlPXRoaXMuY2VudHJvaWRzLm1hcCgoZnVuY3Rpb24odCl7cmV0dXJue2NlbnRyb2lkOnQsZXJyb3I6MCxzaXplOjB9fSkpLHI9MDtyPHQubGVuZ3RoO3IrKyllW3RoaXMuY2x1c3RlcnNbcl1dLmVycm9yKz10aGlzW3NuXSh0W3JdLHRoaXMuY2VudHJvaWRzW3RoaXMuY2x1c3RlcnNbcl1dKSxlW3RoaXMuY2x1c3RlcnNbcl1dLnNpemUrKztmb3IodmFyIG89MDtvPHRoaXMuY2VudHJvaWRzLmxlbmd0aDtvKyspZVtvXS5zaXplP2Vbb10uZXJyb3IvPWVbb10uc2l6ZTplW29dLmVycm9yPW51bGw7cmV0dXJuIG5ldyB1bih0aGlzLmNsdXN0ZXJzLGUsdGhpcy5jb252ZXJnZWQsdGhpcy5pdGVyYXRpb25zLHRoaXNbc25dKX19Y29uc3QgYW49e21heEl0ZXJhdGlvbnM6MTAwLHRvbGVyYW5jZToxZS02LHdpdGhJdGVyYXRpb25zOiExLGluaXRpYWxpemF0aW9uOiJrbWVhbnMrKyIsZGlzdGFuY2VGdW5jdGlvbjpXb307ZnVuY3Rpb24gaG4odCxlLHIsbyxuLHMpe3ZhciBpPWZ1bmN0aW9uKHQsZSxyLG8pe2NvbnN0IG49ZVswXS5sZW5ndGg7Zm9yKHZhciBzPW5ldyBBcnJheShvKSxpPW5ldyBBcnJheShvKSx1PTA7dTxvO3UrKyl7c1t1XT1uZXcgQXJyYXkobiksaVt1XT0wO2Zvcih2YXIgYT0wO2E8bjthKyspc1t1XVthXT0wfWZvcih2YXIgaD0wO2g8ZS5sZW5ndGg7aCsrKXtpW3JbaF1dKys7Zm9yKHZhciBsPTA7bDxuO2wrKylzW3JbaF1dW2xdKz1lW2hdW2xdfWZvcih2YXIgYz0wO2M8bztjKyspZm9yKHZhciBmPTA7ZjxuO2YrKylpW2NdP3NbY11bZl0vPWlbY106c1tjXVtmXT10W2NdW2ZdO3JldHVybiBzfSh0LGUscj1ZbyhlLHQscixuLmRpc3RhbmNlRnVuY3Rpb24pLG8pLHU9ZnVuY3Rpb24odCxlLHIsbyl7Zm9yKHZhciBuPTA7bjx0Lmxlbmd0aDtuKyspaWYocih0W25dLGVbbl0pPm8pcmV0dXJuITE7cmV0dXJuITB9KGksdCxuLmRpc3RhbmNlRnVuY3Rpb24sbi50b2xlcmFuY2UpO3JldHVybiBuZXcgdW4ocixpLHUscyxuLmRpc3RhbmNlRnVuY3Rpb24pfWZ1bmN0aW9uIGxuKHQsZSxyKXtpZihyPU9iamVjdC5hc3NpZ24oe30sYW4sciksZTw9MHx8ZT50Lmxlbmd0aHx8IU51bWJlci5pc0ludGVnZXIoZSkpdGhyb3cgbmV3IEVycm9yKCJLIHNob3VsZCBiZSBhIHBvc2l0aXZlIGludGVnZXIgc21hbGxlciB0aGFuIHRoZSBudW1iZXIgb2YgcG9pbnRzIik7dmFyIG87aWYoQXJyYXkuaXNBcnJheShyLmluaXRpYWxpemF0aW9uKSl7aWYoci5pbml0aWFsaXphdGlvbi5sZW5ndGghPT1lKXRocm93IG5ldyBFcnJvcigiVGhlIGluaXRpYWwgY2VudGVycyBzaG91bGQgaGF2ZSB0aGUgc2FtZSBsZW5ndGggYXMgSyIpO289ci5pbml0aWFsaXphdGlvbn1lbHNlIHN3aXRjaChyLmluaXRpYWxpemF0aW9uKXtjYXNlImttZWFucysrIjpvPWZ1bmN0aW9uKHQsZSxyPXt9KXtjb25zdCBvPSh0PW5ldyBGZSh0KSkucm93cyxuPW5ldyBlbihyLnNlZWQpLHM9W10saT1yLmxvY2FsVHJpYWxzfHwyK01hdGguZmxvb3IoTWF0aC5sb2coZSkpLHU9bi5yYW5kSW50KG8pO3MucHVzaCh0LmdldFJvdyh1KSk7bGV0IGE9bmV3IEZlKDEsdC5yb3dzKTtmb3IobGV0IGU9MDtlPHQucm93cztlKyspYS5zZXQoMCxlLFdvKHQuZ2V0Um93KGUpLHNbMF0pKTtsZXQgaD1bbm4oYS5nZXRSb3coMCkpXTtjb25zdCBsPTEvaFswXVtvLTFdO2xldCBjPUZlLm11bChhLGwpO2ZvcihsZXQgcj0xO3I8ZTtyKyspe2NvbnN0IGU9bi5jaG9pY2Uobyx7cmVwbGFjZTohMCxzaXplOmkscHJvYmFiaWxpdGllczpjWzBdfSksdT1ybih0LnNlbGVjdGlvbihlLG9uKHQuY29sdW1ucykpLHQpO2xldCBsLGYsbTtmb3IobGV0IHQ9MDt0PGk7dCsrKXtjb25zdCByPUZlLm1pbihhLFt1LmdldFJvdyh0KV0pLG89ci5zdW0oKTsodm9pZCAwPT09bHx8bzxmKSYmKGw9ZVt0XSxmPW8sbT1yKX1zW3JdPXQuZ2V0Um93KGwpLGE9bSxoPVtubihhLmdldFJvdygwKSldLGM9RmUubXVsKGEsMS9oWzBdW28tMV0pfXJldHVybiBzfSh0LGUscik7YnJlYWs7Y2FzZSJyYW5kb20iOm89ZnVuY3Rpb24odCxlLHIpe3JldHVybiBuZXcgZW4ocikuY2hvaWNlKHQse3NpemU6ZX0pfSh0LGUsci5zZWVkKTticmVhaztjYXNlIm1vc3REaXN0YW50IjpvPWZ1bmN0aW9uKHQsZSxyLG8pe2NvbnN0IG49bmV3IGVuKG8pO3ZhciBzPW5ldyBBcnJheShlKTtpZihzWzBdPU1hdGguZmxvb3Iobi5yYW5kb20oKSp0Lmxlbmd0aCksZT4xKXtmb3IodmFyIGk9e2Rpc3Q6LTEsaW5kZXg6LTF9LHU9MDt1PHQubGVuZ3RoOysrdSlyW3NbMF1dW3VdPmkuZGlzdCYmKGkuZGlzdD1yW3NbMF1dW3VdLGkuaW5kZXg9dSk7aWYoc1sxXT1pLmluZGV4LGU+Milmb3IodmFyIGE9MjthPGU7KythKXtmb3IodmFyIGg9e2Rpc3Q6LTEsaW5kZXg6LTF9LGw9MDtsPHQubGVuZ3RoOysrbCl7Zm9yKHZhciBjPXtkaXN0Ok51bWJlci5NQVhfVkFMVUUsaW5kZXg6LTF9LGY9MDtmPGE7KytmKXJbZl1bbF08Yy5kaXN0JiYtMT09PXMuaW5kZXhPZihsKSYmKGM9e2Rpc3Q6cltmXVtsXSxpbmRleDpsfSk7Yy5kaXN0IT09TnVtYmVyLk1BWF9WQUxVRSYmYy5kaXN0PmguZGlzdCYmKGg9T2JqZWN0LmFzc2lnbih7fSxjKSl9c1thXT1oLmluZGV4fX1yZXR1cm4gcy5tYXAoKGU9PnRbZV0pKX0odCxlLGZ1bmN0aW9uKHQsZSl7Zm9yKHZhciByPW5ldyBBcnJheSh0Lmxlbmd0aCksbz0wO288dC5sZW5ndGg7KytvKWZvcih2YXIgbj1vO248dC5sZW5ndGg7KytuKXtyW29dfHwocltvXT1uZXcgQXJyYXkodC5sZW5ndGgpKSxyW25dfHwocltuXT1uZXcgQXJyYXkodC5sZW5ndGgpKTtjb25zdCBzPWUodFtvXSx0W25dKTtyW29dW25dPXMscltuXVtvXT1zfXJldHVybiByfSh0LHIuZGlzdGFuY2VGdW5jdGlvbiksci5zZWVkKTticmVhaztkZWZhdWx0OnRocm93IG5ldyBFcnJvcihgVW5rbm93biBpbml0aWFsaXphdGlvbiBtZXRob2Q6ICIke3IuaW5pdGlhbGl6YXRpb259ImApfTA9PT1yLm1heEl0ZXJhdGlvbnMmJihyLm1heEl0ZXJhdGlvbnM9TnVtYmVyLk1BWF9WQUxVRSk7dmFyIG49bmV3IEFycmF5KHQubGVuZ3RoKTtpZihyLndpdGhJdGVyYXRpb25zKXJldHVybiBmdW5jdGlvbioodCxlLHIsbyxuKXtmb3IodmFyIHMsaT0hMSx1PTA7IWkmJnU8bi5tYXhJdGVyYXRpb25zOylzPWhuKHQsZSxyLG8sbiwrK3UpLHlpZWxkIHMuY29tcHV0ZUluZm9ybWF0aW9uKGUpLGk9cy5jb252ZXJnZWQsdD1zLmNlbnRyb2lkc30obyx0LG4sZSxyKTtmb3IodmFyIHMsaT0hMSx1PTA7IWkmJnU8ci5tYXhJdGVyYXRpb25zOylpPShzPWhuKG8sdCxuLGUsciwrK3UpKS5jb252ZXJnZWQsbz1zLmNlbnRyb2lkcztyZXR1cm4gcy5jb21wdXRlSW5mb3JtYXRpb24odCl9ZnVuY3Rpb24gY24odCxlPXt9KXtsZXQgcj1DdChlLCJrTnVtYmVyIik7cj12byhyKT96byhyKToyO2xldCBvLG49Q3QoZSwibW9kZSIpO2lmKCJrLW1lZG9pZHMiIT09biYmImstbWVhbnMiIT09biYmKG49ImstbWVkb2lkcyIpLCJrLW1lZG9pZHMiPT09bilvPWZ1bmN0aW9uKHQsZSl7bGV0IHI9e307ZnVuY3Rpb24gbyh0KXtyZXR1cm4gVm8odCwiOiIpfXByKHQsKCh0LGUpPT57bGV0IG49byh0KTtyW25dPWV9KSk7bGV0IG49S28uQ2x1c3RlcmVyLmdldEluc3RhbmNlKHQsZSkuZ2V0Q2x1c3RlcmVkRGF0YSgpO3JldHVybiBuPWhvKG4sKHQ9PmhvKHQsKHQ9PntsZXQgZT1vKHQpO3JldHVybiByW2VdfSkpKSksbn0odCxyKTtlbHNle2lmKCJrLW1lYW5zIiE9PW4pdGhyb3cgbmV3IEVycm9yKCJpbnZhbGlkIG1vZGUiKTtvPWZ1bmN0aW9uKHQsZSl7bGV0IHI9bG4odCxlKSxvPXt9O3JldHVybiBwcihyLmNsdXN0ZXJzLCgodCxlKT0+e29bdF18fChvW3RdPVtdKSxvW3RdLnB1c2goZSl9KSksY28obyl9KHQscil9cmV0dXJuIG99ZnVuY3Rpb24gZm4odCxlPXt9KXtpZighd28odCkpdGhyb3cgbmV3IEVycm9yKCJkYXRhIGlzIG5vdCBlZmYuIGFycmF5Iik7bGV0IHI9Q3QoZSwia051bWJlciIpO3I9dm8ocik/em8ocik6MjtsZXQgbz1DdChlLCJuQ29tcE5JUEFMUyIpO289dm8obyk/em8obyk6MjtsZXQgbj1DdChlLCJtb2RlIikscz0iIixpPWxlKHQpLHU9MCxhPTA7aWYocHIodCwodD0+eyFmdW5jdGlvbih0KXtpZihmbyh0KSl7Zm9yKGxldCBlIGluIHQpcmV0dXJuITA7cmV0dXJuITF9cmV0dXJuITF9KHQpP3dvKHQpJiYoYSs9MSk6dSs9MX0pKSx1PT09aSlzPSJvYmoiO2Vsc2V7aWYoYSE9PWkpdGhyb3cgbmV3IEVycm9yKCJkYXRhIGlzIG5vdCBvZiB0aGUgc2FtZSB0eXBlIik7cz0ibWF0In1sZXQgaCxsPW51bGw7Im9iaiI9PT1zPyhsPWZ1bmN0aW9uKHQpe2xldCBlPXt9O3ByKHQsKHQ9Pntwcih0LCgodCxyKT0+e2Vbcl18fChlW3JdPTApLDA9PT1lW3JdJiZ2byh0KSYmKGVbcl09MSksMSE9PWVbcl18fHZvKHQpfHwoZVtyXT0tMSl9KSl9KSk7bGV0IHI9W107cmV0dXJuIHByKGUsKCh0LGUpPT57MT09PXQmJnIucHVzaChlKX0pKSxyfSh0KSxoPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGhvKHQsKHQ9PntsZXQgcj15byh0LGUpO3JldHVybiBjbyhyKX0pKX0odCxsKSk6aD10O2xldCBjPUJlKGgse25Db21wTklQQUxTOm99KSxmPWNuKGMse2tOdW1iZXI6cixtb2RlOm59KSxtPWhvKGYsKHQ9PmhvKHQsKHQ9PmNbdF0pKSkpO3JldHVybntrZXlzOmwsZ2luZHM6ZixnbHRkdDpobyhmLChlPT5obyhlLChlPT50W2VdKSkpKSxnbWF0Om19fWxldCBXQ2x1c3Rlcj17UENBOmFzeW5jIGZ1bmN0aW9uKHQsZT17fSl7cmV0dXJuIEJlKHQsZSl9LGNsdXN0ZXI6YXN5bmMgZnVuY3Rpb24odCxlPXt9KXt0cnl7cmV0dXJuIGZuKHQsZSl9Y2F0Y2godCl7cmV0dXJuIFByb21pc2UucmVqZWN0KHQpfX19OwoKbGV0IGluc3RhbmNlID0gbnVsbApmdW5jdGlvbiBpbml0KGlucHV0KXsKCiAgICAvL2luaXQKICAgIGxldCByID0gV0NsdXN0ZXIoLi4uaW5wdXQpCgogICAgLy9vbgogICAgCgogICAgLy9zYXZlCiAgICBpbnN0YW5jZSA9IHIKCn0KCmZ1bmN0aW9uIHNlbmRNZXNzYWdlKGRhdGEpIHsKICAgIHNlbGYucG9zdE1lc3NhZ2UoZGF0YSkKfQoKYXN5bmMgZnVuY3Rpb24gcnVuKGRhdGEpIHsKICAgIC8vIGNvbnNvbGUubG9nKCdpbm5lciB3b3JrZXIgcnVuJyxkYXRhKQoKICAgIC8vbW9kZQogICAgbGV0IG1vZGUgPSBkYXRhLm1vZGUKCiAgICAvL2NoZWNrCiAgICBpZihtb2RlICE9PSAnaW5pdCcgJiYgbW9kZSAhPT0gJ2NhbGwnKXsKICAgICAgICByZXR1cm4KICAgIH0KCiAgICAvL2luaXQKICAgIGlmKG1vZGUgPT09ICdpbml0Jyl7CiAgICAgICAgCiAgICAgICAgdHJ5ewoKICAgICAgICAgICAgLy90eXBlCiAgICAgICAgICAgIGxldCB0eXBlID0gZGF0YS50eXBlCgogICAgICAgICAgICAvL2lucHV0CiAgICAgICAgICAgIGxldCBpbnB1dCA9IGRhdGEuaW5wdXQKICAgIAogICAgICAgICAgICAvL2luc3RhbmNlCiAgICAgICAgICAgIGlmKHR5cGUgPT09ICdmdW5jdGlvbicpewogICAgICAgICAgICAgICAgaW5pdCguLi5pbnB1dCkKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKHR5cGUgPT09ICdvYmplY3QnKXsKICAgICAgICAgICAgICAgIGluc3RhbmNlID0gV0NsdXN0ZXIKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgY2F0Y2goZXJyKXsKICAgICAgICAKICAgICAgICAgICAgLy9zZW5kTWVzc2FnZQogICAgICAgICAgICBsZXQgcmVzID0gewogICAgICAgICAgICAgICAgbW9kZTogJ2VtaXQnLAogICAgICAgICAgICAgICAgZXZOYW1lOiAnZXJyb3InLAogICAgICAgICAgICAgICAgbXNnOiBlcnIsCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2VuZE1lc3NhZ2UocmVzKQoKICAgICAgICB9CiAgICAgICAgICAgIAogICAgfQoKICAgIC8vY2hlY2sKICAgIGlmKG1vZGUgPT09ICdjYWxsJyl7CiAgICAgICAgbGV0IHN0YXRlID0gJycKICAgICAgICBsZXQgbXNnID0gbnVsbAoKICAgICAgICB0cnl7CgogICAgICAgICAgICAvL2Z1bgogICAgICAgICAgICBsZXQgZnVuID0gaW5zdGFuY2VbZGF0YS5mdW5dCgogICAgICAgICAgICAvL2lucHV0CiAgICAgICAgICAgIGxldCBpbnB1dCA9IGRhdGEuaW5wdXQKCiAgICAgICAgICAgIC8vZXhlYwogICAgICAgICAgICBhd2FpdCBmdW4oLi4uaW5wdXQpCiAgICAgICAgICAgICAgICAudGhlbigoc3VjKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU9J3N1Y2Nlc3MnCiAgICAgICAgICAgICAgICAgICAgbXNnPXN1YwogICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGU9J2Vycm9yJwogICAgICAgICAgICAgICAgICAgIG1zZz1lcnIKICAgICAgICAgICAgICAgIH0pCgogICAgICAgIH0KICAgICAgICBjYXRjaChlcnIpewogICAgICAgICAgICBzdGF0ZSA9ICdlcnJvcicKICAgICAgICAgICAgbXNnID0gZXJyCiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vc2VuZE1lc3NhZ2UKICAgICAgICBsZXQgcmVzID0gewogICAgICAgICAgICBtb2RlOiAncmV0dXJuJywKICAgICAgICAgICAgaWQ6IGRhdGEuaWQsCiAgICAgICAgICAgIGZ1bjogZGF0YS5mdW4sCiAgICAgICAgICAgIHN0YXRlLAogICAgICAgICAgICBtc2csCiAgICAgICAgfQogICAgICAgIHNlbmRNZXNzYWdlKHJlcykKCiAgICB9Cgp9CgpzZWxmLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChlKSB7CiAgICAvLyBjb25zb2xlLmxvZygnaW5uZXIgd29ya2VyIHJlY3Y6JywgZS5kYXRhKQoKICAgIC8vZGF0YVJlY3YKICAgIGxldCBkYXRhUmVjdiA9IGUuZGF0YQoKICAgIC8vcnVuCiAgICBydW4oZGF0YVJlY3YpCgp9CiAgICAK");function i(){function d(d){var l,c=window.URL||window.webkitURL;try{return l=new Blob([d]),new Worker(c.createObjectURL(l))}catch(d){console.log(d)}}var l=d(t);if(null===l)return console.log("invalid webworker"),null;function c(){l.terminate(),l=void 0}var Z=m();function b(){var d={mode:"init",type:"object",input:Array.prototype.slice.call(arguments)};l.postMessage(d)}function X(){var d=K(),c=p(),b={mode:"call",id:c,fun:"PCA",input:Array.prototype.slice.call(arguments)};return l.postMessage(b),Z.once(c,(function(l){"success"===l.state?d.resolve(l.msg):d.reject(l.msg)})),d}function y(){var d=K(),c=p(),b={mode:"call",id:c,fun:"cluster",input:Array.prototype.slice.call(arguments)};return l.postMessage(b),Z.once(c,(function(l){"success"===l.state?d.resolve(l.msg):d.reject(l.msg)})),d}return l.onmessage=function(d){var l=d.data,c=l.mode;"emit"!==c&&"return"!==c||("emit"===c&&Z.emit(l.evName,l.msg),"return"===c&&Z.emit(l.id,l))},b(Array.prototype.slice.call(arguments)),Z.PCA=X,Z.cluster=y,Z.terminate=c,Z}var I,u,W=null,h={PCA:(u=Z(y.mark((function d(){var c,Z,b,X=arguments;return y.wrap((function(d){for(;;)switch(d.prev=d.next){case 0:return c=Array.prototype.slice.call(X),Z=i(),d.next=4,Z.PCA.apply(Z,l(c)).finally((function(){Z.terminate()}));case 4:return b=d.sent,d.abrupt("return",b);case 6:case"end":return d.stop()}}),d)}))),function(){return u.apply(this,arguments)}),cluster:(I=Z(y.mark((function d(){var c,Z,b,X=arguments;return y.wrap((function(d){for(;;)switch(d.prev=d.next){case 0:return c=Array.prototype.slice.call(X),Z=i(),d.next=4,Z.cluster.apply(Z,l(c)).finally((function(){Z.terminate()}));case 4:return b=d.sent,d.abrupt("return",b);case 6:case"end":return d.stop()}}),d)}))),function(){return I.apply(this,arguments)})};for(var o in W=m(),h){var V=h[o];W[o]=V}return W}));
|