@ruc-lib/metered-progress-bar 2.0.0

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/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # Metered Progress Bar
2
+
3
+ A customizable Angular progress bar component that displays progress with various styling options and categories. It supports different visual styles like solid, stripes, circles, and rectangles, and can be oriented horizontally or vertically.
4
+
5
+ ## Installation Guide
6
+
7
+ To use the Metered Progress Bar component, you can install the entire RUC library or just this specific component.
8
+
9
+ ### Install the Entire Library
10
+ ```bash
11
+ npm install @uxpractice/ruc-lib
12
+ ```
13
+
14
+ ### Install Individual Component
15
+ If you only need the Metered Progress Bar component:
16
+ ```bash
17
+ npm install @uxpractice/metered-progress-bar
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### 1. Import the Module
23
+ In your Angular module file (e.g., `app.module.ts`), import the `RucMeteredProgressBarModule`:
24
+
25
+ ```typescript
26
+ import { RucMeteredProgressBarModule } from '@uxpractice/metered-progress-bar';
27
+ import { AppComponent } from './app.component';
28
+ import { NgModule } from '@angular/core';
29
+ import { BrowserModule } from '@angular/platform-browser';
30
+
31
+ @NgModule({
32
+ declarations: [AppComponent],
33
+ imports: [
34
+ BrowserModule,
35
+ RucMeteredProgressBarModule
36
+ ],
37
+ providers: [],
38
+ bootstrap: [AppComponent]
39
+ })
40
+ export class AppModule {}
41
+ ```
42
+
43
+ ### 2. Use the Component
44
+ In your component's template, use the `<uxp-ruc-metered-progress-bar>` selector and pass the configuration object to the `rucInputData` input.
45
+
46
+ ```html
47
+ <uxp-ruc-metered-progress-bar [rucInputData]="meteredBarConfig"></uxp-ruc-metered-progress-bar>
48
+ ```
49
+
50
+ ## API Reference
51
+
52
+ ### Component Inputs
53
+
54
+ | Input | Type | Description |
55
+ |----------------|--------------------|----------------------------------------------|
56
+ | `rucInputData` | `MeteredBarConfig` | The main configuration object for the component. |
57
+ | `customTheme` | `string` | An optional CSS class for custom theming. |
58
+
59
+
60
+ ### `MeteredBarConfig`
61
+ This is the main configuration object for the progress bar.
62
+
63
+ | Property | Type | Description |
64
+ |-----------------------------|--------------------------------------------------|---------------------------------------------------------------------------------------------------------|
65
+ | `min` | `number` | The minimum value of the progress bar (e.g., 0). |
66
+ | `max` | `number` | The maximum value of the progress bar (e.g., 100). |
67
+ | `orientation` | `'horizontal' \| 'vertical'` | The orientation of the progress bar. |
68
+ | `barLabels` | `boolean` | If `true`, displays percentage labels on the bar. |
69
+ | `barStyle` | `'solid' \| 'stripe' \| 'circle' \| 'rectangle'` | The visual style of the progress bar segments. Defaults to `solid`. |
70
+ | `categoryLabelsOrientation` | `'top' \| 'bottom' \| 'left' \| 'right'` | The orientation of category labels relative to the bar. |
71
+ | `categoryLabelStyle` | `'basic' \| 'widget'` | The display style for category labels. |
72
+ | `showCategoryLabels` | `boolean` | If `true`, displays the category labels. |
73
+ | `categories` | `CategoryConfig[]` | An array of category configurations that make up the progress bar. |
74
+ | `unitType` | `string` | An optional unit to display next to the value (e.g., 'MB', 'GB', '%'). |
75
+
76
+ ### `CategoryConfig`
77
+ This object defines the configuration for each segment within the progress bar.
78
+
79
+ | Property | Type | Description |
80
+ |-----------|------------------------------------|--------------------------------------------------------------------------|
81
+ | `label` | `string` | The label for the category, displayed in the legend and on hover. |
82
+ | `color` | `string` | The color of the category segment (e.g., `'#34d399'`, `'rgb(251,191,36)'`). |
83
+ | `value` | `number` | The value of the category. |
84
+ | `icon` | `string` (optional) | The name of a Material Icon to display for the category. If empty, a colored dot is shown. |
85
+ | `handler` | `(event?: any) => void` (optional) | A function to handle events for the category (e.g., click). |
86
+
87
+ ## Example Configuration
88
+
89
+ Here's an example of how to configure the Metered Progress Bar in your component's TypeScript file.
90
+
91
+ ```typescript
92
+ import { Component } from '@angular/core';
93
+ import { MeteredBarConfig } from '@uxpractice/metered-progress-bar';
94
+
95
+ @Component({
96
+ selector: 'app-root',
97
+ templateUrl: './app.component.html',
98
+ })
99
+ export class AppComponent {
100
+ meteredBarConfig: MeteredBarConfig = {
101
+ min: 0,
102
+ max: 150,
103
+ orientation: 'horizontal',
104
+ barLabels: true,
105
+ barStyle: 'stripe',
106
+ categoryLabelsOrientation: 'bottom',
107
+ categoryLabelStyle: 'widget',
108
+ showCategoryLabels: true,
109
+ categories: [
110
+ { label: 'Applications', color: '#34d399', value: 95, icon: 'apps' },
111
+ { label: 'Messages', color: '#fbbf24', value: 15, icon: 'message' },
112
+ { label: 'Media', color: '#60a5fa', value: 21, icon: 'perm_media' },
113
+ { label: 'Photos', color: '#6055ea', value: 12, icon: 'collections' }
114
+ ],
115
+ unitType: 'MB'
116
+ };
117
+ }
118
+ ```
119
+
120
+ ## Contribution
121
+
122
+ Contributions are welcome! Feel free to open issues or pull requests for any enhancements or fixes.
123
+
124
+ ## Acknowledgements
125
+
126
+ Thank you for choosing the Metered Progress Bar component. If you have any feedback or suggestions, please let us know!
@@ -0,0 +1,4 @@
1
+ export * from './lib/ruclib-metered-progress-bar.module';
2
+ export * from './lib/model/metered-bar.config';
3
+ export * from './lib/ruc-metered-progress-bar/ruc-metered-progress-bar.component';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYywwQ0FBMEMsQ0FBQztBQUN6RCxjQUFjLGdDQUFnQyxDQUFDO0FBQy9DLGNBQWMsbUVBQW1FLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2xpYi9ydWNsaWItbWV0ZXJlZC1wcm9ncmVzcy1iYXIubW9kdWxlJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvbW9kZWwvbWV0ZXJlZC1iYXIuY29uZmlnJztcclxuZXhwb3J0ICogZnJvbSAnLi9saWIvcnVjLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyL3J1Yy1tZXRlcmVkLXByb2dyZXNzLWJhci5jb21wb25lbnQnO1xyXG4iXX0=
@@ -0,0 +1,9 @@
1
+ export var LablePositionEnums;
2
+ (function (LablePositionEnums) {
3
+ LablePositionEnums["left"] = "left";
4
+ LablePositionEnums["right"] = "right";
5
+ LablePositionEnums["same"] = "same";
6
+ LablePositionEnums["top"] = "top";
7
+ LablePositionEnums["bottom"] = "bottom";
8
+ })(LablePositionEnums || (LablePositionEnums = {}));
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGFibGUtcG9zaXRpb24uZW51bS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZW51bXMvbGFibGUtcG9zaXRpb24uZW51bS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQU4sSUFBWSxrQkFNWDtBQU5ELFdBQVksa0JBQWtCO0lBQzFCLG1DQUFhLENBQUE7SUFDYixxQ0FBZSxDQUFBO0lBQ2YsbUNBQWEsQ0FBQTtJQUNiLGlDQUFXLENBQUE7SUFDWCx1Q0FBaUIsQ0FBQTtBQUNyQixDQUFDLEVBTlcsa0JBQWtCLEtBQWxCLGtCQUFrQixRQU03QiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBlbnVtIExhYmxlUG9zaXRpb25FbnVtcyB7XHJcbiAgICBsZWZ0ID0gXCJsZWZ0XCIsXHJcbiAgICByaWdodCA9IFwicmlnaHRcIixcclxuICAgIHNhbWUgPSBcInNhbWVcIixcclxuICAgIHRvcCA9IFwidG9wXCIsXHJcbiAgICBib3R0b20gPSAnYm90dG9tJ1xyXG59XHJcbiJdfQ==
@@ -0,0 +1,5 @@
1
+ export class MeteredBarConfig {
2
+ }
3
+ export class CategoryConfig {
4
+ }
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0ZXJlZC1iYXIuY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9tb2RlbC9tZXRlcmVkLWJhci5jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxPQUFPLGdCQUFnQjtDQVc1QjtBQUVELE1BQU0sT0FBTyxjQUFjO0NBTTFCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIE1ldGVyZWRCYXJDb25maWcge1xyXG4gICAgbWluITogbnVtYmVyO1xyXG4gICAgbWF4ITogbnVtYmVyO1xyXG4gICAgb3JpZW50YXRpb24hOiBzdHJpbmc7XHJcbiAgICBiYXJMYWJlbHMhOiBib29sZWFuO1xyXG4gICAgYmFyU3R5bGU/OiAnc29saWQnIHwgJ3N0cmlwZScgfCAnY2lyY2xlJyB8ICdyZWN0YW5nbGUnO1xyXG4gICAgY2F0ZWdvcnlMYWJlbHNPcmllbnRhdGlvbiE6IHN0cmluZztcclxuICAgIGNhdGVnb3J5TGFiZWxTdHlsZT86IHN0cmluZztcclxuICAgIHNob3dDYXRlZ29yeUxhYmVscz86IGJvb2xlYW47XHJcbiAgICBjYXRlZ29yaWVzITogQ2F0ZWdvcnlDb25maWdbXTtcclxuICAgIHVuaXRUeXBlPzogc3RyaW5nXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBDYXRlZ29yeUNvbmZpZyB7XHJcbiAgICBsYWJlbCE6IHN0cmluZztcclxuICAgIGNvbG9yITogc3RyaW5nO1xyXG4gICAgdmFsdWUhOiBudW1iZXI7XHJcbiAgICBpY29uPzogc3RyaW5nO1xyXG4gICAgaGFuZGxlcj86IChldmVudD86IGFueSkgPT4gdm9pZDtcclxufVxyXG4iXX0=
@@ -0,0 +1,193 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { MeteredBarConfig } from '../model/metered-bar.config';
3
+ import { LablePositionEnums } from '../enums/lable-position.enum';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ export class RucMeteredProgressBarComponent {
7
+ constructor() {
8
+ this.hoveredCategoryDetail = null;
9
+ this.hoverLabelStyle = { left: '0px', top: '-28px', display: 'none', transform: 'translateX(-50%)' };
10
+ this.progressPercentage = 0;
11
+ }
12
+ /**
13
+ * Calculates the total value of all categories.
14
+ * @returns The sum of all category values.
15
+ */
16
+ get totalValue() {
17
+ return this.rucInputData.categories.reduce((sum, category) => sum + category.value, 0);
18
+ }
19
+ /**
20
+ * Calculates the overall progress percentage of the bar based on total value, min, and max.
21
+ * @returns The progress as a percentage (0-100).
22
+ */
23
+ get progress() {
24
+ return ((this.totalValue - this.rucInputData.min) / (this.rucInputData.max - this.rucInputData.min)) * 100;
25
+ }
26
+ /**
27
+ * Determines if the progress bar is oriented vertically.
28
+ * @returns True if the orientation is 'vertical', false otherwise.
29
+ */
30
+ get isVertical() {
31
+ return this.rucInputData.orientation === 'vertical';
32
+ }
33
+ /**
34
+ * Generates the CSS linear-gradient string for the progress bar.
35
+ * The gradient is composed of segments based on category values and colors.
36
+ * If no categories or total value is zero, it returns a transparent gradient.
37
+ * @returns A CSS linear-gradient string.
38
+ */
39
+ get progressStyles() {
40
+ const direction = this.isVertical ? 'to bottom' : 'to right';
41
+ if (!this.rucInputData || !this.rucInputData.categories) {
42
+ return { background: 'transparent' };
43
+ }
44
+ const total = this.totalValue;
45
+ const colorStops = [];
46
+ let cumulativePercentage = 0;
47
+ if (total > 0) {
48
+ this.rucInputData.categories.forEach(category => {
49
+ if (category.value <= 0)
50
+ return; // Skip categories with zero or negative contribution
51
+ const segmentPercentage = (category.value / total) * 100;
52
+ const color = category.color;
53
+ // Add start of the segment using the previous cumulative percentage
54
+ colorStops.push(`${color} ${cumulativePercentage}%`);
55
+ // Update cumulative percentage for the end of this segment
56
+ cumulativePercentage += segmentPercentage;
57
+ // Add end of the segment
58
+ // Use Math.min to cap at 100% in case of floating point overshoot on the last segment
59
+ colorStops.push(`${color} ${Math.min(cumulativePercentage, 100)}%`);
60
+ });
61
+ }
62
+ if (colorStops.length === 0) {
63
+ return { background: 'transparent' };
64
+ }
65
+ const baseGradient = `linear-gradient(${direction}, ${colorStops.join(', ')})`;
66
+ const styles = {};
67
+ const barStyle = this.rucInputData?.barStyle;
68
+ switch (barStyle) {
69
+ case 'stripe':
70
+ // This uses multiple backgrounds for an overlay effect, as requested.
71
+ styles['background'] = `repeating-linear-gradient(-45deg, transparent, transparent 5px, rgba(0, 0, 0, 0.1) 5px, rgba(0, 0, 0, 0.1) 10px), ${baseGradient}`;
72
+ break;
73
+ case 'circle': {
74
+ // This uses a mask. The background is the color, the mask cuts out the shape.
75
+ styles['background'] = baseGradient;
76
+ // A repeating pattern of circles. Each circle has a diameter of 8px, with a 4px gap.
77
+ const circleMask = 'radial-gradient(circle, black 4px, transparent 4px) 0 0 / 12px 12px';
78
+ styles['-webkit-mask'] = circleMask;
79
+ styles['mask'] = circleMask;
80
+ break;
81
+ }
82
+ case 'rectangle': {
83
+ styles['background'] = baseGradient;
84
+ // For vertical bar, create horizontal rectangles (0deg). For horizontal bar, create vertical rectangles (90deg).
85
+ const rectDirection = this.isVertical ? '0deg' : '90deg';
86
+ // A repeating pattern of bars. Each bar is 6px wide with a 6px gap.
87
+ const rectangleMask = `repeating-linear-gradient(${rectDirection}, black, black 6px, transparent 6px, transparent 12px)`;
88
+ styles['-webkit-mask'] = rectangleMask;
89
+ styles['mask'] = rectangleMask;
90
+ break;
91
+ }
92
+ default: // 'solid' or undefined
93
+ styles['background'] = baseGradient;
94
+ break;
95
+ }
96
+ return styles;
97
+ }
98
+ /**
99
+ * Handles mouse movement over the progress bar to display category-specific hover details.
100
+ * It calculates the hovered segment based on mouse position and updates the hover label.
101
+ * @param event The MouseEvent object.
102
+ */
103
+ onProgressMouseMove(event) {
104
+ const progressBarElement = event.target;
105
+ let currentCumulativeGradientPct = 0;
106
+ let foundCategoryForHover = null;
107
+ let hoverPercentage_onFilledBar = 0;
108
+ let mousePositionWithinProgressDiv = 0;
109
+ if (this.isVertical) {
110
+ mousePositionWithinProgressDiv = event.offsetY; // Y position within the .progress div
111
+ const filledHeightPx = progressBarElement.offsetHeight;
112
+ if (filledHeightPx <= 0) { // Avoid division by zero if element has no height
113
+ this.onProgressMouseLeave();
114
+ return;
115
+ }
116
+ hoverPercentage_onFilledBar = (mousePositionWithinProgressDiv / filledHeightPx) * 100;
117
+ }
118
+ else { // Horizontal
119
+ mousePositionWithinProgressDiv = event.offsetX; // X position within the .progress div
120
+ const filledWidthPx = progressBarElement.offsetWidth;
121
+ if (filledWidthPx <= 0) { // Avoid division by zero if element has no width
122
+ this.onProgressMouseLeave();
123
+ return;
124
+ }
125
+ hoverPercentage_onFilledBar = (mousePositionWithinProgressDiv / filledWidthPx) * 100;
126
+ }
127
+ if (this.totalValue > 0) {
128
+ for (const category of this.rucInputData.categories) {
129
+ if (category.value <= 0)
130
+ continue; // Skip categories with zero or negative contribution
131
+ const segmentGradientPct = (category.value / this.totalValue) * 100;
132
+ const segmentStartGradientPct = currentCumulativeGradientPct;
133
+ const segmentEndGradientPct = currentCumulativeGradientPct + segmentGradientPct;
134
+ // Ensure hoverPercentage is within the segment, handling potential floating point inaccuracies for the last segment
135
+ if (hoverPercentage_onFilledBar >= segmentStartGradientPct && // Check if mouse is within or at the start of the segment
136
+ (hoverPercentage_onFilledBar < segmentEndGradientPct ||
137
+ (segmentEndGradientPct >= 99.99 && hoverPercentage_onFilledBar <= 100.01))) { // Tolerate slight overshoot for last segment
138
+ foundCategoryForHover = category;
139
+ break;
140
+ }
141
+ currentCumulativeGradientPct = segmentEndGradientPct;
142
+ }
143
+ }
144
+ if (foundCategoryForHover) {
145
+ const percentageOfMax = (foundCategoryForHover.value / this.rucInputData.max) * 100; // Calculate percentage relative to max value
146
+ this.hoveredCategoryDetail = { category: foundCategoryForHover, percentageText: percentageOfMax.toFixed(0) + '%' };
147
+ if (this.isVertical) {
148
+ this.hoverLabelStyle = {
149
+ left: 'calc(100% + 5px)',
150
+ top: mousePositionWithinProgressDiv + 'px',
151
+ display: 'block',
152
+ transform: 'translateY(-50%)' // Vertically center label on mouse Y
153
+ };
154
+ }
155
+ else {
156
+ this.hoverLabelStyle = {
157
+ left: mousePositionWithinProgressDiv + 'px',
158
+ top: '-28px',
159
+ display: 'block',
160
+ transform: 'translateX(-50%)' // Horizontally center label on mouse X
161
+ };
162
+ }
163
+ }
164
+ else {
165
+ this.hoveredCategoryDetail = null;
166
+ this.hoverLabelStyle = { ...this.hoverLabelStyle, display: 'none' };
167
+ }
168
+ }
169
+ /**
170
+ * Hides the hover label when the mouse leaves the progress bar.
171
+ */
172
+ onProgressMouseLeave() {
173
+ this.hoveredCategoryDetail = null;
174
+ this.hoverLabelStyle = { ...this.hoverLabelStyle, display: 'none' };
175
+ }
176
+ /**
177
+ * get the label position string value
178
+ */
179
+ get LablePositionEnums() {
180
+ return LablePositionEnums;
181
+ }
182
+ }
183
+ RucMeteredProgressBarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RucMeteredProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
184
+ RucMeteredProgressBarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: RucMeteredProgressBarComponent, selector: "uxp-ruc-metered-progress-bar", inputs: { rucInputData: "rucInputData", customTheme: "customTheme" }, ngImport: i0, template: "<div class=\"progress-container\" class={{customTheme}} [class.vertical]=\"isVertical\" [class.horizontal]=\"!isVertical\">\r\n <div class=\"progress-bar\">\r\n <!-- Removed (mouseenter) and (mouseleave) from progress-bar if only category hover is needed -->\r\n <div *ngIf=\"rucInputData.barLabels\" class=\"progress-label-container {{rucInputData.orientation}}\">\r\n <span class=\"progress-label\">{{progress | number:'1.0-0'}}% of {{rucInputData.max}} {{rucInputData.unitType}}\r\n Used</span>\r\n </div>\r\n <div class=\"progress\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\"\r\n [style.transition]=\"rucInputData.orientation === 'vertical' ? 'height 0.3s ease' : 'width 0.3s ease'\"\r\n [ngStyle]=\"progressStyles\">\r\n <!-- This div is now only for displaying the colored bar -->\r\n </div>\r\n <!-- The hover label is now a sibling to .progress, positioned absolutely within .progress-bar -->\r\n <div class=\"hover-label\" *ngIf=\"hoveredCategoryDetail\" [ngStyle]=\"hoverLabelStyle\">\r\n {{hoveredCategoryDetail.category.label}}: {{hoveredCategoryDetail.percentageText}}\r\n </div>\r\n <!-- This overlay is now a sibling to .progress, sized to match it, to reliably capture mouse events -->\r\n <div class=\"progress-event-overlay\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\" (mousemove)=\"onProgressMouseMove($event)\"\r\n (mouseleave)=\"onProgressMouseLeave()\"></div>\r\n </div>\r\n <div class=\"categories-container\" *ngIf=\"rucInputData.categories.length > 0\">\r\n <div *ngIf=\"rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'basic'\" [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === 'top' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same')\r\n }\" class=\"categories\">\r\n <div class=\"category\" *ngFor=\"let category of rucInputData.categories\" [style.color]=\"category.color\">\r\n <ng-container *ngIf=\"category.icon !== undefined\">\r\n <div *ngIf=\"category.icon; else colorDotBasic\" class=\"category-icon-wrapper\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n <ng-template #colorDotBasic>\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n <span class=\"category-label\">{{category.label}}</span>\r\n <span class=\"category-value\">({{(category.value / rucInputData.max * 100) | number:'1.0-0' }}%)</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'widget'\"\r\n class=\"categories widget-style\" [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.top || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same)\r\n }\">\r\n <ng-container *ngFor=\"let category of rucInputData.categories\">\r\n <div class=\"widget-category\">\r\n <div class=\"widget-content\">\r\n <div class=\"widget-icon-box\">\r\n <ng-container *ngIf=\"category.icon !== undefined\">\r\n <div *ngIf=\"category.icon; else colorDotWidget\" class=\"widget-icon\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n <ng-template #colorDotWidget>\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n <div class=\"widget-label\">{{category.label}}</div>\r\n </div>\r\n </div>\r\n <div class=\"widget-value\">\r\n <div>{{category.value}}</div>\r\n </div>\r\n </div>\r\n\r\n\r\n </ng-container>\r\n </div>\r\n\r\n </div>\r\n</div>", styles: [".progress-container{position:relative;margin:20px 0}.progress-container.horizontal{width:100%;height:35px}.progress-container.horizontal .progress-bar{width:100%;height:42%}.progress-container.vertical{width:60px;height:320px;margin:0 auto}.progress-container.vertical .progress-bar{width:24%;height:100%}.progress-label-container{position:absolute;z-index:2;width:100%;height:100%;pointer-events:none;display:flex}.progress-label-container.horizontal{justify-content:right;align-items:flex-end;bottom:15px}.progress-label-container.vertical{justify-content:flex-start;align-items:flex-end;left:35px}.progress-label{padding:2px 5px;font-size:12px;color:#333;white-space:nowrap}.progress-label-container.horizontal .progress-label{margin-top:5px;margin-right:5px}.progress-label-container.vertical .progress-label{transform:rotate(-90deg);transform-origin:bottom left;margin-right:5px}.progress-bar{position:relative;background:white;border:1px solid #e0e0e0;border-radius:4px}.progress-bar .hover-label{position:absolute;top:-28px;left:50%;transform:translate(-50%);background-color:#000c;color:#fff;padding:4px 8px;border-radius:4px;font-size:.8em;z-index:5;white-space:nowrap;pointer-events:none}.progress-event-overlay{position:absolute;top:0;left:0;z-index:4}.progress{position:relative;background:#2196F3;transition:width .3s ease,height .3s ease}.progress-bar.horizontal .progress{width:100%;height:100%}.progress-bar.vertical .progress{width:100%;height:0}.icons-container{position:absolute;display:flex;justify-content:space-between;width:100%;height:100%;align-items:center}.icons-container i{position:absolute;font-size:1.2em;color:#fff}.start-icon{left:0}.end-icon{right:0}.above-threshold{color:gold}.categories-container{width:100%;box-sizing:border-box}.categories{display:flex;flex-direction:row;flex-wrap:wrap;gap:1px}.categories-block-top,.categories-block-bottom,.categories-block-left,.categories-block-right{position:absolute;z-index:1}.categories-block-top{bottom:100%;left:0;padding-bottom:8px}.categories-block-bottom{top:100%;left:0;padding-top:10px}.categories-block-left{right:100%;top:0;padding-right:8px;width:200px}.categories-block-left .categories{flex-direction:inherit;align-items:flex-start;gap:0px}.categories-block-right{left:100%;top:0;padding-left:8px;width:200px}.categories-block-right .categories{flex-direction:inherit;align-items:flex-start;gap:0px}.category{display:flex;align-items:center;gap:6px;padding:8px;border-radius:4px}.category-label{font-weight:500}.category-value{color:#666;font-size:.9em}.category-color{width:10px;height:10px;border-radius:50%;overflow:hidden;flex-shrink:0}.category-icon-wrapper{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.color-gradient{width:100%;height:100%}.categories.widget-style{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-start;align-items:flex-start;margin:10px 0}.categories.widget-style .widget-category{width:calc(25% - 7.5px);min-width:159px;box-sizing:border-box;flex-shrink:0;flex-grow:0}@media (max-width: 1200px){.categories.widget-style .widget-category{width:calc(33.33% - 6.66px)}}@media (max-width: 768px){.categories.widget-style .widget-category{width:calc(50% - 5px)}}@media (max-width: 480px){.categories.widget-style .widget-category{width:100%}}.categories-block-left,.categories-block-right{flex-direction:inherit;align-items:flex-start;gap:10px}.categories-block-left .widget-category,.categories-block-right .widget-category{width:100%;max-width:none}.widget-category{background-color:#fff;border:1px solid #e0e0e0;border-radius:8px;padding:10px 15px;box-shadow:0 2px 4px #0000001a}.widget-content{display:flex;width:100%;align-items:center;margin:0}.widget-icon{border:1px solid #ddd;border-radius:10px;width:35px;height:35px;line-height:45px;text-align:center;background-color:#fdfdfd}.widget-content .category-color{margin-right:35px}.widget-icon,.widget-color{margin-right:8px;flex-shrink:0}.widget-color{width:24px;height:24px;border-radius:50%}.widget-label{flex-grow:1;text-align:left;display:block}.widget-value{font-weight:700;flex-shrink:0;margin-left:45px;text-align:left;margin-top:5px}.widget-icon-box{display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }] });
185
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RucMeteredProgressBarComponent, decorators: [{
186
+ type: Component,
187
+ args: [{ selector: 'uxp-ruc-metered-progress-bar', template: "<div class=\"progress-container\" class={{customTheme}} [class.vertical]=\"isVertical\" [class.horizontal]=\"!isVertical\">\r\n <div class=\"progress-bar\">\r\n <!-- Removed (mouseenter) and (mouseleave) from progress-bar if only category hover is needed -->\r\n <div *ngIf=\"rucInputData.barLabels\" class=\"progress-label-container {{rucInputData.orientation}}\">\r\n <span class=\"progress-label\">{{progress | number:'1.0-0'}}% of {{rucInputData.max}} {{rucInputData.unitType}}\r\n Used</span>\r\n </div>\r\n <div class=\"progress\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\"\r\n [style.transition]=\"rucInputData.orientation === 'vertical' ? 'height 0.3s ease' : 'width 0.3s ease'\"\r\n [ngStyle]=\"progressStyles\">\r\n <!-- This div is now only for displaying the colored bar -->\r\n </div>\r\n <!-- The hover label is now a sibling to .progress, positioned absolutely within .progress-bar -->\r\n <div class=\"hover-label\" *ngIf=\"hoveredCategoryDetail\" [ngStyle]=\"hoverLabelStyle\">\r\n {{hoveredCategoryDetail.category.label}}: {{hoveredCategoryDetail.percentageText}}\r\n </div>\r\n <!-- This overlay is now a sibling to .progress, sized to match it, to reliably capture mouse events -->\r\n <div class=\"progress-event-overlay\" [style.width]=\"isVertical ? '100%' : progress + '%'\"\r\n [style.height]=\"isVertical ? progress + '%' : '100%'\" (mousemove)=\"onProgressMouseMove($event)\"\r\n (mouseleave)=\"onProgressMouseLeave()\"></div>\r\n </div>\r\n <div class=\"categories-container\" *ngIf=\"rucInputData.categories.length > 0\">\r\n <div *ngIf=\"rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'basic'\" [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === 'top' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same'),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === 'left' || rucInputData.categoryLabelsOrientation === 'same')\r\n }\" class=\"categories\">\r\n <div class=\"category\" *ngFor=\"let category of rucInputData.categories\" [style.color]=\"category.color\">\r\n <ng-container *ngIf=\"category.icon !== undefined\">\r\n <div *ngIf=\"category.icon; else colorDotBasic\" class=\"category-icon-wrapper\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n <ng-template #colorDotBasic>\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n <span class=\"category-label\">{{category.label}}</span>\r\n <span class=\"category-value\">({{(category.value / rucInputData.max * 100) | number:'1.0-0' }}%)</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"rucInputData.showCategoryLabels && rucInputData.categoryLabelStyle === 'widget'\"\r\n class=\"categories widget-style\" [ngClass]=\"{\r\n 'categories-block-top': !isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.top || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-left': isVertical && (rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same),\r\n 'categories-block-right': isVertical && !(rucInputData.categoryLabelsOrientation === LablePositionEnums.left || rucInputData.categoryLabelsOrientation === LablePositionEnums.same)\r\n }\">\r\n <ng-container *ngFor=\"let category of rucInputData.categories\">\r\n <div class=\"widget-category\">\r\n <div class=\"widget-content\">\r\n <div class=\"widget-icon-box\">\r\n <ng-container *ngIf=\"category.icon !== undefined\">\r\n <div *ngIf=\"category.icon; else colorDotWidget\" class=\"widget-icon\">\r\n <i class=\"material-icons\" [style.color]=\"category.color\">{{ category.icon }}</i>\r\n </div>\r\n <ng-template #colorDotWidget>\r\n <div class=\"category-color\">\r\n <div class=\"color-gradient\"\r\n [style.background]=\"category.color ? 'linear-gradient(to right, ' + category.color + ', ' + category.color + ')' : ''\">\r\n </div>\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n <div class=\"widget-label\">{{category.label}}</div>\r\n </div>\r\n </div>\r\n <div class=\"widget-value\">\r\n <div>{{category.value}}</div>\r\n </div>\r\n </div>\r\n\r\n\r\n </ng-container>\r\n </div>\r\n\r\n </div>\r\n</div>", styles: [".progress-container{position:relative;margin:20px 0}.progress-container.horizontal{width:100%;height:35px}.progress-container.horizontal .progress-bar{width:100%;height:42%}.progress-container.vertical{width:60px;height:320px;margin:0 auto}.progress-container.vertical .progress-bar{width:24%;height:100%}.progress-label-container{position:absolute;z-index:2;width:100%;height:100%;pointer-events:none;display:flex}.progress-label-container.horizontal{justify-content:right;align-items:flex-end;bottom:15px}.progress-label-container.vertical{justify-content:flex-start;align-items:flex-end;left:35px}.progress-label{padding:2px 5px;font-size:12px;color:#333;white-space:nowrap}.progress-label-container.horizontal .progress-label{margin-top:5px;margin-right:5px}.progress-label-container.vertical .progress-label{transform:rotate(-90deg);transform-origin:bottom left;margin-right:5px}.progress-bar{position:relative;background:white;border:1px solid #e0e0e0;border-radius:4px}.progress-bar .hover-label{position:absolute;top:-28px;left:50%;transform:translate(-50%);background-color:#000c;color:#fff;padding:4px 8px;border-radius:4px;font-size:.8em;z-index:5;white-space:nowrap;pointer-events:none}.progress-event-overlay{position:absolute;top:0;left:0;z-index:4}.progress{position:relative;background:#2196F3;transition:width .3s ease,height .3s ease}.progress-bar.horizontal .progress{width:100%;height:100%}.progress-bar.vertical .progress{width:100%;height:0}.icons-container{position:absolute;display:flex;justify-content:space-between;width:100%;height:100%;align-items:center}.icons-container i{position:absolute;font-size:1.2em;color:#fff}.start-icon{left:0}.end-icon{right:0}.above-threshold{color:gold}.categories-container{width:100%;box-sizing:border-box}.categories{display:flex;flex-direction:row;flex-wrap:wrap;gap:1px}.categories-block-top,.categories-block-bottom,.categories-block-left,.categories-block-right{position:absolute;z-index:1}.categories-block-top{bottom:100%;left:0;padding-bottom:8px}.categories-block-bottom{top:100%;left:0;padding-top:10px}.categories-block-left{right:100%;top:0;padding-right:8px;width:200px}.categories-block-left .categories{flex-direction:inherit;align-items:flex-start;gap:0px}.categories-block-right{left:100%;top:0;padding-left:8px;width:200px}.categories-block-right .categories{flex-direction:inherit;align-items:flex-start;gap:0px}.category{display:flex;align-items:center;gap:6px;padding:8px;border-radius:4px}.category-label{font-weight:500}.category-value{color:#666;font-size:.9em}.category-color{width:10px;height:10px;border-radius:50%;overflow:hidden;flex-shrink:0}.category-icon-wrapper{display:flex;align-items:center;justify-content:center;width:100%;height:100%}.color-gradient{width:100%;height:100%}.categories.widget-style{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-start;align-items:flex-start;margin:10px 0}.categories.widget-style .widget-category{width:calc(25% - 7.5px);min-width:159px;box-sizing:border-box;flex-shrink:0;flex-grow:0}@media (max-width: 1200px){.categories.widget-style .widget-category{width:calc(33.33% - 6.66px)}}@media (max-width: 768px){.categories.widget-style .widget-category{width:calc(50% - 5px)}}@media (max-width: 480px){.categories.widget-style .widget-category{width:100%}}.categories-block-left,.categories-block-right{flex-direction:inherit;align-items:flex-start;gap:10px}.categories-block-left .widget-category,.categories-block-right .widget-category{width:100%;max-width:none}.widget-category{background-color:#fff;border:1px solid #e0e0e0;border-radius:8px;padding:10px 15px;box-shadow:0 2px 4px #0000001a}.widget-content{display:flex;width:100%;align-items:center;margin:0}.widget-icon{border:1px solid #ddd;border-radius:10px;width:35px;height:35px;line-height:45px;text-align:center;background-color:#fdfdfd}.widget-content .category-color{margin-right:35px}.widget-icon,.widget-color{margin-right:8px;flex-shrink:0}.widget-color{width:24px;height:24px;border-radius:50%}.widget-label{flex-grow:1;text-align:left;display:block}.widget-value{font-weight:700;flex-shrink:0;margin-left:45px;text-align:left;margin-top:5px}.widget-icon-box{display:flex;align-items:center}\n"] }]
188
+ }], propDecorators: { rucInputData: [{
189
+ type: Input
190
+ }], customTheme: [{
191
+ type: Input
192
+ }] } });
193
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVjLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcnVjLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyL3J1Yy1tZXRlcmVkLXByb2dyZXNzLWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3J1Yy1tZXRlcmVkLXByb2dyZXNzLWJhci9ydWMtbWV0ZXJlZC1wcm9ncmVzcy1iYXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakQsT0FBTyxFQUFrQixnQkFBZ0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQy9FLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7QUFVbEUsTUFBTSxPQUFPLDhCQUE4QjtJQVAzQztRQVVFLDBCQUFxQixHQUFnRSxJQUFJLENBQUM7UUFDMUYsb0JBQWUsR0FBdUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQztRQUNwSyx1QkFBa0IsR0FBRyxDQUFDLENBQUM7S0F5THhCO0lBeExDOzs7T0FHRztJQUNILElBQUksVUFBVTtRQUNaLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekYsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQUksUUFBUTtRQUNWLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxD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LEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENhdGVnb3J5Q29uZmlnLCBNZXRlcmVkQmFyQ29uZmlnIH0gZnJvbSAnLi4vbW9kZWwvbWV0ZXJlZC1iYXIuY29uZmlnJztcclxuaW1wb3J0IHsgTGFibGVQb3NpdGlvbkVudW1zIH0gZnJvbSAnLi4vZW51bXMvbGFibGUtcG9zaXRpb24uZW51bSc7XHJcblxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICd1eHAtcnVjLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vcnVjLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9ydWMtbWV0ZXJlZC1wcm9ncmVzcy1iYXIuY29tcG9uZW50LnNjc3MnXSxcclxufSlcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgUnVjTWV0ZXJlZFByb2dyZXNzQmFyQ29tcG9uZW50IHtcclxuICBASW5wdXQoKSBydWNJbnB1dERhdGEhOiBNZXRlcmVkQmFyQ29uZmlnO1xyXG4gIEBJbnB1dCgpIGN1c3RvbVRoZW1lITogc3RyaW5nO1xyXG4gIGhvdmVyZWRDYXRlZ29yeURldGFpbDogeyBjYXRlZ29yeTogQ2F0ZWdvcnlDb25maWcsIHBlcmNlbnRhZ2VUZXh0OiBzdHJpbmcgfSB8IG51bGwgPSBudWxsO1xyXG4gIGhvdmVyTGFiZWxTdHlsZTogeyBsZWZ0OiBzdHJpbmc7IHRvcDogc3RyaW5nOyBkaXNwbGF5OiBzdHJpbmc7IHRyYW5zZm9ybTogc3RyaW5nOyB9ID0geyBsZWZ0OiAnMHB4JywgdG9wOiAnLTI4cHgnLCBkaXNwbGF5OiAnbm9uZScsIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoLTUwJSknIH07XHJcbiAgcHJvZ3Jlc3NQZXJjZW50YWdlID0gMDtcclxuICAvKipcclxuICAgKiBDYWxjdWxhdGVzIHRoZSB0b3RhbCB2YWx1ZSBvZiBhbGwgY2F0ZWdvcmllcy5cclxuICAgKiBAcmV0dXJucyBUaGUgc3VtIG9mIGFsbCBjYXRlZ29yeSB2YWx1ZXMuXHJcbiAgICovXHJcbiAgZ2V0IHRvdGFsVmFsdWUoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLnJ1Y0lucHV0RGF0YS5jYXRlZ29yaWVzLnJlZHVjZSgoc3VtLCBjYXRlZ29yeSkgPT4gc3VtICsgY2F0ZWdvcnkudmFsdWUsIDApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2FsY3VsYXRlcyB0aGUgb3ZlcmFsbCBwcm9ncmVzcyBwZXJjZW50YWdlIG9mIHRoZSBiYXIgYmFzZWQgb24gdG90YWwgdmFsdWUsIG1pbiwgYW5kIG1heC5cclxuICAgKiBAcmV0dXJucyBUaGUgcHJvZ3Jlc3MgYXMgYSBwZXJjZW50YWdlICgwLTEwMCkuXHJcbiAgICovXHJcbiAgZ2V0IHByb2dyZXNzKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gKCh0aGlzLnRvdGFsVmFsdWUgLSB0aGlzLnJ1Y0lucHV0RGF0YS5taW4pIC8gKHRoaXMucnVjSW5wdXREYXRhLm1heCAtIHRoaXMucnVjSW5wdXREYXRhLm1pbikpICogMTAwO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyBpZiB0aGUgcHJvZ3Jlc3MgYmFyIGlzIG9yaWVudGVkIHZlcnRpY2FsbHkuXHJcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgb3JpZW50YXRpb24gaXMgJ3ZlcnRpY2FsJywgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAqL1xyXG4gIGdldCBpc1ZlcnRpY2FsKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMucnVjSW5wdXREYXRhLm9yaWVudGF0aW9uID09PSAndmVydGljYWwnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2VuZXJhdGVzIHRoZSBDU1MgbGluZWFyLWdyYWRpZW50IHN0cmluZyBmb3IgdGhlIHByb2dyZXNzIGJhci5cclxuICAgKiBUaGUgZ3JhZGllbnQgaXMgY29tcG9zZWQgb2Ygc2VnbWVudHMgYmFzZWQgb24gY2F0ZWdvcnkgdmFsdWVzIGFuZCBjb2xvcnMuXHJcbiAgICogSWYgbm8gY2F0ZWdvcmllcyBvciB0b3RhbCB2YWx1ZSBpcyB6ZXJvLCBpdCByZXR1cm5zIGEgdHJhbnNwYXJlbnQgZ3JhZGllbnQuXHJcbiAgICogQHJldHVybnMgQSBDU1MgbGluZWFyLWdyYWRpZW50IHN0cmluZy5cclxuICAgKi9cclxuICBnZXQgcHJvZ3Jlc3NTdHlsZXMoKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB7XHJcbiAgICBjb25zdCBkaXJlY3Rpb24gPSB0aGlzLmlzVmVydGljYWwgPyAndG8gYm90dG9tJyA6ICd0byByaWdodCc7XHJcblxyXG4gICAgaWYgKCF0aGlzLnJ1Y0lucHV0RGF0YSB8fCAhdGhpcy5ydWNJbnB1dERhdGEuY2F0ZWdvcmllcykge1xyXG4gICAgICByZXR1cm4geyBiYWNrZ3JvdW5kOiAndHJhbnNwYXJlbnQnIH07XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdG90YWwgPSB0aGlzLnRvdGFsVmFsdWU7XHJcbiAgICBjb25zdCBjb2xvclN0b3BzOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgbGV0IGN1bXVsYXRpdmVQZXJjZW50YWdlID0gMDtcclxuXHJcbiAgICBpZiAodG90YWwgPiAwKSB7XHJcbiAgICAgIHRoaXMucnVjSW5wdXREYXRhLmNhdGVnb3JpZXMuZm9yRWFjaChjYXRlZ29yeSA9PiB7XHJcbiAgICAgICAgaWYgKGNhdGVnb3J5LnZhbHVlIDw9IDApIHJldHVybjsgLy8gU2tpcCBjYXRlZ29yaWVzIHdpdGggemVybyBvciBuZWdhdGl2ZSBjb250cmlidXRpb25cclxuXHJcbiAgICAgICAgY29uc3Qgc2VnbWVudFBlcmNlbnRhZ2UgPSAoY2F0ZWdvcnkudmFsdWUgLyB0b3RhbCkgKiAxMDA7XHJcbiAgICAgICAgY29uc3QgY29sb3IgPSBjYXRlZ29yeS5jb2xvcjtcclxuXHJcbiAgICAgICAgLy8gQWRkIHN0YXJ0IG9mIHRoZSBzZWdtZW50IHVzaW5nIHRoZSBwcmV2aW91cyBjdW11bGF0aXZlIHBlcmNlbnRhZ2VcclxuICAgICAgICBjb2xvclN0b3BzLnB1c2goYCR7Y29sb3J9ICR7Y3VtdWxhdGl2ZVBlcmNlbnRhZ2V9JWApO1xyXG5cclxuICAgICAgICAvLyBVcGRhdGUgY3VtdWxhdGl2ZSBwZXJjZW50YWdlIGZvciB0aGUgZW5kIG9mIHRoaXMgc2VnbWVudFxyXG4gICAgICAgIGN1bXVsYXRpdmVQZXJjZW50YWdlICs9IHNlZ21lbnRQZXJjZW50YWdlO1xyXG5cclxuICAgICAgICAvLyBBZGQgZW5kIG9mIHRoZSBzZWdtZW50XHJcbiAgICAgICAgLy8gVXNlIE1hdGgubWluIHRvIGNhcCBhdCAxMDAlIGluIGNhc2Ugb2YgZmxvYXRpbmcgcG9pbnQgb3ZlcnNob290IG9uIHRoZSBsYXN0IHNlZ21lbnRcclxuICAgICAgICBjb2xvclN0b3BzLnB1c2goYCR7Y29sb3J9ICR7TWF0aC5taW4oY3VtdWxhdGl2ZVBlcmNlbnRhZ2UsIDEwMCl9JWApO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29sb3JTdG9wcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgcmV0dXJuIHsgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50JyB9O1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGJhc2VHcmFkaWVudCA9IGBsaW5lYXItZ3JhZGllbnQoJHtkaXJlY3Rpb259LCAke2NvbG9yU3RvcHMuam9pbignLCAnKX0pYDtcclxuICAgIGNvbnN0IHN0eWxlczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xyXG4gICAgY29uc3QgYmFyU3R5bGUgPSB0aGlzLnJ1Y0lucHV0RGF0YT8uYmFyU3R5bGU7XHJcblxyXG4gICAgc3dpdGNoIChiYXJTdHlsZSkge1xyXG4gICAgICBjYXNlICdzdHJpcGUnOlxyXG4gICAgICAgIC8vIFRoaXMgdXNlcyBtdWx0aXBsZSBiYWNrZ3JvdW5kcyBmb3IgYW4gb3ZlcmxheSBlZmZlY3QsIGFzIHJlcXVlc3RlZC5cclxuICAgICAgICBzdHlsZXNbJ2JhY2tncm91bmQnXSA9IGByZXBlYXRpbmctbGluZWFyLWdyYWRpZW50KC00NWRlZywgdHJhbnNwYXJlbnQsIHRyYW5zcGFyZW50IDVweCwgcmdiYSgwLCAwLCAwLCAwLjEpIDVweCwgcmdiYSgwLCAwLCAwLCAwLjEpIDEwcHgpLCAke2Jhc2VHcmFkaWVudH1gO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdjaXJjbGUnOiB7XHJcbiAgICAgICAgLy8gVGhpcyB1c2VzIGEgbWFzay4gVGhlIGJhY2tncm91bmQgaXMgdGhlIGNvbG9yLCB0aGUgbWFzayBjdXRzIG91dCB0aGUgc2hhcGUuXHJcbiAgICAgICAgc3R5bGVzWydiYWNrZ3JvdW5kJ10gPSBiYXNlR3JhZGllbnQ7XHJcbiAgICAgICAgLy8gQSByZXBlYXRpbmcgcGF0dGVybiBvZiBjaXJjbGVzLiBFYWNoIGNpcmNsZSBoYXMgYSBkaWFtZXRlciBvZiA4cHgsIHdpdGggYSA0cHggZ2FwLlxyXG4gICAgICAgIGNvbnN0IGNpcmNsZU1hc2sgPSAncmFkaWFsLWdyYWRpZW50KGNpcmNsZSwgYmxhY2sgNHB4LCB0cmFuc3BhcmVudCA0cHgpIDAgMCAvIDEycHggMTJweCc7XHJcbiAgICAgICAgc3R5bGVzWyctd2Via2l0LW1hc2snXSA9IGNpcmNsZU1hc2s7XHJcbiAgICAgICAgc3R5bGVzWydtYXNrJ10gPSBjaXJjbGVNYXNrO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgIGNhc2UgJ3JlY3RhbmdsZSc6IHtcclxuICAgICAgICBzdHlsZXNbJ2JhY2tncm91bmQnXSA9IGJhc2VHcmFkaWVudDtcclxuICAgICAgICAvLyBGb3IgdmVydGljYWwgYmFyLCBjcmVhdGUgaG9yaXpvbnRhbCByZWN0YW5nbGVzICgwZGVnKS4gRm9yIGhvcml6b250YWwgYmFyLCBjcmVhdGUgdmVydGljYWwgcmVjdGFuZ2xlcyAoOTBkZWcpLlxyXG4gICAgICAgIGNvbnN0IHJlY3REaXJlY3Rpb24gPSB0aGlzLmlzVmVydGljYWwgPyAnMGRlZycgOiAnOTBkZWcnO1xyXG4gICAgICAgIC8vIEEgcmVwZWF0aW5nIHBhdHRlcm4gb2YgYmFycy4gRWFjaCBiYXIgaXMgNnB4IHdpZGUgd2l0aCBhIDZweCBnYXAuXHJcbiAgICAgICAgY29uc3QgcmVjdGFuZ2xlTWFzayA9IGByZXBlYXRpbmctbGluZWFyLWdyYWRpZW50KCR7cmVjdERpcmVjdGlvbn0sIGJsYWNrLCBibGFjayA2cHgsIHRyYW5zcGFyZW50IDZweCwgdHJhbnNwYXJlbnQgMTJweClgO1xyXG4gICAgICAgIHN0eWxlc1snLXdlYmtpdC1tYXNrJ10gPSByZWN0YW5nbGVNYXNrO1xyXG4gICAgICAgIHN0eWxlc1snbWFzayddID0gcmVjdGFuZ2xlTWFzaztcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgICBkZWZhdWx0OiAvLyAnc29saWQnIG9yIHVuZGVmaW5lZFxyXG4gICAgICAgIHN0eWxlc1snYmFja2dyb3VuZCddID0gYmFzZUdyYWRpZW50O1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN0eWxlcztcclxuICB9XHJcbiAgLyoqXHJcbiAgICogSGFuZGxlcyBtb3VzZSBtb3ZlbWVudCBvdmVyIHRoZSBwcm9ncmVzcyBiYXIgdG8gZGlzcGxheSBjYXRlZ29yeS1zcGVjaWZpYyBob3ZlciBkZXRhaWxzLlxyXG4gICAqIEl0IGNhbGN1bGF0ZXMgdGhlIGhvdmVyZWQgc2VnbWVudCBiYXNlZCBvbiBtb3VzZSBwb3NpdGlvbiBhbmQgdXBkYXRlcyB0aGUgaG92ZXIgbGFiZWwuXHJcbiAgICogQHBhcmFtIGV2ZW50IFRoZSBNb3VzZUV2ZW50IG9iamVjdC5cclxuICAgKi9cclxuICBvblByb2dyZXNzTW91c2VNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICBjb25zdCBwcm9ncmVzc0JhckVsZW1lbnQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBsZXQgY3VycmVudEN1bXVsYXRpdmVHcmFkaWVudFBjdCA9IDA7XHJcbiAgICBsZXQgZm91bmRDYXRlZ29yeUZvckhvdmVyOiBDYXRlZ29yeUNvbmZpZyB8IG51bGwgPSBudWxsO1xyXG4gICAgbGV0IGhvdmVyUGVyY2VudGFnZV9vbkZpbGxlZEJhciA9IDA7XHJcbiAgICBsZXQgbW91c2VQb3NpdGlvbldpdGhpblByb2dyZXNzRGl2ID0gMDtcclxuXHJcbiAgICBpZiAodGhpcy5pc1ZlcnRpY2FsKSB7XHJcbiAgICAgIG1vdXNlUG9zaXRpb25XaXRoaW5Qcm9ncmVzc0RpdiA9IGV2ZW50Lm9mZnNldFk7IC8vIFkgcG9zaXRpb24gd2l0aGluIHRoZSAucHJvZ3Jlc3MgZGl2XHJcbiAgICAgIGNvbnN0IGZpbGxlZEhlaWdodFB4ID0gcHJvZ3Jlc3NCYXJFbGVtZW50Lm9mZnNldEhlaWdodDtcclxuICAgICAgaWYgKGZpbGxlZEhlaWdodFB4IDw9IDApIHsgLy8gQXZvaWQgZGl2aXNpb24gYnkgemVybyBpZiBlbGVtZW50IGhhcyBubyBoZWlnaHRcclxuICAgICAgICB0aGlzLm9uUHJvZ3Jlc3NNb3VzZUxlYXZlKCk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIGhvdmVyUGVyY2VudGFnZV9vbkZpbGxlZEJhciA9IChtb3VzZVBvc2l0aW9uV2l0aGluUHJvZ3Jlc3NEaXYgLyBmaWxsZWRIZWlnaHRQeCkgKiAxMDA7XHJcbiAgICB9IGVsc2UgeyAvLyBIb3Jpem9udGFsXHJcbiAgICAgIG1vdXNlUG9zaXRpb25XaXRoaW5Qcm9ncmVzc0RpdiA9IGV2ZW50Lm9mZnNldFg7IC8vIFggcG9zaXRpb24gd2l0aGluIHRoZSAucHJvZ3Jlc3MgZGl2XHJcbiAgICAgIGNvbnN0IGZpbGxlZFdpZHRoUHggPSBwcm9ncmVzc0JhckVsZW1lbnQub2Zmc2V0V2lkdGg7XHJcbiAgICAgIGlmIChmaWxsZWRXaWR0aFB4IDw9IDApIHsgLy8gQXZvaWQgZGl2aXNpb24gYnkgemVybyBpZiBlbGVtZW50IGhhcyBubyB3aWR0aFxyXG4gICAgICAgIHRoaXMub25Qcm9ncmVzc01vdXNlTGVhdmUoKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgaG92ZXJQZXJjZW50YWdlX29uRmlsbGVkQmFyID0gKG1vdXNlUG9zaXRpb25XaXRoaW5Qcm9ncmVzc0RpdiAvIGZpbGxlZFdpZHRoUHgpICogMTAwO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnRvdGFsVmFsdWUgPiAwKSB7XHJcbiAgICAgIGZvciAoY29uc3QgY2F0ZWdvcnkgb2YgdGhpcy5ydWNJbnB1dERhdGEuY2F0ZWdvcmllcykge1xyXG4gICAgICAgIGlmIChjYXRlZ29yeS52YWx1ZSA8PSAwKSBjb250aW51ZTsgLy8gU2tpcCBjYXRlZ29yaWVzIHdpdGggemVybyBvciBuZWdhdGl2ZSBjb250cmlidXRpb25cclxuXHJcbiAgICAgICAgY29uc3Qgc2VnbWVudEdyYWRpZW50UGN0ID0gKGNhdGVnb3J5LnZhbHVlIC8gdGhpcy50b3RhbFZhbHVlKSAqIDEwMDtcclxuICAgICAgICBjb25zdCBzZWdtZW50U3RhcnRHcmFkaWVudFBjdCA9IGN1cnJlbnRDdW11bGF0aXZlR3JhZGllbnRQY3Q7XHJcbiAgICAgICAgY29uc3Qgc2VnbWVudEVuZEdyYWRpZW50UGN0ID0gY3VycmVudEN1bXVsYXRpdmVHcmFkaWVudFBjdCArIHNlZ21lbnRHcmFkaWVudFBjdDtcclxuXHJcbiAgICAgICAgLy8gRW5zdXJlIGhvdmVyUGVyY2VudGFnZSBpcyB3aXRoaW4gdGhlIHNlZ21lbnQsIGhhbmRsaW5nIHBvdGVudGlhbCBmbG9hdGluZyBwb2ludCBpbmFjY3VyYWNpZXMgZm9yIHRoZSBsYXN0IHNlZ21lbnRcclxuICAgICAgICBpZiAoaG92ZXJQZXJjZW50YWdlX29uRmlsbGVkQmFyID49IHNlZ21lbnRTdGFydEdyYWRpZW50UGN0ICYmIC8vIENoZWNrIGlmIG1vdXNlIGlzIHdpdGhpbiBvciBhdCB0aGUgc3RhcnQgb2YgdGhlIHNlZ21lbnRcclxuICAgICAgICAgIChob3ZlclBlcmNlbnRhZ2Vfb25GaWxsZWRCYXIgPCBzZWdtZW50RW5kR3JhZGllbnRQY3QgfHxcclxuICAgICAgICAgICAgKHNlZ21lbnRFbmRHcmFkaWVudFBjdCA+PSA5OS45OSAmJiBob3ZlclBlcmNlbnRhZ2Vfb25GaWxsZWRCYXIgPD0gMTAwLjAxKSkpIHsgLy8gVG9sZXJhdGUgc2xpZ2h0IG92ZXJzaG9vdCBmb3IgbGFzdCBzZWdtZW50XHJcbiAgICAgICAgICBmb3VuZENhdGVnb3J5Rm9ySG92ZXIgPSBjYXRlZ29yeTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjdXJyZW50Q3VtdWxhdGl2ZUdyYWRpZW50UGN0ID0gc2VnbWVudEVuZEdyYWRpZW50UGN0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGZvdW5kQ2F0ZWdvcnlGb3JIb3Zlcikge1xyXG4gICAgICBjb25zdCBwZXJjZW50YWdlT2ZNYXggPSAoZm91bmRDYXRlZ29yeUZvckhvdmVyLnZhbHVlIC8gdGhpcy5ydWNJbnB1dERhdGEubWF4KSAqIDEwMDsgLy8gQ2FsY3VsYXRlIHBlcmNlbnRhZ2UgcmVsYXRpdmUgdG8gbWF4IHZhbHVlXHJcbiAgICAgIHRoaXMuaG92ZXJlZENhdGVnb3J5RGV0YWlsID0geyBjYXRlZ29yeTogZm91bmRDYXRlZ29yeUZvckhvdmVyLCBwZXJjZW50YWdlVGV4dDogcGVyY2VudGFnZU9mTWF4LnRvRml4ZWQoMCkgKyAnJScgfTtcclxuICAgICAgaWYgKHRoaXMuaXNWZXJ0aWNhbCkge1xyXG4gICAgICAgIHRoaXMuaG92ZXJMYWJlbFN0eWxlID0ge1xyXG4gICAgICAgICAgbGVmdDogJ2NhbGMoMTAwJSArIDVweCknLCAvLyBQb3NpdGlvbiB0byB0aGUgcmlnaHQgb2YgdGhlIHZlcnRpY2FsIGJhclxyXG4gICAgICAgICAgdG9wOiBtb3VzZVBvc2l0aW9uV2l0aGluUHJvZ3Jlc3NEaXYgKyAncHgnLFxyXG4gICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJyxcclxuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTUwJSknIC8vIFZlcnRpY2FsbHkgY2VudGVyIGxhYmVsIG9uIG1vdXNlIFlcclxuICAgICAgICB9O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuaG92ZXJMYWJlbFN0eWxlID0ge1xyXG4gICAgICAgICAgbGVmdDogbW91c2VQb3NpdGlvbldpdGhpblByb2dyZXNzRGl2ICsgJ3B4JyxcclxuICAgICAgICAgIHRvcDogJy0yOHB4JywgLy8gUG9zaXRpb24gYWJvdmUgaG9yaXpvbnRhbCBiYXJcclxuICAgICAgICAgIGRpc3BsYXk6ICdibG9jaycsXHJcbiAgICAgICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKC01MCUpJyAvLyBIb3Jpem9udGFsbHkgY2VudGVyIGxhYmVsIG9uIG1vdXNlIFhcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmhvdmVyZWRDYXRlZ29yeURldGFpbCA9IG51bGw7XHJcbiAgICAgIHRoaXMuaG92ZXJMYWJlbFN0eWxlID0geyAuLi50aGlzLmhvdmVyTGFiZWxTdHlsZSwgZGlzcGxheTogJ25vbmUnIH07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIaWRlcyB0aGUgaG92ZXIgbGFiZWwgd2hlbiB0aGUgbW91c2UgbGVhdmVzIHRoZSBwcm9ncmVzcyBiYXIuXHJcbiAgICovXHJcbiAgb25Qcm9ncmVzc01vdXNlTGVhdmUoKTogdm9pZCB7XHJcbiAgICB0aGlzLmhvdmVyZWRDYXRlZ29yeURldGFpbCA9IG51bGw7XHJcbiAgICB0aGlzLmhvdmVyTGFiZWxTdHlsZSA9IHsgLi4udGhpcy5ob3ZlckxhYmVsU3R5bGUsIGRpc3BsYXk6ICdub25lJyB9O1xyXG4gIH1cclxuICAvKipcclxuICAgKiBnZXQgdGhlIGxhYmVsIHBvc2l0aW9uICBzdHJpbmcgdmFsdWVcclxuICAgICAqL1xyXG4gIHB1YmxpYyBnZXQgTGFibGVQb3NpdGlvbkVudW1zKCk6IHR5cGVvZiBMYWJsZVBvc2l0aW9uRW51bXMge1xyXG4gICAgcmV0dXJuIExhYmxlUG9zaXRpb25FbnVtcztcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cInByb2dyZXNzLWNvbnRhaW5lclwiIGNsYXNzPXt7Y3VzdG9tVGhlbWV9fSBbY2xhc3MudmVydGljYWxdPVwiaXNWZXJ0aWNhbFwiIFtjbGFzcy5ob3Jpem9udGFsXT1cIiFpc1ZlcnRpY2FsXCI+XHJcbiAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWJhclwiPlxyXG4gICAgPCEtLSBSZW1vdmVkIChtb3VzZWVudGVyKSBhbmQgKG1vdXNlbGVhdmUpIGZyb20gcHJvZ3Jlc3MtYmFyIGlmIG9ubHkgY2F0ZWdvcnkgaG92ZXIgaXMgbmVlZGVkIC0tPlxyXG4gICAgPGRpdiAqbmdJZj1cInJ1Y0lucHV0RGF0YS5iYXJMYWJlbHNcIiBjbGFzcz1cInByb2dyZXNzLWxhYmVsLWNvbnRhaW5lciB7e3J1Y0lucHV0RGF0YS5vcmllbnRhdGlvbn19XCI+XHJcbiAgICAgIDxzcGFuIGNsYXNzPVwicHJvZ3Jlc3MtbGFiZWxcIj57e3Byb2dyZXNzIHwgbnVtYmVyOicxLjAtMCd9fSUgb2Yge3tydWNJbnB1dERhdGEubWF4fX0ge3tydWNJbnB1dERhdGEudW5pdFR5cGV9fVxyXG4gICAgICAgIFVzZWQ8L3NwYW4+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzc1wiIFtzdHlsZS53aWR0aF09XCJpc1ZlcnRpY2FsID8gJzEwMCUnIDogcHJvZ3Jlc3MgKyAnJSdcIlxyXG4gICAgICBbc3R5bGUuaGVpZ2h0XT1cImlzVmVydGljYWwgPyBwcm9ncmVzcyArICclJyA6ICcxMDAlJ1wiXHJcbiAgICAgIFtzdHlsZS50cmFuc2l0aW9uXT1cInJ1Y0lucHV0RGF0YS5vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJyA/ICdoZWlnaHQgMC4zcyBlYXNlJyA6ICd3aWR0aCAwLjNzIGVhc2UnXCJcclxuICAgICAgW25nU3R5bGVdPVwicHJvZ3Jlc3NTdHlsZXNcIj5cclxuICAgICAgPCEtLSBUaGlzIGRpdiBpcyBub3cgb25seSBmb3IgZGlzcGxheWluZyB0aGUgY29sb3JlZCBiYXIgLS0+XHJcbiAgICA8L2Rpdj5cclxuICAgIDwhLS0gVGhlIGhvdmVyIGxhYmVsIGlzIG5vdyBhIHNpYmxpbmcgdG8gLnByb2dyZXNzLCBwb3NpdGlvbmVkIGFic29sdXRlbHkgd2l0aGluIC5wcm9ncmVzcy1iYXIgLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwiaG92ZXItbGFiZWxcIiAqbmdJZj1cImhvdmVyZWRDYXRlZ29yeURldGFpbFwiIFtuZ1N0eWxlXT1cImhvdmVyTGFiZWxTdHlsZVwiPlxyXG4gICAgICB7e2hvdmVyZWRDYXRlZ29yeURldGFpbC5jYXRlZ29yeS5sYWJlbH19OiB7e2hvdmVyZWRDYXRlZ29yeURldGFpbC5wZXJjZW50YWdlVGV4dH19XHJcbiAgICA8L2Rpdj5cclxuICAgIDwhLS0gVGhpcyBvdmVybGF5IGlzIG5vdyBhIHNpYmxpbmcgdG8gLnByb2dyZXNzLCBzaXplZCB0byBtYXRjaCBpdCwgdG8gcmVsaWFibHkgY2FwdHVyZSBtb3VzZSBldmVudHMgLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtZXZlbnQtb3ZlcmxheVwiIFtzdHlsZS53aWR0aF09XCJpc1ZlcnRpY2FsID8gJzEwMCUnIDogcHJvZ3Jlc3MgKyAnJSdcIlxyXG4gICAgICBbc3R5bGUuaGVpZ2h0XT1cImlzVmVydGljYWwgPyBwcm9ncmVzcyArICclJyA6ICcxMDAlJ1wiIChtb3VzZW1vdmUpPVwib25Qcm9ncmVzc01vdXNlTW92ZSgkZXZlbnQpXCJcclxuICAgICAgKG1vdXNlbGVhdmUpPVwib25Qcm9ncmVzc01vdXNlTGVhdmUoKVwiPjwvZGl2PlxyXG4gIDwvZGl2PlxyXG4gIDxkaXYgY2xhc3M9XCJjYXRlZ29yaWVzLWNvbnRhaW5lclwiICpuZ0lmPVwicnVjSW5wdXREYXRhLmNhdGVnb3JpZXMubGVuZ3RoID4gMFwiPlxyXG4gICAgPGRpdiAqbmdJZj1cInJ1Y0lucHV0RGF0YS5zaG93Q2F0ZWdvcnlMYWJlbHMgJiYgcnVjSW5wdXREYXRhLmNhdGVnb3J5TGFiZWxTdHlsZSA9PT0gJ2Jhc2ljJ1wiIFtuZ0NsYXNzXT1cIntcclxuICAgICAgICAgICAnY2F0ZWdvcmllcy1ibG9jay10b3AnOiAgICAhaXNWZXJ0aWNhbCAmJiAocnVjSW5wdXREYXRhLmNhdGVnb3J5TGFiZWxzT3JpZW50YXRpb24gPT09ICd0b3AnIHx8IHJ1Y0lucHV0RGF0YS5jYXRlZ29yeUxhYmVsc09yaWVudGF0aW9uID09PSAnc2FtZScpLFxyXG4gICAgICAgICAgICdjYXRlZ29yaWVzLWJsb2NrLWxlZnQnOiAgIGlzVmVydGljYWwgJiYgKHJ1Y0lucHV0RGF0YS5jYXRlZ29yeUxhYmVsc09yaWVudGF0aW9uID09PSAnbGVmdCcgfHwgcnVjSW5wdXREYXRhLmNhdGVnb3J5TGFiZWxzT3JpZW50YXRpb24gPT09ICdzYW1lJyksXHJcbiAgICAgICAgICAgJ2NhdGVnb3JpZXMtYmxvY2stcmlnaHQnOiAgaXNWZXJ0aWNhbCAmJiAhKHJ1Y0lucHV0RGF0YS5jYXRlZ29yeUxhYmVsc09yaWVudGF0aW9uID09PSAnbGVmdCcgfHwgcnVjSW5wdXREYXRhLmNhdGVnb3J5TGFiZWxzT3JpZW50YXRpb24gPT09ICdzYW1lJylcclxuICAgICAgICAgfVwiIGNsYXNzPVwiY2F0ZWdvcmllc1wiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiY2F0ZWdvcnlcIiAqbmdGb3I9XCJsZXQgY2F0ZWdvcnkgb2YgcnVjSW5wdXREYXRhLmNhdGVnb3JpZXNcIiBbc3R5bGUuY29sb3JdPVwiY2F0ZWdvcnkuY29sb3JcIj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2F0ZWdvcnkuaWNvbiAhPT0gdW5kZWZpbmVkXCI+XHJcbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY2F0ZWdvcnkuaWNvbjsgZWxzZSBjb2xvckRvdEJhc2ljXCIgY2xhc3M9XCJjYXRlZ29yeS1pY29uLXdyYXBwZXJcIj5cclxuICAgICAgICAgICAgPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiIFtzdHlsZS5jb2xvcl09XCJjYXRlZ29yeS5jb2xvclwiPnt7IGNhdGVnb3J5Lmljb24gfX08L2k+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjY29sb3JEb3RCYXNpYz5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhdGVnb3J5LWNvbG9yXCI+XHJcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbG9yLWdyYWRpZW50XCJcclxuICAgICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImNhdGVnb3J5LmNvbG9yID8gJ2xpbmVhci1ncmFkaWVudCh0byByaWdodCwgJyArIGNhdGVnb3J5LmNvbG9yICsgJywgJyArIGNhdGVnb3J5LmNvbG9yICsgJyknIDogJydcIj5cclxuICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwiY2F0ZWdvcnktbGFiZWxcIj57e2NhdGVnb3J5LmxhYmVsfX08L3NwYW4+XHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJjYXRlZ29yeS12YWx1ZVwiPih7eyhjYXRlZ29yeS52YWx1ZSAvIHJ1Y0lucHV0RGF0YS5tYXggKiAxMDApIHwgbnVtYmVyOicxLjAtMCcgfX0lKTwvc3Bhbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2ICpuZ0lmPVwicnVjSW5wdXREYXRhLnNob3dDYXRlZ29yeUxhYmVscyAmJiBydWNJbnB1dERhdGEuY2F0ZWdvcnlMYWJlbFN0eWxlID09PSAnd2lkZ2V0J1wiXHJcbiAgICAgIGNsYXNzPVwiY2F0ZWdvcmllcyB3aWRnZXQtc3R5bGVcIiBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgJ2NhdGVnb3JpZXMtYmxvY2stdG9wJzogICAgIWlzVmVydGljYWwgJiYgKHJ1Y0lucHV0RGF0YS5jYXRlZ29yeUxhYmVsc09yaWVudGF0aW9uID09PSBMYWJsZVBvc2l0aW9uRW51bXMudG9wIHx8IHJ1Y0lucHV0RGF0YS5jYXRlZ29yeUxhYmVsc09yaWVudGF0aW9uID09PSBMYWJsZVBvc2l0aW9uRW51bXMuc2FtZSksXHJcbiAgICAgICAgICAgJ2NhdGVnb3JpZXMtYmxvY2stbGVmdCc6ICAgaXNWZXJ0aWNhbCAmJiAocnVjSW5wdXREYXRhLmNhdGVnb3J5TGFiZWxzT3JpZW50YXRpb24gPT09IExhYmxlUG9zaXRpb25FbnVtcy5sZWZ0IHx8IHJ1Y0lucHV0RGF0YS5jYXRlZ29yeUxhYmVsc09yaWVudGF0aW9uID09PSBMYWJsZVBvc2l0aW9uRW51bXMuc2FtZSksXHJcbiAgICAgICAgICAgJ2NhdGVnb3JpZXMtYmxvY2stcmlnaHQnOiAgaXNWZXJ0aWNhbCAmJiAhKHJ1Y0lucHV0RGF0YS5jYXRlZ29yeUxhYmVsc09yaWVudGF0aW9uID09PSBMYWJsZVBvc2l0aW9uRW51bXMubGVmdCB8fCBydWNJbnB1dERhdGEuY2F0ZWdvcnlMYWJlbHNPcmllbnRhdGlvbiA9PT0gTGFibGVQb3NpdGlvbkVudW1zLnNhbWUpXHJcbiAgICAgICAgIH1cIj5cclxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY2F0ZWdvcnkgb2YgcnVjSW5wdXREYXRhLmNhdGVnb3JpZXNcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwid2lkZ2V0LWNhdGVnb3J5XCI+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwid2lkZ2V0LWNvbnRlbnRcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndpZGdldC1pY29uLWJveFwiPlxyXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjYXRlZ29yeS5pY29uICE9PSB1bmRlZmluZWRcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjYXRlZ29yeS5pY29uOyBlbHNlIGNvbG9yRG90V2lkZ2V0XCIgY2xhc3M9XCJ3aWRnZXQtaWNvblwiPlxyXG4gICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCIgW3N0eWxlLmNvbG9yXT1cImNhdGVnb3J5LmNvbG9yXCI+e3sgY2F0ZWdvcnkuaWNvbiB9fTwvaT5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNjb2xvckRvdFdpZGdldD5cclxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhdGVnb3J5LWNvbG9yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbG9yLWdyYWRpZW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImNhdGVnb3J5LmNvbG9yID8gJ2xpbmVhci1ncmFkaWVudCh0byByaWdodCwgJyArIGNhdGVnb3J5LmNvbG9yICsgJywgJyArIGNhdGVnb3J5LmNvbG9yICsgJyknIDogJydcIj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3aWRnZXQtbGFiZWxcIj57e2NhdGVnb3J5LmxhYmVsfX08L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3aWRnZXQtdmFsdWVcIj5cclxuICAgICAgICAgICAgPGRpdj57e2NhdGVnb3J5LnZhbHVlfX08L2Rpdj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuXHJcbiAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gIDwvZGl2PlxyXG48L2Rpdj4iXX0=
@@ -0,0 +1,20 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { MatIconModule } from '@angular/material/icon';
4
+ import { RucMeteredProgressBarComponent } from './ruc-metered-progress-bar/ruc-metered-progress-bar.component';
5
+ import * as i0 from "@angular/core";
6
+ // import { RucMeteredProgressBarComponent } from './ruc-metered-progress-bar/ruc-metered-progress-bar/ruc-metered-progress-bar.component';
7
+ export class RuclibMeteredProgressBarModule {
8
+ }
9
+ RuclibMeteredProgressBarModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibMeteredProgressBarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
10
+ RuclibMeteredProgressBarModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: RuclibMeteredProgressBarModule, declarations: [RucMeteredProgressBarComponent], imports: [CommonModule, MatIconModule], exports: [RucMeteredProgressBarComponent] });
11
+ RuclibMeteredProgressBarModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibMeteredProgressBarModule, imports: [CommonModule, MatIconModule] });
12
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RuclibMeteredProgressBarModule, decorators: [{
13
+ type: NgModule,
14
+ args: [{
15
+ imports: [CommonModule, MatIconModule],
16
+ declarations: [RucMeteredProgressBarComponent],
17
+ exports: [RucMeteredProgressBarComponent],
18
+ }]
19
+ }] });
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVjbGliLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvcnVjbGliLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sK0RBQStELENBQUM7O0FBQy9HLDJJQUEySTtBQU8zSSxNQUFNLE9BQU8sOEJBQThCOzs0SEFBOUIsOEJBQThCOzZIQUE5Qiw4QkFBOEIsaUJBSDFCLDhCQUE4QixhQURuQyxZQUFZLEVBQUMsYUFBYSxhQUUxQiw4QkFBOEI7NkhBRTdCLDhCQUE4QixZQUovQixZQUFZLEVBQUMsYUFBYTs0RkFJekIsOEJBQThCO2tCQUwxQyxRQUFRO21CQUFDO29CQUNSLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBQyxhQUFhLENBQUM7b0JBQ3JDLFlBQVksRUFBRSxDQUFDLDhCQUE4QixDQUFDO29CQUM5QyxPQUFPLEVBQUUsQ0FBQyw4QkFBOEIsQ0FBQztpQkFDMUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XHJcbmltcG9ydCB7IFJ1Y01ldGVyZWRQcm9ncmVzc0JhckNvbXBvbmVudCB9IGZyb20gJy4vcnVjLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyL3J1Yy1tZXRlcmVkLXByb2dyZXNzLWJhci5jb21wb25lbnQnO1xyXG4vLyBpbXBvcnQgeyBSdWNNZXRlcmVkUHJvZ3Jlc3NCYXJDb21wb25lbnQgfSBmcm9tICcuL3J1Yy1tZXRlcmVkLXByb2dyZXNzLWJhci9ydWMtbWV0ZXJlZC1wcm9ncmVzcy1iYXIvcnVjLW1ldGVyZWQtcHJvZ3Jlc3MtYmFyLmNvbXBvbmVudCc7XHJcblxyXG5ATmdNb2R1bGUoe1xyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsTWF0SWNvbk1vZHVsZV0sXHJcbiAgZGVjbGFyYXRpb25zOiBbUnVjTWV0ZXJlZFByb2dyZXNzQmFyQ29tcG9uZW50XSxcclxuICBleHBvcnRzOiBbUnVjTWV0ZXJlZFByb2dyZXNzQmFyQ29tcG9uZW50XSxcclxufSlcclxuZXhwb3J0IGNsYXNzIFJ1Y2xpYk1ldGVyZWRQcm9ncmVzc0Jhck1vZHVsZSB7fVxyXG4iXX0=
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './index';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVjLWxpYi1tZXRlcmVkUHJvZ3Jlc3NCYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVjLWxpYi1tZXRlcmVkUHJvZ3Jlc3NCYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLFNBQVMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9pbmRleCc7XG4iXX0=