@tolle_/tolle-ui 18.3.0 → 18.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/esm2022/lib/alert-dialog-dynamic.component.mjs +13 -9
  2. package/esm2022/lib/alert-dialog.types.mjs +6 -1
  3. package/esm2022/lib/bar-list.component.mjs +95 -0
  4. package/esm2022/lib/category-bar.component.mjs +130 -0
  5. package/esm2022/lib/chart-spark.component.mjs +120 -0
  6. package/esm2022/lib/chart.component.mjs +131 -45
  7. package/esm2022/lib/chart.service.mjs +33 -8
  8. package/esm2022/lib/progress-circle.component.mjs +138 -0
  9. package/esm2022/lib/tracker.component.mjs +84 -0
  10. package/esm2022/public-api.mjs +6 -1
  11. package/fesm2022/tolle-ui.mjs +722 -60
  12. package/fesm2022/tolle-ui.mjs.map +1 -1
  13. package/lib/alert-dialog-dynamic.component.d.ts +7 -1
  14. package/lib/alert-dialog.types.d.ts +2 -0
  15. package/lib/bar-list.component.d.ts +39 -0
  16. package/lib/category-bar.component.d.ts +49 -0
  17. package/lib/chart-spark.component.d.ts +49 -0
  18. package/lib/chart.component.d.ts +68 -9
  19. package/lib/chart.service.d.ts +25 -5
  20. package/lib/progress-circle.component.d.ts +35 -0
  21. package/lib/tracker.component.d.ts +39 -0
  22. package/package.json +1 -1
  23. package/public-api.d.ts +5 -0
  24. package/registry/docs-content.json +330 -2
  25. package/registry/llms-full.txt +98 -2
  26. package/registry/llms.txt +5 -0
  27. package/registry/manifest.json +380 -3
  28. package/registry/r/alert-dialog-dynamic.json +2 -2
  29. package/registry/r/alert-dialog.json +1 -1
  30. package/registry/r/bar-list.json +21 -0
  31. package/registry/r/category-bar.json +21 -0
  32. package/registry/r/chart-pie.json +1 -1
  33. package/registry/r/chart-spark.json +30 -0
  34. package/registry/r/chart.json +2 -2
  35. package/registry/r/progress-circle.json +21 -0
  36. package/registry/r/tracker.json +25 -0
  37. package/registry/registry.json +112 -0
@@ -11,14 +11,18 @@ export class AlertDialogDynamicComponent {
11
11
  * content panel plays its exit animation before the overlay is torn down.
12
12
  */
13
13
  closing = false;
14
+ /**
15
+ * Result recorded by the action/cancel buttons' `confirmed`/`cancelled`
16
+ * outputs, which fire *before* the button drives the dialog closed. The
17
+ * single close path (`onOpenChange`) then reads it, so a confirm reports
18
+ * `true` instead of racing with the button's own `false` close signal.
19
+ */
20
+ result = false;
14
21
  onOpenChange(open) {
15
22
  if (!open) {
16
- this.close(false);
23
+ this.dialogRef.close(this.result);
17
24
  }
18
25
  }
19
- close(result) {
20
- this.dialogRef.close(result);
21
- }
22
26
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AlertDialogDynamicComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
23
27
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AlertDialogDynamicComponent, isStandalone: true, selector: "tolle-alert-dialog-dynamic", ngImport: i0, template: `
24
28
  <tolle-alert-dialog [open]="!closing" (openChange)="onOpenChange($event)">
@@ -30,10 +34,10 @@ export class AlertDialogDynamicComponent {
30
34
  </tolle-alert-dialog-description>
31
35
  </tolle-alert-dialog-header>
32
36
  <tolle-alert-dialog-footer>
33
- <tolle-alert-dialog-cancel (click)="close(false)">
37
+ <tolle-alert-dialog-cancel (cancelled)="result = false">
34
38
  <tolle-button variant="outline">{{ config.cancelText || 'Cancel' }}</tolle-button>
35
39
  </tolle-alert-dialog-cancel>
36
- <tolle-alert-dialog-action (click)="close(true)">
40
+ <tolle-alert-dialog-action (confirmed)="result = true">
37
41
  <tolle-button [variant]="config.variant === 'destructive' ? 'destructive' : 'default'">
38
42
  {{ config.actionText || 'Continue' }}
39
43
  </tolle-button>
@@ -66,10 +70,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
66
70
  </tolle-alert-dialog-description>
67
71
  </tolle-alert-dialog-header>
68
72
  <tolle-alert-dialog-footer>
69
- <tolle-alert-dialog-cancel (click)="close(false)">
73
+ <tolle-alert-dialog-cancel (cancelled)="result = false">
70
74
  <tolle-button variant="outline">{{ config.cancelText || 'Cancel' }}</tolle-button>
71
75
  </tolle-alert-dialog-cancel>
72
- <tolle-alert-dialog-action (click)="close(true)">
76
+ <tolle-alert-dialog-action (confirmed)="result = true">
73
77
  <tolle-button [variant]="config.variant === 'destructive' ? 'destructive' : 'default'">
74
78
  {{ config.actionText || 'Continue' }}
75
79
  </tolle-button>
@@ -79,4 +83,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
79
83
  </tolle-alert-dialog>
80
84
  `, styles: [":host{display:block}\n"] }]
81
85
  }] });
82
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxlcnQtZGlhbG9nLWR5bmFtaWMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi9hbGVydC1kaWFsb2ctZHluYW1pYy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBMEIsTUFBTSxlQUFlLENBQUM7QUFDbEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsMkJBQTJCLEVBQzNCLDBCQUEwQixFQUMxQix5QkFBeUIsRUFDekIsK0JBQStCLEVBQy9CLDBCQUEwQixFQUMxQiwwQkFBMEIsRUFDMUIsMEJBQTBCLEVBQzNCLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDOztBQTBDckQsTUFBTSxPQUFPLDJCQUEyQjtJQUN0QyxNQUFNLENBQXFCO0lBQzNCLFNBQVMsQ0FBa0I7SUFFM0I7OztPQUdHO0lBQ0gsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUVoQixZQUFZLENBQUMsSUFBYTtRQUN4QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDVixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BCLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQWU7UUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0IsQ0FBQzt3R0FsQlUsMkJBQTJCOzRGQUEzQiwyQkFBMkIsc0ZBdkI1Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJULCtGQWhDQyxZQUFZLCtCQUNaLG9CQUFvQiwwR0FDcEIsMkJBQTJCLGtHQUMzQiwwQkFBMEIseUZBQzFCLHlCQUF5Qix3RkFDekIsK0JBQStCLDhGQUMvQiwwQkFBMEIseUZBQzFCLDBCQUEwQiw4RkFDMUIsMEJBQTBCLDhGQUMxQixlQUFlOzs0RkF5Qk4sMkJBQTJCO2tCQXZDdkMsU0FBUzsrQkFDRSw0QkFBNEIsY0FFMUIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osb0JBQW9CO3dCQUNwQiwyQkFBMkI7d0JBQzNCLDBCQUEwQjt3QkFDMUIseUJBQXlCO3dCQUN6QiwrQkFBK0I7d0JBQy9CLDBCQUEwQjt3QkFDMUIsMEJBQTBCO3dCQUMxQiwwQkFBMEI7d0JBQzFCLGVBQWU7cUJBQ2hCLFlBQ1M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCVCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5qZWN0LCBpbmplY3QsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFsZXJ0RGlhbG9nQ29tcG9uZW50LFxuICBBbGVydERpYWxvZ0NvbnRlbnRDb21wb25lbnQsXG4gIEFsZXJ0RGlhbG9nSGVhZGVyQ29tcG9uZW50LFxuICBBbGVydERpYWxvZ1RpdGxlQ29tcG9uZW50LFxuICBBbGVydERpYWxvZ0Rlc2NyaXB0aW9uQ29tcG9uZW50LFxuICBBbGVydERpYWxvZ0Zvb3RlckNvbXBvbmVudCxcbiAgQWxlcnREaWFsb2dDYW5jZWxDb21wb25lbnQsXG4gIEFsZXJ0RGlhbG9nQWN0aW9uQ29tcG9uZW50XG59IGZyb20gJy4vYWxlcnQtZGlhbG9nLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBCdXR0b25Db21wb25lbnQgfSBmcm9tICcuL2J1dHRvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgQWxlcnREaWFsb2dDb25maWcsIEFsZXJ0RGlhbG9nUmVmIH0gZnJvbSAnLi9hbGVydC1kaWFsb2cudHlwZXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1hbGVydC1kaWFsb2ctZHluYW1pYycsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgQWxlcnREaWFsb2dDb21wb25lbnQsXG4gICAgQWxlcnREaWFsb2dDb250ZW50Q29tcG9uZW50LFxuICAgIEFsZXJ0RGlhbG9nSGVhZGVyQ29tcG9uZW50LFxuICAgIEFsZXJ0RGlhbG9nVGl0bGVDb21wb25lbnQsXG4gICAgQWxlcnREaWFsb2dEZXNjcmlwdGlvbkNvbXBvbmVudCxcbiAgICBBbGVydERpYWxvZ0Zvb3RlckNvbXBvbmVudCxcbiAgICBBbGVydERpYWxvZ0NhbmNlbENvbXBvbmVudCxcbiAgICBBbGVydERpYWxvZ0FjdGlvbkNvbXBvbmVudCxcbiAgICBCdXR0b25Db21wb25lbnRcbiAgXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8dG9sbGUtYWxlcnQtZGlhbG9nIFtvcGVuXT1cIiFjbG9zaW5nXCIgKG9wZW5DaGFuZ2UpPVwib25PcGVuQ2hhbmdlKCRldmVudClcIj5cbiAgICAgICAgPHRvbGxlLWFsZXJ0LWRpYWxvZy1jb250ZW50IFtzaXplXT1cImNvbmZpZy5zaXplIHx8ICdsZydcIj5cbiAgICAgICAgICA8dG9sbGUtYWxlcnQtZGlhbG9nLWhlYWRlcj5cbiAgICAgICAgICAgIDx0b2xsZS1hbGVydC1kaWFsb2ctdGl0bGU+e3sgY29uZmlnLnRpdGxlIH19PC90b2xsZS1hbGVydC1kaWFsb2ctdGl0bGU+XG4gICAgICAgICAgICA8dG9sbGUtYWxlcnQtZGlhbG9nLWRlc2NyaXB0aW9uPlxuICAgICAgICAgICAgICB7eyBjb25maWcuZGVzY3JpcHRpb24gfX1cbiAgICAgICAgICAgIDwvdG9sbGUtYWxlcnQtZGlhbG9nLWRlc2NyaXB0aW9uPlxuICAgICAgICAgIDwvdG9sbGUtYWxlcnQtZGlhbG9nLWhlYWRlcj5cbiAgICAgICAgICA8dG9sbGUtYWxlcnQtZGlhbG9nLWZvb3Rlcj5cbiAgICAgICAgICAgIDx0b2xsZS1hbGVydC1kaWFsb2ctY2FuY2VsIChjbGljayk9XCJjbG9zZShmYWxzZSlcIj5cbiAgICAgICAgICAgICAgPHRvbGxlLWJ1dHRvbiB2YXJpYW50PVwib3V0bGluZVwiPnt7IGNvbmZpZy5jYW5jZWxUZXh0IHx8ICdDYW5jZWwnIH19PC90b2xsZS1idXR0b24+XG4gICAgICAgICAgICA8L3RvbGxlLWFsZXJ0LWRpYWxvZy1jYW5jZWw+XG4gICAgICAgICAgICA8dG9sbGUtYWxlcnQtZGlhbG9nLWFjdGlvbiAoY2xpY2spPVwiY2xvc2UodHJ1ZSlcIj5cbiAgICAgICAgICAgICAgPHRvbGxlLWJ1dHRvbiBbdmFyaWFudF09XCJjb25maWcudmFyaWFudCA9PT0gJ2Rlc3RydWN0aXZlJyA/ICdkZXN0cnVjdGl2ZScgOiAnZGVmYXVsdCdcIj5cbiAgICAgICAgICAgICAgICB7eyBjb25maWcuYWN0aW9uVGV4dCB8fCAnQ29udGludWUnIH19XG4gICAgICAgICAgICAgIDwvdG9sbGUtYnV0dG9uPlxuICAgICAgICAgICAgPC90b2xsZS1hbGVydC1kaWFsb2ctYWN0aW9uPlxuICAgICAgICAgIDwvdG9sbGUtYWxlcnQtZGlhbG9nLWZvb3Rlcj5cbiAgICAgICAgPC90b2xsZS1hbGVydC1kaWFsb2ctY29udGVudD5cbiAgICA8L3RvbGxlLWFsZXJ0LWRpYWxvZz5cbiAgYFxufSlcbmV4cG9ydCBjbGFzcyBBbGVydERpYWxvZ0R5bmFtaWNDb21wb25lbnQge1xuICBjb25maWchOiBBbGVydERpYWxvZ0NvbmZpZztcbiAgZGlhbG9nUmVmITogQWxlcnREaWFsb2dSZWY7XG5cbiAgLyoqXG4gICAqIFNldCBieSBgQWxlcnREaWFsb2dTZXJ2aWNlYCBvbmNlIHRoZSBkaWFsb2cncyByZXN1bHQgaXMgcmVhZHksIHNvIHRoZVxuICAgKiBjb250ZW50IHBhbmVsIHBsYXlzIGl0cyBleGl0IGFuaW1hdGlvbiBiZWZvcmUgdGhlIG92ZXJsYXkgaXMgdG9ybiBkb3duLlxuICAgKi9cbiAgY2xvc2luZyA9IGZhbHNlO1xuXG4gIG9uT3BlbkNoYW5nZShvcGVuOiBib29sZWFuKSB7XG4gICAgaWYgKCFvcGVuKSB7XG4gICAgICB0aGlzLmNsb3NlKGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBjbG9zZShyZXN1bHQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZShyZXN1bHQpO1xuICB9XG59XG4iXX0=
86
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxlcnQtZGlhbG9nLWR5bmFtaWMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi9hbGVydC1kaWFsb2ctZHluYW1pYy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBMEIsTUFBTSxlQUFlLENBQUM7QUFDbEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsMkJBQTJCLEVBQzNCLDBCQUEwQixFQUMxQix5QkFBeUIsRUFDekIsK0JBQStCLEVBQy9CLDBCQUEwQixFQUMxQiwwQkFBMEIsRUFDMUIsMEJBQTBCLEVBQzNCLE1BQU0sMEJBQTBCLENBQUM7QUFDbEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDOztBQTBDckQsTUFBTSxPQUFPLDJCQUEyQjtJQUN0QyxNQUFNLENBQXFCO0lBQzNCLFNBQVMsQ0FBa0I7SUFFM0I7OztPQUdHO0lBQ0gsT0FBTyxHQUFHLEtBQUssQ0FBQztJQUVoQjs7Ozs7T0FLRztJQUNILE1BQU0sR0FBRyxLQUFLLENBQUM7SUFFZixZQUFZLENBQUMsSUFBYTtRQUN4QixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDVixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEMsQ0FBQztJQUNILENBQUM7d0dBdEJVLDJCQUEyQjs0RkFBM0IsMkJBQTJCLHNGQXZCNUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCVCwrRkFoQ0MsWUFBWSwrQkFDWixvQkFBb0IsMEdBQ3BCLDJCQUEyQixrR0FDM0IsMEJBQTBCLHlGQUMxQix5QkFBeUIsd0ZBQ3pCLCtCQUErQiw4RkFDL0IsMEJBQTBCLHlGQUMxQiwwQkFBMEIsOEZBQzFCLDBCQUEwQiw4RkFDMUIsZUFBZTs7NEZBeUJOLDJCQUEyQjtrQkF2Q3ZDLFNBQVM7K0JBQ0UsNEJBQTRCLGNBRTFCLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLG9CQUFvQjt3QkFDcEIsMkJBQTJCO3dCQUMzQiwwQkFBMEI7d0JBQzFCLHlCQUF5Qjt3QkFDekIsK0JBQStCO3dCQUMvQiwwQkFBMEI7d0JBQzFCLDBCQUEwQjt3QkFDMUIsMEJBQTBCO3dCQUMxQixlQUFlO3FCQUNoQixZQUNTOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQlQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEluamVjdCwgaW5qZWN0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBbGVydERpYWxvZ0NvbXBvbmVudCxcbiAgQWxlcnREaWFsb2dDb250ZW50Q29tcG9uZW50LFxuICBBbGVydERpYWxvZ0hlYWRlckNvbXBvbmVudCxcbiAgQWxlcnREaWFsb2dUaXRsZUNvbXBvbmVudCxcbiAgQWxlcnREaWFsb2dEZXNjcmlwdGlvbkNvbXBvbmVudCxcbiAgQWxlcnREaWFsb2dGb290ZXJDb21wb25lbnQsXG4gIEFsZXJ0RGlhbG9nQ2FuY2VsQ29tcG9uZW50LFxuICBBbGVydERpYWxvZ0FjdGlvbkNvbXBvbmVudFxufSBmcm9tICcuL2FsZXJ0LWRpYWxvZy5jb21wb25lbnQnO1xuaW1wb3J0IHsgQnV0dG9uQ29tcG9uZW50IH0gZnJvbSAnLi9idXR0b24uY29tcG9uZW50JztcbmltcG9ydCB7IEFsZXJ0RGlhbG9nQ29uZmlnLCBBbGVydERpYWxvZ1JlZiB9IGZyb20gJy4vYWxlcnQtZGlhbG9nLnR5cGVzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtYWxlcnQtZGlhbG9nLWR5bmFtaWMnLFxuICBzdHlsZXM6IFsnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgfSddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEFsZXJ0RGlhbG9nQ29tcG9uZW50LFxuICAgIEFsZXJ0RGlhbG9nQ29udGVudENvbXBvbmVudCxcbiAgICBBbGVydERpYWxvZ0hlYWRlckNvbXBvbmVudCxcbiAgICBBbGVydERpYWxvZ1RpdGxlQ29tcG9uZW50LFxuICAgIEFsZXJ0RGlhbG9nRGVzY3JpcHRpb25Db21wb25lbnQsXG4gICAgQWxlcnREaWFsb2dGb290ZXJDb21wb25lbnQsXG4gICAgQWxlcnREaWFsb2dDYW5jZWxDb21wb25lbnQsXG4gICAgQWxlcnREaWFsb2dBY3Rpb25Db21wb25lbnQsXG4gICAgQnV0dG9uQ29tcG9uZW50XG4gIF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPHRvbGxlLWFsZXJ0LWRpYWxvZyBbb3Blbl09XCIhY2xvc2luZ1wiIChvcGVuQ2hhbmdlKT1cIm9uT3BlbkNoYW5nZSgkZXZlbnQpXCI+XG4gICAgICAgIDx0b2xsZS1hbGVydC1kaWFsb2ctY29udGVudCBbc2l6ZV09XCJjb25maWcuc2l6ZSB8fCAnbGcnXCI+XG4gICAgICAgICAgPHRvbGxlLWFsZXJ0LWRpYWxvZy1oZWFkZXI+XG4gICAgICAgICAgICA8dG9sbGUtYWxlcnQtZGlhbG9nLXRpdGxlPnt7IGNvbmZpZy50aXRsZSB9fTwvdG9sbGUtYWxlcnQtZGlhbG9nLXRpdGxlPlxuICAgICAgICAgICAgPHRvbGxlLWFsZXJ0LWRpYWxvZy1kZXNjcmlwdGlvbj5cbiAgICAgICAgICAgICAge3sgY29uZmlnLmRlc2NyaXB0aW9uIH19XG4gICAgICAgICAgICA8L3RvbGxlLWFsZXJ0LWRpYWxvZy1kZXNjcmlwdGlvbj5cbiAgICAgICAgICA8L3RvbGxlLWFsZXJ0LWRpYWxvZy1oZWFkZXI+XG4gICAgICAgICAgPHRvbGxlLWFsZXJ0LWRpYWxvZy1mb290ZXI+XG4gICAgICAgICAgICA8dG9sbGUtYWxlcnQtZGlhbG9nLWNhbmNlbCAoY2FuY2VsbGVkKT1cInJlc3VsdCA9IGZhbHNlXCI+XG4gICAgICAgICAgICAgIDx0b2xsZS1idXR0b24gdmFyaWFudD1cIm91dGxpbmVcIj57eyBjb25maWcuY2FuY2VsVGV4dCB8fCAnQ2FuY2VsJyB9fTwvdG9sbGUtYnV0dG9uPlxuICAgICAgICAgICAgPC90b2xsZS1hbGVydC1kaWFsb2ctY2FuY2VsPlxuICAgICAgICAgICAgPHRvbGxlLWFsZXJ0LWRpYWxvZy1hY3Rpb24gKGNvbmZpcm1lZCk9XCJyZXN1bHQgPSB0cnVlXCI+XG4gICAgICAgICAgICAgIDx0b2xsZS1idXR0b24gW3ZhcmlhbnRdPVwiY29uZmlnLnZhcmlhbnQgPT09ICdkZXN0cnVjdGl2ZScgPyAnZGVzdHJ1Y3RpdmUnIDogJ2RlZmF1bHQnXCI+XG4gICAgICAgICAgICAgICAge3sgY29uZmlnLmFjdGlvblRleHQgfHwgJ0NvbnRpbnVlJyB9fVxuICAgICAgICAgICAgICA8L3RvbGxlLWJ1dHRvbj5cbiAgICAgICAgICAgIDwvdG9sbGUtYWxlcnQtZGlhbG9nLWFjdGlvbj5cbiAgICAgICAgICA8L3RvbGxlLWFsZXJ0LWRpYWxvZy1mb290ZXI+XG4gICAgICAgIDwvdG9sbGUtYWxlcnQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgPC90b2xsZS1hbGVydC1kaWFsb2c+XG4gIGBcbn0pXG5leHBvcnQgY2xhc3MgQWxlcnREaWFsb2dEeW5hbWljQ29tcG9uZW50IHtcbiAgY29uZmlnITogQWxlcnREaWFsb2dDb25maWc7XG4gIGRpYWxvZ1JlZiE6IEFsZXJ0RGlhbG9nUmVmO1xuXG4gIC8qKlxuICAgKiBTZXQgYnkgYEFsZXJ0RGlhbG9nU2VydmljZWAgb25jZSB0aGUgZGlhbG9nJ3MgcmVzdWx0IGlzIHJlYWR5LCBzbyB0aGVcbiAgICogY29udGVudCBwYW5lbCBwbGF5cyBpdHMgZXhpdCBhbmltYXRpb24gYmVmb3JlIHRoZSBvdmVybGF5IGlzIHRvcm4gZG93bi5cbiAgICovXG4gIGNsb3NpbmcgPSBmYWxzZTtcblxuICAvKipcbiAgICogUmVzdWx0IHJlY29yZGVkIGJ5IHRoZSBhY3Rpb24vY2FuY2VsIGJ1dHRvbnMnIGBjb25maXJtZWRgL2BjYW5jZWxsZWRgXG4gICAqIG91dHB1dHMsIHdoaWNoIGZpcmUgKmJlZm9yZSogdGhlIGJ1dHRvbiBkcml2ZXMgdGhlIGRpYWxvZyBjbG9zZWQuIFRoZVxuICAgKiBzaW5nbGUgY2xvc2UgcGF0aCAoYG9uT3BlbkNoYW5nZWApIHRoZW4gcmVhZHMgaXQsIHNvIGEgY29uZmlybSByZXBvcnRzXG4gICAqIGB0cnVlYCBpbnN0ZWFkIG9mIHJhY2luZyB3aXRoIHRoZSBidXR0b24ncyBvd24gYGZhbHNlYCBjbG9zZSBzaWduYWwuXG4gICAqL1xuICByZXN1bHQgPSBmYWxzZTtcblxuICBvbk9wZW5DaGFuZ2Uob3BlbjogYm9vbGVhbikge1xuICAgIGlmICghb3Blbikge1xuICAgICAgdGhpcy5kaWFsb2dSZWYuY2xvc2UodGhpcy5yZXN1bHQpO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -2,9 +2,14 @@ import { Subject } from 'rxjs';
2
2
  export class AlertDialogRef {
3
3
  _afterClosed = new Subject();
4
4
  afterClosed$ = this._afterClosed.asObservable();
5
+ /** Guards against the dialog's several close paths racing to emit twice. */
6
+ closed = false;
5
7
  close(result = false) {
8
+ if (this.closed)
9
+ return;
10
+ this.closed = true;
6
11
  this._afterClosed.next(result);
7
12
  this._afterClosed.complete();
8
13
  }
9
14
  }
10
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxlcnQtZGlhbG9nLnR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi9hbGVydC1kaWFsb2cudHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBYyxNQUFNLE1BQU0sQ0FBQztBQWEzQyxNQUFNLE9BQU8sY0FBYztJQUNOLFlBQVksR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO0lBQ3ZELFlBQVksR0FBd0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVyRSxLQUFLLENBQUMsU0FBa0IsS0FBSztRQUN6QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2pDLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN1YmplY3QsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuZXhwb3J0IHR5cGUgQWxlcnREaWFsb2dTaXplID0gJ3hzJyB8ICdzbScgfCAnbWQnIHwgJ2xnJyB8ICd4bCcgfCAnMnhsJyB8ICdmdWxsJyB8ICdmaXQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFsZXJ0RGlhbG9nQ29uZmlnIHtcbiAgICB0aXRsZTogc3RyaW5nO1xuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgY2FuY2VsVGV4dD86IHN0cmluZztcbiAgICBhY3Rpb25UZXh0Pzogc3RyaW5nO1xuICAgIHZhcmlhbnQ/OiAnZGVmYXVsdCcgfCAnZGVzdHJ1Y3RpdmUnO1xuICAgIHNpemU/OiBBbGVydERpYWxvZ1NpemU7XG59XG5cbmV4cG9ydCBjbGFzcyBBbGVydERpYWxvZ1JlZiB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfYWZ0ZXJDbG9zZWQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICAgIGFmdGVyQ2xvc2VkJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMuX2FmdGVyQ2xvc2VkLmFzT2JzZXJ2YWJsZSgpO1xuXG4gICAgY2xvc2UocmVzdWx0OiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fYWZ0ZXJDbG9zZWQubmV4dChyZXN1bHQpO1xuICAgICAgICB0aGlzLl9hZnRlckNsb3NlZC5jb21wbGV0ZSgpO1xuICAgIH1cbn1cbiJdfQ==
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxlcnQtZGlhbG9nLnR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi9hbGVydC1kaWFsb2cudHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBYyxNQUFNLE1BQU0sQ0FBQztBQWEzQyxNQUFNLE9BQU8sY0FBYztJQUNOLFlBQVksR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO0lBQ3ZELFlBQVksR0FBd0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVyRSw0RUFBNEU7SUFDcEUsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUV2QixLQUFLLENBQUMsU0FBa0IsS0FBSztRQUN6QixJQUFJLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNuQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2pDLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN1YmplY3QsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuZXhwb3J0IHR5cGUgQWxlcnREaWFsb2dTaXplID0gJ3hzJyB8ICdzbScgfCAnbWQnIHwgJ2xnJyB8ICd4bCcgfCAnMnhsJyB8ICdmdWxsJyB8ICdmaXQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFsZXJ0RGlhbG9nQ29uZmlnIHtcbiAgICB0aXRsZTogc3RyaW5nO1xuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgY2FuY2VsVGV4dD86IHN0cmluZztcbiAgICBhY3Rpb25UZXh0Pzogc3RyaW5nO1xuICAgIHZhcmlhbnQ/OiAnZGVmYXVsdCcgfCAnZGVzdHJ1Y3RpdmUnO1xuICAgIHNpemU/OiBBbGVydERpYWxvZ1NpemU7XG59XG5cbmV4cG9ydCBjbGFzcyBBbGVydERpYWxvZ1JlZiB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfYWZ0ZXJDbG9zZWQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICAgIGFmdGVyQ2xvc2VkJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMuX2FmdGVyQ2xvc2VkLmFzT2JzZXJ2YWJsZSgpO1xuXG4gICAgLyoqIEd1YXJkcyBhZ2FpbnN0IHRoZSBkaWFsb2cncyBzZXZlcmFsIGNsb3NlIHBhdGhzIHJhY2luZyB0byBlbWl0IHR3aWNlLiAqL1xuICAgIHByaXZhdGUgY2xvc2VkID0gZmFsc2U7XG5cbiAgICBjbG9zZShyZXN1bHQ6IGJvb2xlYW4gPSBmYWxzZSk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jbG9zZWQpIHJldHVybjtcbiAgICAgICAgdGhpcy5jbG9zZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLl9hZnRlckNsb3NlZC5uZXh0KHJlc3VsdCk7XG4gICAgICAgIHRoaXMuX2FmdGVyQ2xvc2VkLmNvbXBsZXRlKCk7XG4gICAgfVxufVxuIl19
@@ -0,0 +1,95 @@
1
+ import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { cn } from './utils/cn';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ /**
7
+ * A ranked list of horizontal bars — label left, value right, bar width
8
+ * scaled to each row's share of the list's largest value. Unlike a chart
9
+ * series or a category bar's segments, every bar is the same accent: rank is
10
+ * carried by length, not by a categorical palette.
11
+ * @new
12
+ */
13
+ export class BarListComponent {
14
+ /**
15
+ * Angular writes a bound `class` input through its styling path, which does
16
+ * not mark an OnPush component dirty — without this hook the component keeps
17
+ * rendering the class it was born with.
18
+ */
19
+ ngOnChanges() {
20
+ this.cdr.markForCheck();
21
+ }
22
+ /** Identity for `*ngFor`, so a redraw patches nodes instead of replacing them. */
23
+ trackByIndex = (index) => index;
24
+ /** Rows to rank, in the order they should be drawn. @default [] */
25
+ data = [];
26
+ /** Row key holding each row's label. @default 'label' */
27
+ labelKey = 'label';
28
+ /** Row key holding each row's numeric value. @default 'value' */
29
+ valueKey = 'value';
30
+ /** Extra Tailwind classes merged onto the list via `cn()` (last-wins). */
31
+ class = '';
32
+ cdr = inject(ChangeDetectorRef);
33
+ get rows() {
34
+ const rows = this.data ?? [];
35
+ const values = rows.map((row) => {
36
+ const num = Number(row?.[this.valueKey]);
37
+ return Number.isFinite(num) ? num : 0;
38
+ });
39
+ const max = values.reduce((m, v) => Math.max(m, v), 0);
40
+ return rows.map((row, i) => {
41
+ const raw = row?.[this.labelKey];
42
+ const value = values[i];
43
+ return {
44
+ label: raw == null ? '' : String(raw),
45
+ value,
46
+ percent: max > 0 ? Math.max(0, Math.min(100, (value / max) * 100)) : 0,
47
+ formattedValue: value.toLocaleString('en-US'),
48
+ };
49
+ });
50
+ }
51
+ get computedClass() {
52
+ return cn('flex w-full flex-col gap-1', this.class);
53
+ }
54
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BarListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
55
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: BarListComponent, isStandalone: true, selector: "tolle-bar-list", inputs: { data: "data", labelKey: "labelKey", valueKey: "valueKey", class: "class" }, usesOnChanges: true, ngImport: i0, template: `
56
+ <div [class]="computedClass">
57
+ <div
58
+ *ngFor="let row of rows; trackBy: trackByIndex"
59
+ class="relative flex items-center overflow-hidden rounded-sm"
60
+ >
61
+ <div class="absolute inset-y-0 left-0 rounded-sm bg-primary/15" [style.width.%]="row.percent"></div>
62
+ <span class="relative z-10 truncate px-2 py-1.5 text-sm text-foreground">{{ row.label }}</span>
63
+ <span class="relative z-10 ml-auto shrink-0 px-2 py-1.5 text-sm font-medium tabular-nums text-foreground">
64
+ {{ row.formattedValue }}
65
+ </span>
66
+ </div>
67
+ </div>
68
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
69
+ }
70
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BarListComponent, decorators: [{
71
+ type: Component,
72
+ args: [{ selector: 'tolle-bar-list', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
73
+ <div [class]="computedClass">
74
+ <div
75
+ *ngFor="let row of rows; trackBy: trackByIndex"
76
+ class="relative flex items-center overflow-hidden rounded-sm"
77
+ >
78
+ <div class="absolute inset-y-0 left-0 rounded-sm bg-primary/15" [style.width.%]="row.percent"></div>
79
+ <span class="relative z-10 truncate px-2 py-1.5 text-sm text-foreground">{{ row.label }}</span>
80
+ <span class="relative z-10 ml-auto shrink-0 px-2 py-1.5 text-sm font-medium tabular-nums text-foreground">
81
+ {{ row.formattedValue }}
82
+ </span>
83
+ </div>
84
+ </div>
85
+ `, styles: [":host{display:block}\n"] }]
86
+ }], propDecorators: { data: [{
87
+ type: Input
88
+ }], labelKey: [{
89
+ type: Input
90
+ }], valueKey: [{
91
+ type: Input
92
+ }], class: [{
93
+ type: Input
94
+ }] } });
95
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi9iYXItbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQWEsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hILE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDOzs7QUFVaEM7Ozs7OztHQU1HO0FBc0JILE1BQU0sT0FBTyxnQkFBZ0I7SUFDM0I7Ozs7T0FJRztJQUNILFdBQVc7UUFDVCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRCxrRkFBa0Y7SUFDbEYsWUFBWSxHQUFHLENBQUMsS0FBYSxFQUFVLEVBQUUsQ0FBQyxLQUFLLENBQUM7SUFFaEQsbUVBQW1FO0lBQzFELElBQUksR0FBMEIsRUFBRSxDQUFDO0lBQzFDLHlEQUF5RDtJQUNoRCxRQUFRLEdBQUcsT0FBTyxDQUFDO0lBQzVCLGlFQUFpRTtJQUN4RCxRQUFRLEdBQUcsT0FBTyxDQUFDO0lBQzVCLDBFQUEwRTtJQUNqRSxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBRUgsR0FBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBRWpELElBQUksSUFBSTtRQUNOLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQzdCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUM5QixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDekMsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUV2RCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDekIsTUFBTSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2pDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QixPQUFPO2dCQUNMLEtBQUssRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7Z0JBQ3JDLEtBQUs7Z0JBQ0wsT0FBTyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RFLGNBQWMsRUFBRSxLQUFLLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQzthQUM5QyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQ2YsT0FBTyxFQUFFLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3RELENBQUM7d0dBOUNVLGdCQUFnQjs0RkFBaEIsZ0JBQWdCLHFMQWZqQjs7Ozs7Ozs7Ozs7OztHQWFULCtGQWZTLFlBQVk7OzRGQWlCWCxnQkFBZ0I7a0JBckI1QixTQUFTOytCQUNFLGdCQUFnQixjQUVkLElBQUksV0FDUCxDQUFDLFlBQVksQ0FBQyxtQkFDTix1QkFBdUIsQ0FBQyxNQUFNLFlBQ3JDOzs7Ozs7Ozs7Ozs7O0dBYVQ7OEJBZ0JRLElBQUk7c0JBQVosS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBPbkNoYW5nZXMsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGNuIH0gZnJvbSAnLi91dGlscy9jbic7XG5cbi8qKiBPbmUgcmVzb2x2ZWQgcm93OiBpdHMgbGFiZWwsIGl0cyB2YWx1ZSwgYW5kIGl0cyBzaGFyZSBvZiB0aGUgbGlzdCdzIGxhcmdlc3QgdmFsdWUuICovXG5leHBvcnQgaW50ZXJmYWNlIEJhckxpc3RSb3cge1xuICBsYWJlbDogc3RyaW5nO1xuICB2YWx1ZTogbnVtYmVyO1xuICBwZXJjZW50OiBudW1iZXI7XG4gIGZvcm1hdHRlZFZhbHVlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSByYW5rZWQgbGlzdCBvZiBob3Jpem9udGFsIGJhcnMg4oCUIGxhYmVsIGxlZnQsIHZhbHVlIHJpZ2h0LCBiYXIgd2lkdGhcbiAqIHNjYWxlZCB0byBlYWNoIHJvdydzIHNoYXJlIG9mIHRoZSBsaXN0J3MgbGFyZ2VzdCB2YWx1ZS4gVW5saWtlIGEgY2hhcnRcbiAqIHNlcmllcyBvciBhIGNhdGVnb3J5IGJhcidzIHNlZ21lbnRzLCBldmVyeSBiYXIgaXMgdGhlIHNhbWUgYWNjZW50OiByYW5rIGlzXG4gKiBjYXJyaWVkIGJ5IGxlbmd0aCwgbm90IGJ5IGEgY2F0ZWdvcmljYWwgcGFsZXR0ZS5cbiAqIEBuZXdcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtYmFyLWxpc3QnLFxuICBzdHlsZXM6IFsnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgfSddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBbY2xhc3NdPVwiY29tcHV0ZWRDbGFzc1wiPlxuICAgICAgPGRpdlxuICAgICAgICAqbmdGb3I9XCJsZXQgcm93IG9mIHJvd3M7IHRyYWNrQnk6IHRyYWNrQnlJbmRleFwiXG4gICAgICAgIGNsYXNzPVwicmVsYXRpdmUgZmxleCBpdGVtcy1jZW50ZXIgb3ZlcmZsb3ctaGlkZGVuIHJvdW5kZWQtc21cIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgaW5zZXQteS0wIGxlZnQtMCByb3VuZGVkLXNtIGJnLXByaW1hcnkvMTVcIiBbc3R5bGUud2lkdGguJV09XCJyb3cucGVyY2VudFwiPjwvZGl2PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInJlbGF0aXZlIHotMTAgdHJ1bmNhdGUgcHgtMiBweS0xLjUgdGV4dC1zbSB0ZXh0LWZvcmVncm91bmRcIj57eyByb3cubGFiZWwgfX08L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwicmVsYXRpdmUgei0xMCBtbC1hdXRvIHNocmluay0wIHB4LTIgcHktMS41IHRleHQtc20gZm9udC1tZWRpdW0gdGFidWxhci1udW1zIHRleHQtZm9yZWdyb3VuZFwiPlxuICAgICAgICAgIHt7IHJvdy5mb3JtYXR0ZWRWYWx1ZSB9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgQmFyTGlzdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qKlxuICAgKiBBbmd1bGFyIHdyaXRlcyBhIGJvdW5kIGBjbGFzc2AgaW5wdXQgdGhyb3VnaCBpdHMgc3R5bGluZyBwYXRoLCB3aGljaCBkb2VzXG4gICAqIG5vdCBtYXJrIGFuIE9uUHVzaCBjb21wb25lbnQgZGlydHkg4oCUIHdpdGhvdXQgdGhpcyBob29rIHRoZSBjb21wb25lbnQga2VlcHNcbiAgICogcmVuZGVyaW5nIHRoZSBjbGFzcyBpdCB3YXMgYm9ybiB3aXRoLlxuICAgKi9cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKiogSWRlbnRpdHkgZm9yIGAqbmdGb3JgLCBzbyBhIHJlZHJhdyBwYXRjaGVzIG5vZGVzIGluc3RlYWQgb2YgcmVwbGFjaW5nIHRoZW0uICovXG4gIHRyYWNrQnlJbmRleCA9IChpbmRleDogbnVtYmVyKTogbnVtYmVyID0+IGluZGV4O1xuXG4gIC8qKiBSb3dzIHRvIHJhbmssIGluIHRoZSBvcmRlciB0aGV5IHNob3VsZCBiZSBkcmF3bi4gQGRlZmF1bHQgW10gKi9cbiAgQElucHV0KCkgZGF0YTogUmVjb3JkPHN0cmluZywgYW55PltdID0gW107XG4gIC8qKiBSb3cga2V5IGhvbGRpbmcgZWFjaCByb3cncyBsYWJlbC4gQGRlZmF1bHQgJ2xhYmVsJyAqL1xuICBASW5wdXQoKSBsYWJlbEtleSA9ICdsYWJlbCc7XG4gIC8qKiBSb3cga2V5IGhvbGRpbmcgZWFjaCByb3cncyBudW1lcmljIHZhbHVlLiBAZGVmYXVsdCAndmFsdWUnICovXG4gIEBJbnB1dCgpIHZhbHVlS2V5ID0gJ3ZhbHVlJztcbiAgLyoqIEV4dHJhIFRhaWx3aW5kIGNsYXNzZXMgbWVyZ2VkIG9udG8gdGhlIGxpc3QgdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgY2xhc3MgPSAnJztcblxuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgZ2V0IHJvd3MoKTogQmFyTGlzdFJvd1tdIHtcbiAgICBjb25zdCByb3dzID0gdGhpcy5kYXRhID8/IFtdO1xuICAgIGNvbnN0IHZhbHVlcyA9IHJvd3MubWFwKChyb3cpID0+IHtcbiAgICAgIGNvbnN0IG51bSA9IE51bWJlcihyb3c/Llt0aGlzLnZhbHVlS2V5XSk7XG4gICAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG51bSkgPyBudW0gOiAwO1xuICAgIH0pO1xuICAgIGNvbnN0IG1heCA9IHZhbHVlcy5yZWR1Y2UoKG0sIHYpID0+IE1hdGgubWF4KG0sIHYpLCAwKTtcblxuICAgIHJldHVybiByb3dzLm1hcCgocm93LCBpKSA9PiB7XG4gICAgICBjb25zdCByYXcgPSByb3c/Llt0aGlzLmxhYmVsS2V5XTtcbiAgICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzW2ldO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbGFiZWw6IHJhdyA9PSBudWxsID8gJycgOiBTdHJpbmcocmF3KSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIHBlcmNlbnQ6IG1heCA+IDAgPyBNYXRoLm1heCgwLCBNYXRoLm1pbigxMDAsICh2YWx1ZSAvIG1heCkgKiAxMDApKSA6IDAsXG4gICAgICAgIGZvcm1hdHRlZFZhbHVlOiB2YWx1ZS50b0xvY2FsZVN0cmluZygnZW4tVVMnKSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRDbGFzcygpIHtcbiAgICByZXR1cm4gY24oJ2ZsZXggdy1mdWxsIGZsZXgtY29sIGdhcC0xJywgdGhpcy5jbGFzcyk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,130 @@
1
+ import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { cn } from './utils/cn';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ /**
7
+ * A single bar split into proportional, labelled ranges — for showing where
8
+ * one value falls against a scale made of categories (a credit score inside
9
+ * "Poor / Fair / Good / Excellent", latency inside "Fast / OK / Slow").
10
+ *
11
+ * Segments take the chart palette by position, since a category bar has no
12
+ * stable per-render identity to key colour off the way a chart series does —
13
+ * pass `colors` to override.
14
+ * @new
15
+ */
16
+ export class CategoryBarComponent {
17
+ /**
18
+ * Angular writes a bound `class` input through its styling path, which does
19
+ * not mark an OnPush component dirty — without this hook the component keeps
20
+ * rendering the class it was born with.
21
+ */
22
+ ngOnChanges() {
23
+ this.cdr.markForCheck();
24
+ }
25
+ /** Identity for `*ngFor`, so a redraw patches nodes instead of replacing them. */
26
+ trackByIndex = (index) => index;
27
+ /** Width of each segment. Values that are not finite and greater than zero are dropped. @default [] */
28
+ values = [];
29
+ /** Name for each segment, used in the accessible summary and as a title tooltip. @default [] */
30
+ labels = [];
31
+ /** Paint for each segment, by index. Falls back to the chart palette --chart-1 through --chart-5. @default [] */
32
+ colors = [];
33
+ /** Position of the pointer, 0-100 on the same scale the segments sum to. Omit to draw no pointer. @default null */
34
+ markerValue = null;
35
+ /** Accessible name, prefixed onto the sr-only summary of segments and marker. @default '' */
36
+ ariaLabel = '';
37
+ /** Extra Tailwind classes merged onto the bar via `cn()` (last-wins). */
38
+ class = '';
39
+ cdr = inject(ChangeDetectorRef);
40
+ get total() {
41
+ return this.values.reduce((sum, v) => (Number.isFinite(v) && v > 0 ? sum + v : sum), 0);
42
+ }
43
+ get segments() {
44
+ const total = this.total;
45
+ if (total <= 0)
46
+ return [];
47
+ return this.values
48
+ .map((value, i) => ({ value, i }))
49
+ .filter(({ value }) => Number.isFinite(value) && value > 0)
50
+ .map(({ value, i }) => ({
51
+ label: this.labels[i] ?? '',
52
+ value,
53
+ percent: (value / total) * 100,
54
+ color: this.colors[i] || 'rgb(var(--chart-' + ((i % 5) + 1) + '))',
55
+ }));
56
+ }
57
+ get clampedMarker() {
58
+ if (this.markerValue == null || !Number.isFinite(this.markerValue))
59
+ return null;
60
+ return Math.min(100, Math.max(0, this.markerValue));
61
+ }
62
+ get summary() {
63
+ const parts = this.segments.map((s) => (s.label ? s.label + ': ' : '') + s.percent.toFixed(0) + '%');
64
+ const marker = this.clampedMarker !== null ? ', current position ' + this.clampedMarker.toFixed(0) + '%' : '';
65
+ const prefix = this.ariaLabel ? this.ariaLabel + '. ' : '';
66
+ return prefix + parts.join(', ') + marker;
67
+ }
68
+ get computedClass() {
69
+ return cn('w-full', this.class);
70
+ }
71
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CategoryBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
72
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: CategoryBarComponent, isStandalone: true, selector: "tolle-category-bar", inputs: { values: "values", labels: "labels", colors: "colors", markerValue: "markerValue", ariaLabel: "ariaLabel", class: "class" }, usesOnChanges: true, ngImport: i0, template: `
73
+ <div [class]="computedClass">
74
+ <div class="relative flex w-full gap-0.5">
75
+ <div
76
+ *ngFor="let segment of segments; let i = index; trackBy: trackByIndex"
77
+ class="h-2 first:rounded-l-full last:rounded-r-full"
78
+ [style.width.%]="segment.percent"
79
+ [style.background]="segment.color"
80
+ [attr.title]="segment.label || null"
81
+ ></div>
82
+
83
+ <span
84
+ *ngIf="clampedMarker !== null"
85
+ class="absolute top-1/2 h-3 w-3 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-background bg-foreground shadow"
86
+ [style.left.%]="clampedMarker"
87
+ ></span>
88
+ </div>
89
+
90
+ <p class="sr-only">{{ summary }}</p>
91
+ </div>
92
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
93
+ }
94
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: CategoryBarComponent, decorators: [{
95
+ type: Component,
96
+ args: [{ selector: 'tolle-category-bar', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
97
+ <div [class]="computedClass">
98
+ <div class="relative flex w-full gap-0.5">
99
+ <div
100
+ *ngFor="let segment of segments; let i = index; trackBy: trackByIndex"
101
+ class="h-2 first:rounded-l-full last:rounded-r-full"
102
+ [style.width.%]="segment.percent"
103
+ [style.background]="segment.color"
104
+ [attr.title]="segment.label || null"
105
+ ></div>
106
+
107
+ <span
108
+ *ngIf="clampedMarker !== null"
109
+ class="absolute top-1/2 h-3 w-3 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-background bg-foreground shadow"
110
+ [style.left.%]="clampedMarker"
111
+ ></span>
112
+ </div>
113
+
114
+ <p class="sr-only">{{ summary }}</p>
115
+ </div>
116
+ `, styles: [":host{display:block}\n"] }]
117
+ }], propDecorators: { values: [{
118
+ type: Input
119
+ }], labels: [{
120
+ type: Input
121
+ }], colors: [{
122
+ type: Input
123
+ }], markerValue: [{
124
+ type: Input
125
+ }], ariaLabel: [{
126
+ type: Input
127
+ }], class: [{
128
+ type: Input
129
+ }] } });
130
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2F0ZWdvcnktYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvY2F0ZWdvcnktYmFyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBYSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEgsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxZQUFZLENBQUM7OztBQVVoQzs7Ozs7Ozs7O0dBU0c7QUE2QkgsTUFBTSxPQUFPLG9CQUFvQjtJQUMvQjs7OztPQUlHO0lBQ0gsV0FBVztRQUNULElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELGtGQUFrRjtJQUNsRixZQUFZLEdBQUcsQ0FBQyxLQUFhLEVBQVUsRUFBRSxDQUFDLEtBQUssQ0FBQztJQUVoRCx1R0FBdUc7SUFDOUYsTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUMvQixnR0FBZ0c7SUFDdkYsTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUMvQixpSEFBaUg7SUFDeEcsTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUMvQixtSEFBbUg7SUFDMUcsV0FBVyxHQUFrQixJQUFJLENBQUM7SUFDM0MsNkZBQTZGO0lBQ3BGLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDeEIseUVBQXlFO0lBQ2hFLEtBQUssR0FBRyxFQUFFLENBQUM7SUFFSCxHQUFHLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFFakQsSUFBWSxLQUFLO1FBQ2YsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMxRixDQUFDO0lBRUQsSUFBSSxRQUFRO1FBQ1YsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUN6QixJQUFJLEtBQUssSUFBSSxDQUFDO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFFMUIsT0FBTyxJQUFJLENBQUMsTUFBTTthQUNmLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUNqQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7YUFDMUQsR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdEIsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRTtZQUMzQixLQUFLO1lBQ0wsT0FBTyxFQUFFLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLEdBQUc7WUFDOUIsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksa0JBQWtCLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJO1NBQ25FLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQztJQUVELElBQUksYUFBYTtRQUNmLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUNoRixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQ3RELENBQUM7SUFFRCxJQUFJLE9BQU87UUFDVCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDckcsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzlHLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDM0QsT0FBTyxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUM7SUFDNUMsQ0FBQztJQUVELElBQUksYUFBYTtRQUNmLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbEMsQ0FBQzt3R0E3RFUsb0JBQW9COzRGQUFwQixvQkFBb0IseU9BdEJyQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQlQsK0ZBdEJTLFlBQVk7OzRGQXdCWCxvQkFBb0I7a0JBNUJoQyxTQUFTOytCQUNFLG9CQUFvQixjQUVsQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLENBQUMsbUJBQ04sdUJBQXVCLENBQUMsTUFBTSxZQUNyQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQlQ7OEJBZ0JRLE1BQU07c0JBQWQsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsTUFBTTtzQkFBZCxLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxLQUFLO3NCQUFiLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIE9uQ2hhbmdlcywgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgY24gfSBmcm9tICcuL3V0aWxzL2NuJztcblxuLyoqIE9uZSByZXNvbHZlZCBzZWdtZW50OiBpdHMgc2hhcmUgb2YgdGhlIGJhcidzIHdpZHRoLCBpdHMgcGFpbnQsIGFuZCB0aGUgbnVtYmVycyBiZWhpbmQgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIENhdGVnb3J5QmFyU2VnbWVudCB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHZhbHVlOiBudW1iZXI7XG4gIHBlcmNlbnQ6IG51bWJlcjtcbiAgY29sb3I6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIHNpbmdsZSBiYXIgc3BsaXQgaW50byBwcm9wb3J0aW9uYWwsIGxhYmVsbGVkIHJhbmdlcyDigJQgZm9yIHNob3dpbmcgd2hlcmVcbiAqIG9uZSB2YWx1ZSBmYWxscyBhZ2FpbnN0IGEgc2NhbGUgbWFkZSBvZiBjYXRlZ29yaWVzIChhIGNyZWRpdCBzY29yZSBpbnNpZGVcbiAqIFwiUG9vciAvIEZhaXIgLyBHb29kIC8gRXhjZWxsZW50XCIsIGxhdGVuY3kgaW5zaWRlIFwiRmFzdCAvIE9LIC8gU2xvd1wiKS5cbiAqXG4gKiBTZWdtZW50cyB0YWtlIHRoZSBjaGFydCBwYWxldHRlIGJ5IHBvc2l0aW9uLCBzaW5jZSBhIGNhdGVnb3J5IGJhciBoYXMgbm9cbiAqIHN0YWJsZSBwZXItcmVuZGVyIGlkZW50aXR5IHRvIGtleSBjb2xvdXIgb2ZmIHRoZSB3YXkgYSBjaGFydCBzZXJpZXMgZG9lcyDigJRcbiAqIHBhc3MgYGNvbG9yc2AgdG8gb3ZlcnJpZGUuXG4gKiBAbmV3XG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RvbGxlLWNhdGVnb3J5LWJhcicsXG4gIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IFtjbGFzc109XCJjb21wdXRlZENsYXNzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwicmVsYXRpdmUgZmxleCB3LWZ1bGwgZ2FwLTAuNVwiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgKm5nRm9yPVwibGV0IHNlZ21lbnQgb2Ygc2VnbWVudHM7IGxldCBpID0gaW5kZXg7IHRyYWNrQnk6IHRyYWNrQnlJbmRleFwiXG4gICAgICAgICAgY2xhc3M9XCJoLTIgZmlyc3Q6cm91bmRlZC1sLWZ1bGwgbGFzdDpyb3VuZGVkLXItZnVsbFwiXG4gICAgICAgICAgW3N0eWxlLndpZHRoLiVdPVwic2VnbWVudC5wZXJjZW50XCJcbiAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZF09XCJzZWdtZW50LmNvbG9yXCJcbiAgICAgICAgICBbYXR0ci50aXRsZV09XCJzZWdtZW50LmxhYmVsIHx8IG51bGxcIlxuICAgICAgICA+PC9kaXY+XG5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICAqbmdJZj1cImNsYW1wZWRNYXJrZXIgIT09IG51bGxcIlxuICAgICAgICAgIGNsYXNzPVwiYWJzb2x1dGUgdG9wLTEvMiBoLTMgdy0zIC10cmFuc2xhdGUteC0xLzIgLXRyYW5zbGF0ZS15LTEvMiByb3VuZGVkLWZ1bGwgYm9yZGVyLTIgYm9yZGVyLWJhY2tncm91bmQgYmctZm9yZWdyb3VuZCBzaGFkb3dcIlxuICAgICAgICAgIFtzdHlsZS5sZWZ0LiVdPVwiY2xhbXBlZE1hcmtlclwiXG4gICAgICAgID48L3NwYW4+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPHAgY2xhc3M9XCJzci1vbmx5XCI+e3sgc3VtbWFyeSB9fTwvcD5cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgQ2F0ZWdvcnlCYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICAvKipcbiAgICogQW5ndWxhciB3cml0ZXMgYSBib3VuZCBgY2xhc3NgIGlucHV0IHRocm91Z2ggaXRzIHN0eWxpbmcgcGF0aCwgd2hpY2ggZG9lc1xuICAgKiBub3QgbWFyayBhbiBPblB1c2ggY29tcG9uZW50IGRpcnR5IOKAlCB3aXRob3V0IHRoaXMgaG9vayB0aGUgY29tcG9uZW50IGtlZXBzXG4gICAqIHJlbmRlcmluZyB0aGUgY2xhc3MgaXQgd2FzIGJvcm4gd2l0aC5cbiAgICovXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqIElkZW50aXR5IGZvciBgKm5nRm9yYCwgc28gYSByZWRyYXcgcGF0Y2hlcyBub2RlcyBpbnN0ZWFkIG9mIHJlcGxhY2luZyB0aGVtLiAqL1xuICB0cmFja0J5SW5kZXggPSAoaW5kZXg6IG51bWJlcik6IG51bWJlciA9PiBpbmRleDtcblxuICAvKiogV2lkdGggb2YgZWFjaCBzZWdtZW50LiBWYWx1ZXMgdGhhdCBhcmUgbm90IGZpbml0ZSBhbmQgZ3JlYXRlciB0aGFuIHplcm8gYXJlIGRyb3BwZWQuIEBkZWZhdWx0IFtdICovXG4gIEBJbnB1dCgpIHZhbHVlczogbnVtYmVyW10gPSBbXTtcbiAgLyoqIE5hbWUgZm9yIGVhY2ggc2VnbWVudCwgdXNlZCBpbiB0aGUgYWNjZXNzaWJsZSBzdW1tYXJ5IGFuZCBhcyBhIHRpdGxlIHRvb2x0aXAuIEBkZWZhdWx0IFtdICovXG4gIEBJbnB1dCgpIGxhYmVsczogc3RyaW5nW10gPSBbXTtcbiAgLyoqIFBhaW50IGZvciBlYWNoIHNlZ21lbnQsIGJ5IGluZGV4LiBGYWxscyBiYWNrIHRvIHRoZSBjaGFydCBwYWxldHRlIC0tY2hhcnQtMSB0aHJvdWdoIC0tY2hhcnQtNS4gQGRlZmF1bHQgW10gKi9cbiAgQElucHV0KCkgY29sb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAvKiogUG9zaXRpb24gb2YgdGhlIHBvaW50ZXIsIDAtMTAwIG9uIHRoZSBzYW1lIHNjYWxlIHRoZSBzZWdtZW50cyBzdW0gdG8uIE9taXQgdG8gZHJhdyBubyBwb2ludGVyLiBAZGVmYXVsdCBudWxsICovXG4gIEBJbnB1dCgpIG1hcmtlclZhbHVlOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIEFjY2Vzc2libGUgbmFtZSwgcHJlZml4ZWQgb250byB0aGUgc3Itb25seSBzdW1tYXJ5IG9mIHNlZ21lbnRzIGFuZCBtYXJrZXIuIEBkZWZhdWx0ICcnICovXG4gIEBJbnB1dCgpIGFyaWFMYWJlbCA9ICcnO1xuICAvKiogRXh0cmEgVGFpbHdpbmQgY2xhc3NlcyBtZXJnZWQgb250byB0aGUgYmFyIHZpYSBgY24oKWAgKGxhc3Qtd2lucykuICovXG4gIEBJbnB1dCgpIGNsYXNzID0gJyc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjZHIgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuXG4gIHByaXZhdGUgZ2V0IHRvdGFsKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWVzLnJlZHVjZSgoc3VtLCB2KSA9PiAoTnVtYmVyLmlzRmluaXRlKHYpICYmIHYgPiAwID8gc3VtICsgdiA6IHN1bSksIDApO1xuICB9XG5cbiAgZ2V0IHNlZ21lbnRzKCk6IENhdGVnb3J5QmFyU2VnbWVudFtdIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMudG90YWw7XG4gICAgaWYgKHRvdGFsIDw9IDApIHJldHVybiBbXTtcblxuICAgIHJldHVybiB0aGlzLnZhbHVlc1xuICAgICAgLm1hcCgodmFsdWUsIGkpID0+ICh7IHZhbHVlLCBpIH0pKVxuICAgICAgLmZpbHRlcigoeyB2YWx1ZSB9KSA9PiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpICYmIHZhbHVlID4gMClcbiAgICAgIC5tYXAoKHsgdmFsdWUsIGkgfSkgPT4gKHtcbiAgICAgICAgbGFiZWw6IHRoaXMubGFiZWxzW2ldID8/ICcnLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgcGVyY2VudDogKHZhbHVlIC8gdG90YWwpICogMTAwLFxuICAgICAgICBjb2xvcjogdGhpcy5jb2xvcnNbaV0gfHwgJ3JnYih2YXIoLS1jaGFydC0nICsgKChpICUgNSkgKyAxKSArICcpKScsXG4gICAgICB9KSk7XG4gIH1cblxuICBnZXQgY2xhbXBlZE1hcmtlcigpOiBudW1iZXIgfCBudWxsIHtcbiAgICBpZiAodGhpcy5tYXJrZXJWYWx1ZSA9PSBudWxsIHx8ICFOdW1iZXIuaXNGaW5pdGUodGhpcy5tYXJrZXJWYWx1ZSkpIHJldHVybiBudWxsO1xuICAgIHJldHVybiBNYXRoLm1pbigxMDAsIE1hdGgubWF4KDAsIHRoaXMubWFya2VyVmFsdWUpKTtcbiAgfVxuXG4gIGdldCBzdW1tYXJ5KCk6IHN0cmluZyB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnNlZ21lbnRzLm1hcCgocykgPT4gKHMubGFiZWwgPyBzLmxhYmVsICsgJzogJyA6ICcnKSArIHMucGVyY2VudC50b0ZpeGVkKDApICsgJyUnKTtcbiAgICBjb25zdCBtYXJrZXIgPSB0aGlzLmNsYW1wZWRNYXJrZXIgIT09IG51bGwgPyAnLCBjdXJyZW50IHBvc2l0aW9uICcgKyB0aGlzLmNsYW1wZWRNYXJrZXIudG9GaXhlZCgwKSArICclJyA6ICcnO1xuICAgIGNvbnN0IHByZWZpeCA9IHRoaXMuYXJpYUxhYmVsID8gdGhpcy5hcmlhTGFiZWwgKyAnLiAnIDogJyc7XG4gICAgcmV0dXJuIHByZWZpeCArIHBhcnRzLmpvaW4oJywgJykgKyBtYXJrZXI7XG4gIH1cblxuICBnZXQgY29tcHV0ZWRDbGFzcygpIHtcbiAgICByZXR1cm4gY24oJ3ctZnVsbCcsIHRoaXMuY2xhc3MpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,120 @@
1
+ import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { ChartComponent, ChartLineComponent, ChartAreaComponent, ChartBarComponent, } from './chart.component';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ /**
7
+ * A minimal inline chart: one series, no grid, no axes, no legend — sized to
8
+ * sit next to a number in a table cell or a stat card. A thin composition
9
+ * over `tolle-chart`; it draws nothing of its own and inherits `--chart-1`
10
+ * the same way any other single-series chart in this library does.
11
+ * @new
12
+ */
13
+ export class ChartSparkComponent {
14
+ /**
15
+ * Angular writes a bound `class` input through its styling path, which does
16
+ * not mark an OnPush component dirty — without this hook the component keeps
17
+ * rendering the class it was born with.
18
+ */
19
+ ngOnChanges() {
20
+ this.cdr.markForCheck();
21
+ }
22
+ /** Rows to plot, in x order. @default [] */
23
+ data = [];
24
+ /** Row key holding each row's numeric value. @default 'value' */
25
+ valueKey = 'value';
26
+ /** Row key holding each row's x position. Only matters once `hover` is on. @default '' */
27
+ xKey = '';
28
+ /** Which mark to draw. @default 'line' */
29
+ type = 'line';
30
+ /** Interpolation for line/area. @default 'linear' */
31
+ curve = 'linear';
32
+ /** Largest bar thickness in px, used when `type` is 'bar'. @default 6 */
33
+ maxBarWidth = 6;
34
+ /** Height in px. @default 32 */
35
+ height = 32;
36
+ /** Renders the crosshair, hit layer and tooltip. @default false */
37
+ hover = false;
38
+ /** Shows the data table instead of leaving it visually hidden. @default false */
39
+ showTable = false;
40
+ /** Accessible name, used as the svg <title>. @default '' */
41
+ ariaLabel = '';
42
+ /** Longer summary used as the svg <desc>. Falls back to `ariaLabel`. @default '' */
43
+ description = '';
44
+ /** Space reserved around the plot — a sparkline has no axis labels to fit. @default { top: 2, right: 2, bottom: 2, left: 2 } */
45
+ margin = { top: 2, right: 2, bottom: 2, left: 2 };
46
+ /** Extra Tailwind classes merged onto the chart via `cn()` (last-wins). */
47
+ class = '';
48
+ cdr = inject(ChangeDetectorRef);
49
+ /** Always exactly one series, reading `valueKey` off each row. */
50
+ get series() {
51
+ return [{ key: this.valueKey, label: this.ariaLabel || this.valueKey }];
52
+ }
53
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChartSparkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
54
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChartSparkComponent, isStandalone: true, selector: "tolle-chart-spark", inputs: { data: "data", valueKey: "valueKey", xKey: "xKey", type: "type", curve: "curve", maxBarWidth: "maxBarWidth", height: "height", hover: "hover", showTable: "showTable", ariaLabel: "ariaLabel", description: "description", margin: "margin", class: "class" }, usesOnChanges: true, ngImport: i0, template: `
55
+ <tolle-chart
56
+ [class]="class"
57
+ [data]="data"
58
+ [series]="series"
59
+ [xKey]="xKey"
60
+ [height]="height"
61
+ [margin]="margin"
62
+ [hover]="hover"
63
+ [showTable]="showTable"
64
+ [ariaLabel]="ariaLabel"
65
+ [description]="description"
66
+ >
67
+ <svg:g *ngIf="type === 'line'" tolle-chart-line [seriesKey]="valueKey" [curve]="curve"></svg:g>
68
+ <svg:g *ngIf="type === 'area'" tolle-chart-area [seriesKey]="valueKey" [curve]="curve"></svg:g>
69
+ <svg:g *ngIf="type === 'bar'" tolle-chart-bar [seriesKey]="valueKey" [maxWidth]="maxBarWidth"></svg:g>
70
+ </tolle-chart>
71
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChartComponent, selector: "tolle-chart", inputs: ["data", "series", "xKey", "height", "margin", "ariaLabel", "description", "stacked", "orientation", "hover", "showTable", "xHeader", "variant", "density", "class"], outputs: ["activeIndexChange"] }, { kind: "component", type: ChartLineComponent, selector: "svg:g[tolle-chart-line]", inputs: ["seriesKey", "curve", "showDots", "dotRadius", "class"] }, { kind: "component", type: ChartAreaComponent, selector: "svg:g[tolle-chart-area]", inputs: ["seriesKey", "curve", "fillOpacity", "class"] }, { kind: "component", type: ChartBarComponent, selector: "svg:g[tolle-chart-bar]", inputs: ["seriesKey", "radius", "maxWidth", "gap", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
72
+ }
73
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChartSparkComponent, decorators: [{
74
+ type: Component,
75
+ args: [{ selector: 'tolle-chart-spark', standalone: true, imports: [CommonModule, ChartComponent, ChartLineComponent, ChartAreaComponent, ChartBarComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
76
+ <tolle-chart
77
+ [class]="class"
78
+ [data]="data"
79
+ [series]="series"
80
+ [xKey]="xKey"
81
+ [height]="height"
82
+ [margin]="margin"
83
+ [hover]="hover"
84
+ [showTable]="showTable"
85
+ [ariaLabel]="ariaLabel"
86
+ [description]="description"
87
+ >
88
+ <svg:g *ngIf="type === 'line'" tolle-chart-line [seriesKey]="valueKey" [curve]="curve"></svg:g>
89
+ <svg:g *ngIf="type === 'area'" tolle-chart-area [seriesKey]="valueKey" [curve]="curve"></svg:g>
90
+ <svg:g *ngIf="type === 'bar'" tolle-chart-bar [seriesKey]="valueKey" [maxWidth]="maxBarWidth"></svg:g>
91
+ </tolle-chart>
92
+ `, styles: [":host{display:block}\n"] }]
93
+ }], propDecorators: { data: [{
94
+ type: Input
95
+ }], valueKey: [{
96
+ type: Input
97
+ }], xKey: [{
98
+ type: Input
99
+ }], type: [{
100
+ type: Input
101
+ }], curve: [{
102
+ type: Input
103
+ }], maxBarWidth: [{
104
+ type: Input
105
+ }], height: [{
106
+ type: Input
107
+ }], hover: [{
108
+ type: Input
109
+ }], showTable: [{
110
+ type: Input
111
+ }], ariaLabel: [{
112
+ type: Input
113
+ }], description: [{
114
+ type: Input
115
+ }], margin: [{
116
+ type: Input
117
+ }], class: [{
118
+ type: Input
119
+ }] } });
120
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhcnQtc3BhcmsuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi9jaGFydC1zcGFyay5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQWEsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hILE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsY0FBYyxFQUNkLGtCQUFrQixFQUNsQixrQkFBa0IsRUFDbEIsaUJBQWlCLEdBR2xCLE1BQU0sbUJBQW1CLENBQUM7OztBQUUzQjs7Ozs7O0dBTUc7QUEwQkgsTUFBTSxPQUFPLG1CQUFtQjtJQUM5Qjs7OztPQUlHO0lBQ0gsV0FBVztRQUNULElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELDRDQUE0QztJQUNuQyxJQUFJLEdBQTBCLEVBQUUsQ0FBQztJQUMxQyxpRUFBaUU7SUFDeEQsUUFBUSxHQUFHLE9BQU8sQ0FBQztJQUM1QiwwRkFBMEY7SUFDakYsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNuQiwwQ0FBMEM7SUFDakMsSUFBSSxHQUE0QixNQUFNLENBQUM7SUFDaEQscURBQXFEO0lBQzVDLEtBQUssR0FBd0IsUUFBUSxDQUFDO0lBQy9DLHlFQUF5RTtJQUNoRSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLGdDQUFnQztJQUN2QixNQUFNLEdBQUcsRUFBRSxDQUFDO0lBQ3JCLG1FQUFtRTtJQUMxRCxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLGlGQUFpRjtJQUN4RSxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQzNCLDREQUE0RDtJQUNuRCxTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ3hCLG9GQUFvRjtJQUMzRSxXQUFXLEdBQUcsRUFBRSxDQUFDO0lBQzFCLGdJQUFnSTtJQUN2SCxNQUFNLEdBQWdCLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQ3hFLDJFQUEyRTtJQUNsRSxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBRUgsR0FBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBRWpELGtFQUFrRTtJQUNsRSxJQUFJLE1BQU07UUFDUixPQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUMxRSxDQUFDO3dHQTFDVSxtQkFBbUI7NEZBQW5CLG1CQUFtQiwwV0FuQnBCOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCVCwrRkFuQlMsWUFBWSxtSUFBRSxjQUFjLHNRQUFFLGtCQUFrQixzSUFBRSxrQkFBa0IsNEhBQUUsaUJBQWlCOzs0RkFxQnRGLG1CQUFtQjtrQkF6Qi9CLFNBQVM7K0JBQ0UsbUJBQW1CLGNBRWpCLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsaUJBQWlCLENBQUMsbUJBQ2pGLHVCQUF1QixDQUFDLE1BQU0sWUFDckM7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJUOzhCQWFRLElBQUk7c0JBQVosS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsTUFBTTtzQkFBZCxLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUcsV0FBVztzQkFBbkIsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBPbkNoYW5nZXMsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENoYXJ0Q29tcG9uZW50LFxuICBDaGFydExpbmVDb21wb25lbnQsXG4gIENoYXJ0QXJlYUNvbXBvbmVudCxcbiAgQ2hhcnRCYXJDb21wb25lbnQsXG4gIHR5cGUgQ2hhcnRNYXJnaW4sXG4gIHR5cGUgQ2hhcnRTZXJpZXMsXG59IGZyb20gJy4vY2hhcnQuY29tcG9uZW50JztcblxuLyoqXG4gKiBBIG1pbmltYWwgaW5saW5lIGNoYXJ0OiBvbmUgc2VyaWVzLCBubyBncmlkLCBubyBheGVzLCBubyBsZWdlbmQg4oCUIHNpemVkIHRvXG4gKiBzaXQgbmV4dCB0byBhIG51bWJlciBpbiBhIHRhYmxlIGNlbGwgb3IgYSBzdGF0IGNhcmQuIEEgdGhpbiBjb21wb3NpdGlvblxuICogb3ZlciBgdG9sbGUtY2hhcnRgOyBpdCBkcmF3cyBub3RoaW5nIG9mIGl0cyBvd24gYW5kIGluaGVyaXRzIGAtLWNoYXJ0LTFgXG4gKiB0aGUgc2FtZSB3YXkgYW55IG90aGVyIHNpbmdsZS1zZXJpZXMgY2hhcnQgaW4gdGhpcyBsaWJyYXJ5IGRvZXMuXG4gKiBAbmV3XG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RvbGxlLWNoYXJ0LXNwYXJrJyxcbiAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogYmxvY2s7IH0nXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgQ2hhcnRDb21wb25lbnQsIENoYXJ0TGluZUNvbXBvbmVudCwgQ2hhcnRBcmVhQ29tcG9uZW50LCBDaGFydEJhckNvbXBvbmVudF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDx0b2xsZS1jaGFydFxuICAgICAgW2NsYXNzXT1cImNsYXNzXCJcbiAgICAgIFtkYXRhXT1cImRhdGFcIlxuICAgICAgW3Nlcmllc109XCJzZXJpZXNcIlxuICAgICAgW3hLZXldPVwieEtleVwiXG4gICAgICBbaGVpZ2h0XT1cImhlaWdodFwiXG4gICAgICBbbWFyZ2luXT1cIm1hcmdpblwiXG4gICAgICBbaG92ZXJdPVwiaG92ZXJcIlxuICAgICAgW3Nob3dUYWJsZV09XCJzaG93VGFibGVcIlxuICAgICAgW2FyaWFMYWJlbF09XCJhcmlhTGFiZWxcIlxuICAgICAgW2Rlc2NyaXB0aW9uXT1cImRlc2NyaXB0aW9uXCJcbiAgICA+XG4gICAgICA8c3ZnOmcgKm5nSWY9XCJ0eXBlID09PSAnbGluZSdcIiB0b2xsZS1jaGFydC1saW5lIFtzZXJpZXNLZXldPVwidmFsdWVLZXlcIiBbY3VydmVdPVwiY3VydmVcIj48L3N2ZzpnPlxuICAgICAgPHN2ZzpnICpuZ0lmPVwidHlwZSA9PT0gJ2FyZWEnXCIgdG9sbGUtY2hhcnQtYXJlYSBbc2VyaWVzS2V5XT1cInZhbHVlS2V5XCIgW2N1cnZlXT1cImN1cnZlXCI+PC9zdmc6Zz5cbiAgICAgIDxzdmc6ZyAqbmdJZj1cInR5cGUgPT09ICdiYXInXCIgdG9sbGUtY2hhcnQtYmFyIFtzZXJpZXNLZXldPVwidmFsdWVLZXlcIiBbbWF4V2lkdGhdPVwibWF4QmFyV2lkdGhcIj48L3N2ZzpnPlxuICAgIDwvdG9sbGUtY2hhcnQ+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIENoYXJ0U3BhcmtDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICAvKipcbiAgICogQW5ndWxhciB3cml0ZXMgYSBib3VuZCBgY2xhc3NgIGlucHV0IHRocm91Z2ggaXRzIHN0eWxpbmcgcGF0aCwgd2hpY2ggZG9lc1xuICAgKiBub3QgbWFyayBhbiBPblB1c2ggY29tcG9uZW50IGRpcnR5IOKAlCB3aXRob3V0IHRoaXMgaG9vayB0aGUgY29tcG9uZW50IGtlZXBzXG4gICAqIHJlbmRlcmluZyB0aGUgY2xhc3MgaXQgd2FzIGJvcm4gd2l0aC5cbiAgICovXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqIFJvd3MgdG8gcGxvdCwgaW4geCBvcmRlci4gQGRlZmF1bHQgW10gKi9cbiAgQElucHV0KCkgZGF0YTogUmVjb3JkPHN0cmluZywgYW55PltdID0gW107XG4gIC8qKiBSb3cga2V5IGhvbGRpbmcgZWFjaCByb3cncyBudW1lcmljIHZhbHVlLiBAZGVmYXVsdCAndmFsdWUnICovXG4gIEBJbnB1dCgpIHZhbHVlS2V5ID0gJ3ZhbHVlJztcbiAgLyoqIFJvdyBrZXkgaG9sZGluZyBlYWNoIHJvdydzIHggcG9zaXRpb24uIE9ubHkgbWF0dGVycyBvbmNlIGBob3ZlcmAgaXMgb24uIEBkZWZhdWx0ICcnICovXG4gIEBJbnB1dCgpIHhLZXkgPSAnJztcbiAgLyoqIFdoaWNoIG1hcmsgdG8gZHJhdy4gQGRlZmF1bHQgJ2xpbmUnICovXG4gIEBJbnB1dCgpIHR5cGU6ICdsaW5lJyB8ICdhcmVhJyB8ICdiYXInID0gJ2xpbmUnO1xuICAvKiogSW50ZXJwb2xhdGlvbiBmb3IgbGluZS9hcmVhLiBAZGVmYXVsdCAnbGluZWFyJyAqL1xuICBASW5wdXQoKSBjdXJ2ZTogJ2xpbmVhcicgfCAnc21vb3RoJyA9ICdsaW5lYXInO1xuICAvKiogTGFyZ2VzdCBiYXIgdGhpY2tuZXNzIGluIHB4LCB1c2VkIHdoZW4gYHR5cGVgIGlzICdiYXInLiBAZGVmYXVsdCA2ICovXG4gIEBJbnB1dCgpIG1heEJhcldpZHRoID0gNjtcbiAgLyoqIEhlaWdodCBpbiBweC4gQGRlZmF1bHQgMzIgKi9cbiAgQElucHV0KCkgaGVpZ2h0ID0gMzI7XG4gIC8qKiBSZW5kZXJzIHRoZSBjcm9zc2hhaXIsIGhpdCBsYXllciBhbmQgdG9vbHRpcC4gQGRlZmF1bHQgZmFsc2UgKi9cbiAgQElucHV0KCkgaG92ZXIgPSBmYWxzZTtcbiAgLyoqIFNob3dzIHRoZSBkYXRhIHRhYmxlIGluc3RlYWQgb2YgbGVhdmluZyBpdCB2aXN1YWxseSBoaWRkZW4uIEBkZWZhdWx0IGZhbHNlICovXG4gIEBJbnB1dCgpIHNob3dUYWJsZSA9IGZhbHNlO1xuICAvKiogQWNjZXNzaWJsZSBuYW1lLCB1c2VkIGFzIHRoZSBzdmcgPHRpdGxlPi4gQGRlZmF1bHQgJycgKi9cbiAgQElucHV0KCkgYXJpYUxhYmVsID0gJyc7XG4gIC8qKiBMb25nZXIgc3VtbWFyeSB1c2VkIGFzIHRoZSBzdmcgPGRlc2M+LiBGYWxscyBiYWNrIHRvIGBhcmlhTGFiZWxgLiBAZGVmYXVsdCAnJyAqL1xuICBASW5wdXQoKSBkZXNjcmlwdGlvbiA9ICcnO1xuICAvKiogU3BhY2UgcmVzZXJ2ZWQgYXJvdW5kIHRoZSBwbG90IOKAlCBhIHNwYXJrbGluZSBoYXMgbm8gYXhpcyBsYWJlbHMgdG8gZml0LiBAZGVmYXVsdCB7IHRvcDogMiwgcmlnaHQ6IDIsIGJvdHRvbTogMiwgbGVmdDogMiB9ICovXG4gIEBJbnB1dCgpIG1hcmdpbjogQ2hhcnRNYXJnaW4gPSB7IHRvcDogMiwgcmlnaHQ6IDIsIGJvdHRvbTogMiwgbGVmdDogMiB9O1xuICAvKiogRXh0cmEgVGFpbHdpbmQgY2xhc3NlcyBtZXJnZWQgb250byB0aGUgY2hhcnQgdmlhIGBjbigpYCAobGFzdC13aW5zKS4gKi9cbiAgQElucHV0KCkgY2xhc3MgPSAnJztcblxuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgLyoqIEFsd2F5cyBleGFjdGx5IG9uZSBzZXJpZXMsIHJlYWRpbmcgYHZhbHVlS2V5YCBvZmYgZWFjaCByb3cuICovXG4gIGdldCBzZXJpZXMoKTogQ2hhcnRTZXJpZXNbXSB7XG4gICAgcmV0dXJuIFt7IGtleTogdGhpcy52YWx1ZUtleSwgbGFiZWw6IHRoaXMuYXJpYUxhYmVsIHx8IHRoaXMudmFsdWVLZXkgfV07XG4gIH1cbn1cbiJdfQ==