{"_id":"ng-hub-ui-utils","_rev":"33-eadd79dd59d4a9e482748923faf795bf","name":"ng-hub-ui-utils","dist-tags":{"latest":"22.19.0"},"versions":{"1.0.0":{"name":"ng-hub-ui-utils","version":"1.0.0","_id":"ng-hub-ui-utils@1.0.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"dist":{"shasum":"cac9a472aeb4b778bbb633e0f8119280a13a9712","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-1.0.0.tgz","fileCount":24,"integrity":"sha512-7MzdgmMr07aDE34bm8w1Yj0AW02gutJS0AED2DFyEhnClyQKUsJahF5of87f7N9SU57GMUUpI6/5MqfnDKEUTw==","signatures":[{"sig":"MEUCIQD8BqfW0aWE1NiafvaoIPwC1Oj0eJs4QDlapI1/6TjzIgIgU5/mSGXdW1aH717zSUaaN5acwYSKtfnTsUS/HHbowvM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":142398},"module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"esm":"./esm2022/ng-hub-ui-utils.mjs","types":"./index.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs","esm2022":"./esm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"9fe26116810d1c23b90cfc713551ad4896181e02","typings":"index.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"_npmVersion":"10.2.4","description":"This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.0.","directories":{},"sideEffects":false,"_nodeVersion":"20.11.0","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=16.0.0","@angular/common":">=16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_1.0.0_1716758329682_0.834631760977899","host":"s3://npm-registry-packages"}},"1.1.0":{"name":"ng-hub-ui-utils","version":"1.1.0","_id":"ng-hub-ui-utils@1.1.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"dist":{"shasum":"d4abf2aa86369a081801c0a88de40217b103783a","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-1.1.0.tgz","fileCount":8,"integrity":"sha512-c9DH6/fZXzHhUhc0fZqFxxZ9Mep0ApYpm56c1jjkHP2rfTJj92JQS0ZgXtFHj1Jot7BY48IMwsBH5LuR2lVIGw==","signatures":[{"sig":"MEUCIQC9kffQmoytXuPwmP2qn7EP4v+ESWWPW3QsnqRFDTP24QIgaO4DlvOyGzaxeBz3+9UiqADE5fMqiXLCsFfas1ECGGY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":163549},"module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"82d0425db71341eb5ec5b143d4eccb9e62839a89","typings":"index.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"_npmVersion":"10.9.4","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/workflow/status/carlos","directories":{},"sideEffects":false,"_nodeVersion":"22.21.1","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=16.0.0","@angular/common":">=16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_1.1.0_1767280776110_0.02712518803812025","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"ng-hub-ui-utils","version":"1.2.0","_id":"ng-hub-ui-utils@1.2.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"dist":{"shasum":"312ece540585d538c0765e16024566d207f94c16","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-1.2.0.tgz","fileCount":8,"integrity":"sha512-7b1gErqZYdXyK//4jZlmibwsSIK5HNgdFHMGluWH23EG3AjUkn5e8obd1S+LFjZ7Qh2BvIHiRyhT+eRLyMKTeA==","signatures":[{"sig":"MEYCIQDb0bF2e/yk4hmnxCXU2VGiIuHgbZrNi538QgYlGuWHrgIhALm95vy24D5Lq6+x8ug00vni9j89WCNkI+pxmPPfoWjB","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":196350},"module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"82d0425db71341eb5ec5b143d4eccb9e62839a89","typings":"index.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"_npmVersion":"10.9.4","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/workflow/status/carlos","directories":{},"sideEffects":false,"_nodeVersion":"22.21.1","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=16.0.0","@angular/common":">=16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_1.2.0_1767360184541_0.0607831192367041","host":"s3://npm-registry-packages-npm-production"}},"22.1.0":{"name":"ng-hub-ui-utils","version":"22.1.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.1.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","dist":{"shasum":"3005d14e4806db2e91d989f76d74df560476f8c5","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.1.0.tgz","fileCount":8,"integrity":"sha512-ZE1TZlBDp4vcKxb8iVG5Esu/oxHGesElInySW7Y4vLTHrbLsXshy5ylNPfLGkt0oWoD8dDmH8sW9xH7n7iAwrA==","signatures":[{"sig":"MEYCIQCC7EkC/2B6qqufzpJUTGOjYLcFCyzLiwdfglua26cgawIhAOIePw5EzLX/bF5FDKv4dciH0h3U2BdHCzUj4yYRuha4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":218084},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"0f5c9ba530b7a4ee1c70a45626136aaf476b8012","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=16.0.0","@angular/common":">=16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.1.0_1782237348508_0.700138165440757","host":"s3://npm-registry-packages-npm-production"}},"22.2.0":{"name":"ng-hub-ui-utils","version":"22.2.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.2.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","dist":{"shasum":"dd30234a511ae9449d44d171d7bfd1301d62a574","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.2.0.tgz","fileCount":8,"integrity":"sha512-U6gQjzKDlt+dML0KWSUhI8ECdT5CfloYMPO0O3X0ky/7EXbyI8BAIhjfw8XQszwMQNQl3PzRDTXzkstS3z36IQ==","signatures":[{"sig":"MEYCIQCCckMNwzrni23C8d+ijAMcLX78ckfE5FFRbG70KXBXWwIhAP3ggHaQ2m6dcYsnPfeCNkHWgQQbxLylzpXXzDPXec5Q","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":252217},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"0a95de02e9adc2d2bab4a7985606ecbc087ead07","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=16.0.0","@angular/common":">=16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.2.0_1782304969016_0.8481870380048293","host":"s3://npm-registry-packages-npm-production"}},"22.3.1":{"name":"ng-hub-ui-utils","version":"22.3.1","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.3.1","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","dist":{"shasum":"53d91fd2bd4848c466a0529c69f692a9fa2d9ecb","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.3.1.tgz","fileCount":8,"integrity":"sha512-o9YZFVZ0Hpk1i7B6zSDwbNhYsJvnhPwLZ8Sktynpebw7sWjOhRcZSKjWJFnDoqpydW7jQ84KicXSh5R2DPAWtQ==","signatures":[{"sig":"MEYCIQCNOZR0wJPKNRYRn2E2SSo8j5SfuQQ3S/UXCAsCNflCUAIhAMFN5M9DDxHwuHA2WzLXerQFPlqr77F0RbaAh67AjDUs","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":341048},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"e90b3b43280014051546e80f8678bd59bc1ff009","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"_npmVersion":"11.13.0","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=16.0.0","@angular/common":">=16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.3.1_1782373709738_0.3987370914793722","host":"s3://npm-registry-packages-npm-production"}},"22.3.2":{"name":"ng-hub-ui-utils","version":"22.3.2","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.3.2","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"c1c5a4e748c6063d53096e62f893d58cbdca8f27","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.3.2.tgz","fileCount":8,"integrity":"sha512-JdH8bb8V+Nyue6hPu9dxcH8nxPlIrFAs6Gpz7O9EdKyFfGttXRtn7R+9UAxZhKCcKpMrtuOXhvvafyQAsTpLpw==","signatures":[{"sig":"MEQCIGa9POOMmo7p7E6QBr/5dYio6n4YHSyW7wOPkW6EciL3AiAYJMbUwPBc3xVuJpXnuBfHumwScgQm59eARXlUo5lt3Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":341205},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"b5261068777c3ea25b996a5de29157836db0ef5c","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"11.13.0","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.3.2_1782468013474_0.990330280679758","host":"s3://npm-registry-packages-npm-production"}},"22.4.0":{"name":"ng-hub-ui-utils","version":"22.4.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.4.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"8d253e25f7aabeeb3654d939939f67fe1cfd737f","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.4.0.tgz","fileCount":9,"integrity":"sha512-DAeYqfvPHRSLHiyHYbozZ7aAghvM2q7wDCaFhK3/LBCpk1qsU13mOt6URi3LEYoUFiV99nkSUWJdZBlpAh2L4g==","signatures":[{"sig":"MEUCICj8+xq2JNy/PbWSNrsuS/qUzheiYw4ufmRASpLgqdC5AiEAvbS+fl5Dn7MrdWndTVF/9kxePK6kpeDrI5AG3MalU0Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":339388},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"1a0802037d0d5a13975b7621b413943ea7785501","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"11.13.0","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.4.0_1782489327116_0.029940087094787904","host":"s3://npm-registry-packages-npm-production"}},"22.5.0":{"name":"ng-hub-ui-utils","version":"22.5.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.5.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"f25aed40937ff3197437275214ccb55bcc8c4d07","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.5.0.tgz","fileCount":9,"integrity":"sha512-sKTpjiluyjv5ZAEjc21RHQkey/2/0BOSkz0iekh4DvtHsLA9AyxeecPmAyndEmDHqAsi48mnOeIrOmvvrJbr/Q==","signatures":[{"sig":"MEQCIEGVMHs7o7envJm1f274kcFr5CrmNbd7oYSOz90jUXDgAiAqbSxFhgWciLxyyNrGlhiKUmQLvHrUByx9bLfwViXkoA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":353783},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"71930697f9a0fb514bc23e39f174896c938fd2df","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"11.13.0","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.5.0_1782731324896_0.8168383694381831","host":"s3://npm-registry-packages-npm-production"}},"22.6.0":{"name":"ng-hub-ui-utils","version":"22.6.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.6.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"ae7680ef36299336f35c9db6325b10d07e6db42c","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.6.0.tgz","fileCount":9,"integrity":"sha512-lun7O3AIcyM8c500QvcE0l33s+PriLILFlWRrDFgi/DYYsL3H80X0Hn7IrmYWt7sYV1SRxzQ+OzuU365YXl+Yg==","signatures":[{"sig":"MEQCIGImZiAENAA4vH0Efd9/q9TxT8ziX+RItlj0TKDHnttCAiAYviRRs52Rw95j6n3xmofrY+iohJ6w5eHVGBBVRnrNmg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":376343},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"e46d8efdbbc3e66df1457886a8959351eafbb250","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"11.13.0","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.6.0_1782808312430_0.3369859370378472","host":"s3://npm-registry-packages-npm-production"}},"22.7.0":{"name":"ng-hub-ui-utils","version":"22.7.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.7.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"025543bf65600337d1a4ccd339c61bb9bdd35a35","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.7.0.tgz","fileCount":9,"integrity":"sha512-QseUbPmmDjyFnTe8Wa39GwpNunkXufWRC1uWn+MelJ+Mc88LN7mHowD9lwLdWGIOWYlDmgbKTeHzeZLU9b6IVA==","signatures":[{"sig":"MEYCIQDFQL3zkTOsXlcqw3Eq+sROuBeaA1x04kOJ8FykUxL3GQIhAM3i+QaLepCnz15+tDf3yBpPiXM70R7ZpK0iiLMRhGVq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":382049},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"a6a6ba61f709a7c03e64a4e727ae29b2dc525e9e","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"11.13.0","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.7.0_1783437383975_0.7179091108357911","host":"s3://npm-registry-packages-npm-production"}},"22.7.1":{"name":"ng-hub-ui-utils","version":"22.7.1","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.7.1","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"6204d3a2813ac428181b78071dc85dbbf654d244","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.7.1.tgz","fileCount":9,"integrity":"sha512-37/1DvMn4c5UpXX1ROCFtkKa+DRg2tKWGB7rbOPl2hNtzmZaPIyMOvxTCYQOVDXdIXZiB23ZXGj72yF6L2ZJIQ==","signatures":[{"sig":"MEUCIQCOlYWdrgGDRW9SWIh5KKMHsyzwwv8AvfEVx+6Zu4sCIwIgARHIbXnV0D4AGrMFkK7HSzpgthv0cVUybbl/UYekaJg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":384244},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"4ed157f6c89007467dd7dc5d905c06fe64d0732e","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"11.13.0","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.7.1_1785233357773_0.5395570229857669","host":"s3://npm-registry-packages-npm-production"}},"22.7.2":{"name":"ng-hub-ui-utils","version":"22.7.2","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.7.2","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"74313297c6dd8316f0a3fa4b2de5ebbf2d24b738","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.7.2.tgz","fileCount":9,"integrity":"sha512-Hk7lp+No52Z6jg+C5LmSGAXaoOZrz+QKHy/QE+lkgOrEQToKTOpFMToi3k+pxVPAR6FLMlHtCMnYdvQMvWGpYQ==","signatures":[{"sig":"MEQCIF6R6WfaIgelCLyWQPz3oQDUMtwV3gt+EkEDHdRh9NL6AiBGjaMm3K93EoSVUwZknxzqTH7uYjKy2YIqF77sAEnxJA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":384255},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"61e38d920d3a24e82e463f9c01ed28c077634e16","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.7.2_1786202336305_0.3480638337200266","host":"s3://npm-registry-packages-npm-production"}},"22.8.0":{"name":"ng-hub-ui-utils","version":"22.8.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.8.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"c89d586ef554be58c77952e6c92a0c201cc90e20","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.8.0.tgz","fileCount":8,"integrity":"sha512-qb2ap6AgM+VfIok3PwHlpdWPPyO3uisxQos5Y0SXTi7+ycUhbdL7jTUT/cVcgxN5HpIySYmA4PwLFcK0LERzAg==","signatures":[{"sig":"MEYCIQDUZxWW+guD5rXeqXbA2YNBCZ7dS3sMbpXOQpTbL4NBpwIhAJQ0PuOFYCJJcAJ7VXS1N0tK1y/oJHHcQdkqruq7J/+s","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":322280},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"90fed07f1aba6f5c79dc574faa6c3699634aa908","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.8.0_1786692855507_0.44008197942326","host":"s3://npm-registry-packages-npm-production"}},"22.8.1":{"name":"ng-hub-ui-utils","version":"22.8.1","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.8.1","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"a97b1b19ef56065f669b9bd6d5f9ea72c1360db3","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.8.1.tgz","fileCount":9,"integrity":"sha512-62IyLmke7guD4Nf0Hn+5jTlbnHsWpacxoO+pSXTpris4bWEbjhbcqlts7OuZaEjz8PnPXo2raP9yU2Vf3bjJow==","signatures":[{"sig":"MEYCIQDbe4U0WwuS5NRri27VT/olHPMuYUoFQiCluflX59abLQIhAJwgLyWkt8pcNE18z3sbw5cyRgAl76ilrzbNpXpVsEsB","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":407744},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"997c46e34ce2077b5819b62ba8d8975464596771","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.8.1_1786801519434_0.8335114379617645","host":"s3://npm-registry-packages-npm-production"}},"22.9.0":{"name":"ng-hub-ui-utils","version":"22.9.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"_id":"ng-hub-ui-utils@22.9.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"0be20fc6da0994b0ab5ffe0a081b4adcc677321e","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.9.0.tgz","fileCount":9,"integrity":"sha512-Gpgx1rfRb+/VTbjhyqGyjc0huz7tGtA//N9/0gB/8vOlXbumq7Xxqn6ORHbYzJMasQpfkX/yCLeUcup0+Cnj6Q==","signatures":[{"sig":"MEUCIQDvK0R1E1LK50AmAdPJZsNegNQFCRzj/FCPtKibJn+YAwIgHReHuHbz/3vdXnknMgX6L3feYVlLjUU0aMQwQlWFZHM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":424211},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"cc6b187b7e30a52dd7202242b304b36479705a4a","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.9.0_1786956418713_0.3039014280497092","host":"s3://npm-registry-packages-npm-production"}},"22.9.1":{"name":"ng-hub-ui-utils","version":"22.9.1","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.9.1","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"59255948280f55375da4446d1c2eadbf583b052e","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.9.1.tgz","fileCount":9,"integrity":"sha512-EVUfPtqD32pNAv3PY7Jy1EVXokVUGKf6OKiVEkYFOMRlcW3wlrdf2zEdNu5xQtiVi9RtiTFWQR0d79p1l49uvA==","signatures":[{"sig":"MEUCIQCg/j7nKc8SFAVH0OK1RM9ZTQkWzbRmmgS/gX4Oqw16CQIgebmFMmvBXh9TBatl7ZMX9q5twVuzXA37nH5CpG2Sd1I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":424261},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"62106f6ac7533b472c2b8abe0bd5aa2b3e6b0b3f","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.9.1_1786970115791_0.7987531610668945","host":"s3://npm-registry-packages-npm-production"}},"22.9.2":{"name":"ng-hub-ui-utils","version":"22.9.2","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.9.2","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"42242fb285834a8647bb0e837dc849d305b98c50","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.9.2.tgz","fileCount":9,"integrity":"sha512-oxIpNrvZ/bBTtADN1LkGbWeEJF8ZNxwdNeNVXd+EXjJCai5B5CYE41kHsBGLsv2pm1eHKJoevo3JwbsOCyYhGg==","signatures":[{"sig":"MEUCIQDF/S0Q6Jq78XtHgpYRFTfnaYrJhtuXyPDwfPoLb0tvRgIgf3e004cXAeVCPdQ0CJgdTj7TPM5CiSoFiN7v3a6W4fE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":424252},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"34d3545af74dcc6f9aafd1096e24d067d777521d","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.9.2_1786982964628_0.6124923829357773","host":"s3://npm-registry-packages-npm-production"}},"22.9.3":{"name":"ng-hub-ui-utils","version":"22.9.3","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.9.3","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"08c69b1a7e5436f5b0638b13308c286c1d77a473","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.9.3.tgz","fileCount":8,"integrity":"sha512-4pWogDpsFyy8CwpTJaAj8xKz6fvB4OCwJc+7Q3iXe83pJ//DnC3kZl8yZuxlqgtnmNHqmbJ+jmcfVgh00JJNIA==","signatures":[{"sig":"MEUCICZit3DhTx6/5hzcez1sJs60N+ggmSDZrda8V4xXXM/dAiEAxcbnyXmYwbAlKNM/PVNh64QcuBCnS6igwLikuEHk0NE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":339385},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"64004f740e276a20dcdf750fe7dc29fb9a2bfb51","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.9.3_1787138352207_0.3569792195880135","host":"s3://npm-registry-packages-npm-production"}},"22.10.0":{"name":"ng-hub-ui-utils","version":"22.10.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.10.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"af4aa12085db615b8d96e7c87897e0700fcff4a2","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.10.0.tgz","fileCount":8,"integrity":"sha512-xSAIY/NabMwqJ8lkYsFFAKNpNc8TNBzE/wbFoNR2U6H77tH3LpwktwOXP/dFzh35qjinMCTki95Vl9YgGWcZ/Q==","signatures":[{"sig":"MEUCIBtUcq1azPD9Bk9LU+QWXpdtF2Zxv8WnLbZwPOyg/dzLAiEA57vRkXo11ldjbmlb/76TfAz8n7RVvCcuA85elloiQBk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":340538},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"d2d20bf87d3d2f1b761be50267f2c3369de7d46b","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.10.0_1787476224757_0.5094948007890467","host":"s3://npm-registry-packages-npm-production"}},"22.11.0":{"name":"ng-hub-ui-utils","version":"22.11.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.11.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"0b7550683c5e4884368079c48a841c0744215067","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.11.0.tgz","fileCount":8,"integrity":"sha512-uDAZwpX7Xs21HeER7cN7kAzLjJhmMw5u9Q/W2N6u+6Ubul8EQN0/nKZmYcNha0+sC6dwbUw59DR87qaQEZMvsQ==","signatures":[{"sig":"MEUCICIGvSIf8ZAdqxPnnihiwDWptvnndw+9iBdNX3Y8eclcAiEAzd1jY/Y5nw7ruXdhPc9dd0KXOjsAfrdVhjq5HKl5yNY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":359027},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"aa9dba10e9998b22b198a2a0d276cf183f0ace2c","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.11.0_1787749153500_0.6617436510165071","host":"s3://npm-registry-packages-npm-production"}},"22.11.1":{"name":"ng-hub-ui-utils","version":"22.11.1","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.11.1","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"c9671a9048451f149aa7f69493a3012f1d8e5b82","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.11.1.tgz","fileCount":8,"integrity":"sha512-xOBOsgaScMg+vgQXi2Fwr0E8ZvQdP3NYmZic+8R2iJ8B5kFdYZSquHXqJ4JryOe5gjhVS57HKFTYioZGJPeZpA==","signatures":[{"sig":"MEUCIQCDr87f32oo4FVNGZj6EFLj+2dTjQQ8Ajz+E5HR2MvDAwIgabAuOCVEpKk9EeLvT2Kr4SpDf5q19PZl5OhZqpyzVdw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":359045},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"885bf80a8b95464bfd98db9649de95144aaf8c60","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.11.1_1788276052141_0.47292012658810667","host":"s3://npm-registry-packages-npm-production"}},"22.12.0":{"name":"ng-hub-ui-utils","version":"22.12.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.12.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"3287da009eb03b3afd9507da80c71e541a8c7a60","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.12.0.tgz","fileCount":8,"integrity":"sha512-8D7yk1Pd/B/Q09o8e4nex32O50wViOZCk4j/gNRfGuyARA1lmn8gmidIZKJ98VYo56vgYUj5TsOU+j/Lhy84DA==","signatures":[{"sig":"MEYCIQDQfSOztJwZ3NPhupfq8+bdM0wnnhnoYuXQs+11ulO9wgIhAIy2RXQ53UcmZ5MneiUbGuLh33uak17S6Jt3XqBPRsrJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":435154},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"18495a569f6e5cbfacdfb3e0dc2cd9c7e7c56fbf","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.12.0_1788436406548_0.18224016309056013","host":"s3://npm-registry-packages-npm-production"}},"22.12.1":{"name":"ng-hub-ui-utils","version":"22.12.1","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.12.1","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"986c5812e9e5c6ee398deba177a75e462b74247b","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.12.1.tgz","fileCount":8,"integrity":"sha512-ZZ/fobqStXvDd5fa0xXNYdZk1hl5WIGPrXc2e4zPxoASoCWpICn/7GbTeQnVYKp4HI2y7youZ5tM7gFl61mQew==","signatures":[{"sig":"MEQCIFTqZSV10wzF3EPSO9iDvrCH+v0VHV+iRHmOygSKDRKDAiB8jWF3PTDjc+jVyF0yaRd4l9skVvLuMejX0l2HwfA64Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCOTVe5E09HnPpm6wL2dlakPp7FR/Q5GzhG9P71YMWetwIgcyc2wCvDztl8AJEFSsSr7HzF+FzJnkf3uffFIL27owI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":456970},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"3b74c565e244bf8931bcc03dbd7eccf8c9ae0b6a","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.12.1_1788726907415_0.47801812695949075","host":"s3://npm-registry-packages-npm-production"}},"22.13.0":{"name":"ng-hub-ui-utils","version":"22.13.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.13.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"dbaba35e18ce87faf0116f6b58785ab09fa02324","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.13.0.tgz","fileCount":8,"integrity":"sha512-QaZBHFaCmv/GWWH8IjEq25w4MCCKqc89JIsj6Liys8kdN+xNqs8kX3K4UbqVXWtaOR6z82VpX6BUHP9iVw4uoA==","signatures":[{"sig":"MEUCIH8NKDmq9DOM7Tv0uz/aTOCfNeXEAgvkSYURT6w4FYYJAiEA5axeyFwIy+9VMLsjjqC+ZccKKVWhWhUwLom4imjiZCg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCpnCqblgP3xgOkcEG30bP/ECVJjoi+7I4JmMmB7bOHEwIhAPu3VCy7TZkO2+AUIil6gyPgyDmfWjZJ9RQtCAGQGIm0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":478511},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"b231b2a1e4973ff7265711a560ead0c739998220","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.13.0_1788799117465_0.9545407590688648","host":"s3://npm-registry-packages-npm-production"}},"22.14.0":{"name":"ng-hub-ui-utils","version":"22.14.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.14.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"4461e8a0654ac280ef0d032b1e43310f9417edd5","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.14.0.tgz","fileCount":8,"integrity":"sha512-RcYHZUKu4QcKXP6I4vkV3sd+CLYTEwWwIDKAdzrCI00p5u9X7+Fgz5B0D62OjBBe16jKUYGb2O33U1/XBNt1Vw==","signatures":[{"sig":"MEUCIA9v1d/JzzyzPnuvhxn6iG/mg9Hl5EyBd8F1bnLPPLt6AiEAxiCuXZcDwmtXHWpDtTyHOOjFRzJOCZxown1mUwwjrVg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIEi2oO8L2z/wfBb1BPC9pF4AlK63UolFn34EcPQrNdzJAiAnNDrswtDHaoVNBPUjldNZXZi96cbd1aq6PO7LXk3BfQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":468317},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"9ad690dbca4bd6fb1db929fcdb946d199b3876c5","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.14.0_1788852537953_0.9489611773776092","host":"s3://npm-registry-packages-npm-production"}},"22.15.0":{"name":"ng-hub-ui-utils","version":"22.15.0","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.15.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/carlos-morcillo/ng-hub-ui-utils/issues"},"dist":{"shasum":"389853e85bc9525a4641d4968e6e9db384f2f6cb","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.15.0.tgz","fileCount":8,"integrity":"sha512-eHE2V4gvgA+8djSSW+VSPUjv1Jg7dhXt1Esl4JTyBlFGm+9sv1YR6rGpMD0rVK7LusMZ7a14OFNFcipip1jh1A==","signatures":[{"sig":"MEUCIAFCuw6ZlkOF156vFBQfLLJ1ja+j4hFBUX8OV1sgRDZWAiEAiUN+CdjS3ZX+1nQTr/5+dC3p3YMSLtCMh1/81ynv1C8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCICymJaXxUiChe6sLW4a1x/omDHX6oIQink++H9BAqIu3AiAvU0YwPVwP/VSzzgSC95DHbP6460vNezmoc8wRHMQXDA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":518194},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"c1e484078a65e9bd2d7156c99695ec16dca43cba","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/carlos-morcillo/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/statu","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"ng-hub-ui-ds":">=22.0.0","@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"peerDependenciesMeta":{"ng-hub-ui-ds":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.15.0_1788875476963_0.9981604065801095","host":"s3://npm-registry-packages-npm-production"}},"22.15.1":{"name":"ng-hub-ui-utils","version":"22.15.1","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.15.1","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/hub-env/hub-ui/issues"},"dist":{"shasum":"2beaef919e2e75aab9183464175481f3841f7732","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.15.1.tgz","fileCount":8,"integrity":"sha512-hW77nrYATWk9ASdW2iZeAGpDTYQPKeLp8zJRUx0OFK1AedoomokkZdnqiW7b6BlCK53cOKI2VGo57RJKJotgWQ==","signatures":[{"sig":"MEQCHwrXScqoV3F5ttbBNVLA+2ekWxQnz3WLooMANfOu4IICIQD/K3yK9TKy7QzhlinpdFMSSICBZHqsy9jbeA/q2UNs/g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDH3NewQPbzrKltRCTUylB1yTBHZyq64Du/FUz3+K4rYQIhAIe6w13J4x7VCjeM5RgMotSaSgbA8CMsGaQNi1rxUBfJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":518026},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"96fcce11cdee49fd5c31782d2891640f98b33b79","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/hub-env/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils) [![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE)","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"ng-hub-ui-ds":">=22.0.0","@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"peerDependenciesMeta":{"ng-hub-ui-ds":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.15.1_1789587005138_0.2678959535283054","host":"s3://npm-registry-packages-npm-production"}},"22.15.2":{"name":"ng-hub-ui-utils","version":"22.15.2","keywords":["angular","ng-hub-ui","hub-ui","utils","utilities","helpers","typescript","standalone","signals","pipes","overlay","popup","tooltip","focus-trap","accessibility","a11y","i18n","internationalization","translation","drag-and-drop","scrollbar","transitions","color","type-guards","angular-library"],"author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.15.2","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/hub-env/hub-ui/issues"},"dist":{"shasum":"f0e2f42fd90b5962e0c884672f591d50f77effe6","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.15.2.tgz","fileCount":8,"integrity":"sha512-P81Pr/ReTb1MviCNyDIwri9Ti8V59Iy2M2hOUi2EXArSSlwqYo98CRn7JH3/xfdDhxJnAnnRNbkDu1UOZLEfnA==","signatures":[{"sig":"MEUCIQD1sKr1zXmjqkml7YKFs61VBrnfXwsR0RpVFXsbClqaAgIgLnKTvvtboAlMHQyVyWK+UoE/OTRxFiasHOqYbDY8wcY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQC9hNk0hPUhNNgJyLPfWGho3CEKho5YbEkMRFTuoEs3nAIhANAAzxhWpa+ISNxY0Vg4s3VynkgOfDvCjRTYYMV3TNpj","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":518743},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"82aae7d0eb2f3a05016c277fab245207d5acde33","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/hub-env/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"Shared utilities for the ng-hub-ui family: standalone pipes, an overlay and popup system, tooltip controller, focus trap, scrollbar compensation, transitions, drag-and-drop helpers, colour utilities and a lightweight i18n layer. Ships no visual components","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"ng-hub-ui-ds":">=22.0.0","@angular/core":">=18.0.0","@angular/common":">=18.0.0"},"peerDependenciesMeta":{"ng-hub-ui-ds":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.15.2_1789924418741_0.25161743687634686","host":"s3://npm-registry-packages-npm-production"}},"22.15.3":{"name":"ng-hub-ui-utils","version":"22.15.3","keywords":["angular","ng-hub-ui","hub-ui","utils","utilities","helpers","typescript","standalone","signals","pipes","overlay","popup","tooltip","focus-trap","accessibility","a11y","i18n","internationalization","translation","drag-and-drop","scrollbar","transitions","color","type-guards","angular-library"],"author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo Fernández","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.15.3","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/hub-env/hub-ui/issues"},"dist":{"shasum":"7953a70d343a459eeec33f7f990c4115fc880f10","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.15.3.tgz","fileCount":8,"integrity":"sha512-uEjX9y+EWLRTbap0FOJvyBeS3axr4c6KduYI6lPSwIo6FaJ5IaEjpx/PBs/tFDlpqW/AvqrAKAJlExjetHq/mQ==","signatures":[{"sig":"MEUCIQCYPdYvlenP+nUTOMtWEndX9ZaG3WcYJd58sAAeGdcBigIgKqUgtLFkhk6SMYaS8BUGEt3COKLREExFY04Xgadoizg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDT+FlKuJb5HqU1GloZoAFJ/jWojV3yuUymOv2Ng83KBQIgTcZo/p+TPNUuSQk7Loq1jwbvN7OH2P5u131z0nh4gXo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":519429},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"1be22b8be7e377cd6363f4d1e631c1d204225440","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/hub-env/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"Shared utilities for the ng-hub-ui family: standalone pipes, an overlay and popup system, tooltip controller, focus trap, scrollbar compensation, transitions, drag-and-drop helpers, colour utilities and a lightweight i18n layer. Ships no visual components","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"ng-hub-ui-ds":">=22.0.0","@angular/core":">=17.1.0","@angular/common":">=17.1.0"},"peerDependenciesMeta":{"ng-hub-ui-ds":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.15.3_1790161030271_0.15605510934388578","host":"s3://npm-registry-packages-npm-production"}},"22.17.0":{"name":"ng-hub-ui-utils","version":"22.17.0","keywords":["angular","ng-hub-ui","hub-ui","utils","utilities","helpers","typescript","standalone","signals","pipes","overlay","popup","tooltip","focus-trap","accessibility","a11y","i18n","internationalization","translation","drag-and-drop","scrollbar","transitions","color","type-guards","angular-library"],"author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo Fernández","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.17.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/hub-env/hub-ui/issues"},"dist":{"shasum":"5bfcda1717226ada5dad63cdac2cbf9b6687bbf5","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.17.0.tgz","fileCount":8,"integrity":"sha512-gKimwPgY3ZSX0VV9Wm+h+tT8iTgMYK9Zg24p6M0TBGaZcXVQlpje4XCXrOknAMTE73fks9XZdiWSwmckRQIguA==","signatures":[{"sig":"MEUCIQDk5Xr0EbXsGjgZo+DmMUHp8E6FfAlfvNbtfvE3celb1QIgbwpLiseu2xrJJtPCedHD6V2byHhabZ+StIi2QtcEMN4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIFkfNxEIsEens4UrJjT5cm78MEZPJQE2aQsC3HizaWMCAiEA1EKXHMItiSPcFYi76+A8kvddEi9uP3zJAQ4zkdbCCAM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":574299},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"98575e658b899c610dba80173fa2f781c0d93e8a","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/hub-env/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"Shared utilities for the ng-hub-ui family: standalone pipes, an overlay and popup system, tooltip controller, focus trap, scrollbar compensation, transitions, drag-and-drop helpers, colour utilities and a lightweight i18n layer. Ships no visual components","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"ng-hub-ui-ds":">=22.0.0","@angular/core":">=17.1.0","@angular/common":">=17.1.0"},"peerDependenciesMeta":{"ng-hub-ui-ds":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.17.0_1790240641061_0.9072013082602386","host":"s3://npm-registry-packages-npm-production"}},"22.18.0":{"name":"ng-hub-ui-utils","version":"22.18.0","keywords":["angular","ng-hub-ui","hub-ui","utils","utilities","helpers","typescript","standalone","signals","pipes","overlay","popup","tooltip","focus-trap","accessibility","a11y","i18n","internationalization","translation","drag-and-drop","scrollbar","transitions","color","type-guards","angular-library"],"author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo Fernández","email":"carlos.morcillo@me.com"},"license":"MIT","_id":"ng-hub-ui-utils@22.18.0","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"homepage":"https://hubui.dev/en/utils/overview/","bugs":{"url":"https://github.com/hub-env/hub-ui/issues"},"dist":{"shasum":"ee5f6c891f757ae99d99c847be9417e1438a7e32","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.18.0.tgz","fileCount":9,"integrity":"sha512-fR51jShf+8KTqWrsAnfrRnR1icEpix4lBYI/FQcQ7l68lQCvQGrWY4bqB3JVQdYA+egBX3K6ZOsJfgW3T6FVvQ==","signatures":[{"sig":"MEYCIQDU6o/kfVFIjKglhFJr1LgL6iKNOxJRnFzhJ8AQcvmeugIhAN+jolekgXgWZR7ceJYKf62xi/BE2/aKdAJc8vK8C2TD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIBMBuAnaLFA437wASFR48DxYtFVIY4hIqw6e4cIDATmUAiEAuuRuu1BwIYbYRp0WUgb+6J2D+mHGC/X/KKGZatMHMSo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":663205},"type":"module","module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"5d5a5c1059a7e1e306e35d2ea0e755b27b3149a2","typings":"types/ng-hub-ui-utils.d.ts","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"repository":{"url":"git+https://github.com/hub-env/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"Shared utilities for the ng-hub-ui family: standalone pipes, an overlay and popup system, tooltip controller, focus trap, scrollbar compensation, transitions, drag-and-drop helpers, colour utilities and a lightweight i18n layer. Ships no visual components","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"ng-hub-ui-ds":">=22.0.0","@angular/core":">=17.1.0","@angular/common":">=17.1.0"},"peerDependenciesMeta":{"ng-hub-ui-ds":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ng-hub-ui-utils_22.18.0_1790494082034_0.7413092865732944","host":"s3://npm-registry-packages-npm-production"}},"22.19.0":{"_id":"ng-hub-ui-utils@22.19.0","bugs":{"url":"https://github.com/hub-env/hub-ui/issues"},"dist":{"shasum":"402f05dd417bdf78e1c0c1324f73a550828f492a","tarball":"https://registry.npmjs.org/ng-hub-ui-utils/-/ng-hub-ui-utils-22.19.0.tgz","fileCount":9,"integrity":"sha512-1Ec+QcqqOqkQYnI+ts8HJUGR9RjKjBVGfHPMF1DOG/ZmhdMKRjcrTqQLURzskqD+jW8HMDsUP29HugesDtfs7Q==","signatures":[{"sig":"MEUCIQCu6/5YtN67llekmqroUBKxbgHAT0CnrpW+aigNcllZ+AIgWyE3Ndvs+mhyWs+WhIzHELIuhLVYQ7mrg03TAhbugWc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIA7RDyMeL0Bs7P2ZnPp0WDk9XzPu3V5GYoFIGjAK9QPrAiEAlYSK8hXlNC0FY9eo73KzOxs4bGsN0ykHILyLPAm+wuo="}],"unpackedSize":682887},"name":"ng-hub-ui-utils","type":"module","author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo Fernández","email":"carlos.morcillo@me.com"},"module":"fesm2022/ng-hub-ui-utils.mjs","exports":{".":{"types":"./types/ng-hub-ui-utils.d.ts","default":"./fesm2022/ng-hub-ui-utils.mjs"},"./package.json":{"default":"./package.json"},"./styles/overlay":"./styles/overlay.scss","./styles/tooltip":"./styles/tooltip.scss","./styles/overlay.scss":"./styles/overlay.scss","./styles/tooltip.scss":"./styles/tooltip.scss"},"gitHead":"5536607c1958cbe5b3b07cd0f5194302cd1a6662","license":"MIT","typings":"types/ng-hub-ui-utils.d.ts","version":"22.19.0","_npmUser":{"name":"inphinito","email":"carlos.morcillo@me.com"},"homepage":"https://hubui.dev/en/utils/overview/","keywords":["angular","ng-hub-ui","hub-ui","utils","utilities","helpers","typescript","standalone","signals","pipes","overlay","popup","tooltip","focus-trap","accessibility","a11y","i18n","internationalization","translation","drag-and-drop","scrollbar","transitions","color","type-guards","angular-library"],"repository":{"url":"git+https://github.com/hub-env/ng-hub-ui-utils.git","type":"git"},"_npmVersion":"10.9.8","description":"Shared utilities for the ng-hub-ui family: standalone pipes, an overlay and popup system, tooltip controller, focus trap, scrollbar compensation, transitions, drag-and-drop helpers, colour utilities and a lightweight i18n layer. Ships no visual components","directories":{},"maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"sideEffects":false,"_nodeVersion":"22.22.3","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"ng-hub-ui-ds":">=22.0.0","@angular/core":">=17.1.0","@angular/common":">=17.1.0"},"peerDependenciesMeta":{"ng-hub-ui-ds":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ng-hub-ui-utils_22.19.0_1790528255152_0.8793121324304458"}}},"time":{"created":"2024-05-26T21:18:49.681Z","modified":"2026-09-27T16:57:35.440Z","1.0.0":"2024-05-26T21:18:49.863Z","1.1.0":"2026-01-01T15:19:36.243Z","1.2.0":"2026-01-02T13:23:04.726Z","22.1.0":"2026-06-23T17:55:48.697Z","22.2.0":"2026-06-24T12:42:49.206Z","22.3.1":"2026-06-25T07:48:29.877Z","22.3.2":"2026-06-26T10:00:13.621Z","22.4.0":"2026-06-26T15:55:27.247Z","22.5.0":"2026-06-29T11:08:45.030Z","22.6.0":"2026-06-30T08:31:52.604Z","22.7.0":"2026-07-07T15:16:24.131Z","22.7.1":"2026-07-28T10:09:17.966Z","22.7.2":"2026-08-08T15:18:56.463Z","22.8.0":"2026-08-14T07:34:15.681Z","22.8.1":"2026-08-15T13:45:19.590Z","22.9.0":"2026-08-17T08:46:58.874Z","22.9.1":"2026-08-17T12:35:15.929Z","22.9.2":"2026-08-17T16:09:24.786Z","22.9.3":"2026-08-19T11:19:12.360Z","22.10.0":"2026-08-23T09:10:24.929Z","22.11.0":"2026-08-26T12:59:13.663Z","22.11.1":"2026-09-01T15:20:52.273Z","22.12.0":"2026-09-03T11:53:26.674Z","22.12.1":"2026-09-06T20:35:07.521Z","22.13.0":"2026-09-07T16:38:37.569Z","22.14.0":"2026-09-08T07:28:58.047Z","22.15.0":"2026-09-08T13:51:17.091Z","22.15.1":"2026-09-16T19:30:05.312Z","22.15.2":"2026-09-20T17:13:38.836Z","22.15.3":"2026-09-23T10:57:10.387Z","22.17.0":"2026-09-24T09:04:01.173Z","22.18.0":"2026-09-27T07:28:02.156Z","22.19.0":"2026-09-27T16:57:35.239Z"},"bugs":{"url":"https://github.com/hub-env/hub-ui/issues"},"author":{"url":"https://www.carlosmorcillo.com","name":"Carlos Morcillo Fernández","email":"carlos.morcillo@me.com"},"license":"MIT","homepage":"https://hubui.dev/en/utils/overview/","keywords":["angular","ng-hub-ui","hub-ui","utils","utilities","helpers","typescript","standalone","signals","pipes","overlay","popup","tooltip","focus-trap","accessibility","a11y","i18n","internationalization","translation","drag-and-drop","scrollbar","transitions","color","type-guards","angular-library"],"repository":{"url":"git+https://github.com/hub-env/ng-hub-ui-utils.git","type":"git"},"description":"Shared utilities for the ng-hub-ui family: standalone pipes, an overlay and popup system, tooltip controller, focus trap, scrollbar compensation, transitions, drag-and-drop helpers, colour utilities and a lightweight i18n layer. Ships no visual components","maintainers":[{"name":"inphinito","email":"carlos.morcillo@me.com"}],"readme":"# ng-hub-ui-utils\n\n[![NPM Version](https://img.shields.io/npm/v/ng-hub-ui-utils.svg)](https://www.npmjs.com/package/ng-hub-ui-utils)\n[![License](https://img.shields.io/npm/l/ng-hub-ui-utils.svg)](LICENSE)\n\n> Common utilities library for Angular, fundamental support for the Hub UI ecosystem.\n\n[Español](./README.es.md) | **English**\n\n## 📝 Description\n\n`ng-hub-ui-utils` is the foundational utilities library for the entire Hub UI ecosystem. It provides a curated set of framework-agnostic helper functions, type guards, standalone Angular pipes, a flexible overlay/popup system, focus-trap and accessibility helpers, scrollbar compensation, a smooth transition engine, and a lightweight internationalization (i18n) system. It ships no visual components — instead it powers the shared low-level behavior used across the rest of the `ng-hub-ui` libraries, while remaining tree-shakable so you only bundle what you import.\n\n## 📑 Table of Contents\n\n- [Description](#-description)\n- [Documentation and Live Examples](#-documentation-and-live-examples)\n- [Library Family `ng-hub-ui`](#-library-family-ng-hub-ui)\n- [Inspiration](#-inspiration)\n- [Features](#-features)\n- [Installation](#-installation)\n- [Quick Start](#-quick-start)\n- [Internationalization (i18n)](#-internationalization-i18n)\n- [Utilities API](#-utilities-api)\n- [Support Components](#-support-components)\n- [Compatibility](#-compatibility)\n- [Development](#-development)\n- [Testing](#-testing)\n- [Changelog](#-changelog)\n- [Issues and Support](#-issues-and-support)\n- [Support the Project](#-support-the-project)\n- [Contributions](#-contributions)\n- [License](#-license)\n\n## 📚 Documentation and Live Examples\n\nThis package is part of [Hub UI](https://hubui.dev/en/), a collection of Angular component libraries for standalone apps.\n\n- Docs: https://hubui.dev/en/utils/overview/\n- Live examples: https://hubui.dev/en/utils/examples/\n- Hub UI: https://hubui.dev/en/\n\n## 🧩 Library Family `ng-hub-ui`\n\nThis library is part of the **ng-hub-ui** ecosystem:\n\n- [**ng-hub-ui-accordion**](https://www.npmjs.com/package/ng-hub-ui-accordion) (deprecated — use ng-hub-ui-panels)\n- [**ng-hub-ui-action-sheet**](https://www.npmjs.com/package/ng-hub-ui-action-sheet)\n- [**ng-hub-ui-avatar**](https://www.npmjs.com/package/ng-hub-ui-avatar)\n- [**ng-hub-ui-board**](https://www.npmjs.com/package/ng-hub-ui-board)\n- [**ng-hub-ui-breadcrumbs**](https://www.npmjs.com/package/ng-hub-ui-breadcrumbs)\n- [**ng-hub-ui-calendar**](https://www.npmjs.com/package/ng-hub-ui-calendar)\n- [**ng-hub-ui-dropdown**](https://www.npmjs.com/package/ng-hub-ui-dropdown)\n- [**ng-hub-ui-ds**](https://www.npmjs.com/package/ng-hub-ui-ds)\n- [**ng-hub-ui-forms**](https://www.npmjs.com/package/ng-hub-ui-forms)\n- [**ng-hub-ui-history**](https://www.npmjs.com/package/ng-hub-ui-history)\n- [**ng-hub-ui-milestones**](https://www.npmjs.com/package/ng-hub-ui-milestones)\n- [**ng-hub-ui-modal**](https://www.npmjs.com/package/ng-hub-ui-modal)\n- [**ng-hub-ui-nav**](https://www.npmjs.com/package/ng-hub-ui-nav)\n- [**ng-hub-ui-paginable**](https://www.npmjs.com/package/ng-hub-ui-paginable)\n- [**ng-hub-ui-panels**](https://www.npmjs.com/package/ng-hub-ui-panels)\n- [**ng-hub-ui-portal**](https://www.npmjs.com/package/ng-hub-ui-portal)\n- [**ng-hub-ui-skeleton**](https://www.npmjs.com/package/ng-hub-ui-skeleton)\n- [**ng-hub-ui-sortable**](https://www.npmjs.com/package/ng-hub-ui-sortable)\n- [**ng-hub-ui-spreadsheet**](https://www.npmjs.com/package/ng-hub-ui-spreadsheet)\n- [**ng-hub-ui-stepper**](https://www.npmjs.com/package/ng-hub-ui-stepper)\n- [**ng-hub-ui-utils**](https://www.npmjs.com/package/ng-hub-ui-utils) ← You are here\n\n## 💡 Inspiration\n\nThis utilities library emerged from the need to provide common, reusable, and optimized support functions for the entire Hub UI ecosystem. Inspired by best practices in Angular development and internal utilities from libraries like Angular Bootstrap and Material Design, it provides essential tools for developing modern UI components.\n\n## ✨ Features\n\n### 🔧 Focus Management and Accessibility\n\nAdvanced utilities for focus handling, focus trapping, and keyboard navigation.\n\n```typescript\nimport { getFocusableBoundaryElements, FOCUSABLE_ELEMENTS_SELECTOR } from 'ng-hub-ui-utils';\n\n// Get focusable elements in a container\nconst [firstElement, lastElement] = getFocusableBoundaryElements(containerElement);\n\n// Create a focus trap in a modal\nconst focusTrap = hubFocusTrap(ngZone, modalElement, stopFocusTrap$);\n```\n\n### 🪟 Overlay Service\n\nAdvanced system for creating overlays and floating components with flexible positioning.\n\n```typescript\nimport { OverlayService, OverlayConfig } from 'ng-hub-ui-utils';\n\n@Component({\n\tselector: 'app-example'\n})\nexport class ExampleComponent {\n\tconstructor(private overlayService: OverlayService) {}\n\n\topenOverlay(elementRef: ElementRef) {\n\t\t// Create overlay with configuration\n\t\tconst overlayRef = this.overlayService.create({\n\t\t\thasBackdrop: true,\n\t\t\tbackdropClass: 'custom-backdrop'\n\t\t});\n\n\t\t// Configure position strategy\n\t\tconst positionStrategy = this.overlayService\n\t\t\t.position()\n\t\t\t.flexibleConnectedTo(elementRef)\n\t\t\t.withPositions([\n\t\t\t\t{\n\t\t\t\t\toriginX: 'start',\n\t\t\t\t\toriginY: 'bottom',\n\t\t\t\t\toverlayX: 'start',\n\t\t\t\t\toverlayY: 'top'\n\t\t\t\t}\n\t\t\t]);\n\n\t\t// Render a component (or a TemplateRef) into the overlay; you get the host element back\n\t\tconst overlayElement = overlayRef.attach(MyComponent);\n\t}\n}\n```\n\n**Stacking (z-index).** `OverlayRef` resolves its inline z-index through the design-system tokens — `var(--hub-overlay-zindex, 1000)` for the container and `var(--hub-overlay-backdrop-zindex, 999)` for the backdrop — so re-stacking an overlay (e.g. a dropdown above a modal) is a plain CSS override, no `!important` needed. For a single instance, pass an explicit layer instead:\n\n```typescript\nthis.overlayService.create({ zIndex: 1100 }); // OverlayConfig.zIndex: number | string — takes precedence over the token\n```\n\n### 🎯 Popup Service\n\n`PopupService<T>` hosts a dynamically created popup component and runs its show/hide\ntransition. It is a concrete class — subclass it when the popup needs its own API, as\nbelow, or provide it through a factory.\n\n```typescript\nimport { PopupService } from 'ng-hub-ui-utils';\n\n@Injectable()\nexport class MyPopupService extends PopupService<MyPopupComponent> {\n\tconstructor() {\n\t\tsuper(MyPopupComponent);\n\t}\n\n\topenPopup(content?: string | TemplateRef<any>) {\n\t\tconst { windowRef, transition$ } = super.open(content, {}, true);\n\t\treturn { windowRef, transition$ };\n\t}\n}\n```\n\n### 📜 Scrollbar Management\n\nIntelligent scrollbar control with layout compensation.\n\n```typescript\nimport { ScrollBar } from 'ng-hub-ui-utils';\n\nconstructor(private scrollBar: ScrollBar) {}\n\nopenModal() {\n  // Hide scrollbar and compensate for space\n  const reverter = this.scrollBar.hide();\n\n  // On modal close, restore scrollbar\n  modalClose.subscribe(() => reverter());\n}\n```\n\n### ⚡ Transition System\n\nUtilities for smooth animations and transitions with automatic detection.\n\n```typescript\nimport { hubRunTransition } from 'ng-hub-ui-utils';\n\n// Execute transition with callback\nhubRunTransition(\n\tthis.ngZone,\n\telement,\n\t(element, animation, context) => {\n\t\t// Transition start logic\n\t\telement.classList.add('transitioning');\n\n\t\treturn () => {\n\t\t\t// Cleanup at transition end\n\t\t\telement.classList.remove('transitioning');\n\t\t};\n\t},\n\t{\n\t\tanimation: true,\n\t\trunningTransition: 'continue',\n\t\tcontext: { customData: 'value' }\n\t}\n).subscribe(() => {\n\tconsole.log('Transition completed');\n});\n```\n\n### 🌐 Internationalization (i18n)\n\nLightweight, dependency-injection based translation system with a reactive pipe. Register translation dictionaries at bootstrap with `provideHubTranslation`, then translate keys in templates with the `translate` pipe.\n\n```typescript\nimport { provideHubTranslation, HubTranslationService, TranslatePipe } from 'ng-hub-ui-utils';\n\n// In your application config / bootstrap providers\nbootstrapApplication(AppComponent, {\n\tproviders: [\n\t\tprovideHubTranslation({\n\t\t\tlanguage: 'en',\n\t\t\tfallbackLanguage: 'en',\n\t\t\tdictionaries: {\n\t\t\t\ten: { greeting: 'Hello {name}!' },\n\t\t\t\tes: { greeting: '¡Hola {name}!' }\n\t\t\t}\n\t\t})\n\t]\n});\n```\n\n```typescript\n@Component({\n\tstandalone: true,\n\timports: [TranslatePipe],\n\ttemplate: `\n\t\t<!-- Simple key -->\n\t\t<p>{{ 'greeting' | translate }}</p>\n\n\t\t<!-- With interpolation params -->\n\t\t<p>{{ 'greeting' | translate: { name: 'Carlos' } }}</p>\n\t`\n})\nexport class ExampleComponent {}\n```\n\nSee [Internationalization (i18n)](#-internationalization-i18n) for the full API.\n\n### 🧰 Standalone Angular Pipes\n\nComplete set of utility pipes for validation, transformation, and data manipulation.\n\n```typescript\nimport { GetPipe, IsStringPipe, IsObjectPipe, IsObservablePipe, UcfirstPipe, UnwrapAsyncPipe } from 'ng-hub-ui-utils';\n\n@Component({\n\tstandalone: true,\n\timports: [GetPipe, IsStringPipe, UcfirstPipe, UnwrapAsyncPipe],\n\ttemplate: `\n\t\t<!-- Safe nested property access -->\n\t\t<p>{{ user | get: 'address.city' : 'Unknown' }}</p>\n\n\t\t<!-- Capitalize first letter -->\n\t\t<h1>{{ title | ucfirst }}</h1>\n\n\t\t<!-- Type checking in templates -->\n\t\t@if (value | isString) {\n\t\t\t<span>It's a string: {{ value }}</span>\n\t\t}\n\n\t\t<!-- Unwrap Observable or direct value -->\n\t\t<div>{{ observableOrValue | unwrapAsync }}</div>\n\t`\n})\nexport class ExampleComponent {\n\tuser = { address: { city: 'New York' } };\n\ttitle = 'hello world';\n\tvalue: any = 'test';\n\tobservableOrValue = of('Observable value');\n}\n```\n\n**Available Pipes:**\n\n- **GetPipe** (`get`): Safe nested property access with default values\n- **IsStringPipe** (`isString`): Check if value is a string\n- **IsObjectPipe** (`isObject`): Check if value is an object\n- **IsObservablePipe** (`isObservable`): Check if value is an Observable\n- **UcfirstPipe** (`ucfirst`): Capitalize first letter of a string\n- **UnwrapAsyncPipe** (`unwrapAsync`): Unwrap Observable or return direct value\n\n### 🛠️ General Utility Functions\n\nComplete set of helpers for validation, transformation, and data manipulation.\n\n```typescript\nimport {\n\ttoInteger,\n\ttoString,\n\tgetValueInRange,\n\tisString,\n\tisNumber,\n\tisInteger,\n\tisDefined,\n\tisPromise,\n\tpadNumber,\n\tregExpEscape,\n\tclosest,\n\treflow,\n\tremoveAccents,\n\tgetActiveElement\n} from 'ng-hub-ui-utils';\n\n// Safe conversions\nconst numValue = toInteger('42'); // 42\nconst strValue = toString(null); // ''\n\n// Type validations\nif (isString(value)) {\n\t/* ... */\n}\nif (isPromise(result)) {\n\t/* ... */\n}\n\n// DOM manipulation\nconst parent = closest(element, '.container');\nreflow(element); // Force browser reflow\n\n// String utilities\nconst clean = removeAccents('niño'); // \"nino\"\nconst escaped = regExpEscape('hello?'); // \"hello\\\\?\"\n\n// Focus management\nconst activeEl = getActiveElement(); // Includes shadow DOM\n```\n\n### 🎯 Full TypeScript Support\n\nStrict typing throughout the library with well-defined interfaces and types.\n\n```typescript\n// Transition types\ntype TransitionStartFn<T> = (element: HTMLElement, animation: boolean, context: T) => TransitionEndFn | void;\n\ninterface TransitionOptions<T> {\n\tanimation: boolean;\n\trunningTransition: 'continue' | 'stop';\n\tcontext?: T;\n}\n\n// Scrollbar reverter type\ntype ScrollbarReverter = () => void;\n```\n\n### ⚡ Optimized Tree-shaking\n\nImport only the utilities you need to optimize your bundle.\n\n```typescript\n// Specific imports\nimport { toInteger, isString } from 'ng-hub-ui-utils';\nimport { ScrollBar } from 'ng-hub-ui-utils';\nimport { hubRunTransition } from 'ng-hub-ui-utils';\nimport { GetPipe, UcfirstPipe } from 'ng-hub-ui-utils';\n```\n\n### 🏷️ Tooltip Directive\n\nAdd a lightweight, themeable tooltip to any element with the `HubTooltipDirective`\n(`[hubTooltip]`). The tooltip is appended to `<body>` (never clipped) and shows on\nhover/focus.\n\n```typescript\nimport { HubTooltipDirective } from 'ng-hub-ui-utils';\n\n@Component({\n\tstandalone: true,\n\timports: [HubTooltipDirective],\n\ttemplate: `<button hubTooltip=\"Save changes\" hubTooltipPlacement=\"top\">Save</button>`\n})\nexport class ExampleComponent {}\n```\n\n> **Styles (required since 22.4.0).** The tooltip no longer injects its CSS at\n> runtime — import its stylesheet once in your app (e.g. `styles.scss`), the same\n> way as `overlay`:\n>\n> ```scss\n> @use 'ng-hub-ui-utils/styles/tooltip';\n> ```\n\nInputs: `hubTooltip` (text), `hubTooltipPlacement` (`top` | `bottom` | `left` | `right`,\ndefault `top`), `hubTooltipDelay` (fade ms, default `150`), `hubTooltipOffset` (px, default `8`).\n\n**The placement is a preference, not an instruction (since 22.16.0).** A tooltip that would open\noff the edge of the window opens on the opposite side instead, at all four edges, and one centred\non a host near the inline edge is slid back inside rather than flipped — flipping does nothing for\nan overflow on the cross axis. It gives way only when it genuinely has no room, so a tooltip that\ndid not need to move does not, and the fit is re-run while the label is open, on window resize and\non a scroll anywhere above it. Under RTL the inline edge is the other one and the flip follows it,\nwhile `hubTooltipPlacement=\"left\"` still means the host's left edge.\n\nIf you have been writing `hubTooltipPlacement=\"bottom\"` by hand on every hint in a header, you can\nstop: the attribute is still honoured wherever it fits, but it is no longer what keeps the label\non screen. The class on the bubble (`hub-tooltip--top`, `--bottom`, `--left`, `--right`) names the\nside it ended up on, so an arrow styled off it follows the flip.\n\n> **`TooltipDirective` (`[tooltip]`) was removed in 22.14.0**, having been deprecated since\n> 22.9.0. Its bare input names (`tooltip`, `placement`, `delay`, `offset`) belonged to every\n> directive on the element that declared them, which is how it collided with `[hubDropdown]`'s\n> own `placement` and with the `tooltip` input of `<hub-badge>`. Migration is attribute for\n> attribute: `tooltip` → `hubTooltip`, `placement` → `hubTooltipPlacement`,\n> `delay` → `hubTooltipDelay`, `offset` → `hubTooltipOffset`. A template left writing\n> `tooltip=\"…\"` still compiles and shows nothing at all, so check the markup as well as the\n> imports.\n\nShow the label **only while the host is truncated** with `HubOverflowTooltipDirective`\n(`[hubOverflowTooltip]`), which tracks truncation live with a `ResizeObserver` and a\n`MutationObserver` and resolves its tooltip through `HUB_TOOLTIP_ADAPTER`:\n\n```html\n<span class=\"label\" [hubOverflowTooltip]=\"item.label\">{{ item.label }}</span>\n```\n\nThe element that is **hovered** and the element that is **measured** need not be the same.\nBy default they are, but a control whose text is clipped by a box inside it wants them apart:\nthe hover area is the whole control, while the only box that can report truncation is the\ninner one — a child that clips its own text never lets the overflow reach its parent, so\nmeasuring the parent reports none and the tooltip goes quiet. Point\n`hubOverflowTooltipMeasure` at the inner box with a CSS selector, resolved inside the host:\n\n```html\n<div class=\"chip\" [hubOverflowTooltip]=\"item.label\" hubOverflowTooltipMeasure=\".chip__title\">\n\t<span class=\"chip__icon\"></span>\n\t<span class=\"chip__title\">{{ item.label }}</span>\n</div>\n```\n\nUnset — or pointing at nothing — the host measures itself, exactly as before.\n\nTheme it from any scope with `--hub-tooltip-*` variables:\n\n```css\n.my-scope {\n\t--hub-tooltip-bg: var(--hub-sys-color-primary);\n\t--hub-tooltip-color: #fff;\n\t--hub-tooltip-border-radius: 999px;\n\t--hub-tooltip-opacity: 1;\n}\n```\n\nAvailable tokens: `--hub-tooltip-bg`, `--hub-tooltip-color`, `--hub-tooltip-opacity`,\n`--hub-tooltip-padding-x`, `--hub-tooltip-padding-y`, `--hub-tooltip-border-radius`,\n`--hub-tooltip-font-size`, `--hub-tooltip-font-weight`, `--hub-tooltip-line-height`,\n`--hub-tooltip-max-width`, `--hub-tooltip-zindex`, `--hub-tooltip-transition-duration`,\n`--hub-tooltip-shadow`, `--hub-tooltip-font-family`, `--hub-tooltip-white-space`,\n`--hub-tooltip-text-align`.\n\nThe last two arrived in 22.10.0, for the tooltip that carries a sentence rather than a\nname: they are set on the **host**, which is the only element you can reach, because the\nbubble itself lives on `<body>`, outside every component's styles.\n\n#### Tooltip adapter for other libraries (`hubTooltipAdapter`)\n\nThe same tooltip engine is exposed as a framework-agnostic adapter so sibling\nlibraries can offer the hub-ui tooltip **without hard-depending on this package**.\nWire it into their optional tooltip token — e.g. for badges or breadcrumbs:\n\n```ts\nimport { hubTooltipAdapter } from 'ng-hub-ui-utils';\nimport { provideHubBadgeTooltip } from 'ng-hub-ui-badges';\nimport { provideHubBreadcrumbTooltip } from 'ng-hub-ui-breadcrumbs';\n\nproviders: [provideHubBadgeTooltip(hubTooltipAdapter), provideHubBreadcrumbTooltip(hubTooltipAdapter)];\n```\n\nInside this package the same token works the other way round: `[hubOverflowTooltip]`\nresolves its tooltip through `HUB_TOOLTIP_ADAPTER`, which defaults to `hubTooltipAdapter`.\nSwap it app-wide, or for one subtree, with `provideHubTooltip()`:\n\n```ts\nimport { provideHubTooltip, HubTooltipAdapter } from 'ng-hub-ui-utils';\n\nconst myTooltip: HubTooltipAdapter = {\n\tattach(host, text, options) {\n\t\t/* … returns a HubTooltipHandle with update(text) and destroy() */\n\t}\n};\n\nproviders: [provideHubTooltip(myTooltip)];\n```\n\nAlso available: the imperative `HubTooltipController` (engine) and the\n`HubTooltipAdapter` / `HubTooltipHandle` / `HubTooltipOptions` / `HubTooltipPlacement`\ntypes. See the ecosystem-wide\n[Synergies & agnosticism](../../README.md#synergies--agnosticism) section.\n\n### 🔢 Grid Primitives\n\nThe arithmetic a sheet of cells is made of, with no DOM and no framework in it. A grid has a\nhandful of problems every implementation solves again and gets wrong in the same places: where the\ncursor goes at an edge, what rectangle two corners describe, which cell a merged block swallowed,\nand which tracks are worth drawing at all. `ng-hub-ui-spreadsheet` is built on these, which is how\nit installs without `@angular/cdk`.\n\n```ts\nimport {\n\tresolveGridIntent,\n\tmoveGridFocus,\n\tgridRangeBetween,\n\tbuildSpanMap,\n\tanchorOf,\n\tgridWindow,\n\tgrowWindowToSpans\n} from 'ng-hub-ui-utils';\n\n// A key read as an intent, so the grid does not grow a switch statement per browser. The\n// roving tab stop is `gridCellTabIndex(cell, active, 'roving')`.\nconst intent = resolveGridIntent(event, { pageSize: 20 });\n\n// The cursor, with the three different answers at the end of a row told apart.\nconst next = moveGridFocus(cursor, { row: 0, col: 1 }, bounds, { horizontal: 'continuous' });\n\n// A selection kept as two corners, so ten thousand cells cost nothing.\nconst range = gridRangeBetween(anchor, cursor);\n\n// Merged blocks: the cursor lands on the block and never inside it.\nconst spans = buildSpanMap([{ row: 4, col: 0, rowSpan: 3, colSpan: 2 }]);\nconst landing = anchorOf(spans, cursor);\n\n// Only what the viewport covers, with the pixels the rest would have taken, so the scrollbar\n// still tells the truth. Then widened until every block it touches is drawn whole.\nconst window = growWindowToSpans(\n\tgridWindow({ offset: scrollTop, viewport: height, sizes: 32, count: rows.length, pinned: 1 }),\n\tblocks,\n\t'row',\n\t32,\n\t{ count: rows.length, pinned: 1 }\n);\n```\n\nAlso exported: `resolveGridEdge`, `isWithinGridRange`, `gridRangeCells`, `gridRangeSize`,\n`clampGridRange`, `spanAt`, `isCovered`, `coversRange`, `gridCellTabIndex`, and the types\n`HubGridCoords`, `HubGridBounds`, `HubGridRange`, `HubGridSpan`, `HubGridSpanMap`, `HubGridWrap`,\n`HubGridEdge`, `HubGridIntent`, `HubGridWindow` and `HubGridTrackSizes`.\n\nAlso exported for a selection of several rectangles: `isWithinGridSelection`, `addGridRange`,\n`gridSelectionCells`, `gridSelectionSize`, `gridSelectionBounds`, `clampGridSelection` and\n`gridSelectionTable` — the last of which decides whether a disjoint selection can be copied at all\n(it can when the rectangles line up, and returns `null` when there is no honest table to write).\n\n## 🚀 Installation\n\n```bash\nnpm install ng-hub-ui-utils\n# or\nyarn add ng-hub-ui-utils\n```\n\n## 📖 Quick Start\n\n```typescript\n// Import specific utilities\nimport { toInteger, isString, ScrollBar, getFocusableBoundaryElements, GetPipe, UcfirstPipe } from 'ng-hub-ui-utils';\n\n@Component({\n\tselector: 'app-example',\n\tstandalone: true,\n\timports: [GetPipe, UcfirstPipe],\n\ttemplate: `\n\t\t<div #container>\n\t\t\t<h1>{{ title | ucfirst }}</h1>\n\t\t\t<p>{{ user | get: 'name' : 'Anonymous' }}</p>\n\t\t</div>\n\t`\n})\nexport class ExampleComponent {\n\tconstructor(private scrollBar: ScrollBar) {}\n\n\t@ViewChild('container') containerElement!: ElementRef<HTMLElement>;\n\n\ttitle = 'welcome';\n\tuser = { name: 'John Doe' };\n\n\tngAfterViewInit() {\n\t\t// Get focusable elements\n\t\tconst [first, last] = getFocusableBoundaryElements(this.containerElement.nativeElement);\n\n\t\t// Safe conversion\n\t\tconst value = toInteger('42');\n\n\t\tif (isString(this.title)) {\n\t\t\tconsole.log(\"It's a string\");\n\t\t}\n\t}\n\n\topenOverlay() {\n\t\t// Hide scrollbar during overlay\n\t\tconst reverter = this.scrollBar.hide();\n\n\t\t// Restore on close\n\t\tthis.overlayRef.onClose(() => reverter());\n\t}\n}\n```\n\n## 🌐 Internationalization (i18n)\n\nThe i18n system (available since `v1.2.0`) lets you register translation dictionaries via dependency injection and resolve keys reactively in templates. Updating the active translations at runtime automatically refreshes any `translate` pipe in the view.\n\n### `provideHubTranslation(config?)`\n\nEnvironment provider helper that registers `HubTranslationService` and its configuration. Call it once in your application bootstrap providers.\n\n### `provideHubTranslationAdapter(factory)`\n\nUse this provider when the application owns translations through Transloco, ngx-translate or another reactive service. The factory runs once in Angular's injection context and returns an observable-like source of complete dictionaries. Every Hub UI library using `HubTranslationService` receives language changes without component-level subscriptions.\n\n```typescript\nfunction provideHubTranslation(config?: HubTranslationConfig): EnvironmentProviders;\n```\n\n### `HubTranslationConfig`\n\n```typescript\ninterface HubTranslationConfig {\n\t/** Map of language code → translation dictionary. */\n\tdictionaries?: Record<string, Record<string, any>>;\n\t/** Active language code (defaults to fallbackLanguage, then 'en'). */\n\tlanguage?: string;\n\t/** Fallback language merged under the active language (defaults to 'en'). */\n\tfallbackLanguage?: string;\n}\n```\n\nThe configuration is also exposed through the `HUB_TRANSLATION_CONFIG` injection token for advanced scenarios.\n\n### `HUB_TRANSLATION_PREFIX`\n\nInjection token that scopes a library's lookups to a collision-safe `HUBUI.<LIBRARY>.*`\nnamespace. `TranslatePipe` resolves the prefixed key first and falls back to the bare key,\nso a flat dictionary that predates the token keeps working untouched.\n\n```typescript\nproviders: [{ provide: HUB_TRANSLATION_PREFIX, useValue: 'HUBUI.TABLE' }];\n```\n\nThe adapter types are exported alongside it: `HubTranslationSource`,\n`HubTranslationOverrides`, `HubTranslationAdapterConfig`, `HubTranslationAdapterFactory`\nand the `HUB_TRANSLATION_SOURCE` token `provideHubTranslationAdapter()` registers.\n\n### `HubTranslationService`\n\nInjectable service that holds the active translations and notifies subscribers when they change.\n\n```typescript\n@Injectable()\nclass HubTranslationService {\n\t/** Currently active flat translations map. */\n\ttranslations: Record<string, string>;\n\t/** Emits whenever the active translations are updated. */\n\ttranslationObserver: Observable<Record<string, string>>;\n\n\t/** Resolves a key (supports dot notation) against the active translations. */\n\tgetTranslation(key: string): any;\n\t/** Replaces the active translations, merging them over the fallback dictionary. */\n\tsetTranslations(translations?: Record<string, string>): void;\n}\n```\n\n```typescript\nimport { HubTranslationService } from 'ng-hub-ui-utils';\n\n@Component({/* ... */})\nexport class LanguageSwitcherComponent {\n\tprivate translationSvc = inject(HubTranslationService);\n\n\tswitchToSpanish() {\n\t\t// Swap the active dictionary at runtime; the `translate` pipe updates automatically.\n\t\tthis.translationSvc.setTranslations({ greeting: '¡Hola {name}!' });\n\t}\n}\n```\n\n### `TranslatePipe` (`translate`)\n\nImpure standalone pipe that resolves a translation key with optional interpolation params. It subscribes to the service so the view stays in sync when translations change.\n\n```typescript\n// Simple key\n{{ 'greeting' | translate }}\n\n// With an object of interpolation params\n{{ 'greeting' | translate: { name: 'Carlos' } }}\n\n// Params can also be written inline as a pseudo-object string\n{{ 'greeting' | translate: \"{name: 'Carlos'}\" }}\n```\n\nIf a key has no matching translation, the key itself is returned. Interpolation tokens use the `{paramName}` syntax (powered by the `interpolateString` utility).\n\n### Supporting utilities\n\nThese functions back the i18n system and are exported for direct use:\n\n- `getValue(target: any, key: string): any` - Reads a nested value by dot-notation key.\n- `interpolateString(text: string, params?: object): string` - Replaces `{token}` placeholders in a string.\n- `equals(o1: any, o2: any): boolean` - Deep equality check used to memoize the pipe value.\n\n## 📊 Utilities API\n\n### Conversion Functions\n\n- `toInteger(value: any): number` - Safely converts to integer\n- `toString(value: any): string` - Converts to string handling null/undefined\n- `getValueInRange(value: number, max: number, min?: number): number` - Limits value to range\n- `padNumber(value: number): string` - Adds leading zero to numbers\n\n### Validation Functions\n\n- `isString(value: any): value is string` - Checks if value is a string\n- `isNumber(value: any): value is number` - Checks if value is a valid number\n- `isInteger(value: any): value is number` - Checks if value is an integer\n- `isDefined(value: any): boolean` - Checks if not null/undefined\n- `isPromise<T>(v: any): v is Promise<T>` - Checks if value is a Promise\n\n### String Functions\n\n- `regExpEscape(text: string): string` - Escapes special characters for RegExp\n- `removeAccents(str: string): string` - Removes accents from text\n- `interpolateString(expr?: string, params?: any, templateMatcher?: RegExp): string` - Replaces `{{ token }}` placeholders\n- `generateUniqueId(length: number): string` - Random alphanumeric id, for a DOM node that needs one\n\n### Object Functions\n\n- `equals(o1: any, o2: any): boolean` - Deep equality\n- `getValue(target: any, key: string): any` - Reads a nested value by dot-notation key\n- `isObject(item: any): boolean` - Whether the value is a non-array object\n- `mergeDeep(target: any, source: any): any` - Recursive merge; the only deep object helper in the package\n\n### Signal Utilities\n\n- `debouncedSignal<T>(source: Signal<T>, delay?: number | Signal<number>): Signal<T>` - Mirrors a signal, delaying each change; the delay can itself be a signal\n\n### DOM Functions\n\n- `closest(element: HTMLElement, selector?: string): HTMLElement | null` - Finds parent element by selector\n- `reflow(element: HTMLElement): DOMRect` - Forces browser reflow\n- `getActiveElement(root?: Document | ShadowRoot): Element | null` - Gets active element including Shadow DOM\n\n### Accent Resolution\n\n- `resolveHubAccent(value: string | null | undefined): string | null` - The \"any colour\" accent resolver shared across the family: a bareword becomes `var(--hub-sys-color-<name>, <name>)`, a literal `#hex` / `rgb()` / `oklch()` / `var()` passes through unchanged, and an empty value yields `null`\n\n### Colour Functions\n\n- `parseColor(value): HubRgb | null` - Parses hex (3/4/6/8), `rgb()`, `hsl()`, `oklch()`, `oklab()`, the 148 CSS named colours and `transparent`, in modern and legacy syntax. No DOM, so it runs under SSR. Returns `null` — never throws — for anything it cannot resolve, `var()` and `currentColor` included\n- `toRgb(color): HubRgb | null` - Normalises a string or parsed colour to channels\n- `toHex(color): string | null` - Renders as `#rrggbb`, or `#rrggbbaa` when translucent\n- `isValidColor(value): boolean` - Whether the parser can resolve the string\n- `HUB_NAMED_COLORS: Readonly<Record<string, string>>` - The 148 CSS named colours\n\n### Contrast Functions\n\n- `relativeLuminance(color): number | null` - WCAG 2 relative luminance, 0 to 1\n- `contrastRatio(a, b): number | null` - WCAG 2 contrast ratio, 1 to 21\n- `contrastAPCA(text, background): number | null` - APCA lightness contrast, polarity-aware\n- `compositeOver(foreground, background): HubColor` - Blends translucent over opaque\n- `readableOn(background, metric?): string` - Black or white, whichever reads better. Defaults to `'lightness'`, the same decision `--hub-sys-color-*-on` makes in CSS; `'apca'` and `'wcag'` are also available\n- `HUB_INK_LIGHTNESS_THRESHOLD: number` - The OKLCh lightness above which a surface takes dark ink\n\n### OKLCh Functions\n\n- `rgbToOklch(color): HubOklch` / `oklchToRgb(color): HubRgb` - Conversions in the space the design system mixes in\n- `maxSrgbChroma(l, h): number` - Highest in-gamut chroma for a hue at a lightness. The sRGB gamut is not a cylinder — at L 0.578 blue reaches 0.232 and amber only 0.119 — so a palette cannot give every hue the same absolute chroma\n- `isInSrgbGamut(color): boolean` - Whether the colour survives the trip to sRGB\n- `clampToSrgbGamut(color): HubOklch` - Reduces chroma until it fits, preserving lightness and hue\n\n### Palette Derivation\n\nOne brand colour, the whole palette — and the two numbers that keep it honest.\n\n- `harmoniseSemantics(primary, options?): HubSemanticPalette | null` - Rotates `success`, `warning`, `danger` and `info` towards the brand's hue and returns them as hex. Lightness is left exactly where the anchor had it, because it is what carries the contrast each role was chosen for; chroma is reduced only when the new hue cannot hold it inside sRGB\n- `tintNeutrals(primary, options?): HubNeutralRamp | null` - Leans the grey ramp (`100` … `900`) the same way, keeping each step's lightness\n- `HUB_MAX_HUE_SHIFT: number` (15) - How far a role may rotate, in degrees. Not taste: success and danger sit 135.8° apart in OKLCh, and a viewer with deuteranopia separates them by hue alone. A brand hue between the two pulls both inwards, so the gap closes by up to twice the cap; at 22.9° it would reach the 90° floor. 15° leaves the worst case at 105.8°\n- `HUB_MAX_NEUTRAL_CHROMA: number` (0.015) - The most chroma a tinted neutral may carry. Anchored on the ramp the design system already ships — `gray-600` measures 0.0165 and `gray-500` 0.0145 — so a tinted ramp is never more colourful than the grey people already accept as grey\n- `HUB_SEMANTIC_ANCHORS` / `HUB_NEUTRAL_ANCHORS` - The untinted starting points, so a product that harmonises nothing still gets the palette the stylesheet ships\n- Types: `HubSemanticRole`, `HubSemanticPalette`, `HubNeutralStep`, `HubNeutralRamp`, `HubHarmoniseOptions`, `HubTintNeutralsOptions`\n\n```typescript\nimport { harmoniseSemantics, tintNeutrals } from 'ng-hub-ui-utils';\n\nharmoniseSemantics('#6f42c1');\n// { success: '#00866b', warning: '#ffbd6e', danger: '#d8336b', info: '#44c4ff' }\n\ntintNeutrals('#6f42c1'); // greys leaning violet, chroma never above 0.015\n```\n\nA brand with no hue of its own — a pure grey — leaves both sets untouched: OKLCh's hue on a grey\nis rounding noise, and harmonising towards it would rotate every role in a direction nobody chose.\n\n### Focus Functions\n\n- `getFocusableBoundaryElements(element: HTMLElement): HTMLElement[]` - Gets first and last focusable elements\n- `hubFocusTrap(zone, element, stopFocusTrap$, refocusOnClick?)` - Creates focus trap for modals/overlays\n- `FOCUSABLE_ELEMENTS_SELECTOR: string` - CSS selector for focusable elements\n\n### Drag and Drop\n\nThe engine-agnostic half of native HTML5 drag and drop, shared by the libraries that\nimplement it. The UI primitives — handle, placeholder and preview directives — stay in each\nlibrary, because their selectors and data models differ.\n\n- `HubDragDropService` - Root-provided coordinator. A drag spans two component instances and the native `dataTransfer` payload is unreadable during `dragover`, so a shared service is the only reliable channel for what is being dragged and from where. Owners `register()` / `unregister()`; `begin()`, `setTarget()` and the readonly `active` / `target` / `isDragging` signals report the drag in progress. It coordinates state only — it never mutates your collections\n- `moveItemInArray<T>(array, fromIndex, toIndex): void` / `transferArrayItem<T>(source, target, fromIndex, toIndex): void` / `copyArrayItem<T>(source, target, fromIndex, toIndex): void` - In-place array moves, mirroring the `@angular/cdk` helpers of the same names\n- `clamp(value, max)`, `computeTargetIndex(...)`, `toAbsoluteIndex(...)`, `containsNode(...)` - Index arithmetic for sliced and nested lists\n- `resolveDropPosition(...)` with `DropRect` and `DragAxis` - Where a pointer sits relative to an item: `'before'` or `'after'`, on a vertical, horizontal or grid axis\n- `createNativeDragImage(...)` returning `DragImageResult` - Renders the drag preview the browser shows\n- `createPointerDragSession(config: PointerDragSessionConfig): PointerDragSession` - Pointer Events fallback for touch, where native drag events are not delivered\n- Types: `DropPosition`, `DragPointerMode`, `DragContainerRef<T>`, `ActiveDrag<T>`, `DragTarget<T>`, `DragRegistration`\n\n### Directives\n\n- `HubTooltipDirective` (`[hubTooltip]`) - Tooltip on hover/focus, flipped away from the window edges. Inputs: `hubTooltip`, `hubTooltipPlacement`, `hubTooltipDelay`, `hubTooltipOffset`\n- `HubOverflowTooltipDirective` (`[hubOverflowTooltip]`) - Tooltip shown only while the label is truncated. Inputs: `hubOverflowTooltip`, `placement`, `hubOverflowTooltipMeasure` (CSS selector, resolved inside the host, naming the box whose truncation decides it; defaults to the host)\n- `provideHubTooltip(adapter: HubTooltipAdapter)` and `HUB_TOOLTIP_ADAPTER` - Swap the implementation behind `[hubOverflowTooltip]`, app-wide or per subtree; defaults to `hubTooltipAdapter`\n\n### Pipes\n\n#### GetPipe\n\n```typescript\n// Safe nested property access\n{{ object | get:'path.to.property':'defaultValue' }}\n```\n\n#### IsStringPipe\n\n```typescript\n// Type checking\n@if (value | isString) { <span>String value</span> }\n```\n\n#### IsObjectPipe\n\n```typescript\n// Object checking\n@if (value | isObject) { <span>Object value</span> }\n```\n\n#### IsObservablePipe\n\n```typescript\n// Observable checking\n@if (stream | isObservable) { <span>Observable stream</span> }\n```\n\n#### UcfirstPipe\n\n```typescript\n// Capitalize first letter\n{{ 'hello world' | ucfirst }}  <!-- Hello world -->\n```\n\n#### UnwrapAsyncPipe\n\n```typescript\n// Unwrap Observable or return direct value\n{\n\t{\n\t\tobservableOrValue | unwrapAsync;\n\t}\n}\n```\n\n### Services\n\n#### OverlayService\n\n```typescript\n@Injectable({ providedIn: 'root' })\nclass OverlayService {\n\tcreate(config?: OverlayConfig): OverlayRef;\n\tposition(): OverlayPosition;\n}\n\nclass OverlayRef {\n\t// Renders a template or a component into the overlay and returns the host element,\n\t// not a ComponentRef: the overlay owns the view it created and tears it down itself.\n\tattach(content: TemplateRef<unknown> | Type<unknown>, viewContainerRef?: ViewContainerRef): HTMLElement;\n\tdetach(): void;\n\tdispose(): void;\n\thasAttached(): boolean;\n\tupdatePosition(): void;\n\tonBackdropClick(callback: () => void): void;\n\t// Only the topmost open overlay is told, so a dropdown inside a dialog takes Escape\n\t// for itself and leaves the dialog open.\n\tonKeydown(callback: (event: KeyboardEvent) => void): void;\n}\n\nclass OverlayPosition {\n\t// The element the panel is anchored to. The overlay watches it and follows it when it moves.\n\treadonly origin: HTMLElement | null;\n\tflexibleConnectedTo(origin: ElementRef | HTMLElement): this;\n\twithPositions(positions: ConnectionPosition[]): this;\n\t// `start` / `end` are logical and read from the origin element; this overrides that.\n\twithDirection(direction: 'ltr' | 'rtl' | null): this;\n}\n```\n\n`HUB_DROPDOWN_POSITIONS` is the ready-made fallback chain for a dropdown — below the\norigin, flipping above when there is no room — expressed logically so one list serves\nboth text directions:\n\n```typescript\nimport { HUB_DROPDOWN_POSITIONS } from 'ng-hub-ui-utils';\n\noverlayService\n\t.position()\n\t.flexibleConnectedTo(origin)\n\t.withPositions([...HUB_DROPDOWN_POSITIONS]);\n```\n\n#### Viewport fitting (`viewport-fit`)\n\nThe arithmetic behind both the overlay strategy and the tooltip, exported on its own so a floating\nelement that is neither does not have to write a third copy. It takes plain numbers, touches no DOM\nand runs unchanged on a server render.\n\n```typescript\nimport { hubAnchorToViewport, hubToAnchorSide, hubToPhysicalSide, hubViewportOf } from 'ng-hub-ui-utils';\n\nconst rtl = getComputedStyle(host).direction === 'rtl';\n\nconst placed = hubAnchorToViewport({\n\tanchor: host.getBoundingClientRect(),\n\tbox: { width: panel.offsetWidth, height: panel.offsetHeight },\n\tviewport: hubViewportOf(panel), // null on a server render: nothing flips\n\tside: hubToAnchorSide('bottom', rtl), // 'block-start' | 'block-end' | 'inline-start' | 'inline-end'\n\talign: 'start', // logical: mirrors under RTL\n\toffset: 8,\n\tmargin: 0,\n\trtl\n});\n\n// placed.x / placed.y are viewport coordinates — add scrollX / scrollY for an absolutely\n// positioned element. placed.side is where it ended up, placed.flipped whether that was a flip.\npanel.dataset['side'] = hubToPhysicalSide(placed.side, rtl);\n```\n\nThe requested side is kept unless it genuinely cannot hold the box **and** the opposite side has\nmore room, so nothing flips for free; the cross axis is clamped rather than flipped, since a box\ncentred on an anchor near the inline edge overflows there whichever side it opens on. Sides are\nlogical so a single fallback rule serves both text directions — `hubToAnchorSide` and\n`hubToPhysicalSide` round-trip a physical edge through that axis without changing what the caller\nasked for.\n\nAlso exported: `hubFitsInViewport(point, size, viewport, margin?)`,\n`hubClampToViewport(point, size, viewport, margin?)` and `hubOppositeSide(side)`.\n\n#### ScrollBar Service\n\n```typescript\n@Injectable({ providedIn: 'root' })\nclass ScrollBar {\n\thide(): ScrollbarReverter; // Hides scrollbar with compensation\n}\n```\n\n#### PopupService&lt;T&gt;\n\nA concrete generic class, not an abstract one: it takes the popup component type in its\nconstructor, and it reads its collaborators with `inject()`, so it has to be created inside\nan injection context — as an `@Injectable()` subclass, or from a factory provider.\n\n```typescript\nclass PopupService<T> {\n\tconstructor(componentType: Type<T>);\n\topen(\n\t\tcontent?: string | TemplateRef<any>,\n\t\ttemplateContext?: any,\n\t\tanimation?: boolean\n\t): { windowRef: ComponentRef<T>; transition$: Observable<void> };\n\tclose(animation?: boolean): Observable<void>;\n}\n\n// The nodes and view a popup projects, returned internally by the content resolver.\nclass ContentRef {\n\tconstructor(nodes: Node[][], viewRef?: ViewRef, componentRef?: ComponentRef<any>);\n}\n```\n\n### Transition Utilities\n\n- `hubRunTransition<T>(zone, element, startFn, options)` - Advanced transition system with Observable\n- `hubCompleteTransition(element)` - Completes a running transition on an element\n- `getTransitionDurationMs(element)` - Gets CSS transition duration in milliseconds\n- `runInZone<T>(zone)` - RxJS operator to execute observables inside NgZone\n\n## 🎨 Support Components\n\nThis library doesn't include visual components, but support utilities used by other components in the Hub UI ecosystem:\n\n| Utility         | Description                         | Used by                              |\n| --------------- | ----------------------------------- | ------------------------------------ |\n| Overlay Service | Flexible overlay positioning system | ng-hub-ui-modal, ng-hub-ui-portal    |\n| Focus Trap      | Focus management in modals/overlays | ng-hub-ui-modal, ng-hub-ui-portal    |\n| Scrollbar       | Scrollbar compensation              | ng-hub-ui-modal, ng-hub-ui-portal    |\n| Popup Service   | Host for dynamically created popups | ng-hub-ui-modal, ng-hub-ui-portal    |\n| Transitions     | Smooth animations                   | ng-hub-ui-accordion, ng-hub-ui-modal |\n| Type Guards     | Type validation functions           | ng-hub-ui-stepper                    |\n| Pipes           | Template utilities                  | All Hub UI components                |\n\n## 🤝 Compatibility\n\n- Angular 16+\n- TypeScript 4.8+\n- Node.js 16+\n- Browsers: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+\n\n## 🛠️ Development\n\n```bash\ngit clone https://github.com/hub-env/ng-hub-ui-utils\ncd ng-hub-ui-utils\nnpm install\nnpm run build\nnpm run test\n```\n\n### Available Scripts\n\n```bash\nnpm run build:lib        # Build library\nnpm run test:unit        # Unit tests\nnpm run test:e2e         # End-to-end tests\nnpm run lint             # Linting\nnpm run format           # Format code\n```\n\n## 🧪 Testing\n\n```typescript\nimport { TestBed } from '@angular/core/testing';\nimport { ScrollBar, toInteger, isString, GetPipe } from 'ng-hub-ui-utils';\n\ndescribe('ng-hub-ui-utils', () => {\n\tit('should convert values safely', () => {\n\t\texpect(toInteger('42')).toBe(42);\n\t\texpect(toInteger('invalid')).toBe(NaN);\n\t\texpect(isString('hello')).toBe(true);\n\t\texpect(isString(42)).toBe(false);\n\t});\n\n\tit('should manage scrollbar', () => {\n\t\tconst scrollBar = TestBed.inject(ScrollBar);\n\t\tconst reverter = scrollBar.hide();\n\n\t\texpect(typeof reverter).toBe('function');\n\t\treverter(); // Cleanup\n\t});\n\n\tit('should get nested properties safely', () => {\n\t\tconst pipe = new GetPipe();\n\t\tconst obj = { user: { name: 'John' } };\n\n\t\texpect(pipe.transform(obj, 'user.name')).toBe('John');\n\t\texpect(pipe.transform(obj, 'user.age', 0)).toBe(0);\n\t});\n});\n```\n\n## 📋 Changelog\n\nAll notable changes are documented in the [CHANGELOG.md](./CHANGELOG.md), following [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\nRecent highlights:\n\n- **1.2.1** — Renamed internal i18n files and refreshed `TranslatePipe`; added a test suite for `HubTranslationService`.\n- **1.2.0** — Added the i18n system (`HubTranslationService`, `provideHubTranslation`, `TranslatePipe`, translation tokens) plus the `equals`, `interpolateString` and `getValue` utilities.\n\n### External translation services\n\n`HubTranslationService` is intentionally framework-agnostic. Applications using Transloco or ngx-translate can extract a library namespace when the language changes and pass it to `setTranslations()`. Libraries such as Calendar, Stepper and Paginable consume that bridge; their README files document the namespace each expects.\n\n```typescript\n// Transloco: hubTranslation.setTranslations(transloco.translateObject('STEPPER'))\n// ngx-translate: hubTranslation.setTranslations(translate.instant('STEPPER'))\n```\n\n## 🐛 Issues and Support\n\n- [Report a bug](https://github.com/hub-env/hub-ui/issues)\n- [Request a feature](https://github.com/hub-env/hub-ui/issues/new?template=feature_request.yml)\n- [Repository](https://github.com/hub-env/ng-hub-ui-utils)\n- **Author**: [Carlos Morcillo](https://www.carlosmorcillo.com)\n\n## ☕ Support the Project\n\nIf Hub UI has been useful to you, consider supporting its development:\n\n[![Buy Me A Coffee](https://img.shields.io/badge/Buy%20Me%20A%20Coffee-support-yellow.svg?style=flat-square&logo=buy-me-a-coffee)](https://buymeacoffee.com/carlosmorcillo)\n[![Sponsor](https://img.shields.io/badge/Sponsor-GitHub-red.svg?style=flat-square&logo=github)](https://github.com/sponsors/carlos-morcillo)\n\nYour support helps to:\n\n- 🚀 Keep the project active\n- 🐛 Fix bugs faster\n- ✨ Develop new features\n- 📚 Improve documentation\n\n## 🤝 Contributions\n\nContributions are welcome! Please:\n\n1. 🍴 Fork the repository\n2. 🌿 Create a branch for your feature (`git checkout -b feature/new-utility`)\n3. ✍️ Commit your changes (`git commit -am 'feat: add new utility'`)\n4. 📤 Push to the branch (`git push origin feature/new-utility`)\n5. 🔄 Open a Pull Request\n\nCheck our [contribution guidelines](CONTRIBUTING.md) for more details.\n\n## 💼 Commercial support\n\nThese libraries are maintained by [Carlos Morcillo Fernández](https://www.carlosmorcillo.com), a freelance frontend architect working with teams that build and maintain Angular applications.\n\nIf your team depends on Hub-UI and needs more than an issue thread can solve, that is my day job: architecture audits, design systems, Angular migrations and team mentoring. For projects that also need design and a full team, I run them through [Frog Hub](https://froghub.es), my development studio.\n\nHave a look at [the services](https://www.carlosmorcillo.com/en/services/) or [tell me about your project](https://www.carlosmorcillo.com/en/contact/).\n\n## 📄 License\n\nMIT © Hub UI contributors\n\n```\nMIT License\n\nCopyright (c) 2025 Hub UI Team\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n\n---\n\n⭐ **If you like this project, don't forget to give it a star on GitHub!**\n\n[![GitHub stars](https://img.shields.io/github/stars/hub-env/hub-ui.svg?style=social&label=Star)](https://github.com/hub-env/hub-ui)\n","readmeFilename":"README.md"}