@datagrok-libraries/statistics 1.0.0 → 1.0.2

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/lbfgs/lbfgs.js CHANGED
@@ -42,14 +42,14 @@ export function limitedMemoryBFGS(optimizable, parameters) {
42
42
  var oldValue = value;
43
43
 
44
44
  if (scale == 0.0) {
45
- console.log("Line search can't step in initial direction.");
45
+ //console.log("Line search can't step in initial direction.");
46
46
  }
47
47
 
48
48
  for (var iteration = 0; iteration < maxIterations; iteration++) {
49
49
  var start = +new Date();
50
50
  var end;
51
51
 
52
- //console.log("Beginning L-BFGS iteration, v=" + value + " ||g||=" + numeric.norm2(gradient));
52
+ ////console.log("Beginning L-BFGS iteration, v=" + value + " ||g||=" + numeric.norm2(gradient));
53
53
 
54
54
  // Update the buffers with diffs
55
55
  if (parameterChangeBuffer.length < memorySize) {
@@ -82,7 +82,9 @@ export function limitedMemoryBFGS(optimizable, parameters) {
82
82
  var scalingFactor = sy / yy;
83
83
  scaleBuffer.unshift(1.0 / sy);
84
84
 
85
- if (scalingFactor > 0.0) { console.log("Scaling factor greater than zero: " + scalingFactor); }
85
+ if (scalingFactor > 0.0) {
86
+ //console.log("Scaling factor greater than zero: " + scalingFactor);
87
+ }
86
88
 
87
89
  // Renaming the "gradient" array to "direction" -- but it's the same memory.
88
90
  copyInto(direction, gradient);
@@ -128,7 +130,7 @@ export function limitedMemoryBFGS(optimizable, parameters) {
128
130
 
129
131
  scale = backtrackingLineSearch(optimizable, direction, gradient, parameters);
130
132
  if (scale == 0.0) {
131
- console.log("Cannot step in current direction");
133
+ //console.log("Cannot step in current direction");
132
134
  }
133
135
 
134
136
  value = optimizable.getValue(parameters);
@@ -136,23 +138,23 @@ export function limitedMemoryBFGS(optimizable, parameters) {
136
138
 
137
139
  // Test for convergence
138
140
  if (2.0 * (value - oldValue) <= tolerance * (Math.abs(value) + Math.abs(oldValue) + epsilon)) {
139
- console.log("Value difference below threshold: " + value + " - " + oldValue);
141
+ //console.log("Value difference below threshold: " + value + " - " + oldValue);
140
142
  end = +new Date();
141
- console.log("Finished iterations " + (end - lbfgsStart));
143
+ //console.log("Finished iterations " + (end - lbfgsStart));
142
144
  return true;
143
145
  }
144
146
 
145
147
  var gradientNorm = numeric.norm2(gradient);
146
148
  if (gradientNorm < gradientTolerance) {
147
- console.log("Gradient norm below threshold: " + gradientNorm);
149
+ //console.log("Gradient norm below threshold: " + gradientNorm);
148
150
  end = +new Date();
149
- console.log("Finished iterations " + (end - lbfgsStart));
151
+ //console.log("Finished iterations " + (end - lbfgsStart));
150
152
  return true;
151
153
  }
152
154
  else if (gradientNorm == 0.0) {
153
- console.log("Gradient norm is zero");
155
+ //console.log("Gradient norm is zero");
154
156
  end = +new Date();
155
- console.log("Finished iterations " + (end - lbfgsStart));
157
+ //console.log("Finished iterations " + (end - lbfgsStart));
156
158
  return true;
157
159
  }
158
160
 
@@ -182,7 +184,7 @@ function backtrackingLineSearch(optimizable, direction, gradient, parameters) {
182
184
  // Make sure the initial step size isn't too big
183
185
  var twoNorm = numeric.norm2(direction);
184
186
  if (twoNorm > MAXIMUM_STEP) {
185
- console.log("Initial step " + twoNorm + " is too big, reducing")
187
+ //console.log("Initial step " + twoNorm + " is too big, reducing")
186
188
  numeric.muleq(direction, MAXIMUM_STEP / twoNorm);
187
189
  }
188
190
 
@@ -206,14 +208,14 @@ function backtrackingLineSearch(optimizable, direction, gradient, parameters) {
206
208
  }
207
209
 
208
210
  if (scale < minimumScale) {
209
- console.log("Step too small, exiting.");
211
+ //console.log("Step too small, exiting.");
210
212
  return 0.0;
211
213
  }
212
214
 
213
215
  var value = optimizable.getValue(parameters);
214
216
 
215
217
  if (value >= originalValue + DECREASE_FRACTION * scale * slope) {
216
- //console.log("Exiting line search at value " + value);
218
+ ////console.log("Exiting line search at value " + value);
217
219
  return scale;
218
220
  }
219
221
  else if (! isFinite(value)) {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "friendlyName": "statistics",
7
- "version": "1.0.0",
7
+ "version": "1.0.2",
8
8
  "description": "",
9
9
  "dependencies": {
10
10
  "datagrok-api": "1.12.1",
@@ -1,59 +1,18 @@
1
- declare type Likelihood = {
2
- value: number;
3
- const: number;
4
- mult: number;
1
+ declare type FitResult = {
2
+ parameters: number[];
3
+ fittedCurve: (x: number) => number;
4
+ confidenceTop: (x: number) => number;
5
+ confidenceBottom: (x: number) => number;
6
+ sigma: number;
5
7
  };
6
- interface ICurveFitter<TArg> {
7
- data: {
8
- observed: number[];
9
- args: TArg[];
10
- };
11
- params: number[];
12
- cf(params: number[], args: TArg): number;
13
- of(targetFunc: (params: number[], args: TArg) => number, data: {
14
- observed: number[];
15
- args: TArg[];
16
- }, params: number[]): Likelihood;
17
- }
18
- export declare class CurveFitter<TArg> implements ICurveFitter<TArg> {
19
- errorModel: string;
20
- data: {
21
- observed: number[];
22
- args: TArg[];
23
- };
24
- params: number[];
25
- cf: (params: number[], args: TArg) => number;
26
- of: typeof objectiveNormalConstant;
27
- optimizable: {
28
- getValue: (parameters: number[]) => number;
29
- getGradient: (parameters: number[], gradient: number[]) => number[];
30
- };
31
- fitHistory: {
32
- iterations: number;
33
- parameters: {
34
- [iteration: number]: number[];
35
- };
36
- likelihood: {
37
- [iteration: number]: number;
38
- };
39
- };
40
- constructor(curveFunction: (params: number[], args: TArg) => number, data: {
41
- observed: number[];
42
- args: TArg[];
43
- }, params: number[], errorModel?: 'constant' | 'proportional');
44
- performFit(): void;
45
- get parameters(): number[];
46
- get curveFunction(): Function;
47
- get confidence(): {
48
- top: Function;
49
- bottom: Function;
50
- };
51
- private getDerivative;
8
+ export declare enum FitErrorModel {
9
+ Constant = 0,
10
+ Proportional = 1
52
11
  }
12
+ export declare function fit(data: {
13
+ x: number[];
14
+ y: number[];
15
+ }, params: number[], curveFunction: (params: number[], x: number) => number, errorModel: FitErrorModel): FitResult;
53
16
  export declare function sigmoid(params: number[], x: number): number;
54
- declare function objectiveNormalConstant<TArg>(targetFunc: (params: number[], args: TArg) => number, data: {
55
- observed: number[];
56
- args: TArg[];
57
- }, params: number[]): Likelihood;
58
17
  export {};
59
18
  //# sourceMappingURL=fit-curve.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fit-curve.d.ts","sourceRoot":"","sources":["fit-curve.ts"],"names":[],"mappings":"AAEA,aAAK,UAAU,GAAG;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAA;CACb,CAAC;AAEF,UAAU,YAAY,CAAC,IAAI;IACzB,IAAI,EAAE;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,IAAI,EAAE,CAAA;KAAC,CAAC;IACzC,MAAM,EAAE,MAAM,EAAE,CAAC;IAGjB,EAAE,CAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAAA;IAEzC,EAAE,CAAE,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,EACxB,IAAI,EAAE;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,IAAI,EAAE,CAAA;KAAC,EACxC,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;CAC9D;AAED,qBAAa,WAAW,CAAC,IAAI,CAAE,YAAW,YAAY,CAAC,IAAI,CAAC;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,IAAI,EAAE,CAAA;KAAC,CAAC;IACzC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,EAAE,WAUkC,MAAM,EAAE,QAAQ,IAAI,KAAK,MAAM,CAVhE;IACH,EAAE,iCAAC;IACH,WAAW;+BAoCgB,MAAM,EAAE;kCAGL,MAAM,EAAE,YAAY,MAAM,EAAE;MAvC9C;IACZ,UAAU,EAAE;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE;YAAC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;SAAC,CAAC;QAC/D,UAAU,EAAE;YAAC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAA;SAAC,CAAA;KAAC,CAItD;gBAEU,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,EACvD,IAAI,EAAE;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,IAAI,EAAE,CAAA;KAAC,EACxC,MAAM,EAAE,MAAM,EAAE,EAChB,UAAU,GAAE,UAAU,GAAG,cAA2B;IA2ChE,UAAU,IAAI,IAAI;IAKlB,IAAI,UAAU,IAAI,MAAM,EAAE,CAEzB;IAED,IAAI,aAAa,IAAI,QAAQ,CAQ5B;IAED,IAAI,UAAU,IAAI;QAAC,GAAG,EAAC,QAAQ,CAAC;QAAC,MAAM,EAAE,QAAQ,CAAA;KAAC,CAwBjD;IAGD,OAAO,CAAC,aAAa;CAmBtB;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED,iBAAS,uBAAuB,CAAC,IAAI,EACG,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,EACpD,IAAI,EAAE;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,IAAI,EAAE,CAAA;CAAC,EACxC,MAAM,EAAE,MAAM,EAAE,GACrD,UAAU,CAuBZ"}
1
+ {"version":3,"file":"fit-curve.d.ts","sourceRoot":"","sources":["fit-curve.ts"],"names":[],"mappings":"AAQA,aAAK,SAAS,GAAG;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,CAAC,CAAC,EAAC,MAAM,KAAI,MAAM,CAAC;IACjC,aAAa,EAAE,CAAC,CAAC,EAAC,MAAM,KAAI,MAAM,CAAC;IACnC,gBAAgB,EAAE,CAAC,CAAC,EAAC,MAAM,KAAI,MAAM,CAAC;IACtC,KAAK,EAAE,MAAM,CAAA;CACd,CAAC;AAMF,oBAAY,aAAa;IACvB,QAAQ,IAAA;IACR,YAAY,IAAA;CACb;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAA;CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EACjD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,EAAE,UAAU,EAAE,aAAa,GAAG,SAAS,CAoEhH;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAO3D"}
@@ -1,100 +1,65 @@
1
1
  import { limitedMemoryBFGS } from "../../lbfgs/lbfgs";
2
- export class CurveFitter {
3
- constructor(curveFunction, data, params, errorModel = 'constant') {
4
- this.fitHistory = {
5
- iterations: 0,
6
- parameters: {},
7
- likelihood: {}
8
- };
9
- if (data.observed.length == 0 || data.observed.length != data.args.length)
10
- throw new Error('invalid data');
11
- this.data = data;
12
- this.params = params;
13
- this.errorModel = errorModel;
14
- this.cf = curveFunction;
15
- switch (errorModel) {
16
- case 'constant':
17
- this.of = objectiveNormalConstant;
18
- case 'proportional':
19
- this.of = objectiveNormalProportional;
20
- // case 'combinational1':
21
- // this.of = objectiveNormalAdditive;
22
- // case 'combinational2':
23
- // this.of = objectiveNormalAdditive;
24
- default:
25
- this.of = objectiveNormalConstant;
26
- }
27
- this.optimizable = {
28
- getValue: (parameters) => {
29
- return this.of(this.cf, this.data, parameters).value;
30
- },
31
- getGradient: (parameters, gradient) => {
32
- const length = Object.keys(this.fitHistory.parameters).length;
33
- this.fitHistory.iterations++;
34
- this.fitHistory.parameters[length] = parameters.slice();
35
- this.fitHistory.likelihood[length] = this.of(this.cf, this.data, parameters).value;
36
- console.log(parameters.slice());
37
- for (let i = 0; i < parameters.length; i++)
38
- gradient[i] = this.getDerivative(parameters, i);
39
- return gradient;
40
- }
41
- };
42
- }
43
- performFit() {
44
- limitedMemoryBFGS(this.optimizable, this.params);
45
- limitedMemoryBFGS(this.optimizable, this.params);
46
- }
47
- get parameters() {
48
- return this.params;
49
- }
50
- get curveFunction() {
51
- let res = (arg) => {
52
- let params = this.fitHistory.parameters[this.fitHistory.iterations - 1];
53
- return this.cf(params, arg);
54
- };
55
- return res;
56
- }
57
- get confidence() {
58
- let params = this.fitHistory.parameters[this.fitHistory.iterations - 1];
59
- let error = this.errorModel == "constant" ?
60
- this.of(this.cf, this.data, params).const :
61
- this.of(this.cf, this.data, params).mult;
62
- let top = (arg) => {
63
- let value = this.cf(params, arg);
64
- if (this.errorModel == "constant")
65
- return value + 1.4 * error;
66
- else
67
- return value + 1.4 * (Math.abs(value) * error);
68
- };
69
- let bottom = (arg) => {
70
- let value = this.cf(params, arg);
71
- if (this.errorModel == "constant")
72
- return value - 1.4 * error;
73
- else
74
- return value - 1.4 * (Math.abs(value) * error);
75
- };
76
- return { top: top, bottom: bottom };
2
+ export var FitErrorModel;
3
+ (function (FitErrorModel) {
4
+ FitErrorModel[FitErrorModel["Constant"] = 0] = "Constant";
5
+ FitErrorModel[FitErrorModel["Proportional"] = 1] = "Proportional";
6
+ })(FitErrorModel || (FitErrorModel = {}));
7
+ export function fit(data, params, curveFunction, errorModel) {
8
+ let of;
9
+ switch (errorModel) {
10
+ case FitErrorModel.Constant:
11
+ of = objectiveNormalConstant;
12
+ break;
13
+ case FitErrorModel.Proportional:
14
+ of = objectiveNormalProportional;
15
+ break;
16
+ default:
17
+ of = objectiveNormalConstant;
18
+ break;
77
19
  }
78
- //central difference
79
- getDerivative(params, selectedParam) {
80
- let step = params[selectedParam] * 0.0001;
81
- step = step == 0 ? 0.001 : step;
82
- let paramsTop = [];
83
- let paramsBottom = [];
84
- for (let i = 0; i < params.length; i++) {
85
- if (i == selectedParam) {
86
- paramsTop.push(params[i] + step);
87
- paramsBottom.push(params[i] - step);
88
- }
89
- else {
90
- paramsTop.push(params[i]);
91
- paramsBottom.push(params[i]);
92
- }
20
+ let iterations = 0;
21
+ let optimizable = {
22
+ getValue: (parameters) => {
23
+ return of(curveFunction, data, parameters).value;
24
+ },
25
+ getGradient: (parameters, gradient) => {
26
+ const length = Object.keys(parameters).length;
27
+ iterations++;
28
+ for (let i = 0; i < parameters.length; i++)
29
+ gradient[i] = getObjectiveDerivative(of, curveFunction, data, parameters, i);
30
+ return gradient;
93
31
  }
94
- const drvTop = this.of(this.cf, this.data, paramsTop).value;
95
- const drvBottom = this.of(this.cf, this.data, paramsBottom).value;
96
- return (drvTop - drvBottom) / (2 * step);
97
- }
32
+ };
33
+ limitedMemoryBFGS(optimizable, params);
34
+ limitedMemoryBFGS(optimizable, params);
35
+ let fittedCurve = (x) => {
36
+ return curveFunction(params, x);
37
+ };
38
+ let top = (x) => {
39
+ let value = curveFunction(params, x);
40
+ if (errorModel == FitErrorModel.Constant)
41
+ return value + 1.4 * error;
42
+ else
43
+ return value + 1.4 * (Math.abs(value) * error);
44
+ };
45
+ let error = errorModel == FitErrorModel.Proportional ?
46
+ of(curveFunction, data, params).const :
47
+ of(curveFunction, data, params).mult;
48
+ let bottom = (x) => {
49
+ let value = curveFunction(params, x);
50
+ if (errorModel == FitErrorModel.Constant)
51
+ return value - 1.4 * error;
52
+ else
53
+ return value - 1.4 * (Math.abs(value) * error);
54
+ };
55
+ let fitRes = {
56
+ parameters: params,
57
+ fittedCurve: fittedCurve,
58
+ confidenceTop: top,
59
+ confidenceBottom: bottom,
60
+ sigma: error
61
+ };
62
+ return fitRes;
98
63
  }
99
64
  export function sigmoid(params, x) {
100
65
  const A = params[0];
@@ -104,16 +69,35 @@ export function sigmoid(params, x) {
104
69
  const res = D + (A - D) / (1 + Math.pow(10, (x - C) * B));
105
70
  return res;
106
71
  }
72
+ function getObjectiveDerivative(of, curveFunction, data, params, selectedParam) {
73
+ let step = params[selectedParam] * 0.0001;
74
+ step = step == 0 ? 0.001 : step;
75
+ let paramsTop = [];
76
+ let paramsBottom = [];
77
+ for (let i = 0; i < params.length; i++) {
78
+ if (i == selectedParam) {
79
+ paramsTop.push(params[i] + step);
80
+ paramsBottom.push(params[i] - step);
81
+ }
82
+ else {
83
+ paramsTop.push(params[i]);
84
+ paramsBottom.push(params[i]);
85
+ }
86
+ }
87
+ const drvTop = of(curveFunction, data, paramsTop).value;
88
+ const drvBottom = of(curveFunction, data, paramsBottom).value;
89
+ return (drvTop - drvBottom) / (2 * step);
90
+ }
107
91
  function objectiveNormalConstant(targetFunc, data, params) {
108
92
  //assure observed and args same length
109
93
  const pi = Math.PI;
110
94
  let sigma = 0;
111
95
  let sigmaSq = 0;
112
96
  let likelihood = 0;
113
- let residuesSquares = new Float32Array(data.args.length);
114
- for (let i = 0; i < data.args.length; i++) {
115
- const obs = data.observed[i];
116
- const pred = targetFunc(params, data.args[i]);
97
+ let residuesSquares = new Float32Array(data.x.length);
98
+ for (let i = 0; i < data.x.length; i++) {
99
+ const obs = data.y[i];
100
+ const pred = targetFunc(params, data.x[i]);
117
101
  residuesSquares[i] = Math.pow(obs - pred, 2);
118
102
  }
119
103
  for (let i = 0; i < residuesSquares.length; i++)
@@ -130,10 +114,10 @@ function objectiveNormalProportional(targetFunc, data, params) {
130
114
  let sigma = 0;
131
115
  let sigmaSq = 0;
132
116
  let likelihood = 0;
133
- let residuesSquares = new Float32Array(data.args.length);
134
- for (let i = 0; i < data.args.length; i++) {
135
- const obs = data.observed[i];
136
- const pred = targetFunc(params, data.args[i]);
117
+ let residuesSquares = new Float32Array(data.x.length);
118
+ for (let i = 0; i < data.x.length; i++) {
119
+ const obs = data.y[i];
120
+ const pred = targetFunc(params, data.x[i]);
137
121
  residuesSquares[i] = Math.pow(obs - pred, 2);
138
122
  }
139
123
  for (let i = 0; i < residuesSquares.length; i++)
@@ -144,4 +128,4 @@ function objectiveNormalProportional(targetFunc, data, params) {
144
128
  likelihood += residuesSquares[i] / sigmaSq + Math.log(2 * pi * sigmaSq);
145
129
  return { value: -likelihood, const: sigma, mult: 0 };
146
130
  }
147
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml0LWN1cnZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZml0LWN1cnZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLG1CQUFtQixDQUFBO0FBb0JuRCxNQUFNLE9BQU8sV0FBVztJQWN0QixZQUFZLGFBQXVELEVBQ3ZELElBQXdDLEVBQ3hDLE1BQWdCLEVBQ2hCLGFBQTBDLFVBQVU7UUFWaEUsZUFBVSxHQUNpRDtZQUN6RCxVQUFVLEVBQUUsQ0FBQztZQUNiLFVBQVUsRUFBRSxFQUFFO1lBQ2QsVUFBVSxFQUFFLEVBQUU7U0FDZixDQUFDO1FBUUEsSUFBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQ3RFLE1BQU0sSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFbEMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLEVBQUUsR0FBRyxhQUFhLENBQUM7UUFFeEIsUUFBTyxVQUFVLEVBQUU7WUFDakIsS0FBSyxVQUFVO2dCQUNiLElBQUksQ0FBQyxFQUFFLEdBQUcsdUJBQXVCLENBQUM7WUFDcEMsS0FBSyxjQUFjO2dCQUNqQixJQUFJLENBQUMsRUFBRSxHQUFHLDJCQUEyQixDQUFDO1lBQ3hDLHlCQUF5QjtZQUN6Qix1Q0FBdUM7WUFDdkMseUJBQXlCO1lBQ3pCLHVDQUF1QztZQUN2QztnQkFDRSxJQUFJLENBQUMsRUFBRSxHQUFHLHVCQUF1QixDQUFDO1NBQ3JDO1FBRUQsSUFBSSxDQUFDLFdBQVcsR0FBRztZQUNqQixRQUFRLEVBQUUsQ0FBQyxVQUFvQixFQUFFLEVBQUU7Z0JB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QUFDLENBQUM7SUFFM0IsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFO1FBQzlDLFVBQVUsSUFBSSxlQUFlLENBQUMsQ0FBQyxDQUFDLEdBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFDLEVBQUUsR0FBQyxPQUFPLENBQUMsQ0FBQztJQUVsRSxPQUFPLEVBQUMsS0FBSyxFQUFFLENBQUMsVUFBVSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBQyxDQUFDO0FBQ25ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2xpbWl0ZWRNZW1vcnlCRkdTfSBmcm9tIFwiLi4vLi4vbGJmZ3MvbGJmZ3NcIlxuXG50eXBlIExpa2VsaWhvb2QgPSB7XG4gIHZhbHVlOiBudW1iZXIsIFxuICBjb25zdDogbnVtYmVyLCBcbiAgbXVsdDogbnVtYmVyXG59O1xuXG5pbnRlcmZhY2UgSUN1cnZlRml0dGVyPFRBcmc+IHtcbiAgZGF0YToge29ic2VydmVkOiBudW1iZXJbXSwgYXJnczogVEFyZ1tdfTtcbiAgcGFyYW1zOiBudW1iZXJbXTtcblxuICAvL2N1cnZlIGZ1bmN0aW9uXG4gIGNmIChwYXJhbXM6IG51bWJlcltdLCBhcmdzOiBUQXJnKTogbnVtYmVyXG4gIC8vb2JqZWN0aXZlIGZ1bmN0aW9uXG4gIG9mICh0YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7b2JzZXJ2ZWQ6IG51bWJlcltdLCBhcmdzOiBUQXJnW119LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogbnVtYmVyW10pOiBMaWtlbGlob29kXG59XG5cbmV4cG9ydCBjbGFzcyBDdXJ2ZUZpdHRlcjxUQXJnPiBpbXBsZW1lbnRzIElDdXJ2ZUZpdHRlcjxUQXJnPiB7XG4gIGVycm9yTW9kZWw6IHN0cmluZztcbiAgZGF0YToge29ic2VydmVkOiBudW1iZXJbXSwgYXJnczogVEFyZ1tdfTtcbiAgcGFyYW1zOiBudW1iZXJbXTtcbiAgY2Y7XG4gIG9mO1xuICBvcHRpbWl6YWJsZTtcbiAgZml0SGlzdG9yeToge2l0ZXJhdGlvbnM6IG51bWJlciwgcGFyYW1ldGVyczoge1tpdGVyYXRpb246IG51bWJlcl06IG51bWJlcltdfSwgXG4gICAgICAgICAgICAgICAgbGlrZWxpaG9vZDoge1tpdGVyYXRpb246IG51bWJlcl06IG51bWJlcn19ID0ge1xuICAgIGl0ZXJhdGlvbnM6IDAsXG4gICAgcGFyYW1ldGVyczoge30sXG4gICAgbGlrZWxpaG9vZDoge31cbiAgfTtcblxuICBjb25zdHJ1Y3RvcihjdXJ2ZUZ1bmN0aW9uOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbiAgICAgICAgICAgICAgZGF0YToge29ic2VydmVkOiBudW1iZXJbXSwgYXJnczogVEFyZ1tdfSxcbiAgICAgICAgICAgICAgcGFyYW1zOiBudW1iZXJbXSxcbiAgICAgICAgICAgICAgZXJyb3JNb2RlbDogJ2NvbnN0YW50JyB8ICdwcm9wb3J0aW9uYWwnID0gJ2NvbnN0YW50J1xuICAgICAgICAgICAgICApIHtcblxuICAgIGlmKGRhdGEub2JzZXJ2ZWQubGVuZ3RoID09IDAgfHwgZGF0YS5vYnNlcnZlZC5sZW5ndGggIT0gZGF0YS5hcmdzLmxlbmd0aClcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBkYXRhJyk7XG4gICAgICBcbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zO1xuICAgIHRoaXMuZXJyb3JNb2RlbCA9IGVycm9yTW9kZWw7XG4gICAgdGhpcy5jZiA9IGN1cnZlRnVuY3Rpb247XG5cbiAgICBzd2l0Y2goZXJyb3JNb2RlbCkge1xuICAgICAgY2FzZSAnY29uc3RhbnQnOlxuICAgICAgICB0aGlzLm9mID0gb2JqZWN0aXZlTm9ybWFsQ29uc3RhbnQ7XG4gICAgICBjYXNlICdwcm9wb3J0aW9uYWwnOlxuICAgICAgICB0aGlzLm9mID0gb2JqZWN0aXZlTm9ybWFsUHJvcG9ydGlvbmFsO1xuICAgICAgLy8gY2FzZSAnY29tYmluYXRpb25hbDEnOlxuICAgICAgLy8gICB0aGlzLm9mID0gb2JqZWN0aXZlTm9ybWFsQWRkaXRpdmU7XG4gICAgICAvLyBjYXNlICdjb21iaW5hdGlvbmFsMic6XG4gICAgICAvLyAgIHRoaXMub2YgPSBvYmplY3RpdmVOb3JtYWxBZGRpdGl2ZTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRoaXMub2YgPSBvYmplY3RpdmVOb3JtYWxDb25zdGFudDtcbiAgICB9XG5cbiAgICB0aGlzLm9wdGltaXphYmxlID0ge1xuICAgICAgZ2V0VmFsdWU6IChwYXJhbWV0ZXJzOiBudW1iZXJbXSkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtZXRlcnMpLnZhbHVlO1xuICAgICAgfSxcbiAgICAgIGdldEdyYWRpZW50OiAocGFyYW1ldGVyczogbnVtYmVyW10sIGdyYWRpZW50OiBudW1iZXJbXSkgPT4ge1xuICAgICAgICBjb25zdCBsZW5ndGggPSBPYmplY3Qua2V5cyh0aGlzLmZpdEhpc3RvcnkucGFyYW1ldGVycykubGVuZ3RoO1xuICAgICAgICB0aGlzLmZpdEhpc3RvcnkuaXRlcmF0aW9ucysrO1xuICAgICAgICB0aGlzLmZpdEhpc3RvcnkucGFyYW1ldGVyc1tsZW5ndGhdID0gcGFyYW1ldGVycy5zbGljZSgpO1xuICAgICAgICB0aGlzLmZpdEhpc3RvcnkubGlrZWxpaG9vZFtsZW5ndGhdID0gdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtZXRlcnMpLnZhbHVlO1xuICAgICAgICBjb25zb2xlLmxvZyhwYXJhbWV0ZXJzLnNsaWNlKCkpO1xuICAgICAgICBcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgIGdyYWRpZW50W2ldID0gdGhpcy5nZXREZXJpdmF0aXZlKHBhcmFtZXRlcnMsIGkpO1xuXG4gICAgICAgIHJldHVybiBncmFkaWVudDtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgcGVyZm9ybUZpdCgpOiB2b2lkIHtcbiAgICBsaW1pdGVkTWVtb3J5QkZHUyh0aGlzLm9wdGltaXphYmxlLCB0aGlzLnBhcmFtcyk7XG4gICAgbGltaXRlZE1lbW9yeUJGR1ModGhpcy5vcHRpbWl6YWJsZSwgdGhpcy5wYXJhbXMpO1xuICB9XG5cbiAgZ2V0IHBhcmFtZXRlcnMoKTogbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLnBhcmFtcztcbiAgfVxuXG4gIGdldCBjdXJ2ZUZ1bmN0aW9uKCk6IEZ1bmN0aW9uIHtcbiAgICBsZXQgcmVzID0gKGFyZzogVEFyZykgPT57XG4gICAgICBsZXQgcGFyYW1zID0gdGhpcy5maXRIaXN0b3J5LnBhcmFtZXRlcnNbdGhpcy5maXRIaXN0b3J5Lml0ZXJhdGlvbnMgLSAxXTtcblxuICAgICAgcmV0dXJuIHRoaXMuY2YocGFyYW1zLCBhcmcpO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBnZXQgY29uZmlkZW5jZSgpOiB7dG9wOkZ1bmN0aW9uLCBib3R0b206IEZ1bmN0aW9ufSB7XG4gICAgbGV0IHBhcmFtcyA9IHRoaXMuZml0SGlzdG9yeS5wYXJhbWV0ZXJzW3RoaXMuZml0SGlzdG9yeS5pdGVyYXRpb25zIC0gMV07XG5cbiAgICBsZXQgZXJyb3IgPSB0aGlzLmVycm9yTW9kZWwgPT0gXCJjb25zdGFudFwiID9cbiAgICAgICAgICAgICAgICB0aGlzLm9mKHRoaXMuY2YsIHRoaXMuZGF0YSwgcGFyYW1zKS5jb25zdCA6XG4gICAgICAgICAgICAgICAgdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtcykubXVsdDtcblxuICAgIGxldCB0b3AgPSAoYXJnOiBUQXJnKSA9PntcbiAgICAgIGxldCB2YWx1ZSA9IHRoaXMuY2YocGFyYW1zLCBhcmcpO1xuICAgICAgaWYgKHRoaXMuZXJyb3JNb2RlbCA9PSBcImNvbnN0YW50XCIpXG4gICAgICAgIHJldHVybiAgdmFsdWUgKyAxLjQqZXJyb3I7XG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiAgdmFsdWUgKyAxLjQqKE1hdGguYWJzKHZhbHVlKSplcnJvcik7XG4gICAgfVxuXG4gICAgbGV0IGJvdHRvbSA9IChhcmc6IFRBcmcpID0+e1xuICAgICAgbGV0IHZhbHVlID0gdGhpcy5jZihwYXJhbXMsIGFyZyk7XG4gICAgICBpZiAodGhpcy5lcnJvck1vZGVsID09IFwiY29uc3RhbnRcIilcbiAgICAgICAgcmV0dXJuICB2YWx1ZSAtIDEuNCplcnJvcjtcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0dXJuICB2YWx1ZSAtIDEuNCooTWF0aC5hYnModmFsdWUpKmVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge3RvcDogdG9wLCBib3R0b206IGJvdHRvbX07XG4gIH1cblxuICAvL2NlbnRyYWwgZGlmZmVyZW5jZVxuICBwcml2YXRlIGdldERlcml2YXRpdmUocGFyYW1zOiBudW1iZXJbXSwgc2VsZWN0ZWRQYXJhbTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgc3RlcCA9IHBhcmFtc1tzZWxlY3RlZFBhcmFtXSowLjAwMDE7XG4gICAgc3RlcCA9IHN0ZXAgPT0gMCA/IDAuMDAxIDogc3RlcDsgXG4gICAgbGV0IHBhcmFtc1RvcDogbnVtYmVyW10gPSBbXTtcbiAgICBsZXQgcGFyYW1zQm90dG9tOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZihpID09IHNlbGVjdGVkUGFyYW0pIHtcbiAgICAgICAgcGFyYW1zVG9wLnB1c2gocGFyYW1zW2ldICsgc3RlcCk7XG4gICAgICAgIHBhcmFtc0JvdHRvbS5wdXNoKHBhcmFtc1tpXSAtIHN0ZXApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFyYW1zVG9wLnB1c2gocGFyYW1zW2ldKTtcbiAgICAgICAgcGFyYW1zQm90dG9tLnB1c2gocGFyYW1zW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZHJ2VG9wID0gdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtc1RvcCkudmFsdWU7XG4gICAgY29uc3QgZHJ2Qm90dG9tID0gdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtc0JvdHRvbSkudmFsdWU7XG5cbiAgICByZXR1cm4gKGRydlRvcCAtIGRydkJvdHRvbSkvKDIqc3RlcCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNpZ21vaWQocGFyYW1zOiBudW1iZXJbXSwgeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgQSA9IHBhcmFtc1swXTtcbiAgY29uc3QgQiA9IHBhcmFtc1sxXTtcbiAgY29uc3QgQyA9IHBhcmFtc1syXTtcbiAgY29uc3QgRCA9IHBhcmFtc1szXTtcbiAgY29uc3QgcmVzID0gRCArIChBIC0gRCkvKDEgKyBNYXRoLnBvdygxMCwgKHggLSBDKSpCKSk7XG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIG9iamVjdGl2ZU5vcm1hbENvbnN0YW50PFRBcmc+IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7b2JzZXJ2ZWQ6IG51bWJlcltdLCBhcmdzOiBUQXJnW119LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogbnVtYmVyW11cbik6IExpa2VsaWhvb2Qge1xuICAvL2Fzc3VyZSBvYnNlcnZlZCBhbmQgYXJncyBzYW1lIGxlbmd0aFxuICBjb25zdCBwaSA9IE1hdGguUEk7XG4gIGxldCBzaWdtYSA9IDA7XG4gIGxldCBzaWdtYVNxID0gMDtcbiAgbGV0IGxpa2VsaWhvb2QgPSAwO1xuXG4gIGxldCByZXNpZHVlc1NxdWFyZXMgPSBuZXcgRmxvYXQzMkFycmF5KGRhdGEuYXJncy5sZW5ndGgpO1xuICBmb3IobGV0IGkgPSAwOyBpIDwgZGF0YS5hcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgb2JzID0gZGF0YS5vYnNlcnZlZFtpXTtcbiAgICBjb25zdCBwcmVkID0gdGFyZ2V0RnVuYyhwYXJhbXMsIGRhdGEuYXJnc1tpXSk7XG4gICAgcmVzaWR1ZXNTcXVhcmVzW2ldID0gTWF0aC5wb3cob2JzIC0gcHJlZCwgMik7XG4gIH1cbiAgXG4gIGZvcihsZXQgaSA9IDA7IGkgPCByZXNpZHVlc1NxdWFyZXMubGVuZ3RoOyBpKyspXG4gICAgc2lnbWFTcSArPSByZXNpZHVlc1NxdWFyZXNbaV07XG4gIHNpZ21hU3EgLz0gcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDtcbiAgc2lnbWEgPSBNYXRoLnNxcnQoc2lnbWFTcSk7XG5cbiAgZm9yKGxldCBpID0gMDsgaSA8IHJlc2lkdWVzU3F1YXJlcy5sZW5ndGg7IGkrKylcbiAgICBsaWtlbGlob29kICs9IHJlc2lkdWVzU3F1YXJlc1tpXS9zaWdtYVNxICsgTWF0aC5sb2coMiAqIHBpICogc2lnbWFTcSk7XG5cbiAgcmV0dXJuIHt2YWx1ZTogLWxpa2VsaWhvb2QsIGNvbnN0OiBzaWdtYSwgbXVsdDogMH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxufVxuXG5mdW5jdGlvbiBvYmplY3RpdmVOb3JtYWxQcm9wb3J0aW9uYWw8VEFyZz4gKFxuICB0YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbiAgZGF0YToge29ic2VydmVkOiBudW1iZXJbXSwgYXJnczogVEFyZ1tdfSxcbiAgcGFyYW1zOiBudW1iZXJbXVxuKTogTGlrZWxpaG9vZCB7XG4vL2Fzc3VyZSBvYnNlcnZlZCBhbmQgYXJncyBzYW1lIGxlbmd0aFxuY29uc3QgcGkgPSBNYXRoLlBJO1xubGV0IHNpZ21hID0gMDtcbmxldCBzaWdtYVNxID0gMDtcbmxldCBsaWtlbGlob29kID0gMDtcblxubGV0IHJlc2lkdWVzU3F1YXJlcyA9IG5ldyBGbG9hdDMyQXJyYXkoZGF0YS5hcmdzLmxlbmd0aCk7XG5mb3IobGV0IGkgPSAwOyBpIDwgZGF0YS5hcmdzLmxlbmd0aDsgaSsrKSB7XG5jb25zdCBvYnMgPSBkYXRhLm9ic2VydmVkW2ldO1xuY29uc3QgcHJlZCA9IHRhcmdldEZ1bmMocGFyYW1zLCBkYXRhLmFyZ3NbaV0pXG5yZXNpZHVlc1NxdWFyZXNbaV0gPSBNYXRoLnBvdyhvYnMgLSBwcmVkLCAyKTtcbn1cblxuZm9yKGxldCBpID0gMDsgaSA8IHJlc2lkdWVzU3F1YXJlcy5sZW5ndGg7IGkrKylcbnNpZ21hU3EgKz0gcmVzaWR1ZXNTcXVhcmVzW2ldO1xuc2lnbWFTcSAvPSByZXNpZHVlc1NxdWFyZXMubGVuZ3RoO1xuc2lnbWEgPSBNYXRoLnNxcnQoc2lnbWFTcSk7XG5cbmZvcihsZXQgaSA9IDA7IGkgPCByZXNpZHVlc1NxdWFyZXMubGVuZ3RoOyBpKyspXG5saWtlbGlob29kICs9IHJlc2lkdWVzU3F1YXJlc1tpXS9zaWdtYVNxICsgTWF0aC5sb2coMipwaSpzaWdtYVNxKTtcblxucmV0dXJuIHt2YWx1ZTogLWxpa2VsaWhvb2QsIGNvbnN0OiBzaWdtYSwgbXVsdDogMH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxufSJdfQ==
131
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml0LWN1cnZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZml0LWN1cnZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLG1CQUFtQixDQUFBO0FBb0JuRCxNQUFNLENBQU4sSUFBWSxhQUdYO0FBSEQsV0FBWSxhQUFhO0lBQ3ZCLHlEQUFRLENBQUE7SUFDUixpRUFBWSxDQUFBO0FBQ2QsQ0FBQyxFQUhXLGFBQWEsS0FBYixhQUFhLFFBR3hCO0FBRUQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxJQUErQixFQUFFLE1BQWdCLEVBQ2pELGFBQXNELEVBQUUsVUFBeUI7SUFFbkcsSUFBSSxFQUFxQixDQUFDO0lBQzFCLFFBQU8sVUFBVSxFQUFFO1FBQ2pCLEtBQUssYUFBYSxDQUFDLFFBQVE7WUFDekIsRUFBRSxHQUFHLHVCQUF1QixDQUFDO1lBQzdCLE1BQU07UUFDUixLQUFLLGFBQWEsQ0FBQyxZQUFZO1lBQzdCLEVBQUUsR0FBRywyQkFBMkIsQ0FBQztZQUNqQyxNQUFNO1FBQ1I7WUFDRSxFQUFFLEdBQUcsdUJBQXVCLENBQUM7WUFDN0IsTUFBTTtLQUNUO0lBRUQsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBRW5CLElBQUksV0FBVyxHQUFHO1FBQ2hCLFFBQVEsRUFBRSxDQUFDLFVBQW9CLEVBQUUsRUFBRTtZQUNqQyxPQUFPLEVBQUUsQ0FBQyxhQUFhLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUNuRCxDQUFDO1FBQ0QsV0FBVyxFQUFFLENBQUMsVUFBb0IsRUFBRSxRQUFrQixFQUFFLEVBQUU7WUFDeEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxNQUFNLENBQUM7WUFDOUMsVUFBVSxFQUFFLENBQUM7WUFFYixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUU7Z0JBQ3hDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxzQkFBc0IsQ0FBQyxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFL0UsT0FBTyxRQUFRLENBQUM7UUFDbEIsQ0FBQztLQUNGLENBQUM7SUFFRixpQkFBaUIsQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDdkMsaUJBQWlCLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRXZDLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDOUIsT0FBTyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xDLENBQUMsQ0FBQTtJQUVELElBQUksR0FBRyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDdEIsSUFBSSxLQUFLLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyQyxJQUFJLFVBQVUsSUFBSSxhQUFhLENBQUMsUUFBUTtZQUN0QyxPQUFRLEtBQUssR0FBRyxHQUFHLEdBQUMsS0FBSyxDQUFDOztZQUUxQixPQUFRLEtBQUssR0FBRyxHQUFHLEdBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hELENBQUMsQ0FBQTtJQUVELElBQUksS0FBSyxHQUFHLFVBQVUsSUFBSSxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdEQsRUFBRSxDQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdkMsRUFBRSxDQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDO0lBRXJDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDekIsSUFBSSxLQUFLLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyQyxJQUFJLFVBQVUsSUFBSSxhQUFhLENBQUMsUUFBUTtZQUN0QyxPQUFRLEtBQUssR0FBRyxHQUFHLEdBQUMsS0FBSyxDQUFDOztZQUUxQixPQUFRLEtBQUssR0FBRyxHQUFHLEdBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hELENBQUMsQ0FBQTtJQUVELElBQUksTUFBTSxHQUFjO1FBQ3RCLFVBQVUsRUFBRSxNQUFNO1FBQ2xCLFdBQVcsRUFBRSxXQUFXO1FBQ3hCLGFBQWEsRUFBRSxHQUFHO1FBQ2xCLGdCQUFnQixFQUFFLE1BQU07UUFDeEIsS0FBSyxFQUFFLEtBQUs7S0FDYixDQUFDO0lBRUYsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELE1BQU0sVUFBVSxPQUFPLENBQUMsTUFBZ0IsRUFBRSxDQUFTO0lBQ2pELE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQixNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEIsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BCLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQixNQUFNLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCxTQUFTLHNCQUFzQixDQUFDLEVBQXFCLEVBQUUsYUFBc0QsRUFDekcsSUFBZ0MsRUFBRSxNQUFnQixFQUFFLGFBQXFCO0lBQzNFLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBQyxNQUFNLENBQUM7SUFDeEMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ2hDLElBQUksU0FBUyxHQUFhLEVBQUUsQ0FBQztJQUM3QixJQUFJLFlBQVksR0FBYSxFQUFFLENBQUM7SUFDaEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDdEMsSUFBRyxDQUFDLElBQUksYUFBYSxFQUFFO1lBQ3JCLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1lBQ2pDLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1NBQ3JDO2FBQU07WUFDTCxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFCLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDOUI7S0FDRjtJQUNELE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxhQUFhLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUN4RCxNQUFNLFNBQVMsR0FBRyxFQUFFLENBQUMsYUFBYSxFQUFFLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFFOUQsT0FBTyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsR0FBQyxDQUFDLENBQUMsR0FBQyxJQUFJLENBQUMsQ0FBQztBQUN2QyxDQUFDO0FBRUQsU0FBUyx1QkFBdUIsQ0FDOUIsVUFBbUQsRUFDbkQsSUFBZ0MsRUFDaEMsTUFBZ0I7SUFFaEIsc0NBQXNDO0lBQ3RDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDbkIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztJQUVuQixJQUFJLGVBQWUsR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RELEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUN2QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNDLGVBQWUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7S0FDNUM7SUFFRCxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUU7UUFDOUMsT0FBTyxJQUFJLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QixPQUFPLElBQUksZUFBZSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUUzQixLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUU7UUFDOUMsVUFBVSxJQUFJLGVBQWUsQ0FBQyxDQUFDLENBQUMsR0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDO0lBRXRFLE9BQU8sRUFBQyxLQUFLLEVBQUUsQ0FBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFDLENBQUM7QUFDckQsQ0FBQztBQUVELFNBQVMsMkJBQTJCLENBQ3BDLFVBQW1ELEVBQ25ELElBQWdDLEVBQ2hDLE1BQWdCO0lBRWQsc0NBQXNDO0lBQ3RDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDbkIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztJQUVuQixJQUFJLGVBQWUsR0FBRyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RELEtBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUN2QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7S0FDNUM7SUFFRCxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUU7UUFDOUMsT0FBTyxJQUFJLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QixPQUFPLElBQUksZUFBZSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUUzQixLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUU7UUFDOUMsVUFBVSxJQUFJLGVBQWUsQ0FBQyxDQUFDLENBQUMsR0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUMsRUFBRSxHQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRWxFLE9BQU8sRUFBQyxLQUFLLEVBQUUsQ0FBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFDLENBQUM7QUFDckQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7bGltaXRlZE1lbW9yeUJGR1N9IGZyb20gXCIuLi8uLi9sYmZncy9sYmZnc1wiXG5cbnR5cGUgTGlrZWxpaG9vZCA9IHtcbiAgdmFsdWU6IG51bWJlciwgXG4gIGNvbnN0OiBudW1iZXIsIFxuICBtdWx0OiBudW1iZXJcbn07XG5cbnR5cGUgRml0UmVzdWx0ID0ge1xuICBwYXJhbWV0ZXJzOiBudW1iZXJbXSxcbiAgZml0dGVkQ3VydmU6ICh4Om51bWJlcik9PiBudW1iZXIsXG4gIGNvbmZpZGVuY2VUb3A6ICh4Om51bWJlcik9PiBudW1iZXIsXG4gIGNvbmZpZGVuY2VCb3R0b206ICh4Om51bWJlcik9PiBudW1iZXIsXG4gIHNpZ21hOiBudW1iZXJcbn07XG5cbnR5cGUgT2JqZWN0aXZlRnVuY3Rpb24gPSAodGFyZ2V0RnVuYzogKHBhcmFtczogbnVtYmVyW10sIHg6IG51bWJlcikgPT4gbnVtYmVyLCBcbmRhdGE6IHt4OiBudW1iZXJbXSwgeTogbnVtYmVyW119LFxucGFyYW1zOiBudW1iZXJbXSkgPT4gTGlrZWxpaG9vZDtcblxuZXhwb3J0IGVudW0gRml0RXJyb3JNb2RlbCB7XG4gIENvbnN0YW50LFxuICBQcm9wb3J0aW9uYWxcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpdChkYXRhOnt4OiBudW1iZXJbXSwgeTogbnVtYmVyW119LCBwYXJhbXM6IG51bWJlcltdLFxuICAgICAgICAgICAgICAgICAgICBjdXJ2ZUZ1bmN0aW9uOiAocGFyYW1zOiBudW1iZXJbXSwgeDogbnVtYmVyKSA9PiBudW1iZXIsIGVycm9yTW9kZWw6IEZpdEVycm9yTW9kZWwpOiBGaXRSZXN1bHQge1xuXG4gIGxldCBvZjogT2JqZWN0aXZlRnVuY3Rpb247XG4gIHN3aXRjaChlcnJvck1vZGVsKSB7XG4gICAgY2FzZSBGaXRFcnJvck1vZGVsLkNvbnN0YW50OlxuICAgICAgb2YgPSBvYmplY3RpdmVOb3JtYWxDb25zdGFudDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgRml0RXJyb3JNb2RlbC5Qcm9wb3J0aW9uYWw6XG4gICAgICBvZiA9IG9iamVjdGl2ZU5vcm1hbFByb3BvcnRpb25hbDtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBvZiA9IG9iamVjdGl2ZU5vcm1hbENvbnN0YW50O1xuICAgICAgYnJlYWs7XG4gIH1cblxuICBsZXQgaXRlcmF0aW9ucyA9IDA7XG5cbiAgbGV0IG9wdGltaXphYmxlID0ge1xuICAgIGdldFZhbHVlOiAocGFyYW1ldGVyczogbnVtYmVyW10pID0+IHtcbiAgICAgIHJldHVybiBvZihjdXJ2ZUZ1bmN0aW9uLCBkYXRhLCBwYXJhbWV0ZXJzKS52YWx1ZTtcbiAgICB9LFxuICAgIGdldEdyYWRpZW50OiAocGFyYW1ldGVyczogbnVtYmVyW10sIGdyYWRpZW50OiBudW1iZXJbXSkgPT4ge1xuICAgICAgY29uc3QgbGVuZ3RoID0gT2JqZWN0LmtleXMocGFyYW1ldGVycykubGVuZ3RoO1xuICAgICAgaXRlcmF0aW9ucysrO1xuICAgICAgXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlcnMubGVuZ3RoOyBpKyspXG4gICAgICAgIGdyYWRpZW50W2ldID0gZ2V0T2JqZWN0aXZlRGVyaXZhdGl2ZShvZiwgY3VydmVGdW5jdGlvbiwgZGF0YSwgcGFyYW1ldGVycywgaSk7XG5cbiAgICAgIHJldHVybiBncmFkaWVudDtcbiAgICB9XG4gIH07XG5cbiAgbGltaXRlZE1lbW9yeUJGR1Mob3B0aW1pemFibGUsIHBhcmFtcyk7XG4gIGxpbWl0ZWRNZW1vcnlCRkdTKG9wdGltaXphYmxlLCBwYXJhbXMpO1xuXG4gIGxldCBmaXR0ZWRDdXJ2ZSA9ICh4OiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gY3VydmVGdW5jdGlvbihwYXJhbXMsIHgpO1xuICB9XG5cbiAgbGV0IHRvcCA9ICh4OiBudW1iZXIpID0+e1xuICAgIGxldCB2YWx1ZSA9IGN1cnZlRnVuY3Rpb24ocGFyYW1zLCB4KTtcbiAgICBpZiAoZXJyb3JNb2RlbCA9PSBGaXRFcnJvck1vZGVsLkNvbnN0YW50KVxuICAgICAgcmV0dXJuICB2YWx1ZSArIDEuNCplcnJvcjtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gIHZhbHVlICsgMS40KihNYXRoLmFicyh2YWx1ZSkqZXJyb3IpO1xuICB9XG5cbiAgbGV0IGVycm9yID0gZXJyb3JNb2RlbCA9PSBGaXRFcnJvck1vZGVsLlByb3BvcnRpb25hbCA/XG4gIG9mKGN1cnZlRnVuY3Rpb24sIGRhdGEsIHBhcmFtcykuY29uc3QgOlxuICBvZihjdXJ2ZUZ1bmN0aW9uLCBkYXRhLCBwYXJhbXMpLm11bHQ7XG5cbiAgbGV0IGJvdHRvbSA9ICh4OiBudW1iZXIpID0+IHtcbiAgICBsZXQgdmFsdWUgPSBjdXJ2ZUZ1bmN0aW9uKHBhcmFtcywgeCk7XG4gICAgaWYgKGVycm9yTW9kZWwgPT0gRml0RXJyb3JNb2RlbC5Db25zdGFudClcbiAgICAgIHJldHVybiAgdmFsdWUgLSAxLjQqZXJyb3I7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuICB2YWx1ZSAtIDEuNCooTWF0aC5hYnModmFsdWUpKmVycm9yKTtcbiAgfVxuXG4gIGxldCBmaXRSZXM6IEZpdFJlc3VsdCA9IHtcbiAgICBwYXJhbWV0ZXJzOiBwYXJhbXMsXG4gICAgZml0dGVkQ3VydmU6IGZpdHRlZEN1cnZlLFxuICAgIGNvbmZpZGVuY2VUb3A6IHRvcCxcbiAgICBjb25maWRlbmNlQm90dG9tOiBib3R0b20sXG4gICAgc2lnbWE6IGVycm9yXG4gIH07XG5cbiAgcmV0dXJuIGZpdFJlcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNpZ21vaWQocGFyYW1zOiBudW1iZXJbXSwgeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgQSA9IHBhcmFtc1swXTtcbiAgY29uc3QgQiA9IHBhcmFtc1sxXTtcbiAgY29uc3QgQyA9IHBhcmFtc1syXTtcbiAgY29uc3QgRCA9IHBhcmFtc1szXTtcbiAgY29uc3QgcmVzID0gRCArIChBIC0gRCkvKDEgKyBNYXRoLnBvdygxMCwgKHggLSBDKSpCKSk7XG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIGdldE9iamVjdGl2ZURlcml2YXRpdmUob2Y6IE9iamVjdGl2ZUZ1bmN0aW9uLCBjdXJ2ZUZ1bmN0aW9uOiAocGFyYW1zOiBudW1iZXJbXSwgeDogbnVtYmVyKSA9PiBudW1iZXIsIFxuICAgIGRhdGE6IHt4OiBudW1iZXJbXSwgeTogbnVtYmVyW119LCBwYXJhbXM6IG51bWJlcltdLCBzZWxlY3RlZFBhcmFtOiBudW1iZXIpOiBudW1iZXIge1xuICBsZXQgc3RlcCA9IHBhcmFtc1tzZWxlY3RlZFBhcmFtXSowLjAwMDE7XG4gIHN0ZXAgPSBzdGVwID09IDAgPyAwLjAwMSA6IHN0ZXA7IFxuICBsZXQgcGFyYW1zVG9wOiBudW1iZXJbXSA9IFtdO1xuICBsZXQgcGFyYW1zQm90dG9tOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtcy5sZW5ndGg7IGkrKykge1xuICAgIGlmKGkgPT0gc2VsZWN0ZWRQYXJhbSkge1xuICAgICAgcGFyYW1zVG9wLnB1c2gocGFyYW1zW2ldICsgc3RlcCk7XG4gICAgICBwYXJhbXNCb3R0b20ucHVzaChwYXJhbXNbaV0gLSBzdGVwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcGFyYW1zVG9wLnB1c2gocGFyYW1zW2ldKTtcbiAgICAgIHBhcmFtc0JvdHRvbS5wdXNoKHBhcmFtc1tpXSk7XG4gICAgfVxuICB9XG4gIGNvbnN0IGRydlRvcCA9IG9mKGN1cnZlRnVuY3Rpb24sIGRhdGEsIHBhcmFtc1RvcCkudmFsdWU7XG4gIGNvbnN0IGRydkJvdHRvbSA9IG9mKGN1cnZlRnVuY3Rpb24sIGRhdGEsIHBhcmFtc0JvdHRvbSkudmFsdWU7XG5cbiAgcmV0dXJuIChkcnZUb3AgLSBkcnZCb3R0b20pLygyKnN0ZXApO1xufVxuXG5mdW5jdGlvbiBvYmplY3RpdmVOb3JtYWxDb25zdGFudCAoXG4gIHRhcmdldEZ1bmM6IChwYXJhbXM6IG51bWJlcltdLCB4OiBudW1iZXIpID0+IG51bWJlciwgXG4gIGRhdGE6IHt5OiBudW1iZXJbXSwgeDogbnVtYmVyW119LFxuICBwYXJhbXM6IG51bWJlcltdXG4pOiBMaWtlbGlob29kIHtcbiAgLy9hc3N1cmUgb2JzZXJ2ZWQgYW5kIGFyZ3Mgc2FtZSBsZW5ndGhcbiAgY29uc3QgcGkgPSBNYXRoLlBJO1xuICBsZXQgc2lnbWEgPSAwO1xuICBsZXQgc2lnbWFTcSA9IDA7XG4gIGxldCBsaWtlbGlob29kID0gMDtcblxuICBsZXQgcmVzaWR1ZXNTcXVhcmVzID0gbmV3IEZsb2F0MzJBcnJheShkYXRhLngubGVuZ3RoKTtcbiAgZm9yKGxldCBpID0gMDsgaSA8IGRhdGEueC5sZW5ndGg7IGkrKykge1xuICBjb25zdCBvYnMgPSBkYXRhLnlbaV07XG4gIGNvbnN0IHByZWQgPSB0YXJnZXRGdW5jKHBhcmFtcywgZGF0YS54W2ldKTtcbiAgcmVzaWR1ZXNTcXVhcmVzW2ldID0gTWF0aC5wb3cob2JzIC0gcHJlZCwgMik7XG4gIH1cblxuICBmb3IobGV0IGkgPSAwOyBpIDwgcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDsgaSsrKVxuICBzaWdtYVNxICs9IHJlc2lkdWVzU3F1YXJlc1tpXTtcbiAgc2lnbWFTcSAvPSByZXNpZHVlc1NxdWFyZXMubGVuZ3RoO1xuICBzaWdtYSA9IE1hdGguc3FydChzaWdtYVNxKTtcblxuICBmb3IobGV0IGkgPSAwOyBpIDwgcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDsgaSsrKVxuICBsaWtlbGlob29kICs9IHJlc2lkdWVzU3F1YXJlc1tpXS9zaWdtYVNxICsgTWF0aC5sb2coMiAqIHBpICogc2lnbWFTcSk7XG5cbiAgcmV0dXJuIHt2YWx1ZTogLWxpa2VsaWhvb2QsIGNvbnN0OiBzaWdtYSwgbXVsdDogMH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxufVxuXG5mdW5jdGlvbiBvYmplY3RpdmVOb3JtYWxQcm9wb3J0aW9uYWwgKFxudGFyZ2V0RnVuYzogKHBhcmFtczogbnVtYmVyW10sIHg6IG51bWJlcikgPT4gbnVtYmVyLCBcbmRhdGE6IHt5OiBudW1iZXJbXSwgeDogbnVtYmVyW119LFxucGFyYW1zOiBudW1iZXJbXVxuKTogTGlrZWxpaG9vZCB7XG4gIC8vYXNzdXJlIG9ic2VydmVkIGFuZCBhcmdzIHNhbWUgbGVuZ3RoXG4gIGNvbnN0IHBpID0gTWF0aC5QSTtcbiAgbGV0IHNpZ21hID0gMDtcbiAgbGV0IHNpZ21hU3EgPSAwO1xuICBsZXQgbGlrZWxpaG9vZCA9IDA7XG5cbiAgbGV0IHJlc2lkdWVzU3F1YXJlcyA9IG5ldyBGbG9hdDMyQXJyYXkoZGF0YS54Lmxlbmd0aCk7XG4gIGZvcihsZXQgaSA9IDA7IGkgPCBkYXRhLngubGVuZ3RoOyBpKyspIHtcbiAgY29uc3Qgb2JzID0gZGF0YS55W2ldO1xuICBjb25zdCBwcmVkID0gdGFyZ2V0RnVuYyhwYXJhbXMsIGRhdGEueFtpXSlcbiAgcmVzaWR1ZXNTcXVhcmVzW2ldID0gTWF0aC5wb3cob2JzIC0gcHJlZCwgMik7XG4gIH1cblxuICBmb3IobGV0IGkgPSAwOyBpIDwgcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDsgaSsrKVxuICBzaWdtYVNxICs9IHJlc2lkdWVzU3F1YXJlc1tpXTtcbiAgc2lnbWFTcSAvPSByZXNpZHVlc1NxdWFyZXMubGVuZ3RoO1xuICBzaWdtYSA9IE1hdGguc3FydChzaWdtYVNxKTtcblxuICBmb3IobGV0IGkgPSAwOyBpIDwgcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDsgaSsrKVxuICBsaWtlbGlob29kICs9IHJlc2lkdWVzU3F1YXJlc1tpXS9zaWdtYVNxICsgTWF0aC5sb2coMipwaSpzaWdtYVNxKTtcblxuICByZXR1cm4ge3ZhbHVlOiAtbGlrZWxpaG9vZCwgY29uc3Q6IHNpZ21hLCBtdWx0OiAwfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG59XG4iXX0=