@datagrok/eda 1.1.25 → 1.1.28
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/.vscode/settings.json +5 -0
- package/CHANGELOG.md +12 -0
- package/README.md +1 -0
- package/dist/05e5e0770f54f07e9474.wasm +0 -0
- package/dist/111.js +2 -0
- package/dist/111.js.map +1 -0
- package/dist/153.js +2 -0
- package/dist/153.js.map +1 -0
- package/dist/23.js +2 -2
- package/dist/23.js.map +1 -0
- package/dist/234.js +2 -0
- package/dist/234.js.map +1 -0
- package/dist/242.js +2 -0
- package/dist/242.js.map +1 -0
- package/dist/260.js +2 -0
- package/dist/260.js.map +1 -0
- package/dist/317.js +2 -0
- package/dist/317.js.map +1 -0
- package/dist/33.js +2 -0
- package/dist/33.js.map +1 -0
- package/dist/348.js +2 -0
- package/dist/348.js.map +1 -0
- package/dist/377.js +2 -0
- package/dist/377.js.map +1 -0
- package/dist/412.js +2 -0
- package/dist/412.js.map +1 -0
- package/dist/415.js +2 -0
- package/dist/415.js.map +1 -0
- package/dist/531.js +2 -0
- package/dist/531.js.map +1 -0
- package/dist/583.js +2 -0
- package/dist/583.js.map +1 -0
- package/dist/589.js +2 -0
- package/dist/589.js.map +1 -0
- package/dist/603.js +2 -0
- package/dist/603.js.map +1 -0
- package/dist/656.js +2 -0
- package/dist/656.js.map +1 -0
- package/dist/682.js +2 -0
- package/dist/682.js.map +1 -0
- package/dist/705.js +2 -0
- package/dist/705.js.map +1 -0
- package/dist/731.js +2 -0
- package/dist/731.js.map +1 -0
- package/dist/738.js +3 -0
- package/dist/738.js.map +1 -0
- package/dist/763.js +2 -0
- package/dist/763.js.map +1 -0
- package/dist/778.js +2 -0
- package/dist/778.js.map +1 -0
- package/dist/783.js +2 -0
- package/dist/783.js.map +1 -0
- package/dist/793.js +2 -0
- package/dist/793.js.map +1 -0
- package/dist/907.js +2 -0
- package/dist/907.js.map +1 -0
- package/dist/91.js +2 -0
- package/dist/91.js.map +1 -0
- package/dist/950.js +2 -0
- package/dist/950.js.map +1 -0
- package/dist/package-test.js +2 -2
- package/dist/package-test.js.map +1 -0
- package/dist/package.js +2 -2
- package/dist/package.js.map +1 -0
- package/package.json +92 -92
- package/scripts/command.txt +1 -1
- package/scripts/func.json +1 -1
- package/scripts/module.json +1 -1
- package/src/missing-values-imputation/ui.ts +80 -66
- package/src/package.ts +288 -38
- package/src/pls/pls-tools.ts +16 -15
- package/src/regression.ts +232 -0
- package/src/svm.ts +78 -38
- package/tsconfig.json +4 -4
- package/wasm/EDA.js +65 -1
- package/wasm/EDA.wasm +0 -0
- package/wasm/EDAAPI.js +30 -0
- package/wasm/EDAForWebWorker.js +1 -1
- package/wasm/callWasm.js +384 -393
- package/wasm/regression-api.cpp +66 -0
- package/wasm/regression.h +128 -0
- package/wasm/workers/fitLinearRegressionParamsWithDataNormalizingWorker.js +13 -0
- package/wasm/workers/fitLinearRegressionParamsWorker.js +13 -0
- package/webpack.config.js +1 -1
- package/dist/208.js +0 -2
- package/dist/221.js +0 -2
- package/dist/231.js +0 -2
- package/dist/261.js +0 -2
- package/dist/282.js +0 -2
- package/dist/334.js +0 -2
- package/dist/356.js +0 -2
- package/dist/36.js +0 -2
- package/dist/367.js +0 -2
- package/dist/374.js +0 -2
- package/dist/40.js +0 -2
- package/dist/413.js +0 -2
- package/dist/42.js +0 -2
- package/dist/427.js +0 -2
- package/dist/467.js +0 -2
- package/dist/523.js +0 -3
- package/dist/533.js +0 -2
- package/dist/590.js +0 -2
- package/dist/65.js +0 -2
- package/dist/694.js +0 -2
- package/dist/729.js +0 -2
- package/dist/796.js +0 -2
- package/dist/902.js +0 -2
- package/dist/910.js +0 -2
- package/dist/972.js +0 -2
- package/dist/f5343e2c2e15952ce916.wasm +0 -0
- /package/dist/{523.js.LICENSE.txt → 738.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#include "regression.h"
|
|
2
|
+
|
|
3
|
+
#include <emscripten.h>
|
|
4
|
+
|
|
5
|
+
// The following provides convenient naming of the exported functions.
|
|
6
|
+
extern "C" {
|
|
7
|
+
int fitLinearRegressionParamsWithDataNormalizing(
|
|
8
|
+
float * features, int featuresRowCount, int featuresColCount,
|
|
9
|
+
float * featureAvgs, int featureAvgsCount,
|
|
10
|
+
float * featureStdDevs, int featureStdDevsCount,
|
|
11
|
+
float * targets, int targetsCount,
|
|
12
|
+
float targetsAvg,
|
|
13
|
+
float targetsStdDev,
|
|
14
|
+
int paramsCount,
|
|
15
|
+
float * params, int paramsLength) noexcept;
|
|
16
|
+
|
|
17
|
+
int fitLinearRegressionParams(
|
|
18
|
+
float * features, int featuresRowCount, int featuresColCount,
|
|
19
|
+
float * targets, int targetsCount,
|
|
20
|
+
int paramsCount,
|
|
21
|
+
float * params, int paramsLength) noexcept;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//name: fitLinearRegressionParamsWithDataNormalizing
|
|
25
|
+
//input: column_list features
|
|
26
|
+
//input: column featureAvgs
|
|
27
|
+
//input: column featureStdDevs
|
|
28
|
+
//input: column targets
|
|
29
|
+
//input: double targetsAvg
|
|
30
|
+
//input: double targetsStdDev
|
|
31
|
+
//input: int paramsCount
|
|
32
|
+
//output: column params [new(paramsCount)]
|
|
33
|
+
EMSCRIPTEN_KEEPALIVE
|
|
34
|
+
int fitLinearRegressionParamsWithDataNormalizing(
|
|
35
|
+
float * features, int featuresRowCount, int featuresColCount,
|
|
36
|
+
float * featureAvgs, int featureAvgsCount,
|
|
37
|
+
float * featureStdDevs, int featureStdDevsCount,
|
|
38
|
+
float * targets, int targetsCount,
|
|
39
|
+
float targetsAvg,
|
|
40
|
+
float targetsStdDev,
|
|
41
|
+
int paramsCount,
|
|
42
|
+
float * params, int paramsLength) noexcept {
|
|
43
|
+
// Check sizes
|
|
44
|
+
if ((featuresRowCount != targetsCount) || (featuresColCount != paramsLength - 1))
|
|
45
|
+
return regr::INCORRECT_SIZES;
|
|
46
|
+
|
|
47
|
+
return regr::fitLinearRegressionParams(features, featureAvgs, featureStdDevs, targets, targetsAvg, targetsStdDev, params, targetsCount, featuresColCount);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//name: fitLinearRegressionParams
|
|
51
|
+
//input: column_list features
|
|
52
|
+
//input: column targets
|
|
53
|
+
//input: int paramsCount
|
|
54
|
+
//output: column params [new(paramsCount)]
|
|
55
|
+
EMSCRIPTEN_KEEPALIVE
|
|
56
|
+
int fitLinearRegressionParams(
|
|
57
|
+
float * features, int featuresRowCount, int featuresColCount,
|
|
58
|
+
float * targets, int targetsCount,
|
|
59
|
+
int paramsCount,
|
|
60
|
+
float * params, int paramsLength) noexcept {
|
|
61
|
+
// Check sizes
|
|
62
|
+
if ((featuresRowCount != targetsCount) || (featuresColCount != paramsLength - 1))
|
|
63
|
+
return regr::INCORRECT_SIZES;
|
|
64
|
+
|
|
65
|
+
return regr::fitLinearRegressionParams(features, targets, params, targetsCount, featuresColCount);
|
|
66
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// regression.h
|
|
2
|
+
|
|
3
|
+
/* Linear regression coefficients computation.
|
|
4
|
+
|
|
5
|
+
Implemented 2 approaches: with & without data normalizing.
|
|
6
|
+
Data normalizing provides better results in te case of big data. */
|
|
7
|
+
|
|
8
|
+
#include "../../../../Eigen/Eigen/Dense"
|
|
9
|
+
using namespace Eigen;
|
|
10
|
+
|
|
11
|
+
#ifndef REGRESSION_H
|
|
12
|
+
#define REGRESSION_H
|
|
13
|
+
|
|
14
|
+
namespace regr {
|
|
15
|
+
|
|
16
|
+
// computation result code
|
|
17
|
+
enum ResultCode {
|
|
18
|
+
NO_ERRORS = 0,
|
|
19
|
+
UNKNOWN_PROBLEM,
|
|
20
|
+
INCORRECT_SIZES,
|
|
21
|
+
DATA_WITH_ZERO_VARIATION
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/* Compute coeffcicients of linear regression.
|
|
25
|
+
features - features data pointer, X (column-by-column)
|
|
26
|
+
featureAvgs - mean values of feature columns
|
|
27
|
+
featureStdDevs - standard deviations of feature columns
|
|
28
|
+
targets - target values, Y
|
|
29
|
+
targetsAvg - target mean value
|
|
30
|
+
targetsStdDev - target standard deviation
|
|
31
|
+
params - parameters to be computed
|
|
32
|
+
samplesCount - number of samples
|
|
33
|
+
featuresCount - number of features
|
|
34
|
+
|
|
35
|
+
REMARK. Data normalization is applied. */
|
|
36
|
+
template<typename Float>
|
|
37
|
+
int fitLinearRegressionParams(
|
|
38
|
+
Float* features,
|
|
39
|
+
Float* featureAvgs,
|
|
40
|
+
Float* featureStdDevs,
|
|
41
|
+
Float* targets,
|
|
42
|
+
Float targetsAvg,
|
|
43
|
+
Float targetsStdDev,
|
|
44
|
+
Float* params,
|
|
45
|
+
int samplesCount,
|
|
46
|
+
int featuresCount) noexcept
|
|
47
|
+
{
|
|
48
|
+
// Associate matrices with pointers
|
|
49
|
+
Map<Vector<Float, Dynamic>> beta(params, featuresCount);
|
|
50
|
+
|
|
51
|
+
Map<Vector<Float, Dynamic>> y(targets, samplesCount);
|
|
52
|
+
Vector<Float, 1> avgY;
|
|
53
|
+
avgY(0) = targetsAvg;
|
|
54
|
+
|
|
55
|
+
Map<Matrix<Float, Dynamic, Dynamic, RowMajor>> X(features, featuresCount, samplesCount);
|
|
56
|
+
Map<Vector<Float, Dynamic>> avgX(featureAvgs, featuresCount);
|
|
57
|
+
Map<Vector<Float, Dynamic>> stdDevX(featureStdDevs, featuresCount);
|
|
58
|
+
|
|
59
|
+
// Normalize data
|
|
60
|
+
y = (y.rowwise() - avgY) / targetsStdDev;
|
|
61
|
+
|
|
62
|
+
X = X.colwise() - avgX;
|
|
63
|
+
for (int i = 0; i < featuresCount; ++i)
|
|
64
|
+
X.row(i) = X.row(i) / stdDevX(i);
|
|
65
|
+
|
|
66
|
+
// Compute linear regression coefs
|
|
67
|
+
auto buf = X * y;
|
|
68
|
+
|
|
69
|
+
// Here, other Eigen decompositions can be used
|
|
70
|
+
beta = (X * X.transpose()).ldlt().solve(buf);
|
|
71
|
+
|
|
72
|
+
// Rescale coefs, since data was normalized
|
|
73
|
+
Float sum = 0;
|
|
74
|
+
for (int i = 0; i < featuresCount; ++i) {
|
|
75
|
+
params[i] *= targetsStdDev / featureStdDevs[i];
|
|
76
|
+
sum += params[i] * featureAvgs[i];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
params[featuresCount] = targetsAvg - sum;
|
|
80
|
+
|
|
81
|
+
return NO_ERRORS;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Compute coeffcicients of linear regression.
|
|
85
|
+
features - features data pointer, X (column-by-column)
|
|
86
|
+
targets - target values, Y
|
|
87
|
+
params - parameters to be computed
|
|
88
|
+
samplesCount - number of samples
|
|
89
|
+
featuresCount - number of features */
|
|
90
|
+
template<typename Float>
|
|
91
|
+
int fitLinearRegressionParams(
|
|
92
|
+
Float* features,
|
|
93
|
+
Float* targets,
|
|
94
|
+
Float* params,
|
|
95
|
+
int samplesCount,
|
|
96
|
+
int featuresCount) noexcept
|
|
97
|
+
{
|
|
98
|
+
// Associate matrices with pointers
|
|
99
|
+
Map<Vector<Float, Dynamic>> beta(params, featuresCount + 1);
|
|
100
|
+
Map<Vector<Float, Dynamic>> y(targets, samplesCount);
|
|
101
|
+
|
|
102
|
+
// Data matrix: D = [X | 1] (transposed)
|
|
103
|
+
Matrix<Float, Dynamic, Dynamic, RowMajor> X(featuresCount + 1, samplesCount);
|
|
104
|
+
auto ptr = X.data();
|
|
105
|
+
|
|
106
|
+
// Fill D with feature values
|
|
107
|
+
size_t size = sizeof(Float) * featuresCount * samplesCount;
|
|
108
|
+
std::memcpy(ptr, features, size);
|
|
109
|
+
|
|
110
|
+
ptr += featuresCount * samplesCount;
|
|
111
|
+
|
|
112
|
+
// Add row of 1-s
|
|
113
|
+
for (int i = 0; i < samplesCount; ++i)
|
|
114
|
+
ptr[i] = 1;
|
|
115
|
+
|
|
116
|
+
// Compute linear regression coefs
|
|
117
|
+
auto buf = X * y;
|
|
118
|
+
|
|
119
|
+
// Here, other Eigen decompositions can be used
|
|
120
|
+
beta = (X * X.transpose()).colPivHouseholderQr().solve(buf);
|
|
121
|
+
|
|
122
|
+
return NO_ERRORS;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
}; // regr
|
|
126
|
+
|
|
127
|
+
#endif // !REGRESSION_H
|
|
128
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// The following code is generated automatically.
|
|
2
|
+
|
|
3
|
+
import {exportEDA} from '../../wasm/EDAForWebWorker';
|
|
4
|
+
import {cppWrapper} from '../../wasm/callWasmForWebWorker.js';
|
|
5
|
+
|
|
6
|
+
onmessage = async function (evt) {
|
|
7
|
+
exportEDA().then(module =>
|
|
8
|
+
{
|
|
9
|
+
let args = evt.data;
|
|
10
|
+
let result = cppWrapper(module, args, 'fitLinearRegressionParamsWithDataNormalizing', 'number');
|
|
11
|
+
postMessage({'callResult': result, 'args': args});
|
|
12
|
+
} )
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// The following code is generated automatically.
|
|
2
|
+
|
|
3
|
+
import {exportEDA} from '../../wasm/EDAForWebWorker';
|
|
4
|
+
import {cppWrapper} from '../../wasm/callWasmForWebWorker.js';
|
|
5
|
+
|
|
6
|
+
onmessage = async function (evt) {
|
|
7
|
+
exportEDA().then(module =>
|
|
8
|
+
{
|
|
9
|
+
let args = evt.data;
|
|
10
|
+
let result = cppWrapper(module, args, 'fitLinearRegressionParams', 'number');
|
|
11
|
+
postMessage({'callResult': result, 'args': args});
|
|
12
|
+
} )
|
|
13
|
+
}
|
package/webpack.config.js
CHANGED
package/dist/208.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var eda;(()=>{"use strict";var e,r,t={1208:(e,r,t)=>{var o=t(6845),a=t(2086);onmessage=async function(e){(0,o.P)().then((r=>{let t=e.data,o=(0,a.Gz)(r,t,"normalizeDataset","number");postMessage({callResult:o,args:t})}))}}},o={};function a(e){var r=o[e];if(void 0!==r)return r.exports;var n=o[e]={id:e,loaded:!1,exports:{}};return t[e](n,n.exports,a),n.loaded=!0,n.exports}a.m=t,a.x=()=>{var e=a.O(void 0,[902],(()=>a(1208)));return a.O(e)},a.amdO={},e=[],a.O=(r,t,o,n)=>{if(!t){var i=1/0;for(p=0;p<e.length;p++){for(var[t,o,n]=e[p],s=!0,c=0;c<t.length;c++)(!1&n||i>=n)&&Object.keys(a.O).every((e=>a.O[e](t[c])))?t.splice(c--,1):(s=!1,n<i&&(i=n));if(s){e.splice(p--,1);var l=o();void 0!==l&&(r=l)}}return r}n=n||0;for(var p=e.length;p>0&&e[p-1][2]>n;p--)e[p]=e[p-1];e[p]=[t,o,n]},a.d=(e,r)=>{for(var t in r)a.o(r,t)&&!a.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce(((r,t)=>(a.f[t](e,r),r)),[])),a.u=e=>e+".js",a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.hmd=e=>((e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set:()=>{throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e),a.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),(()=>{var e;a.g.importScripts&&(e=a.g.location+"");var r=a.g.document;if(!e&&r&&(r.currentScript&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var o=t.length-1;o>-1&&!e;)e=t[o--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),a.p=e})(),(()=>{a.b=self.location+"";var e={208:1};a.f.i=(r,t)=>{e[r]||importScripts(a.p+a.u(r))};var r=self.webpackChunkeda=self.webpackChunkeda||[],t=r.push.bind(r);r.push=r=>{var[o,n,i]=r;for(var s in n)a.o(n,s)&&(a.m[s]=n[s]);for(i&&i(a);o.length;)e[o.pop()]=1;t(r)}})(),r=a.x,a.x=()=>a.e(902).then(r);var n=a.x();eda=n})();
|
|
2
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFtQkUsS0FBS0MsS0FBS0gsR0FDOURBLEVBQW1CRSxLQXZCQzVFLElBQ25CLElBQUtpQixFQUFVNkQsRUFBYUMsR0FBVy9FLEVBQ3ZDLElBQUksSUFBSUssS0FBWXlFLEVBQ2hCMUUsRUFBb0I4QixFQUFFNEMsRUFBYXpFLEtBQ3JDRCxFQUFvQlEsRUFBRVAsR0FBWXlFLEVBQVl6RSxJQUloRCxJQURHMEUsR0FBU0EsRUFBUTNFLEdBQ2RhLEVBQVNNLFFBQ2RrRCxFQUFnQnhELEVBQVMrRCxPQUFTLEVBQ25DTCxFQUEyQjNFLEVBQUssQyxLWG5CN0JQLEVBQU9XLEVBQW9CUyxFQUMvQlQsRUFBb0JTLEVBQUksSUFDaEJULEVBQW9CbUMsRUFBRSxLQUFLMUMsS0FBS0osR1lEeEMsSUFBSXFCLEVBQXNCVixFQUFvQlMsSSIsInNvdXJjZXMiOlsid2VicGFjazovL2VkYS93ZWJwYWNrL3J1bnRpbWUvY2h1bmsgbG9hZGVkIiwid2VicGFjazovL2VkYS93ZWJwYWNrL3J1bnRpbWUvc3RhcnR1cCBjaHVuayBkZXBlbmRlbmNpZXMiLCJ3ZWJwYWNrOi8vZWRhLy4vd2FzbS93b3JrZXJzL25vcm1hbGl6ZURhdGFzZXRXb3JrZXIuanMiLCJ3ZWJwYWNrOi8vZWRhL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL2VkYS93ZWJwYWNrL3J1bnRpbWUvYW1kIG9wdGlvbnMiLCJ3ZWJwYWNrOi8vZWRhL3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly9lZGEvd2VicGFjay9ydW50aW1lL2Vuc3VyZSBjaHVuayIsIndlYnBhY2s6Ly9lZGEvd2VicGFjay9ydW50aW1lL2dldCBqYXZhc2NyaXB0IGNodW5rIGZpbGVuYW1lIiwid2VicGFjazovL2VkYS93ZWJwYWNrL3J1bnRpbWUvZ2xvYmFsIiwid2VicGFjazovL2VkYS93ZWJwYWNrL3J1bnRpbWUvaGFybW9ueSBtb2R1bGUgZGVjb3JhdG9yIiwid2VicGFjazovL2VkYS93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL2VkYS93ZWJwYWNrL3J1bnRpbWUvcHVibGljUGF0aCIsIndlYnBhY2s6Ly9lZGEvd2VicGFjay9ydW50aW1lL2ltcG9ydFNjcmlwdHMgY2h1bmsgbG9hZGluZyIsIndlYnBhY2s6Ly9lZGEvd2VicGFjay9zdGFydHVwIl0sInNvdXJjZXNDb250ZW50IjpbInZhciBkZWZlcnJlZCA9IFtdO1xuX193ZWJwYWNrX3JlcXVpcmVfXy5PID0gKHJlc3VsdCwgY2h1bmtJZHMsIGZuLCBwcmlvcml0eSkgPT4ge1xuXHRpZihjaHVua0lkcykge1xuXHRcdHByaW9yaXR5ID0gcHJpb3JpdHkgfHwgMDtcblx0XHRmb3IodmFyIGkgPSBkZWZlcnJlZC5sZW5ndGg7IGkgPiAwICYmIGRlZmVycmVkW2kgLSAxXVsyXSA+IHByaW9yaXR5OyBpLS0pIGRlZmVycmVkW2ldID0gZGVmZXJyZWRbaSAtIDFdO1xuXHRcdGRlZmVycmVkW2ldID0gW2NodW5rSWRzLCBmbiwgcHJpb3JpdHldO1xuXHRcdHJldHVybjtcblx0fVxuXHR2YXIgbm90RnVsZmlsbGVkID0gSW5maW5pdHk7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgZGVmZXJyZWQubGVuZ3RoOyBpKyspIHtcblx0XHR2YXIgW2NodW5rSWRzLCBmbiwgcHJpb3JpdHldID0gZGVmZXJyZWRbaV07XG5cdFx0dmFyIGZ1bGZpbGxlZCA9IHRydWU7XG5cdFx0Zm9yICh2YXIgaiA9IDA7IGogPCBjaHVua0lkcy5sZW5ndGg7IGorKykge1xuXHRcdFx0aWYgKChwcmlvcml0eSAmIDEgPT09IDAgfHwgbm90RnVsZmlsbGVkID49IHByaW9yaXR5KSAmJiBPYmplY3Qua2V5cyhfX3dlYnBhY2tfcmVxdWlyZV9fLk8pLmV2ZXJ5KChrZXkpID0+IChfX3dlYnBhY2tfcmVxdWlyZV9fLk9ba2V5XShjaHVua0lkc1tqXSkpKSkge1xuXHRcdFx0XHRjaHVua0lkcy5zcGxpY2Uoai0tLCAxKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZ1bGZpbGxlZCA9IGZhbHNlO1xuXHRcdFx0XHRpZihwcmlvcml0eSA8IG5vdEZ1bGZpbGxlZCkgbm90RnVsZmlsbGVkID0gcHJpb3JpdHk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmKGZ1bGZpbGxlZCkge1xuXHRcdFx0ZGVmZXJyZWQuc3BsaWNlKGktLSwgMSlcblx0XHRcdHZhciByID0gZm4oKTtcblx0XHRcdGlmIChyICE9PSB1bmRlZmluZWQpIHJlc3VsdCA9IHI7XG5cdFx0fVxuXHR9XG5cdHJldHVybiByZXN1bHQ7XG59OyIsInZhciBuZXh0ID0gX193ZWJwYWNrX3JlcXVpcmVfXy54O1xuX193ZWJwYWNrX3JlcXVpcmVfXy54ID0gKCkgPT4ge1xuXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXy5lKDkwMikudGhlbihuZXh0KTtcbn07IiwiLy8gVGhlIGZvbGxvd2luZyBjb2RlIGlzIGdlbmVyYXRlZCBhdXRvbWF0aWNhbGx5LlxuXG5pbXBvcnQge2V4cG9ydEVEQX0gZnJvbSAnLi4vLi4vd2FzbS9FREFGb3JXZWJXb3JrZXInO1xuaW1wb3J0IHtjcHBXcmFwcGVyfSBmcm9tICcuLi8uLi93YXNtL2NhbGxXYXNtRm9yV2ViV29ya2VyLmpzJztcblxub25tZXNzYWdlID0gYXN5bmMgZnVuY3Rpb24gKGV2dCkge1xuICBleHBvcnRFREEoKS50aGVuKG1vZHVsZSA9PiBcbiAgICB7XG4gICAgICBsZXQgYXJncyA9IGV2dC5kYXRhO1xuICAgICAgbGV0IHJlc3VsdCA9IGNwcFdyYXBwZXIobW9kdWxlLCBhcmdzLCAnbm9ybWFsaXplRGF0YXNldCcsICdudW1iZXInKTtcbiAgICAgIHBvc3RNZXNzYWdlKHsnY2FsbFJlc3VsdCc6IHJlc3VsdCwgJ2FyZ3MnOiBhcmdzfSk7XG4gICAgfSApXG59IiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHRpZDogbW9kdWxlSWQsXG5cdFx0bG9hZGVkOiBmYWxzZSxcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXShtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG5cdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuLy8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbl9fd2VicGFja19yZXF1aXJlX18ubSA9IF9fd2VicGFja19tb2R1bGVzX187XG5cbi8vIHRoZSBzdGFydHVwIGZ1bmN0aW9uXG5fX3dlYnBhY2tfcmVxdWlyZV9fLnggPSAoKSA9PiB7XG5cdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuXHQvLyBUaGlzIGVudHJ5IG1vZHVsZSBkZXBlbmRzIG9uIG90aGVyIGxvYWRlZCBjaHVua3MgYW5kIGV4ZWN1dGlvbiBuZWVkIHRvIGJlIGRlbGF5ZWRcblx0dmFyIF9fd2VicGFja19leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fLk8odW5kZWZpbmVkLCBbOTAyXSwgKCkgPT4gKF9fd2VicGFja19yZXF1aXJlX18oMTIwOCkpKVxuXHRfX3dlYnBhY2tfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXy5PKF9fd2VicGFja19leHBvcnRzX18pO1xuXHRyZXR1cm4gX193ZWJwYWNrX2V4cG9ydHNfXztcbn07XG5cbiIsIl9fd2VicGFja19yZXF1aXJlX18uYW1kTyA9IHt9OyIsIi8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb25zIGZvciBoYXJtb255IGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uZCA9IChleHBvcnRzLCBkZWZpbml0aW9uKSA9PiB7XG5cdGZvcih2YXIga2V5IGluIGRlZmluaXRpb24pIHtcblx0XHRpZihfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZGVmaW5pdGlvbiwga2V5KSAmJiAhX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIGtleSkpIHtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBrZXksIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBkZWZpbml0aW9uW2tleV0gfSk7XG5cdFx0fVxuXHR9XG59OyIsIl9fd2VicGFja19yZXF1aXJlX18uZiA9IHt9O1xuLy8gVGhpcyBmaWxlIGNvbnRhaW5zIG9ubHkgdGhlIGVudHJ5IGNodW5rLlxuLy8gVGhlIGNodW5rIGxvYWRpbmcgZnVuY3Rpb24gZm9yIGFkZGl0aW9uYWwgY2h1bmtzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmUgPSAoY2h1bmtJZCkgPT4ge1xuXHRyZXR1cm4gUHJvbWlzZS5hbGwoT2JqZWN0LmtleXMoX193ZWJwYWNrX3JlcXVpcmVfXy5mKS5yZWR1Y2UoKHByb21pc2VzLCBrZXkpID0+IHtcblx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmZba2V5XShjaHVua0lkLCBwcm9taXNlcyk7XG5cdFx0cmV0dXJuIHByb21pc2VzO1xuXHR9LCBbXSkpO1xufTsiLCIvLyBUaGlzIGZ1bmN0aW9uIGFsbG93IHRvIHJlZmVyZW5jZSBhc3luYyBjaHVua3MgYW5kIHNpYmxpbmcgY2h1bmtzIGZvciB0aGUgZW50cnlwb2ludFxuX193ZWJwYWNrX3JlcXVpcmVfXy51ID0gKGNodW5rSWQpID0+IHtcblx0Ly8gcmV0dXJuIHVybCBmb3IgZmlsZW5hbWVzIGJhc2VkIG9uIHRlbXBsYXRlXG5cdHJldHVybiBcIlwiICsgY2h1bmtJZCArIFwiLmpzXCI7XG59OyIsIl9fd2VicGFja19yZXF1aXJlX18uZyA9IChmdW5jdGlvbigpIHtcblx0aWYgKHR5cGVvZiBnbG9iYWxUaGlzID09PSAnb2JqZWN0JykgcmV0dXJuIGdsb2JhbFRoaXM7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIHRoaXMgfHwgbmV3IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHJldHVybiB3aW5kb3c7XG5cdH1cbn0pKCk7IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5obWQgPSAobW9kdWxlKSA9PiB7XG5cdG1vZHVsZSA9IE9iamVjdC5jcmVhdGUobW9kdWxlKTtcblx0aWYgKCFtb2R1bGUuY2hpbGRyZW4pIG1vZHVsZS5jaGlsZHJlbiA9IFtdO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kdWxlLCAnZXhwb3J0cycsIHtcblx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdHNldDogKCkgPT4ge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdFUyBNb2R1bGVzIG1heSBub3QgYXNzaWduIG1vZHVsZS5leHBvcnRzIG9yIGV4cG9ydHMuKiwgVXNlIEVTTSBleHBvcnQgc3ludGF4LCBpbnN0ZWFkOiAnICsgbW9kdWxlLmlkKTtcblx0XHR9XG5cdH0pO1xuXHRyZXR1cm4gbW9kdWxlO1xufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwidmFyIHNjcmlwdFVybDtcbmlmIChfX3dlYnBhY2tfcmVxdWlyZV9fLmcuaW1wb3J0U2NyaXB0cykgc2NyaXB0VXJsID0gX193ZWJwYWNrX3JlcXVpcmVfXy5nLmxvY2F0aW9uICsgXCJcIjtcbnZhciBkb2N1bWVudCA9IF9fd2VicGFja19yZXF1aXJlX18uZy5kb2N1bWVudDtcbmlmICghc2NyaXB0VXJsICYmIGRvY3VtZW50KSB7XG5cdGlmIChkb2N1bWVudC5jdXJyZW50U2NyaXB0KVxuXHRcdHNjcmlwdFVybCA9IGRvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjO1xuXHRpZiAoIXNjcmlwdFVybCkge1xuXHRcdHZhciBzY3JpcHRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzY3JpcHRcIik7XG5cdFx0aWYoc2NyaXB0cy5sZW5ndGgpIHtcblx0XHRcdHZhciBpID0gc2NyaXB0cy5sZW5ndGggLSAxO1xuXHRcdFx0d2hpbGUgKGkgPiAtMSAmJiAhc2NyaXB0VXJsKSBzY3JpcHRVcmwgPSBzY3JpcHRzW2ktLV0uc3JjO1xuXHRcdH1cblx0fVxufVxuLy8gV2hlbiBzdXBwb3J0aW5nIGJyb3dzZXJzIHdoZXJlIGFuIGF1dG9tYXRpYyBwdWJsaWNQYXRoIGlzIG5vdCBzdXBwb3J0ZWQgeW91IG11c3Qgc3BlY2lmeSBhbiBvdXRwdXQucHVibGljUGF0aCBtYW51YWxseSB2aWEgY29uZmlndXJhdGlvblxuLy8gb3IgcGFzcyBhbiBlbXB0eSBzdHJpbmcgKFwiXCIpIGFuZCBzZXQgdGhlIF9fd2VicGFja19wdWJsaWNfcGF0aF9fIHZhcmlhYmxlIGZyb20geW91ciBjb2RlIHRvIHVzZSB5b3VyIG93biBsb2dpYy5cbmlmICghc2NyaXB0VXJsKSB0aHJvdyBuZXcgRXJyb3IoXCJBdXRvbWF0aWMgcHVibGljUGF0aCBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlclwiKTtcbnNjcmlwdFVybCA9IHNjcmlwdFVybC5yZXBsYWNlKC8jLiokLywgXCJcIikucmVwbGFjZSgvXFw/LiokLywgXCJcIikucmVwbGFjZSgvXFwvW15cXC9dKyQvLCBcIi9cIik7XG5fX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBzY3JpcHRVcmw7IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5iID0gc2VsZi5sb2NhdGlvbiArIFwiXCI7XG5cbi8vIG9iamVjdCB0byBzdG9yZSBsb2FkZWQgY2h1bmtzXG4vLyBcIjFcIiBtZWFucyBcImFscmVhZHkgbG9hZGVkXCJcbnZhciBpbnN0YWxsZWRDaHVua3MgPSB7XG5cdDIwODogMVxufTtcblxuLy8gaW1wb3J0U2NyaXB0cyBjaHVuayBsb2FkaW5nXG52YXIgaW5zdGFsbENodW5rID0gKGRhdGEpID0+IHtcblx0dmFyIFtjaHVua0lkcywgbW9yZU1vZHVsZXMsIHJ1bnRpbWVdID0gZGF0YTtcblx0Zm9yKHZhciBtb2R1bGVJZCBpbiBtb3JlTW9kdWxlcykge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhtb3JlTW9kdWxlcywgbW9kdWxlSWQpKSB7XG5cdFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLm1bbW9kdWxlSWRdID0gbW9yZU1vZHVsZXNbbW9kdWxlSWRdO1xuXHRcdH1cblx0fVxuXHRpZihydW50aW1lKSBydW50aW1lKF9fd2VicGFja19yZXF1aXJlX18pO1xuXHR3aGlsZShjaHVua0lkcy5sZW5ndGgpXG5cdFx0aW5zdGFsbGVkQ2h1bmtzW2NodW5rSWRzLnBvcCgpXSA9IDE7XG5cdHBhcmVudENodW5rTG9hZGluZ0Z1bmN0aW9uKGRhdGEpO1xufTtcbl9fd2VicGFja19yZXF1aXJlX18uZi5pID0gKGNodW5rSWQsIHByb21pc2VzKSA9PiB7XG5cdC8vIFwiMVwiIGlzIHRoZSBzaWduYWwgZm9yIFwiYWxyZWFkeSBsb2FkZWRcIlxuXHRpZighaW5zdGFsbGVkQ2h1bmtzW2NodW5rSWRdKSB7XG5cdFx0aWYodHJ1ZSkgeyAvLyBhbGwgY2h1bmtzIGhhdmUgSlNcblx0XHRcdGltcG9ydFNjcmlwdHMoX193ZWJwYWNrX3JlcXVpcmVfXy5wICsgX193ZWJwYWNrX3JlcXVpcmVfXy51KGNodW5rSWQpKTtcblx0XHR9XG5cdH1cbn07XG5cbnZhciBjaHVua0xvYWRpbmdHbG9iYWwgPSBzZWxmW1wid2VicGFja0NodW5rZWRhXCJdID0gc2VsZltcIndlYnBhY2tDaHVua2VkYVwiXSB8fCBbXTtcbnZhciBwYXJlbnRDaHVua0xvYWRpbmdGdW5jdGlvbiA9IGNodW5rTG9hZGluZ0dsb2JhbC5wdXNoLmJpbmQoY2h1bmtMb2FkaW5nR2xvYmFsKTtcbmNodW5rTG9hZGluZ0dsb2JhbC5wdXNoID0gaW5zdGFsbENodW5rO1xuXG4vLyBubyBITVJcblxuLy8gbm8gSE1SIG1hbmlmZXN0IiwiLy8gcnVuIHN0YXJ0dXBcbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXy54KCk7XG4iXSwibmFtZXMiOlsiZGVmZXJyZWQiLCJuZXh0Iiwib25tZXNzYWdlIiwiYXN5bmMiLCJldnQiLCJ0aGVuIiwibW9kdWxlIiwiYXJncyIsImRhdGEiLCJyZXN1bHQiLCJwb3N0TWVzc2FnZSIsIl9fd2VicGFja19tb2R1bGVfY2FjaGVfXyIsIl9fd2VicGFja19yZXF1aXJlX18iLCJtb2R1bGVJZCIsImNhY2hlZE1vZHVsZSIsInVuZGVmaW5lZCIsImV4cG9ydHMiLCJpZCIsImxvYWRlZCIsIl9fd2VicGFja19tb2R1bGVzX18iLCJtIiwieCIsIl9fd2VicGFja19leHBvcnRzX18iLCJPIiwiYW1kTyIsImNodW5rSWRzIiwiZm4iLCJwcmlvcml0eSIsIm5vdEZ1bGZpbGxlZCIsIkluZmluaXR5IiwiaSIsImxlbmd0aCIsImZ1bGZpbGxlZCIsImoiLCJPYmplY3QiLCJrZXlzIiwiZXZlcnkiLCJrZXkiLCJzcGxpY2UiLCJyIiwiZCIsImRlZmluaXRpb24iLCJvIiwiZGVmaW5lUHJvcGVydHkiLCJlbnVtZXJhYmxlIiwiZ2V0IiwiZiIsImUiLCJjaHVua0lkIiwiUHJvbWlzZSIsImFsbCIsInJlZHVjZSIsInByb21pc2VzIiwidSIsImciLCJnbG9iYWxUaGlzIiwidGhpcyIsIkZ1bmN0aW9uIiwid2luZG93IiwiaG1kIiwiY3JlYXRlIiwiY2hpbGRyZW4iLCJzZXQiLCJFcnJvciIsIm9iaiIsInByb3AiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJzY3JpcHRVcmwiLCJpbXBvcnRTY3JpcHRzIiwibG9jYXRpb24iLCJkb2N1bWVudCIsImN1cnJlbnRTY3JpcHQiLCJzcmMiLCJzY3JpcHRzIiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJyZXBsYWNlIiwicCIsImIiLCJzZWxmIiwiaW5zdGFsbGVkQ2h1bmtzIiwiY2h1bmtMb2FkaW5nR2xvYmFsIiwicGFyZW50Q2h1bmtMb2FkaW5nRnVuY3Rpb24iLCJwdXNoIiwiYmluZCIsIm1vcmVNb2R1bGVzIiwicnVudGltZSIsInBvcCJdLCJzb3VyY2VSb290IjoiIn0=
|