@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.
@@ -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
- * Calculates smart axis scale for charts
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
- * @description This function can throw errors if:
17
- * - maxData < 0 and acceptNegative is false
18
- * - minNegative is undefined and acceptNegative is true
19
- * - maxData < minNegative (only when acceptNegative is true)
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
- * @throws {Error} Validation errors for invalid input combinations
23
- * @required Always wrap this function in try-catch and handle exceptions
24
- * @param maxData - Maximum data value
25
- * @param options - Configuration options for axis scaling
26
- * @returns Axis scale configuration
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 = (maxData, options) => {
29
- // Input validation - fail fast approach
27
+ export const getSmartAxisScale = (originalMaxData, options) => {
28
+ let maxData = originalMaxData;
30
29
  validateInputs(maxData, options);
31
- // Extract and set defaults
32
- const { minTickCount = DEFAULT_MIN_TICK_COUNT, maxTickCount = DEFAULT_MAX_TICK_COUNT, stepCandidates = [], acceptNegative = false, minNegative, acceptStepIsTypeFloat = false } = options || {};
33
- // Generate step candidates if not provided
34
- const finalStepCandidates = stepCandidates.length > 0
35
- ? [...stepCandidates]
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
- adjustedMaxData = -1;
36
+ maxData = -1;
78
37
  }
79
- // Add negative step candidates
80
- if (stepCandidates) {
81
- stepCandidates.unshift(...stepCandidates.map(item => -item));
38
+ if (maxData <= 0) {
39
+ rangeDistance = options.minNegative;
82
40
  }
83
- if (adjustedMaxData <= 0) {
84
- distanceToZero = minNegative;
41
+ if (rangeDistance > NEGATIVE_THRESHOLD) {
42
+ rangeDistance = FALLBACK_NEGATIVE_VALUE;
85
43
  }
86
- if (distanceToZero > NEGATIVE_THRESHOLD) {
87
- distanceToZero = FALLBACK_NEGATIVE_VALUE;
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(distanceToZero) < MIN_DISTANCE_TO_ZERO) {
95
- distanceToZero = MIN_DISTANCE_TO_ZERO;
49
+ if (Math.abs(rangeDistance) < MIN_DISTANCE_TO_ZERO) {
50
+ rangeDistance = MIN_DISTANCE_TO_ZERO;
96
51
  }
97
- return { distanceToZero, reverse, adjustedMaxData };
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(distanceToZero / step)) + (reverse === -1 ? 2 : 1);
106
- let maxValue = adjustedMaxData <= 0 ? 0 : step * tickCount * reverse;
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 && adjustedMaxData < maxValue) {
109
- if (options?.acceptNegative) {
110
- minValue = calculateMinValue(step, tickCount, options.minNegative);
111
- }
112
- // Adjust tick count based on distance calculation
113
- const distanceCheck = distanceToZero - (tickCount - 1) * step;
114
- if (distanceCheck < -1 * (step / 4)) {
115
- tickCount -= 1;
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
- return null;
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 (distanceToZero === maxValue) {
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
- * Generates step candidates with performance optimizations
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
- function generateStepCandidates(maxData, minStep, minNegative, acceptStepIsTypeFloat) {
163
- const stepCandidates = [];
103
+ const getStepCandidates = (maxData, minStep, minNegative, acceptStepIsTypeFloat = false, stepCandidatesByOptions, includeNegativeSteps = false) => {
104
+ // Nếu 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
- // Pre-populate power cache for better performance
166
- for (let powNumber = 0; powNumber < MAX_POW_NUMBER; 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 powByTemp = POWER_CACHE.get(powNumber);
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 floatStep = powByTemp * (((templateNumber - 1) * 2 + 1) / 2);
174
- stepCandidates.push(floatStep);
120
+ const step = powValue * (((templateNumber - 1) * 2 + 1) / 2);
121
+ stepCandidates.push(step);
175
122
  }
176
- const step = powByTemp * templateNumber;
123
+ const step = powValue * templateNumber;
177
124
  stepCandidates.push(step);
178
- // Early termination for performance
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LXNtYXJ0LWF4aXMtc2NhbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWJzLXVpL3V0aWxzL3NyYy9nZXQtc21hcnQtYXhpcy1zY2FsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw2REFBNkQ7QUFDN0QsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFdBQVcsQ0FBQztBQW1CbEMsdUNBQXVDO0FBQ3ZDLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLE1BQU0sc0JBQXNCLEdBQUcsRUFBRSxDQUFDO0FBQ2xDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBQy9CLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDOUIsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNuQyxNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUM7QUFDMUIsTUFBTSxtQkFBbUIsR0FBRyxFQUFFLENBQUM7QUFFL0IscUZBQXFGO0FBQ3JGLE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0FBRTlDOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsQ0FDL0IsT0FBZSxFQUNmLE9BQTBCLEVBQ1QsRUFBRTtJQUNuQix3Q0FBd0M7SUFDeEMsY0FBYyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUVqQywyQkFBMkI7SUFDM0IsTUFBTSxFQUNKLFlBQVksR0FBRyxzQkFBc0IsRUFDckMsWUFBWSxHQUFHLHNCQUFzQixFQUNyQyxjQUFjLEdBQUcsRUFBRSxFQUNuQixjQUFjLEdBQUcsS0FBSyxFQUN0QixXQUFXLEVBQ1gscUJBQXFCLEdBQUcsS0FBSyxFQUM5QixHQUFHLE9BQU8sSUFBSSxFQUFFLENBQUM7SUFFbEIsMkNBQTJDO0lBQzNDLE1BQU0sbUJBQW1CLEdBQUcsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDLEdBQUcsY0FBYyxDQUFDO1FBQ3JCLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0lBRXRGLHlDQUF5QztJQUN6Qyx3REFBd0Q7SUFFeEQsNkJBQTZCO0lBQzdCLE1BQU0sV0FBVyxHQUFHLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixDQUFDLENBQUM7SUFFcEcscUJBQXFCO0lBQ3JCLE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUNuQyxXQUFXLEVBQ1gsbUJBQW1CLEVBQ25CLFlBQVksRUFDWixZQUFZLEVBQ1osT0FBTyxDQUNSLENBQUM7SUFFRixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2pCLE9BQU8sWUFBWSxDQUFDO0lBQ3RCLENBQUM7SUFFRCx1QkFBdUI7SUFDdkIsT0FBTyxzQkFBc0IsQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQzFFLENBQUMsQ0FBQztBQUVGOztHQUVHO0FBQ0gsU0FBUyxjQUFjLENBQUMsT0FBZSxFQUFFLE9BQTBCO0lBQ2pFLElBQUksT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxjQUFjLEVBQUUsQ0FBQztRQUM1QyxNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVELElBQUksT0FBTyxFQUFFLGNBQWMsRUFBRSxDQUFDO1FBQzVCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMscURBQXFELENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBQ0QsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsV0FBVyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQzdCLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUNsRCxDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsb0JBQW9CLENBQzNCLE9BQWUsRUFDZixjQUF1QixFQUN2QixXQUFvQixFQUNwQixjQUF5QjtJQUV6QixJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUM7SUFDN0IsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLElBQUksZUFBZSxHQUFHLE9BQU8sQ0FBQztJQUU5QixJQUFJLGNBQWMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1FBQzFDLElBQUksT0FBTyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2xCLGVBQWUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN2QixDQUFDO1FBRUQsK0JBQStCO1FBQy9CLElBQUksY0FBYyxFQUFFLENBQUM7WUFDbkIsY0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDL0QsQ0FBQztRQUVELElBQUksZUFBZSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3pCLGNBQWMsR0FBRyxXQUFXLENBQUM7UUFDL0IsQ0FBQztRQUVELElBQUksY0FBYyxHQUFHLGtCQUFrQixFQUFFLENBQUM7WUFDeEMsY0FBYyxHQUFHLHVCQUF1QixDQUFDO1FBQzNDLENBQUM7UUFFRCxJQUFJLGVBQWUsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixjQUFjLEdBQUcsZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDekQsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLEdBQUcsb0JBQW9CLEVBQUUsQ0FBQztRQUNwRCxjQUFjLEdBQUcsb0JBQW9CLENBQUM7SUFDeEMsQ0FBQztJQUVELE9BQU8sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxDQUFDO0FBQ3RELENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsZ0JBQWdCLENBQ3ZCLFdBQW9ELEVBQ3BELGNBQXdCLEVBQ3hCLFlBQW9CLEVBQ3BCLFlBQW9CLEVBQ3BCLE9BQTBCO0lBRTFCLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxHQUFHLFdBQVcsQ0FBQztJQUVqRSxLQUFLLE1BQU0sSUFBSSxJQUFJLGNBQWMsRUFBRSxDQUFDO1FBQ2xDLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RixJQUFJLFFBQVEsR0FBRyxlQUFlLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxTQUFTLEdBQUcsT0FBTyxDQUFDO1FBQ3JFLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztRQUVqQixJQUFJLFNBQVMsSUFBSSxZQUFZLElBQUksU0FBUyxJQUFJLFlBQVksSUFBSSxlQUFlLEdBQUcsUUFBUSxFQUFFLENBQUM7WUFDekYsSUFBSSxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUM7Z0JBQzVCLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNyRSxDQUFDO1lBRUQsa0RBQWtEO1lBQ2xELE1BQU0sYUFBYSxHQUFHLGNBQWMsR0FBRyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDOUQsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDcEMsU0FBUyxJQUFJLENBQUMsQ0FBQztZQUNqQixDQUFDO1lBRUQsUUFBUSxHQUFHLENBQUMsSUFBSSxHQUFHLFNBQVMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztZQUUvRCxPQUFPO2dCQUNMLFFBQVEsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztnQkFDeEIsR0FBRyxFQUFFLFFBQVE7Z0JBQ2IsR0FBRyxFQUFFLFFBQVE7Z0JBQ2IsVUFBVSxFQUFFLFNBQVM7YUFDdEIsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGlCQUFpQixDQUFDLElBQVksRUFBRSxTQUFpQixFQUFFLFdBQW9CO0lBQzlFLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztJQUVqQixJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDeEIsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsT0FBTyxJQUFJLElBQUksU0FBUyxJQUFJLFFBQVEsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNwRCxRQUFRLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztZQUN2QixJQUFJLEVBQUUsQ0FBQztRQUNULENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxzQkFBc0IsQ0FBQyxjQUFzQixFQUFFLFlBQW9CO0lBQzFFLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6RCxJQUFJLFFBQVEsR0FBRyxJQUFJLEdBQUcsWUFBWSxDQUFDO0lBRW5DLElBQUksY0FBYyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ2hDLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDbkMsUUFBUSxHQUFHLElBQUksR0FBRyxZQUFZLENBQUM7SUFDakMsQ0FBQztJQUVELE9BQU87UUFDTCxRQUFRLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFDeEIsR0FBRyxFQUFFLFFBQVE7UUFDYixHQUFHLEVBQUUsQ0FBQztRQUNOLFVBQVUsRUFBRSxZQUFZO0tBQ3pCLENBQUM7QUFDSixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLHNCQUFzQixDQUM3QixPQUFlLEVBQ2YsT0FBZSxFQUNmLFdBQW9CLEVBQ3BCLHFCQUErQjtJQUUvQixNQUFNLGNBQWMsR0FBYSxFQUFFLENBQUM7SUFDcEMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDO0lBRXZGLGtEQUFrRDtJQUNsRCxLQUFLLElBQUksU0FBUyxHQUFHLENBQUMsRUFBRSxTQUFTLEdBQUcsY0FBYyxFQUFFLFNBQVMsRUFBRSxFQUFFLENBQUM7UUFDaEUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUNoQyxXQUFXLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3RELENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBRSxDQUFDO1FBRTlDLEtBQUssSUFBSSxjQUFjLEdBQUcsQ0FBQyxFQUFFLGNBQWMsR0FBRyxtQkFBbUIsRUFBRSxjQUFjLEVBQUUsRUFBRSxDQUFDO1lBQ3BGLElBQUkscUJBQXFCLEVBQUUsQ0FBQztnQkFDMUIsTUFBTSxTQUFTLEdBQUcsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ25FLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDakMsQ0FBQztZQUVELE1BQU0sSUFBSSxHQUFHLFNBQVMsR0FBRyxjQUFjLENBQUM7WUFDeEMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUUxQixvQ0FBb0M7WUFDcEMsSUFBSSxJQUFJLElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ3pCLE9BQU8sY0FBYyxDQUFDO1lBQ3hCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sY0FBYyxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uICovXG5pbXBvcnQgeyBpc05pbCB9IGZyb20gXCIuL2hlbHBlcnNcIjtcblxuLy8gRGVmaW5lIGludGVyZmFjZXMgZm9yIGJldHRlciB0eXBlIHNhZmV0eVxuaW50ZXJmYWNlIEF4aXNTY2FsZU9wdGlvbnMge1xuICBtaW5UaWNrQ291bnQ/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==