@libs-ui/utils 0.2.283 → 0.2.285
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/esm2022/get-smart-axis-scale.mjs +123 -135
- package/fesm2022/libs-ui-utils.mjs +122 -134
- package/fesm2022/libs-ui-utils.mjs.map +1 -1
- package/get-smart-axis-scale.d.ts +15 -12
- package/package.json +2 -2
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
1
|
import { isNil } from "./helpers";
|
|
3
|
-
// Constants for better maintainability
|
|
4
2
|
const DEFAULT_MIN_TICK_COUNT = 5;
|
|
5
3
|
const DEFAULT_MAX_TICK_COUNT = 10;
|
|
6
4
|
const MIN_DISTANCE_TO_ZERO = 3;
|
|
@@ -8,144 +6,78 @@ const NEGATIVE_THRESHOLD = -5;
|
|
|
8
6
|
const FALLBACK_NEGATIVE_VALUE = -4;
|
|
9
7
|
const MAX_POW_NUMBER = 14;
|
|
10
8
|
const MAX_TEMPLATE_NUMBER = 10;
|
|
11
|
-
// Cache for power calculations - shared across function calls for better performance
|
|
12
|
-
const POWER_CACHE = new Map();
|
|
13
9
|
/**
|
|
14
|
-
*
|
|
10
|
+
* Tính toán smart axis scale cho biểu đồ
|
|
11
|
+
*
|
|
12
|
+
* @param maxData - Giá trị tối đa của dữ liệu
|
|
13
|
+
* @param options - Các tùy chọn cấu hình axis scale
|
|
14
|
+
* @returns Cấu hình axis scale bao gồm stepSize, max, min, tickAmount
|
|
15
15
|
*
|
|
16
|
-
* @
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* - minNegative > 0 (only when acceptNegative is true)
|
|
16
|
+
* @throws {Error} INVALID_NEGATIVE_DATA - khi maxData < 0 mà acceptNegative = false
|
|
17
|
+
* @throws {Error} MISSING_MIN_NEGATIVE - khi acceptNegative = true nhưng thiếu minNegative
|
|
18
|
+
* @throws {Error} INVALID_RANGE - khi maxData < minNegative
|
|
19
|
+
* @throws {Error} INVALID_MIN_NEGATIVE - khi minNegative >= 0
|
|
21
20
|
*
|
|
22
|
-
* @
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const result = getSmartAxisScale(100, { minTickCount: 5, maxTickCount: 10 });
|
|
24
|
+
* // returns { stepSize: 20, max: 120, min: 0, tickAmount: 6 }
|
|
25
|
+
* ```
|
|
27
26
|
*/
|
|
28
|
-
export const getSmartAxisScale = (
|
|
29
|
-
|
|
27
|
+
export const getSmartAxisScale = (originalMaxData, options) => {
|
|
28
|
+
let maxData = originalMaxData;
|
|
30
29
|
validateInputs(maxData, options);
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
: generateStepCandidates(maxData, minTickCount, minNegative, acceptStepIsTypeFloat);
|
|
37
|
-
// Remove console.log for production code
|
|
38
|
-
// console.log(`stepCandidates: `, finalStepCandidates);
|
|
39
|
-
// Calculate scale parameters
|
|
40
|
-
const scaleParams = calculateScaleParams(maxData, acceptNegative, minNegative, finalStepCandidates);
|
|
41
|
-
// Find optimal scale
|
|
42
|
-
const optimalScale = findOptimalScale(scaleParams, finalStepCandidates, minTickCount, maxTickCount, options);
|
|
43
|
-
if (optimalScale) {
|
|
44
|
-
return optimalScale;
|
|
45
|
-
}
|
|
46
|
-
// Fallback calculation
|
|
47
|
-
return calculateFallbackScale(scaleParams.distanceToZero, minTickCount);
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* Validates input parameters
|
|
51
|
-
*/
|
|
52
|
-
function validateInputs(maxData, options) {
|
|
53
|
-
if (maxData < 0 && !options?.acceptNegative) {
|
|
54
|
-
throw new Error("maxData is less than 0 and acceptNegative is false");
|
|
55
|
-
}
|
|
56
|
-
if (options?.acceptNegative) {
|
|
57
|
-
if (isNil(options.minNegative)) {
|
|
58
|
-
throw new Error("minNegative is required when acceptNegative is true");
|
|
59
|
-
}
|
|
60
|
-
if (maxData < options.minNegative) {
|
|
61
|
-
throw new Error("maxData is less than minNegative");
|
|
62
|
-
}
|
|
63
|
-
if (options.minNegative >= 0) {
|
|
64
|
-
throw new Error("minNegative must be negative");
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Calculates scale parameters for axis calculation
|
|
70
|
-
*/
|
|
71
|
-
function calculateScaleParams(maxData, acceptNegative, minNegative, stepCandidates) {
|
|
72
|
-
let distanceToZero = maxData;
|
|
73
|
-
let reverse = 1;
|
|
74
|
-
let adjustedMaxData = maxData;
|
|
75
|
-
if (acceptNegative && !isNil(minNegative)) {
|
|
30
|
+
const minTickCount = options?.minTickCount || DEFAULT_MIN_TICK_COUNT;
|
|
31
|
+
const maxTickCount = options?.maxTickCount || DEFAULT_MAX_TICK_COUNT;
|
|
32
|
+
let scaleDirection = 1;
|
|
33
|
+
let rangeDistance = maxData;
|
|
34
|
+
if (options?.acceptNegative && !isNil(options.minNegative)) {
|
|
76
35
|
if (maxData === 0) {
|
|
77
|
-
|
|
36
|
+
maxData = -1;
|
|
78
37
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
stepCandidates.unshift(...stepCandidates.map(item => -item));
|
|
38
|
+
if (maxData <= 0) {
|
|
39
|
+
rangeDistance = options.minNegative;
|
|
82
40
|
}
|
|
83
|
-
if (
|
|
84
|
-
|
|
41
|
+
if (rangeDistance > NEGATIVE_THRESHOLD) {
|
|
42
|
+
rangeDistance = FALLBACK_NEGATIVE_VALUE;
|
|
85
43
|
}
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (adjustedMaxData > 0) {
|
|
90
|
-
distanceToZero = adjustedMaxData + Math.abs(minNegative);
|
|
91
|
-
reverse = -1;
|
|
44
|
+
if (maxData > 0) {
|
|
45
|
+
rangeDistance = maxData + Math.abs(options.minNegative);
|
|
46
|
+
scaleDirection = -1;
|
|
92
47
|
}
|
|
93
48
|
}
|
|
94
|
-
if (Math.abs(
|
|
95
|
-
|
|
49
|
+
if (Math.abs(rangeDistance) < MIN_DISTANCE_TO_ZERO) {
|
|
50
|
+
rangeDistance = MIN_DISTANCE_TO_ZERO;
|
|
96
51
|
}
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Finds optimal scale from step candidates
|
|
101
|
-
*/
|
|
102
|
-
function findOptimalScale(scaleParams, stepCandidates, minTickCount, maxTickCount, options) {
|
|
103
|
-
const { distanceToZero, reverse, adjustedMaxData } = scaleParams;
|
|
52
|
+
const stepCandidates = getStepCandidates(maxData, minTickCount, options?.minNegative || 0, options?.acceptStepIsTypeFloat, options?.stepCandidates, options?.acceptNegative);
|
|
104
53
|
for (const step of stepCandidates) {
|
|
105
|
-
let tickCount = Math.abs(Math.ceil(
|
|
106
|
-
let maxValue =
|
|
54
|
+
let tickCount = Math.abs(Math.ceil(rangeDistance / step)) + (scaleDirection === -1 ? 2 : 1);
|
|
55
|
+
let maxValue = maxData <= 0 ? 0 : step * tickCount * scaleDirection;
|
|
107
56
|
let minValue = 0;
|
|
108
|
-
if (tickCount >= minTickCount && tickCount <= maxTickCount
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
57
|
+
if (tickCount >= minTickCount && tickCount <= maxTickCount) {
|
|
58
|
+
if (maxData < maxValue) {
|
|
59
|
+
if (options?.acceptNegative) {
|
|
60
|
+
let tick = 1;
|
|
61
|
+
while (!isNil(options.minNegative) && tick <= tickCount && minValue >= options.minNegative) {
|
|
62
|
+
minValue = tick * step;
|
|
63
|
+
tick++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const maxValuePositive = maxValue - Math.abs(minValue);
|
|
67
|
+
tickCount = maxValuePositive - originalMaxData > Math.abs(step) && tickCount - 1 >= minTickCount ? tickCount - 1 : tickCount;
|
|
68
|
+
maxValue = (step * tickCount * scaleDirection) - (minValue * scaleDirection);
|
|
69
|
+
return {
|
|
70
|
+
stepSize: Math.abs(step),
|
|
71
|
+
max: maxValue,
|
|
72
|
+
min: minValue,
|
|
73
|
+
tickAmount: tickCount
|
|
74
|
+
};
|
|
116
75
|
}
|
|
117
|
-
maxValue = (step * tickCount * reverse) - (minValue * reverse);
|
|
118
|
-
return {
|
|
119
|
-
stepSize: Math.abs(step),
|
|
120
|
-
max: maxValue,
|
|
121
|
-
min: minValue,
|
|
122
|
-
tickAmount: tickCount
|
|
123
|
-
};
|
|
124
76
|
}
|
|
125
77
|
}
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Calculates minimum value for negative acceptance
|
|
130
|
-
*/
|
|
131
|
-
function calculateMinValue(step, tickCount, minNegative) {
|
|
132
|
-
let minValue = 0;
|
|
133
|
-
if (!isNil(minNegative)) {
|
|
134
|
-
let tick = 1;
|
|
135
|
-
while (tick <= tickCount && minValue >= minNegative) {
|
|
136
|
-
minValue = tick * step;
|
|
137
|
-
tick++;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return minValue;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Calculates fallback scale when no optimal scale is found
|
|
144
|
-
*/
|
|
145
|
-
function calculateFallbackScale(distanceToZero, minTickCount) {
|
|
146
|
-
let step = Math.ceil(distanceToZero / minTickCount) || 1;
|
|
78
|
+
let step = Math.ceil(rangeDistance / minTickCount) || 1;
|
|
147
79
|
let maxValue = step * minTickCount;
|
|
148
|
-
if (
|
|
80
|
+
if (rangeDistance === maxValue) {
|
|
149
81
|
step = step + Math.ceil(step / 10);
|
|
150
82
|
maxValue = step * minTickCount;
|
|
151
83
|
}
|
|
@@ -155,32 +87,88 @@ function calculateFallbackScale(distanceToZero, minTickCount) {
|
|
|
155
87
|
min: 0,
|
|
156
88
|
tickAmount: minTickCount
|
|
157
89
|
};
|
|
158
|
-
}
|
|
90
|
+
};
|
|
91
|
+
// Cache cho các giá trị lũy thừa 10 để tối ưu hiệu suất
|
|
92
|
+
const POWER_CACHE = new Map();
|
|
159
93
|
/**
|
|
160
|
-
*
|
|
94
|
+
* Tạo danh sách các step candidates cho việc tính toán scale
|
|
95
|
+
* @param maxData - Giá trị dữ liệu tối đa
|
|
96
|
+
* @param minStep - Số bước tối thiểu
|
|
97
|
+
* @param minNegative - Giá trị âm tối thiểu
|
|
98
|
+
* @param acceptStepIsTypeFloat - Có chấp nhận step thập phân không
|
|
99
|
+
* @param stepCandidatesByOptions - Step candidates do người dùng cung cấp
|
|
100
|
+
* @param includeNegativeSteps - Có bao gồm các step âm không
|
|
101
|
+
* @returns Danh sách các step candidates
|
|
161
102
|
*/
|
|
162
|
-
|
|
163
|
-
|
|
103
|
+
const getStepCandidates = (maxData, minStep, minNegative, acceptStepIsTypeFloat = false, stepCandidatesByOptions, includeNegativeSteps = false) => {
|
|
104
|
+
// Nếu có step candidates tùy chỉnh, sử dụng chúng
|
|
105
|
+
if (stepCandidatesByOptions && stepCandidatesByOptions.length > 0) {
|
|
106
|
+
return stepCandidatesByOptions;
|
|
107
|
+
}
|
|
108
|
+
const stepCandidates = new Array();
|
|
164
109
|
const maxValueStep = Math.abs(Math.max(maxData, Math.abs(minNegative || 0))) / minStep;
|
|
165
|
-
//
|
|
166
|
-
for (let powNumber = 0; powNumber
|
|
110
|
+
// Tạo step candidates dựa trên lũy thừa của 10
|
|
111
|
+
for (let powNumber = 0; powNumber <= MAX_POW_NUMBER; powNumber++) {
|
|
112
|
+
// Sử dụng cache để tối ưu hiệu suất
|
|
167
113
|
if (!POWER_CACHE.has(powNumber)) {
|
|
168
114
|
POWER_CACHE.set(powNumber, Math.pow(10, powNumber));
|
|
169
115
|
}
|
|
170
|
-
const
|
|
116
|
+
const powValue = POWER_CACHE.get(powNumber);
|
|
171
117
|
for (let templateNumber = 1; templateNumber < MAX_TEMPLATE_NUMBER; templateNumber++) {
|
|
118
|
+
// Thêm step thập phân nếu được chấp nhận
|
|
172
119
|
if (acceptStepIsTypeFloat) {
|
|
173
|
-
const
|
|
174
|
-
stepCandidates.push(
|
|
120
|
+
const step = powValue * (((templateNumber - 1) * 2 + 1) / 2);
|
|
121
|
+
stepCandidates.push(step);
|
|
175
122
|
}
|
|
176
|
-
const step =
|
|
123
|
+
const step = powValue * templateNumber;
|
|
177
124
|
stepCandidates.push(step);
|
|
178
|
-
//
|
|
125
|
+
// Dừng khi step đã đủ lớn
|
|
179
126
|
if (step >= maxValueStep) {
|
|
127
|
+
checkAndSetNegativeSteps(stepCandidates, includeNegativeSteps, minNegative);
|
|
180
128
|
return stepCandidates;
|
|
181
129
|
}
|
|
182
130
|
}
|
|
183
131
|
}
|
|
132
|
+
checkAndSetNegativeSteps(stepCandidates, includeNegativeSteps, minNegative);
|
|
184
133
|
return stepCandidates;
|
|
185
|
-
}
|
|
186
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LXNtYXJ0LWF4aXMtc2NhbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWJzLXVpL3V0aWxzL3NyYy9nZXQtc21hcnQtYXhpcy1zY2FsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw2REFBNkQ7QUFDN0QsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFdBQVcsQ0FBQztBQW1CbEMsdUNBQXVDO0FBQ3ZDLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLE1BQU0sc0JBQXNCLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBQy9CLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDOUIsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNuQyxNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUM7QUFDMUIsTUFBTSxtQkFBbUIsR0FBRyxFQUFFLENBQUM7QUFFL0IscUZBQXFGO0FBQ3JGLE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0FBRTlDOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsQ0FDL0IsT0FBZSxFQUNmLE9BQTBCLEVBQ1QsRUFBRTtJQUNuQix3Q0FBd0M7SUFDeEMsY0FBYyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUVqQywyQkFBMkI7SUFDM0IsTUFBTSxFQUNKLFlBQVksR0FBRyxzQkFBc0IsRUFDckMsWUFBWSxHQUFHLHNCQUFzQixFQUNyQyxjQUFjLEdBQUcsRUFBRSxFQUNuQixjQUFjLEdBQUcsS0FBSyxFQUN0QixXQUFXLEVBQ1gscUJBQXFCLEdBQUcsS0FBSyxFQUM5QixHQUFHLE9BQU8sSUFBSSxFQUFFLENBQUM7SUFFbEIsMkNBQTJDO0lBQzNDLE1BQU0sbUJBQW1CLEdBQUcsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQ25ELENB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LENBQUMsQ0FBQyxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ25FLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDakMsQ0FBQztZQUVELE1BQU0sSUFBSSxHQUFHLFNBQVMsR0FBRyxjQUFjLENBQUM7WUFDeEMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUUxQixvQ0FBb0M7WUFDcEMsSUFBSSxJQUFJLElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ3pCLE9BQU8sY0FBYyxDQUFDO1lBQ3hCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sY0FBYyxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5pbXBvcnQgeyBpc05pbCB9IGZyb20gXCIuL2hlbHBlcnNcIjtcblxuLy8gRGVmaW5lIGludGVyZmFjZXMgZm9yIGJldHRlciB0eXBlIHNhZmV0eVxuaW50ZXJmYWNlIEF4aXNTY2FsZU9wdGlvbnMge1xuICBtaW5UaWNrQ291bnQ/OiBudW1iZXI7XG4gIG1heFRpY2tDb3VudD86IG51bWJlcjtcbiAgc3RlcENhbmRpZGF0ZXM/OiBudW1iZXJbXTtcbiAgYWNjZXB0TmVnYXRpdmU/OiBib29sZWFuO1xuICBtaW5OZWdhdGl2ZT86IG51bWJlcjtcbiAgYWNjZXB0U3RlcElzVHlwZUZsb2F0PzogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIEF4aXNTY2FsZVJlc3VsdCB7XG4gIHN0ZXBTaXplOiBudW1iZXI7XG4gIG1heDogbnVtYmVyO1xuICBtaW46IG51bWJlcjtcbiAgdGlja0Ftb3VudDogbnVtYmVyO1xufVxuXG4vLyBDb25zdGFudHMgZm9yIGJldHRlciBtYWludGFpbmFiaWxpdHlcbmNvbnN0IERFRkFVTFRfTUlOX1RJQ0tfQ09VTlQgPSA1O1xuY29uc3QgREVGQVVMVF9NQVhfVElDS19DT1VOVCA9IDEwO1xuY29uc3QgTUlOX0RJU1RBTkNFX1RPX1pFUk8gPSAzO1xuY29uc3QgTkVHQVRJVkVfVEhSRVNIT0xEID0gLTU7XG5jb25zdCBGQUxMQkFDS19ORUdBVElWRV9WQUxVRSA9IC00O1xuY29uc3QgTUFYX1BPV19OVU1CRVIgPSAxNDtcbmNvbnN0IE1BWF9URU1QTEFURV9OVU1CRVIgPSAxMDtcblxuLy8gQ2FjaGUgZm9yIHBvd2VyIGNhbGN1bGF0aW9ucyAtIHNoYXJlZCBhY3Jvc3MgZnVuY3Rpb24gY2FsbHMgZm9yIGJldHRlciBwZXJmb3JtYW5jZVxuY29uc3QgUE9XRVJfQ0FDSEUgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgc21hcnQgYXhpcyBzY2FsZSBmb3IgY2hhcnRzXG4gKiBcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIGZ1bmN0aW9uIGNhbiB0aHJvdyBlcnJvcnMgaWY6XG4gKiAtIG1heERhdGEgPCAwIGFuZCBhY2NlcHROZWdhdGl2ZSBpcyBmYWxzZVxuICogLSBtaW5OZWdhdGl2ZSBpcyB1bmRlZmluZWQgYW5kIGFjY2VwdE5lZ2F0aXZlIGlzIHRydWVcbiAqIC0gbWF4RGF0YSA8IG1pbk5lZ2F0aXZlIChvbmx5IHdoZW4gYWNjZXB0TmVnYXRpdmUgaXMgdHJ1ZSlcbiAqIC0gbWluTmVnYXRpdmUgPiAwIChvbmx5IHdoZW4gYWNjZXB0TmVnYXRpdmUgaXMgdHJ1ZSlcbiAqIFxuICogQHRocm93cyB7RXJyb3J9IFZhbGlkYXRpb24gZXJyb3JzIGZvciBpbnZhbGlkIGlucHV0IGNvbWJpbmF0aW9uc1xuICogQHJlcXVpcmVkIEFsd2F5cyB3cmFwIHRoaXMgZnVuY3Rpb24gaW4gdHJ5LWNhdGNoIGFuZCBoYW5kbGUgZXhjZXB0aW9uc1xuICogQHBhcmFtIG1heERhdGEgLSBNYXhpbXVtIGRhdGEgdmFsdWVcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBheGlzIHNjYWxpbmdcbiAqIEByZXR1cm5zIEF4aXMgc2NhbGUgY29uZmlndXJhdGlvblxuICovXG5leHBvcnQgY29uc3QgZ2V0U21hcnRBeGlzU2NhbGUgPSAoXG4gIG1heERhdGE6IG51bWJlciwgXG4gIG9wdGlvbnM/OiBBeGlzU2NhbGVPcHRpb25zXG4pOiBBeGlzU2NhbGVSZXN1bHQgPT4ge1xuICAvLyBJbnB1dCB2YWxpZGF0aW9uIC0gZmFpbCBmYXN0IGFwcHJvYWNoXG4gIHZhbGlkYXRlSW5wdXRzKG1heERhdGEsIG9wdGlvbnMpO1xuICBcbiAgLy8gRXh0cmFjdCBhbmQgc2V0IGRlZmF1bHRzXG4gIGNvbnN0IHtcbiAgICBtaW5UaWNrQ291bnQgPSBERUZBVUxUX01JTl9USUNLX0NPVU5ULFxuICAgIG1heFRpY2tDb3VudCA9IERFRkFVTFRfTUFYX1RJQ0tfQ09VTlQsXG4gICAgc3RlcENhbmRpZGF0ZXMgPSBbXSxcbiAgICBhY2NlcHROZWdhdGl2ZSA9IGZhbHNlLFxuICAgIG1pbk5lZ2F0aXZlLFxuICAgIGFjY2VwdFN0ZXBJc1R5cGVGbG9hdCA9IGZhbHNlXG4gIH0gPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIEdlbmVyYXRlIHN0ZXAgY2FuZGlkYXRlcyBpZiBub3QgcHJvdmlkZWRcbiAgY29uc3QgZmluYWxTdGVwQ2FuZGlkYXRlcyA9IHN0ZXBDYW5kaWRhdGVzLmxlbmd0aCA+IDAgXG4gICAgPyBbLi4uc3RlcENhbmRpZGF0ZXNdXG4gICAgOiBnZW5lcmF0ZVN0ZXBDYW5kaWRhdGVzKG1heERhdGEsIG1pblRpY2tDb3VudCwgbWluTmVnYXRpdmUsIGFjY2VwdFN0ZXBJc1R5cGVGbG9hdCk7XG5cbiAgLy8gUmVtb3ZlIGNvbnNvbGUubG9nIGZvciBwcm9kdWN0aW9uIGNvZGVcbiAgLy8gY29uc29sZS5sb2coYHN0ZXBDYW5kaWRhdGVzOiBgLCBmaW5hbFN0ZXBDYW5kaWRhdGVzKTtcblxuICAvLyBDYWxjdWxhdGUgc2NhbGUgcGFyYW1ldGVyc1xuICBjb25zdCBzY2FsZVBhcmFtcyA9IGNhbGN1bGF0ZVNjYWxlUGFyYW1zKG1heERhdGEsIGFjY2VwdE5lZ2F0aXZlLCBtaW5OZWdhdGl2ZSwgZmluYWxTdGVwQ2FuZGlkYXRlcyk7XG4gIFxuICAvLyBGaW5kIG9wdGltYWwgc2NhbGVcbiAgY29uc3Qgb3B0aW1hbFNjYWxlID0gZmluZE9wdGltYWxTY2FsZShcbiAgICBzY2FsZVBhcmFtcywgXG4gICAgZmluYWxTdGVwQ2FuZGlkYXRlcywgXG4gICAgbWluVGlja0NvdW50LCBcbiAgICBtYXhUaWNrQ291bnQsIFxuICAgIG9wdGlvbnNcbiAgKTtcblxuICBpZiAob3B0aW1hbFNjYWxlKSB7XG4gICAgcmV0dXJuIG9wdGltYWxTY2FsZTtcbiAgfVxuXG4gIC8vIEZhbGxiYWNrIGNhbGN1bGF0aW9uXG4gIHJldHVybiBjYWxjdWxhdGVGYWxsYmFja1NjYWxlKHNjYWxlUGFyYW1zLmRpc3RhbmNlVG9aZXJvLCBtaW5UaWNrQ291bnQpO1xufTtcblxuLyoqXG4gKiBWYWxpZGF0ZXMgaW5wdXQgcGFyYW1ldGVyc1xuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUlucHV0cyhtYXhEYXRhOiBudW1iZXIsIG9wdGlvbnM/OiBBeGlzU2NhbGVPcHRpb25zKTogdm9pZCB7XG4gIGlmIChtYXhEYXRhIDwgMCAmJiAhb3B0aW9ucz8uYWNjZXB0TmVnYXRpdmUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJtYXhEYXRhIGlzIGxlc3MgdGhhbiAwIGFuZCBhY2NlcHROZWdhdGl2ZSBpcyBmYWxzZVwiKTtcbiAgfVxuICBcbiAgaWYgKG9wdGlvbnM/LmFjY2VwdE5lZ2F0aXZlKSB7XG4gICAgaWYgKGlzTmlsKG9wdGlvbnMubWluTmVnYXRpdmUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtaW5OZWdhdGl2ZSBpcyByZXF1aXJlZCB3aGVuIGFjY2VwdE5lZ2F0aXZlIGlzIHRydWVcIik7XG4gICAgfVxuICAgIGlmIChtYXhEYXRhIDwgb3B0aW9ucy5taW5OZWdhdGl2ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWF4RGF0YSBpcyBsZXNzIHRoYW4gbWluTmVnYXRpdmVcIik7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLm1pbk5lZ2F0aXZlID49IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pbk5lZ2F0aXZlIG11c3QgYmUgbmVnYXRpdmVcIik7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyBzY2FsZSBwYXJhbWV0ZXJzIGZvciBheGlzIGNhbGN1bGF0aW9uXG4gKi9cbmZ1bmN0aW9uIGNhbGN1bGF0ZVNjYWxlUGFyYW1zKFxuICBtYXhEYXRhOiBudW1iZXIsIFxuICBhY2NlcHROZWdhdGl2ZTogYm9vbGVhbiwgXG4gIG1pbk5lZ2F0aXZlPzogbnVtYmVyLCBcbiAgc3RlcENhbmRpZGF0ZXM/OiBudW1iZXJbXVxuKSB7XG4gIGxldCBkaXN0YW5jZVRvWmVybyA9IG1heERhdGE7XG4gIGxldCByZXZlcnNlID0gMTtcbiAgbGV0IGFkanVzdGVkTWF4RGF0YSA9IG1heERhdGE7XG5cbiAgaWYgKGFjY2VwdE5lZ2F0aXZlICYmICFpc05pbChtaW5OZWdhdGl2ZSkpIHtcbiAgICBpZiAobWF4RGF0YSA9PT0gMCkge1xuICAgICAgYWRqdXN0ZWRNYXhEYXRhID0gLTE7XG4gICAgfVxuXG4gICAgLy8gQWRkIG5lZ2F0aXZlIHN0ZXAgY2FuZGlkYXRlc1xuICAgIGlmIChzdGVwQ2FuZGlkYXRlcykge1xuICAgICAgc3RlcENhbmRpZGF0ZXMudW5zaGlmdCguLi5zdGVwQ2FuZGlkYXRlcy5tYXAoaXRlbSA9PiAtaXRlbSkpO1xuICAgIH1cblxuICAgIGlmIChhZGp1c3RlZE1heERhdGEgPD0gMCkge1xuICAgICAgZGlzdGFuY2VUb1plcm8gPSBtaW5OZWdhdGl2ZTtcbiAgICB9XG4gICAgXG4gICAgaWYgKGRpc3RhbmNlVG9aZXJvID4gTkVHQVRJVkVfVEhSRVNIT0xEKSB7XG4gICAgICBkaXN0YW5jZVRvWmVybyA9IEZBTExCQUNLX05FR0FUSVZFX1ZBTFVFO1xuICAgIH1cbiAgICBcbiAgICBpZiAoYWRqdXN0ZWRNYXhEYXRhID4gMCkge1xuICAgICAgZGlzdGFuY2VUb1plcm8gPSBhZGp1c3RlZE1heERhdGEgKyBNYXRoLmFicyhtaW5OZWdhdGl2ZSk7XG4gICAgICByZXZlcnNlID0gLTE7XG4gICAgfVxuICB9XG5cbiAgaWYgKE1hdGguYWJzKGRpc3RhbmNlVG9aZXJvKSA8IE1JTl9ESVNUQU5DRV9UT19aRVJPKSB7XG4gICAgZGlzdGFuY2VUb1plcm8gPSBNSU5fRElTVEFOQ0VfVE9fWkVSTztcbiAgfVxuXG4gIHJldHVybiB7IGRpc3RhbmNlVG9aZXJvLCByZXZlcnNlLCBhZGp1c3RlZE1heERhdGEgfTtcbn1cblxuLyoqXG4gKiBGaW5kcyBvcHRpbWFsIHNjYWxlIGZyb20gc3RlcCBjYW5kaWRhdGVzXG4gKi9cbmZ1bmN0aW9uIGZpbmRPcHRpbWFsU2NhbGUoXG4gIHNjYWxlUGFyYW1zOiBSZXR1cm5UeXBlPHR5cGVvZiBjYWxjdWxhdGVTY2FsZVBhcmFtcz4sXG4gIHN0ZXBDYW5kaWRhdGVzOiBudW1iZXJbXSxcbiAgbWluVGlja0NvdW50OiBudW1iZXIsXG4gIG1heFRpY2tDb3VudDogbnVtYmVyLFxuICBvcHRpb25zPzogQXhpc1NjYWxlT3B0aW9uc1xuKTogQXhpc1NjYWxlUmVzdWx0IHwgbnVsbCB7XG4gIGNvbnN0IHsgZGlzdGFuY2VUb1plcm8sIHJldmVyc2UsIGFkanVzdGVkTWF4RGF0YSB9ID0gc2NhbGVQYXJhbXM7XG5cbiAgZm9yIChjb25zdCBzdGVwIG9mIHN0ZXBDYW5kaWRhdGVzKSB7XG4gICAgbGV0IHRpY2tDb3VudCA9IE1hdGguYWJzKE1hdGguY2VpbChkaXN0YW5jZVRvWmVybyAvIHN0ZXApKSArIChyZXZlcnNlID09PSAtMSA/IDIgOiAxKTtcbiAgICBsZXQgbWF4VmFsdWUgPSBhZGp1c3RlZE1heERhdGEgPD0gMCA/IDAgOiBzdGVwICogdGlja0NvdW50ICogcmV2ZXJzZTtcbiAgICBsZXQgbWluVmFsdWUgPSAwO1xuXG4gICAgaWYgKHRpY2tDb3VudCA+PSBtaW5UaWNrQ291bnQgJiYgdGlja0NvdW50IDw9IG1heFRpY2tDb3VudCAmJiBhZGp1c3RlZE1heERhdGEgPCBtYXhWYWx1ZSkge1xuICAgICAgaWYgKG9wdGlvbnM/LmFjY2VwdE5lZ2F0aXZlKSB7XG4gICAgICAgIG1pblZhbHVlID0gY2FsY3VsYXRlTWluVmFsdWUoc3RlcCwgdGlja0NvdW50LCBvcHRpb25zLm1pbk5lZ2F0aXZlKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gQWRqdXN0IHRpY2sgY291bnQgYmFzZWQgb24gZGlzdGFuY2UgY2FsY3VsYXRpb25cbiAgICAgIGNvbnN0IGRpc3RhbmNlQ2hlY2sgPSBkaXN0YW5jZVRvWmVybyAtICh0aWNrQ291bnQgLSAxKSAqIHN0ZXA7XG4gICAgICBpZiAoZGlzdGFuY2VDaGVjayA8IC0xICogKHN0ZXAgLyA0KSkge1xuICAgICAgICB0aWNrQ291bnQgLT0gMTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgbWF4VmFsdWUgPSAoc3RlcCAqIHRpY2tDb3VudCAqIHJldmVyc2UpIC0gKG1pblZhbHVlICogcmV2ZXJzZSk7XG4gICAgICBcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN0ZXBTaXplOiBNYXRoLmFicyhzdGVwKSxcbiAgICAgICAgbWF4OiBtYXhWYWx1ZSxcbiAgICAgICAgbWluOiBtaW5WYWx1ZSxcbiAgICAgICAgdGlja0Ftb3VudDogdGlja0NvdW50XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgbWluaW11bSB2YWx1ZSBmb3IgbmVnYXRpdmUgYWNjZXB0YW5jZVxuICovXG5mdW5jdGlvbiBjYWxjdWxhdGVNaW5WYWx1ZShzdGVwOiBudW1iZXIsIHRpY2tDb3VudDogbnVtYmVyLCBtaW5OZWdhdGl2ZT86IG51bWJlcik6IG51bWJlciB7XG4gIGxldCBtaW5WYWx1ZSA9IDA7XG4gIFxuICBpZiAoIWlzTmlsKG1pbk5lZ2F0aXZlKSkge1xuICAgIGxldCB0aWNrID0gMTtcbiAgICB3aGlsZSAodGljayA8PSB0aWNrQ291bnQgJiYgbWluVmFsdWUgPj0gbWluTmVnYXRpdmUpIHtcbiAgICAgIG1pblZhbHVlID0gdGljayAqIHN0ZXA7XG4gICAgICB0aWNrKys7XG4gICAgfVxuICB9XG4gIFxuICByZXR1cm4gbWluVmFsdWU7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyBmYWxsYmFjayBzY2FsZSB3aGVuIG5vIG9wdGltYWwgc2NhbGUgaXMgZm91bmRcbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlRmFsbGJhY2tTY2FsZShkaXN0YW5jZVRvWmVybzogbnVtYmVyLCBtaW5UaWNrQ291bnQ6IG51bWJlcik6IEF4aXNTY2FsZVJlc3VsdCB7XG4gIGxldCBzdGVwID0gTWF0aC5jZWlsKGRpc3RhbmNlVG9aZXJvIC8gbWluVGlja0NvdW50KSB8fCAxO1xuICBsZXQgbWF4VmFsdWUgPSBzdGVwICogbWluVGlja0NvdW50O1xuICBcbiAgaWYgKGRpc3RhbmNlVG9aZXJvID09PSBtYXhWYWx1ZSkge1xuICAgIHN0ZXAgPSBzdGVwICsgTWF0aC5jZWlsKHN0ZXAgLyAxMCk7XG4gICAgbWF4VmFsdWUgPSBzdGVwICogbWluVGlja0NvdW50O1xuICB9XG4gIFxuICByZXR1cm4ge1xuICAgIHN0ZXBTaXplOiBNYXRoLmFicyhzdGVwKSxcbiAgICBtYXg6IG1heFZhbHVlLFxuICAgIG1pbjogMCxcbiAgICB0aWNrQW1vdW50OiBtaW5UaWNrQ291bnRcbiAgfTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgc3RlcCBjYW5kaWRhdGVzIHdpdGggcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uc1xuICovXG5mdW5jdGlvbiBnZW5lcmF0ZVN0ZXBDYW5kaWRhdGVzKFxuICBtYXhEYXRhOiBudW1iZXIsIFxuICBtaW5TdGVwOiBudW1iZXIsIFxuICBtaW5OZWdhdGl2ZT86IG51bWJlciwgXG4gIGFjY2VwdFN0ZXBJc1R5cGVGbG9hdD86IGJvb2xlYW5cbik6IG51bWJlcltdIHtcbiAgY29uc3Qgc3RlcENhbmRpZGF0ZXM6IG51bWJlcltdID0gW107XG4gIGNvbnN0IG1heFZhbHVlU3RlcCA9IE1hdGguYWJzKE1hdGgubWF4KG1heERhdGEsIE1hdGguYWJzKG1pbk5lZ2F0aXZlIHx8IDApKSkgLyBtaW5TdGVwO1xuXG4gIC8vIFByZS1wb3B1bGF0ZSBwb3dlciBjYWNoZSBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlXG4gIGZvciAobGV0IHBvd051bWJlciA9IDA7IHBvd051bWJlciA8IE1BWF9QT1dfTlVNQkVSOyBwb3dOdW1iZXIrKykge1xuICAgIGlmICghUE9XRVJfQ0FDSEUuaGFzKHBvd051bWJlcikpIHtcbiAgICAgIFBPV0VSX0NBQ0hFLnNldChwb3dOdW1iZXIsIE1hdGgucG93KDEwLCBwb3dOdW1iZXIpKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb3dCeVRlbXAgPSBQT1dFUl9DQUNIRS5nZXQocG93TnVtYmVyKSE7XG5cbiAgICBmb3IgKGxldCB0ZW1wbGF0ZU51bWJlciA9IDE7IHRlbXBsYXRlTnVtYmVyIDwgTUFYX1RFTVBMQVRFX05VTUJFUjsgdGVtcGxhdGVOdW1iZXIrKykge1xuICAgICAgaWYgKGFjY2VwdFN0ZXBJc1R5cGVGbG9hdCkge1xuICAgICAgICBjb25zdCBmbG9hdFN0ZXAgPSBwb3dCeVRlbXAgKiAoKCh0ZW1wbGF0ZU51bWJlciAtIDEpICogMiArIDEpIC8gMik7XG4gICAgICAgIHN0ZXBDYW5kaWRhdGVzLnB1c2goZmxvYXRTdGVwKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc3Qgc3RlcCA9IHBvd0J5VGVtcCAqIHRlbXBsYXRlTnVtYmVyO1xuICAgICAgc3RlcENhbmRpZGF0ZXMucHVzaChzdGVwKTtcbiAgICAgIFxuICAgICAgLy8gRWFybHkgdGVybWluYXRpb24gZm9yIHBlcmZvcm1hbmNlXG4gICAgICBpZiAoc3RlcCA+PSBtYXhWYWx1ZVN0ZXApIHtcbiAgICAgICAgcmV0dXJuIHN0ZXBDYW5kaWRhdGVzO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzdGVwQ2FuZGlkYXRlcztcbn0iXX0=
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Kiểm tra và thêm các step âm vào danh sách candidates nếu cần
|
|
137
|
+
* @param stepCandidates - Danh sách step candidates hiện tại
|
|
138
|
+
* @param acceptNegative - Có chấp nhận giá trị âm không
|
|
139
|
+
* @param minNegative - Giá trị âm tối thiểu
|
|
140
|
+
*/
|
|
141
|
+
const checkAndSetNegativeSteps = (stepCandidates, acceptNegative, minNegative) => {
|
|
142
|
+
if (acceptNegative && minNegative < 0) {
|
|
143
|
+
// Tạo các step âm và thêm vào đầu danh sách
|
|
144
|
+
const negativeSteps = [...stepCandidates].map(step => -step);
|
|
145
|
+
stepCandidates.unshift(...negativeSteps);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Kiểm tra tính hợp lệ của các tham số đầu vào
|
|
150
|
+
* @param maxData - Giá trị dữ liệu tối đa
|
|
151
|
+
* @param options - Các tùy chọn cấu hình
|
|
152
|
+
* @throws {Error} Khi các tham số không hợp lệ
|
|
153
|
+
*/
|
|
154
|
+
const validateInputs = (maxData, options) => {
|
|
155
|
+
// Kiểm tra maxData âm khi không chấp nhận giá trị âm
|
|
156
|
+
if (maxData < 0 && !options?.acceptNegative) {
|
|
157
|
+
throw new Error("maxData is less than 0 and acceptNegative is false");
|
|
158
|
+
}
|
|
159
|
+
if (options?.acceptNegative) {
|
|
160
|
+
// Kiểm tra minNegative có được cung cấp không
|
|
161
|
+
if (isNil(options.minNegative)) {
|
|
162
|
+
throw new Error("minNegative is required when acceptNegative is true");
|
|
163
|
+
}
|
|
164
|
+
// Kiểm tra maxData phải >= minNegative
|
|
165
|
+
if (maxData < options.minNegative) {
|
|
166
|
+
throw new Error("maxData is less than minNegative");
|
|
167
|
+
}
|
|
168
|
+
// Kiểm tra minNegative phải là số âm
|
|
169
|
+
if (options.minNegative >= 0) {
|
|
170
|
+
throw new Error("minNegative must be negative");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LXNtYXJ0LWF4aXMtc2NhbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWJzLXVpL3V0aWxzL3NyYy9nZXQtc21hcnQtYXhpcy1zY2FsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLE1BQU0sc0JBQXNCLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBQy9CLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDOUIsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNuQyxNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUM7QUFDMUIsTUFBTSxtQkFBbUIsR0FBRyxFQUFFLENBQUM7QUFtQi9COzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLENBQUMsZUFBdUIsRUFBRSxPQUEwQixFQUFtQixFQUFFO0lBQ3hHLElBQUksT0FBTyxHQUFHLGVBQWUsQ0FBQztJQUU5QixjQUFjLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2pDLE1BQU0sWUFBWSxHQUFHLE9BQU8sRUFBRSxZQUFZLElBQUksc0JBQXNCLENBQUM7SUFDckUsTUFBTSxZQUFZLEdBQUcsT0FBTyxFQUFFLFlBQVksSUFBSSxzQkFBc0IsQ0FBQztJQUVyRSxJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUM7SUFDdkIsSUFBSSxhQUFhLEdBQUcsT0FBTyxDQUFDO0lBRzVCLElBQUksT0FBTyxFQUFFLGNBQWMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztRQUMzRCxJQUFJLE9BQU8sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNsQixPQUFPLEdBQUcsQ0FBQyxD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fSBmcm9tIFwiLi9oZWxwZXJzXCI7XG5jb25zdCBERUZBVUxUX01JTl9USUNLX0NPVU5UID0gNTtcbmNvbnN0IERFRkFVTFRfTUFYX1RJQ0tfQ09VTlQgPSAxMDtcbmNvbnN0IE1JTl9ESVNUQU5DRV9UT19aRVJPID0gMztcbmNvbnN0IE5FR0FUSVZFX1RIUkVTSE9MRCA9IC01O1xuY29uc3QgRkFMTEJBQ0tfTkVHQVRJVkVfVkFMVUUgPSAtNDtcbmNvbnN0IE1BWF9QT1dfTlVNQkVSID0gMTQ7XG5jb25zdCBNQVhfVEVNUExBVEVfTlVNQkVSID0gMTA7XG5cbi8vIOKchSBUaMOqbSBpbnRlcmZhY2VzIMSR4buDIHTEg25nIGPGsOG7nW5nIHR5cGUgc2FmZXR5XG5pbnRlcmZhY2UgQXhpc1NjYWxlT3B0aW9ucyB7XG4gIG1pblRpY2tDb3VudD86IG51bWJlcjsgLy8gU+G7kSBsxrDhu6NuZyB0aWNrIHThu5FpIHRoaeG7g3VcbiAgbWF4VGlja0NvdW50PzogbnVtYmVyOyAvLyBT4buRIGzGsOG7o25nIHRpY2sgdOG7kWkgxJFhXG4gIHN0ZXBDYW5kaWRhdGVzPzogbnVtYmVyW107IC8vIERhbmggc8OhY2ggY8OhYyBzdGVwIGNhbmRpZGF0ZXMgdMO5eSBjaOG7iW5oXG4gIGFjY2VwdE5lZ2F0aXZlPzogYm9vbGVhbjsgLy8gQ8OzIGNo4bqlcCBuaOG6rW4gZ2nDoSB0cuG7iyDDom0ga2jDtG5nXG4gIG1pbk5lZ2F0aXZlPzogbnVtYmVyOyAvLyBHacOhIHRy4buLIMOibSB04buRaSB0aGnhu4N1XG4gIGFjY2VwdFN0ZXBJc1R5cGVGbG9hdD86IGJvb2xlYW47IC8vIEPDsyBjaOG6pXAgbmjhuq1uIHN0ZXAgbMOgIHPhu5EgdGjhuq1wIHBow6JuIGtow7RuZ1xufVxuXG5pbnRlcmZhY2UgQXhpc1NjYWxlUmVzdWx0IHtcbiAgc3RlcFNpemU6IG51bWJlcjsgLy8gS8OtY2ggdGjGsOG7m2MgYsaw4bubY1xuICBtYXg6IG51bWJlcjsgLy8gR2nDoSB0cuG7iyB04buRaSDEkWEgY+G7p2EgdHLhu6VjXG4gIG1pbjogbnVtYmVyOyAvLyBHacOhIHRy4buLIHThu5FpIHRoaeG7g3UgY+G7p2EgdHLhu6VjXG4gIHRpY2tBbW91bnQ6IG51bWJlcjsgLy8gU+G7kSBsxrDhu6NuZyB0aWNrXG59XG5cbi8qKlxuICogVMOtbmggdG/DoW4gc21hcnQgYXhpcyBzY2FsZSBjaG8gYmnhu4N1IMSR4buTXG4gKiBcbiAqIEBwYXJhbSBtYXhEYXRhIC0gR2nDoSB0cuG7iyB04buRaSDEkWEgY+G7p2EgZOG7ryBsaeG7h3VcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ8OhYyB0w7l5IGNo4buNbiBj4bqldSBow6xuaCBheGlzIHNjYWxlXG4gKiBAcmV0dXJucyBD4bqldSBow6xuaCBheGlzIHNjYWxlIGJhbyBn4buTbSBzdGVwU2l6ZSwgbWF4LCBtaW4sIHRpY2tBbW91bnRcbiAqIFxuICogQHRocm93cyB7RXJyb3J9IElOVkFMSURfTkVHQVRJVkVfREFUQSAtIGtoaSBtYXhEYXRhIDwgMCBtw6AgYWNjZXB0TmVnYXRpdmUgPSBmYWxzZVxuICogQHRocm93cyB7RXJyb3J9IE1JU1NJTkdfTUlOX05FR0FUSVZFIC0ga2hpIGFjY2VwdE5lZ2F0aXZlID0gdHJ1ZSBuaMawbmcgdGhp4bq/dSBtaW5OZWdhdGl2ZVxuICogQHRocm93cyB7RXJyb3J9IElOVkFMSURfUkFOR0UgLSBraGkgbWF4RGF0YSA8IG1pbk5lZ2F0aXZlXG4gKiBAdGhyb3dzIHtFcnJvcn0gSU5WQUxJRF9NSU5fTkVHQVRJVkUgLSBraGkgbWluTmVnYXRpdmUgPj0gMFxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVzdWx0ID0gZ2V0U21hcnRBeGlzU2NhbGUoMTAwLCB7IG1pblRpY2tDb3VudDogNSwgbWF4VGlja0NvdW50OiAxMCB9KTtcbiAqIC8vIHJldHVybnMgeyBzdGVwU2l6ZTogMjAsIG1heDogMTIwLCBtaW46IDAsIHRpY2tBbW91bnQ6IDYgfVxuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRTbWFydEF4aXNTY2FsZSA9IChvcmlnaW5hbE1heERhdGE6IG51bWJlciwgb3B0aW9ucz86IEF4aXNTY2FsZU9wdGlvbnMpOiBBeGlzU2NhbGVSZXN1bHQgPT4ge1xuICBsZXQgbWF4RGF0YSA9IG9yaWdpbmFsTWF4RGF0YTtcbiAgXG4gIHZhbGlkYXRlSW5wdXRzKG1heERhdGEsIG9wdGlvbnMpO1xuICBjb25zdCBtaW5UaWNrQ291bnQgPSBvcHRpb25zPy5taW5UaWNrQ291bnQgfHwgREVGQVVMVF9NSU5fVElDS19DT1VOVDtcbiAgY29uc3QgbWF4VGlja0NvdW50ID0gb3B0aW9ucz8ubWF4VGlja0NvdW50IHx8IERFRkFVTFRfTUFYX1RJQ0tfQ09VTlQ7XG4gIFxuICBsZXQgc2NhbGVEaXJlY3Rpb24gPSAxO1xuICBsZXQgcmFuZ2VEaXN0YW5jZSA9IG1heERhdGE7XG4gIFxuICBcbiAgaWYgKG9wdGlvbnM/LmFjY2VwdE5lZ2F0aXZlICYmICFpc05pbChvcHRpb25zLm1pbk5lZ2F0aXZlKSkge1xuICAgIGlmIChtYXhEYXRhID09PSAwKSB7XG4gICAgICBtYXhEYXRhID0gLTE7XG4gICAgfVxuICAgIGlmIChtYXhEYXRhIDw9IDApIHtcbiAgICAgIHJhbmdlRGlzdGFuY2UgPSBvcHRpb25zLm1pbk5lZ2F0aXZlO1xuICAgIH1cbiAgICBpZiAocmFuZ2VEaXN0YW5jZSA+IE5FR0FUSVZFX1RIUkVTSE9MRCkge1xuICAgICAgcmFuZ2VEaXN0YW5jZSA9IEZBTExCQUNLX05FR0FUSVZFX1ZBTFVFO1xuICAgIH1cbiAgICBpZiAobWF4RGF0YSA+IDApIHtcbiAgICAgIHJhbmdlRGlzdGFuY2UgPSBtYXhEYXRhICsgTWF0aC5hYnMob3B0aW9ucy5taW5OZWdhdGl2ZSk7XG4gICAgICBzY2FsZURpcmVjdGlvbiA9IC0xO1xuICAgIH1cbiAgfVxuICBpZiAoTWF0aC5hYnMocmFuZ2VEaXN0YW5jZSkgPCBNSU5fRElTVEFOQ0VfVE9fWkVSTykge1xuICAgIHJhbmdlRGlzdGFuY2UgPSBNSU5fRElTVEFOQ0VfVE9fWkVSTztcbiAgfVxuICBcbiAgY29uc3Qgc3RlcENhbmRpZGF0ZXMgPSBnZXRTdGVwQ2FuZGlkYXRlcyhcbiAgICBtYXhEYXRhLFxuICAgIG1pblRpY2tDb3VudCxcbiAgICBvcHRpb25zPy5taW5OZWdhdGl2ZSB8fCAwLFxuICAgIG9wdGlvbnM/LmFjY2VwdFN0ZXBJc1R5cGVGbG9hdCxcbiAgICBvcHRpb25zPy5zdGVwQ2FuZGlkYXRlcyxcbiAgICBvcHRpb25zPy5hY2NlcHROZWdhdGl2ZVxuICApO1xuICBmb3IgKGNvbnN0IHN0ZXAgb2Ygc3RlcENhbmRpZGF0ZXMpIHtcbiAgICBsZXQgdGlja0NvdW50ID0gTWF0aC5hYnMoTWF0aC5jZWlsKHJhbmdlRGlzdGFuY2UgLyBzdGVwKSkgKyAoc2NhbGVEaXJlY3Rpb24gPT09IC0xID8gMiA6IDEpO1xuICAgIGxldCBtYXhWYWx1ZSA9IG1heERhdGEgPD0gMCA/IDAgOiBzdGVwICogdGlja0NvdW50ICogc2NhbGVEaXJlY3Rpb247XG4gICAgbGV0IG1pblZhbHVlID0gMDtcblxuICAgIGlmICh0aWNrQ291bnQgPj0gbWluVGlja0NvdW50ICYmIHRpY2tDb3VudCA8PSBtYXhUaWNrQ291bnQpIHtcbiAgICAgIGlmIChtYXhEYXRhIDwgbWF4VmFsdWUpIHtcbiAgICAgICAgaWYgKG9wdGlvbnM/LmFjY2VwdE5lZ2F0aXZlKSB7XG4gICAgICAgICAgbGV0IHRpY2sgPSAxO1xuICAgICAgICAgIHdoaWxlICghaXNOaWwob3B0aW9ucy5taW5OZWdhdGl2ZSkgJiYgdGljayA8PSB0aWNrQ291bnQgJiYgbWluVmFsdWUgPj0gb3B0aW9ucy5taW5OZWdhdGl2ZSkge1xuICAgICAgICAgICAgbWluVmFsdWUgPSB0aWNrICogc3RlcDtcbiAgICAgICAgICAgIHRpY2srKztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWF4VmFsdWVQb3NpdGl2ZSA9IG1heFZhbHVlIC0gTWF0aC5hYnMobWluVmFsdWUpO1xuICAgICAgICB0aWNrQ291bnQgPSBtYXhWYWx1ZVBvc2l0aXZlIC0gb3JpZ2luYWxNYXhEYXRhID4gTWF0aC5hYnMoc3RlcCkgJiYgdGlja0NvdW50IC0gMSA+PSBtaW5UaWNrQ291bnQgPyB0aWNrQ291bnQgLSAxIDogdGlja0NvdW50O1xuXG4gICAgICAgIG1heFZhbHVlID0gKHN0ZXAgKiB0aWNrQ291bnQgKiBzY2FsZURpcmVjdGlvbikgLSAobWluVmFsdWUgKiBzY2FsZURpcmVjdGlvbik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3RlcFNpemU6IE1hdGguYWJzKHN0ZXApLFxuICAgICAgICAgIG1heDogbWF4VmFsdWUsXG4gICAgICAgICAgbWluOiBtaW5WYWx1ZSxcbiAgICAgICAgICB0aWNrQW1vdW50OiB0aWNrQ291bnRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBsZXQgc3RlcCA9IE1hdGguY2VpbChyYW5nZURpc3RhbmNlIC8gbWluVGlja0NvdW50KSB8fCAxO1xuICBsZXQgbWF4VmFsdWUgPSBzdGVwICogbWluVGlja0NvdW50O1xuICBpZiAocmFuZ2VEaXN0YW5jZSA9PT0gbWF4VmFsdWUpIHtcbiAgICBzdGVwID0gc3RlcCArIE1hdGguY2VpbChzdGVwIC8gMTApO1xuICAgIG1heFZhbHVlID0gc3RlcCAqIG1pblRpY2tDb3VudDtcbiAgfVxuICByZXR1cm4ge1xuICAgIHN0ZXBTaXplOiBNYXRoLmFicyhzdGVwKSxcbiAgICBtYXg6IG1heFZhbHVlLFxuICAgIG1pbjogMCxcbiAgICB0aWNrQW1vdW50OiBtaW5UaWNrQ291bnRcbiAgfTtcbn1cblxuLy8gQ2FjaGUgY2hvIGPDoWMgZ2nDoSB0cuG7iyBsxal5IHRo4burYSAxMCDEkeG7gyB04buRaSDGsHUgaGnhu4d1IHN14bqldFxuY29uc3QgUE9XRVJfQ0FDSEUgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuXG4vKipcbiAqIFThuqFvIGRhbmggc8OhY2ggY8OhYyBzdGVwIGNhbmRpZGF0ZXMgY2hvIHZp4buHYyB0w61uaCB0b8OhbiBzY2FsZVxuICogQHBhcmFtIG1heERhdGEgLSBHacOhIHRy4buLIGThu68gbGnhu4d1IHThu5FpIMSRYVxuICogQHBhcmFtIG1pblN0ZXAgLSBT4buRIGLGsOG7m2MgdOG7kWkgdGhp4buDdVxuICogQHBhcmFtIG1pbk5lZ2F0aXZlIC0gR2nDoSB0cuG7iyDDom0gdOG7kWkgdGhp4buDdVxuICogQHBhcmFtIGFjY2VwdFN0ZXBJc1R5cGVGbG9hdCAtIEPDsyBjaOG6pXAgbmjhuq1uIHN0ZXAgdGjhuq1wIHBow6JuIGtow7RuZ1xuICogQHBhcmFtIHN0ZXBDYW5kaWRhdGVzQnlPcHRpb25zIC0gU3RlcCBjYW5kaWRhdGVzIGRvIG5nxrDhu51pIGTDuW5nIGN1bmcgY+G6pXBcbiAqIEBwYXJhbSBpbmNsdWRlTmVnYXRpdmVTdGVwcyAtIEPDsyBiYW8gZ+G7k20gY8OhYyBzdGVwIMOibSBraMO0bmdcbiAqIEByZXR1cm5zIERhbmggc8OhY2ggY8OhYyBzdGVwIGNhbmRpZGF0ZXNcbiAqL1xuY29uc3QgZ2V0U3RlcENhbmRpZGF0ZXMgPSAoXG4gIG1heERhdGE6IG51bWJlcixcbiAgbWluU3RlcDogbnVtYmVyLFxuICBtaW5OZWdhdGl2ZTogbnVtYmVyLFxuICBhY2NlcHRTdGVwSXNUeXBlRmxvYXQgPSBmYWxzZSxcbiAgc3RlcENhbmRpZGF0ZXNCeU9wdGlvbnM/OiBudW1iZXJbXSxcbiAgaW5jbHVkZU5lZ2F0aXZlU3RlcHMgPSBmYWxzZVxuKTogbnVtYmVyW10gPT4ge1xuICAvLyBO4bq/dSBjw7Mgc3RlcCBjYW5kaWRhdGVzIHTDuXkgY2jhu4luaCwgc+G7rSBk4bulbmcgY2jDum5nXG4gIGlmKHN0ZXBDYW5kaWRhdGVzQnlPcHRpb25zICYmIHN0ZXBDYW5kaWRhdGVzQnlPcHRpb25zLmxlbmd0aCA+IDApe1xuICAgIHJldHVybiBzdGVwQ2FuZGlkYXRlc0J5T3B0aW9ucztcbiAgfVxuICBcbiAgY29uc3Qgc3RlcENhbmRpZGF0ZXM9IG5ldyBBcnJheTxudW1iZXI+KCk7XG4gIGNvbnN0IG1heFZhbHVlU3RlcCA9IE1hdGguYWJzKE1hdGgubWF4KG1heERhdGEsIE1hdGguYWJzKG1pbk5lZ2F0aXZlIHx8IDApKSkgLyBtaW5TdGVwO1xuXG4gIC8vIFThuqFvIHN0ZXAgY2FuZGlkYXRlcyBk4buxYSB0csOqbiBsxal5IHRo4burYSBj4bunYSAxMFxuICBmb3IgKGxldCBwb3dOdW1iZXIgPSAwOyBwb3dOdW1iZXIgPD0gTUFYX1BPV19OVU1CRVI7IHBvd051bWJlcisrKSB7XG4gICAgLy8gU+G7rSBk4bulbmcgY2FjaGUgxJHhu4MgdOG7kWkgxrB1IGhp4buHdSBzdeG6pXRcbiAgICBpZighUE9XRVJfQ0FDSEUuaGFzKHBvd051bWJlcikpe1xuICAgICAgUE9XRVJfQ0FDSEUuc2V0KHBvd051bWJlcixNYXRoLnBvdygxMCxwb3dOdW1iZXIpKTtcbiAgICB9XG4gICAgY29uc3QgcG93VmFsdWUgPSBQT1dFUl9DQUNIRS5nZXQocG93TnVtYmVyKSBhcyBudW1iZXI7XG4gICAgXG4gICAgZm9yIChsZXQgdGVtcGxhdGVOdW1iZXIgPSAxOyB0ZW1wbGF0ZU51bWJlciA8IE1BWF9URU1QTEFURV9OVU1CRVI7IHRlbXBsYXRlTnVtYmVyKyspIHtcbiAgICAgIC8vIFRow6ptIHN0ZXAgdGjhuq1wIHBow6JuIG7hur91IMSRxrDhu6NjIGNo4bqlcCBuaOG6rW5cbiAgICAgIGlmIChhY2NlcHRTdGVwSXNUeXBlRmxvYXQpIHtcbiAgICAgICAgY29uc3Qgc3RlcCA9IHBvd1ZhbHVlICogKCgodGVtcGxhdGVOdW1iZXIgLSAxKSAqIDIgKyAxKSAvIDIpO1xuICAgICAgICBzdGVwQ2FuZGlkYXRlcy5wdXNoKHN0ZXApO1xuICAgICAgfVxuICAgICAgXG4gICAgICBjb25zdCBzdGVwID0gcG93VmFsdWUgKiB0ZW1wbGF0ZU51bWJlcjtcbiAgICAgIHN0ZXBDYW5kaWRhdGVzLnB1c2goc3RlcCk7XG5cbiAgICAgIC8vIEThu6tuZyBraGkgc3RlcCDEkcOjIMSR4bunIGzhu5tuXG4gICAgICBpZiAoc3RlcCA+PSBtYXhWYWx1ZVN0ZXApIHtcbiAgICAgICAgY2hlY2tBbmRTZXROZWdhdGl2ZVN0ZXBzKHN0ZXBDYW5kaWRhdGVzLCBpbmNsdWRlTmVnYXRpdmVTdGVwcywgbWluTmVnYXRpdmUpO1xuICAgICAgICByZXR1cm4gc3RlcENhbmRpZGF0ZXM7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIFxuICBjaGVja0FuZFNldE5lZ2F0aXZlU3RlcHMoc3RlcENhbmRpZGF0ZXMsIGluY2x1ZGVOZWdhdGl2ZVN0ZXBzLCBtaW5OZWdhdGl2ZSk7XG4gIHJldHVybiBzdGVwQ2FuZGlkYXRlcztcbn1cblxuLyoqXG4gKiBLaeG7g20gdHJhIHbDoCB0aMOqbSBjw6FjIHN0ZXAgw6JtIHbDoG8gZGFuaCBzw6FjaCBjYW5kaWRhdGVzIG7hur91IGPhuqduXG4gKiBAcGFyYW0gc3RlcENhbmRpZGF0ZXMgLSBEYW5oIHPDoWNoIHN0ZXAgY2FuZGlkYXRlcyBoaeG7h24gdOG6oWlcbiAqIEBwYXJhbSBhY2NlcHROZWdhdGl2ZSAtIEPDsyBjaOG6pXAgbmjhuq1uIGdpw6EgdHLhu4sgw6JtIGtow7RuZ1xuICogQHBhcmFtIG1pbk5lZ2F0aXZlIC0gR2nDoSB0cuG7iyDDom0gdOG7kWkgdGhp4buDdVxuICovXG5jb25zdCBjaGVja0FuZFNldE5lZ2F0aXZlU3RlcHMgPSAoc3RlcENhbmRpZGF0ZXM6IG51bWJlcltdLCBhY2NlcHROZWdhdGl2ZTogYm9vbGVhbiwgbWluTmVnYXRpdmU6IG51bWJlcik6IHZvaWQgPT4ge1xuICBpZiAoYWNjZXB0TmVnYXRpdmUgJiYgbWluTmVnYXRpdmUgPCAwKSB7XG4gICAgLy8gVOG6oW8gY8OhYyBzdGVwIMOibSB2w6AgdGjDqm0gdsOgbyDEkeG6p3UgZGFuaCBzw6FjaFxuICAgIGNvbnN0IG5lZ2F0aXZlU3RlcHMgPSBbLi4uc3RlcENhbmRpZGF0ZXNdLm1hcChzdGVwID0+IC1zdGVwKTtcbiAgICBzdGVwQ2FuZGlkYXRlcy51bnNoaWZ0KC4uLm5lZ2F0aXZlU3RlcHMpO1xuICB9XG59IFxuXG4vKipcbiAqIEtp4buDbSB0cmEgdMOtbmggaOG7o3AgbOG7hyBj4bunYSBjw6FjIHRoYW0gc+G7kSDEkeG6p3UgdsOgb1xuICogQHBhcmFtIG1heERhdGEgLSBHacOhIHRy4buLIGThu68gbGnhu4d1IHThu5FpIMSRYVxuICogQHBhcmFtIG9wdGlvbnMgLSBDw6FjIHTDuXkgY2jhu41uIGPhuqV1IGjDrG5oXG4gKiBAdGhyb3dzIHtFcnJvcn0gS2hpIGPDoWMgdGhhbSBz4buRIGtow7RuZyBo4bujcCBs4buHXG4gKi9cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKG1heERhdGE6IG51bWJlciwgb3B0aW9ucz86IEF4aXNTY2FsZU9wdGlvbnMpOiB2b2lkID0+IHtcbiAgLy8gS2nhu4NtIHRyYSBtYXhEYXRhIMOibSBraGkga2jDtG5nIGNo4bqlcCBuaOG6rW4gZ2nDoSB0cuG7iyDDom1cbiAgaWYgKG1heERhdGEgPCAwICYmICFvcHRpb25zPy5hY2NlcHROZWdhdGl2ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIm1heERhdGEgaXMgbGVzcyB0aGFuIDAgYW5kIGFjY2VwdE5lZ2F0aXZlIGlzIGZhbHNlXCIpO1xuICB9XG4gIFxuICBpZiAob3B0aW9ucz8uYWNjZXB0TmVnYXRpdmUpIHtcbiAgICAvLyBLaeG7g20gdHJhIG1pbk5lZ2F0aXZlIGPDsyDEkcaw4bujYyBjdW5nIGPhuqVwIGtow7RuZ1xuICAgIGlmIChpc05pbChvcHRpb25zLm1pbk5lZ2F0aXZlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWluTmVnYXRpdmUgaXMgcmVxdWlyZWQgd2hlbiBhY2NlcHROZWdhdGl2ZSBpcyB0cnVlXCIpO1xuICAgIH1cblxuICAgIC8vIEtp4buDbSB0cmEgbWF4RGF0YSBwaOG6o2kgPj0gbWluTmVnYXRpdmVcbiAgICBpZiAobWF4RGF0YSA8IG9wdGlvbnMubWluTmVnYXRpdmUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIm1heERhdGEgaXMgbGVzcyB0aGFuIG1pbk5lZ2F0aXZlXCIpO1xuICAgIH1cblxuICAgIC8vIEtp4buDbSB0cmEgbWluTmVnYXRpdmUgcGjhuqNpIGzDoCBz4buRIMOibVxuICAgIGlmIChvcHRpb25zLm1pbk5lZ2F0aXZlID49IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIm1pbk5lZ2F0aXZlIG11c3QgYmUgbmVnYXRpdmVcIik7XG4gICAgfVxuICB9XG59ICJdfQ==
|