@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.
Files changed (111) hide show
  1. package/.vscode/settings.json +5 -0
  2. package/CHANGELOG.md +12 -0
  3. package/README.md +1 -0
  4. package/dist/05e5e0770f54f07e9474.wasm +0 -0
  5. package/dist/111.js +2 -0
  6. package/dist/111.js.map +1 -0
  7. package/dist/153.js +2 -0
  8. package/dist/153.js.map +1 -0
  9. package/dist/23.js +2 -2
  10. package/dist/23.js.map +1 -0
  11. package/dist/234.js +2 -0
  12. package/dist/234.js.map +1 -0
  13. package/dist/242.js +2 -0
  14. package/dist/242.js.map +1 -0
  15. package/dist/260.js +2 -0
  16. package/dist/260.js.map +1 -0
  17. package/dist/317.js +2 -0
  18. package/dist/317.js.map +1 -0
  19. package/dist/33.js +2 -0
  20. package/dist/33.js.map +1 -0
  21. package/dist/348.js +2 -0
  22. package/dist/348.js.map +1 -0
  23. package/dist/377.js +2 -0
  24. package/dist/377.js.map +1 -0
  25. package/dist/412.js +2 -0
  26. package/dist/412.js.map +1 -0
  27. package/dist/415.js +2 -0
  28. package/dist/415.js.map +1 -0
  29. package/dist/531.js +2 -0
  30. package/dist/531.js.map +1 -0
  31. package/dist/583.js +2 -0
  32. package/dist/583.js.map +1 -0
  33. package/dist/589.js +2 -0
  34. package/dist/589.js.map +1 -0
  35. package/dist/603.js +2 -0
  36. package/dist/603.js.map +1 -0
  37. package/dist/656.js +2 -0
  38. package/dist/656.js.map +1 -0
  39. package/dist/682.js +2 -0
  40. package/dist/682.js.map +1 -0
  41. package/dist/705.js +2 -0
  42. package/dist/705.js.map +1 -0
  43. package/dist/731.js +2 -0
  44. package/dist/731.js.map +1 -0
  45. package/dist/738.js +3 -0
  46. package/dist/738.js.map +1 -0
  47. package/dist/763.js +2 -0
  48. package/dist/763.js.map +1 -0
  49. package/dist/778.js +2 -0
  50. package/dist/778.js.map +1 -0
  51. package/dist/783.js +2 -0
  52. package/dist/783.js.map +1 -0
  53. package/dist/793.js +2 -0
  54. package/dist/793.js.map +1 -0
  55. package/dist/907.js +2 -0
  56. package/dist/907.js.map +1 -0
  57. package/dist/91.js +2 -0
  58. package/dist/91.js.map +1 -0
  59. package/dist/950.js +2 -0
  60. package/dist/950.js.map +1 -0
  61. package/dist/package-test.js +2 -2
  62. package/dist/package-test.js.map +1 -0
  63. package/dist/package.js +2 -2
  64. package/dist/package.js.map +1 -0
  65. package/package.json +92 -92
  66. package/scripts/command.txt +1 -1
  67. package/scripts/func.json +1 -1
  68. package/scripts/module.json +1 -1
  69. package/src/missing-values-imputation/ui.ts +80 -66
  70. package/src/package.ts +288 -38
  71. package/src/pls/pls-tools.ts +16 -15
  72. package/src/regression.ts +232 -0
  73. package/src/svm.ts +78 -38
  74. package/tsconfig.json +4 -4
  75. package/wasm/EDA.js +65 -1
  76. package/wasm/EDA.wasm +0 -0
  77. package/wasm/EDAAPI.js +30 -0
  78. package/wasm/EDAForWebWorker.js +1 -1
  79. package/wasm/callWasm.js +384 -393
  80. package/wasm/regression-api.cpp +66 -0
  81. package/wasm/regression.h +128 -0
  82. package/wasm/workers/fitLinearRegressionParamsWithDataNormalizingWorker.js +13 -0
  83. package/wasm/workers/fitLinearRegressionParamsWorker.js +13 -0
  84. package/webpack.config.js +1 -1
  85. package/dist/208.js +0 -2
  86. package/dist/221.js +0 -2
  87. package/dist/231.js +0 -2
  88. package/dist/261.js +0 -2
  89. package/dist/282.js +0 -2
  90. package/dist/334.js +0 -2
  91. package/dist/356.js +0 -2
  92. package/dist/36.js +0 -2
  93. package/dist/367.js +0 -2
  94. package/dist/374.js +0 -2
  95. package/dist/40.js +0 -2
  96. package/dist/413.js +0 -2
  97. package/dist/42.js +0 -2
  98. package/dist/427.js +0 -2
  99. package/dist/467.js +0 -2
  100. package/dist/523.js +0 -3
  101. package/dist/533.js +0 -2
  102. package/dist/590.js +0 -2
  103. package/dist/65.js +0 -2
  104. package/dist/694.js +0 -2
  105. package/dist/729.js +0 -2
  106. package/dist/796.js +0 -2
  107. package/dist/902.js +0 -2
  108. package/dist/910.js +0 -2
  109. package/dist/972.js +0 -2
  110. package/dist/f5343e2c2e15952ce916.wasm +0 -0
  111. /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
@@ -23,7 +23,7 @@ module.exports = {
23
23
  },
24
24
  ],
25
25
  },
26
- devtool: 'inline-source-map',
26
+ devtool: 'source-map',
27
27
  externals: {
28
28
  'datagrok-api/dg': 'DG',
29
29
  'datagrok-api/grok': 'grok',
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=