{"_id":"@apx-ui/toolkit","_rev":"14-92105053e99624873822f608621c28ea","name":"@apx-ui/toolkit","dist-tags":{"latest":"1.0.14"},"versions":{"1.0.0":{"name":"@apx-ui/toolkit","version":"1.0.0","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.0","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"95c179b11d2bb7f2e3257d28411934dc251c22d8","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.0.tgz","fileCount":84,"integrity":"sha512-WxyakCGpYv7rVtCNWmfLkKl1S/1lPti1WkjRz5S6s+qwLDscCxQNVF1fJ+4APuZTwrK0XqZvrD5Q3IfDnM/3sA==","signatures":[{"sig":"MEUCIQDtQFG/p0LGW1OEc+MqGzpo4ARg9rxm0Z3hh7QaJkDHSQIgeaZgVE7lkWJchT8DfMeejoFs8T+lCyq3gDpHaKJwPms=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":476176},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"0d3d319667713032d148e77155cf3bf69ecf42ae","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.9.3","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"22.19.0","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.0_1756898122226_0.6376294559327269","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@apx-ui/toolkit","version":"1.0.2","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.2","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"b4865738ceb840f01ee6a0392362a3b3e6522260","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.2.tgz","fileCount":84,"integrity":"sha512-4am8uzx8PXdHuzOGZxHnG2zJrUsFM3jt8tWIGXJSdziDjozzzfee58RVQ9Lt0h6zUe3PcX5bTgcviTNgKt0Ltg==","signatures":[{"sig":"MEUCIF9s3dViq/qkzllD4Yx0r7zertoW/h9DJUCIwe+Pi5G8AiEAzZCHrqRPn/oiv+7JBnWa7wSfrJObYbW3ABE/nGS1A9I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":476899},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"8b09ff42ddd8caddb36cc2be8277f2432eee36a3","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.2_1756924591601_0.5877936764514309","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@apx-ui/toolkit","version":"1.0.3","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.3","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"b2aca46841ce96e16487bdab59dd75c576359d32","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.3.tgz","fileCount":84,"integrity":"sha512-Oc8c47bMzRfRzyyXMJE/PHYnd/QxcGqsEOCP8eDSPrNx96ZfQ9sNx2fH7IOrttC72PuStJDQMoO3dmGTY8I55Q==","signatures":[{"sig":"MEQCIAy8uLGPY+XCkBMXdLhsEXOWrELHfYseJpSgdPORF17BAiBjJgjYpaS1wSE5Aj/rA0FvJuyXSW1D31ypYJWyWg8Paw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":477030},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"396bf85fe82840fecd090eaaf4a512e50e1fa33d","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.3_1756929630077_0.678000503207284","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@apx-ui/toolkit","version":"1.0.4","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.4","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"4fec0ea695beb48f66b7fdcf246f3a2c0e00b299","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.4.tgz","fileCount":84,"integrity":"sha512-kC0vAYogWx0eWhFml+WjuVqceQSK7z9wAhk/ZcH9sriDHxCZ1yIyZgK8WnIfyPKCgF4KM1rHjp2fnftu7llfNA==","signatures":[{"sig":"MEUCIQD9dQ318mbcy+kFSidDSceAx5hWwD6VWAdDlRasAouoZAIgdziOHFOzYnGvwSK/V+Ma6AdoP49sraPyinJ/ZYD19T4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":477030},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"e219b2057dfe393fa03c5bf710b5b031d6fdd188","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.4_1756930051860_0.25078904295189486","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@apx-ui/toolkit","version":"1.0.5","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.5","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"8032a25bd947d4837af122fa5f03d03fc6c0bf00","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.5.tgz","fileCount":84,"integrity":"sha512-XvIp+smK69YkfzPGpGXfTX5w6UZKF+R9ck8e+6e0vdyEPz5IMY1idJLevjdZVlnQ7/1voPQfa/WNm9ZYp11lzg==","signatures":[{"sig":"MEUCIQC4QGaI3ck+I9t7BLHDoWjzH2N8GDLMbkV1Xd2vPMbCaQIgDIWn6LELZZJ+BaVafs/6cLhDb3dudcCzv8sZDsA9LKc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":477030},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"0c988a943e35831ee2c5160a1f8b4b2b09d0ffad","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.5_1756972637653_0.6054863208517116","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@apx-ui/toolkit","version":"1.0.6","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.6","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"37e86dc891eea6f515e135f13747ecdc669c1382","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.6.tgz","fileCount":84,"integrity":"sha512-Xpyzf7AcvTAenSWgRhIq1o40ujSqGZzcqNTeF7iENLUrgdwsRqqii2dK0p6hlIRhRhInQQEUSLijtnAPxzGWmQ==","signatures":[{"sig":"MEYCIQD/YzBx9jNXF6TzbmoViWtToEZ8U2QifCEERxl9WyI1xQIhAPu+C6jdJ6ZRf+41Z1JUfMl6VB/wWYwAdQWAj6SYKgVH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":477030},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"62343472dfa30d78617941f99b96d58c2a4b575d","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.6_1757097010292_0.5767834948364934","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@apx-ui/toolkit","version":"1.0.7","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.7","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"439218d5e27fbd15ef893c15d3e03ccf0ad43736","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.7.tgz","fileCount":84,"integrity":"sha512-WM0JQIO4rcgtE5LucQFYYDz9IEHQR3dyBQq5asjlwOxEC4wr7urtaR4xDC5iNok+1OwZT69mmAnMN3Ds9yNeoA==","signatures":[{"sig":"MEUCIQCtYV1qsPkj/VDh6g4TVxaTnoCugBpLGQ4c1M1jaPZYAgIgC4/Yd/AGUOjnJcygsuJvaiJqQST6p7Vl20Z1AtwUbJ4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":489263},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"951745fe32e820c09c48c9c63812cd12c092e6c1","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.7_1757098697971_0.9470645162378517","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@apx-ui/toolkit","version":"1.0.8","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.8","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"bbf5f72c7ceb71e508a4459b720e9c43885c2990","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.8.tgz","fileCount":90,"integrity":"sha512-PR6XENbFbLfph/YbwOFUTX9ADJfu73ECwO8TQojCUWtlh+Y2LN1cH1qsQc6dw7Sv4Vp6w9HrrGBfMHvNh3JjHg==","signatures":[{"sig":"MEUCIQDqjRW6IuAx/qpwCPAJdkFC6CWaTnbkd5gWmUcvp1flAgIgRL7Aes47Key1auYncyQ87uYnemfFuybKF1UGxoSh9b8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":546460},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"2d4398d01501788931ec2a76fc4a9286fee993bf","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","dependencies":{},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.8_1757100064957_0.4739257018977776","host":"s3://npm-registry-packages-npm-production"}},"1.0.9":{"name":"@apx-ui/toolkit","version":"1.0.9","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.9","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"3da8f0fda3f7c6cb45fe461f8e656591ebb2378d","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.9.tgz","fileCount":66,"integrity":"sha512-PLI2kaXvw46t5jnP1EBILIFUO0wiXC2uFbKecSnZoS5AvbRTYq/DPpOMWBZXhzEnpaDaNXgT309QNDmhwyYwww==","signatures":[{"sig":"MEUCIQCGpVt+GWKgjH8sAzvdiM4ntlhIdTXF7S/wnMFUzVFe6wIgGbZFqACLdXZDcfH2KnwBYxWsLD9Z/O58nUtvnjm5AnI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":372748},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"91aab42f9b0fc69ff8b1d06c52b35fdb67a51bea","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","prepare":"husky","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","husky":"^9.1.7","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.9_1757101483786_0.7249561012780639","host":"s3://npm-registry-packages-npm-production"}},"1.0.10":{"name":"@apx-ui/toolkit","version":"1.0.10","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.10","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"7cc3471a6a4e83b07fbc79a0b9b53143f1bf3bf2","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.10.tgz","fileCount":66,"integrity":"sha512-ML2GeUAUPWRv78GfvlvRVmlwdvCBrUOoe8fB5sFKKUxHzdBkqT/KxHHsIFr7yQJYxmtC24uht88FjTy19xHwZw==","signatures":[{"sig":"MEUCIQC4AkMsEXSXvAZmyk10MP8XiMgExwzINraZSkZIRaQQlQIgMbCOJoNjegH5FQuiIJANBIE8cSE6GTAZM4UCaUKbTUM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":372749},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"31ebedf7e7257158baf544db0a1ad5f404d7fc35","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","prepare":"husky","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","husky":"^9.1.7","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.10_1757102117368_0.8855535359120337","host":"s3://npm-registry-packages-npm-production"}},"1.0.11":{"name":"@apx-ui/toolkit","version":"1.0.11","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.11","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"ef7cef5b3ab57d67409796d1658ae8f204c5a204","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.11.tgz","fileCount":66,"integrity":"sha512-/ZYkCO4OIS7CGr9/U6DG79jgRytL4lAeNwntmf3KIMzRGdSXY0YK+E+UDkJkpozeWlQ5X4OtJFWRTMERwE5+/Q==","signatures":[{"sig":"MEUCIHGfLKtDqcmtuGYjQG3U0DlwbhfSZ9sh7qxoR410Xt9eAiEAoLJO5aYMdeuQTEE284wLtgNGdA4DUIu3jBAt4xXEasQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":373770},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"3f69b5c6dfd844ac9ec0e701d433857cbe04ee00","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","prepare":"husky","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","husky":"^9.1.7","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.11_1758377620544_0.24738928669872573","host":"s3://npm-registry-packages-npm-production"}},"1.0.12":{"name":"@apx-ui/toolkit","version":"1.0.12","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.12","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"4cd7e695b1cb87f8159ac5e9cb00b724dc6749b6","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.12.tgz","fileCount":66,"integrity":"sha512-QUuN28Ckfs4YoiXBfpse92ioGWXganKGC9sstt9CJU9uVDe/eW0/ALTGnA8i3sCsAffFj3oO7t+NI3Js3X06Cg==","signatures":[{"sig":"MEUCIATqeewYhW8FcakbKmNKdVSVQFLH8Sn9BRCroMe/HEbkAiEA4hUcvNcZ6ELZbuXE0GVQKU+KG+UhUIlc1wpZBtbs0S0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":373805},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"6f2cc57f46d392fa1713b16ac1b4b03bec3564f9","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","prepare":"husky","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","husky":"^9.1.7","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.12_1758378138783_0.04383142103933624","host":"s3://npm-registry-packages-npm-production"}},"1.0.13":{"name":"@apx-ui/toolkit","version":"1.0.13","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","_id":"@apx-ui/toolkit@1.0.13","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"homepage":"https://github.com/appna-io/apx-toolkit#readme","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"dist":{"shasum":"b8d5a2b8af6d9d75ab07a8c9a9d4b1b6d7f13526","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.13.tgz","fileCount":66,"integrity":"sha512-/2psA+4PiAhyVt1s79PpA7ZhODcBCK7UWqzV5teMMpOfr8nw83MRE7+30Y56pDvMciYqZzfmVUyeTgE5K25kHw==","signatures":[{"sig":"MEQCIDVPvM8tcpJXuSgdi+4kYbpSbSlLNmF4RzmDKzwDqmv1AiBxAuYdFT1jkVGL1HntSMCxP91d4H2DG31g+Z47jbVODg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":374987},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"bed4f91abd4e9352b1c97c516f2b23695e5b1315","scripts":{"dev":"tsc --watch","lint":"eslint -c ./.eslintrc .","test":"jest","build":"tsc","clean":"rm -rf dist","upload":"npm version patch --no-git-tag-version && npm publish","prepare":"husky","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","test:watch":"jest --watch","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"repository":{"url":"git+https://github.com/appna-io/apx-toolkit.git","type":"git"},"_npmVersion":"10.7.0","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","directories":{},"_nodeVersion":"20.15.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","husky":"^9.1.7","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/toolkit_1.0.13_1759133057295_0.8645414118736172","host":"s3://npm-registry-packages-npm-production"}},"1.0.14":{"name":"@apx-ui/toolkit","version":"1.0.14","type":"module","description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","dev":"tsc --watch","test":"jest","test:watch":"jest --watch","lint:fix":"eslint -c ./.eslintrc --fix 'src/**/*.{ts,tsx}'","lint":"eslint -c ./.eslintrc .","clean":"rm -rf dist","prepublishOnly":"npm run clean && npm run build","upload":"npm version patch --no-git-tag-version && npm publish","build:docs":"npm run build && node docs/src/build-browser.js","serve:docs":"cd docs && python3 -m http.server 8080","prepare":"husky"},"publishConfig":{"registry":"https://registry.npmjs.org/","access":"public"},"repository":{"type":"git","url":"git+https://github.com/appna-io/apx-toolkit.git"},"keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"author":{"name":"AppNA UX Team"},"license":"ISC","devDependencies":{"@types/jest":"^29.5.0","@types/node":"^20.0.0","eslint-plugin-apx-eslint":"^1.0.0","husky":"^9.1.7","jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0"},"_id":"@apx-ui/toolkit@1.0.14","gitHead":"50f7d0e00aebdd695e9b6d5630260b44b02f5be1","bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"homepage":"https://github.com/appna-io/apx-toolkit#readme","_nodeVersion":"20.15.0","_npmVersion":"10.7.0","dist":{"integrity":"sha512-PlpccBEPGP/uv1cyZU6puMbmKmKIAB5X164LZKGS9guhgOmuB08kH/YEVS0RoTAGWf6FzINknlDOyTZFijufVg==","shasum":"4fd80da2ccc3b533c81d9d5ecda585e08aa19365","tarball":"https://registry.npmjs.org/@apx-ui/toolkit/-/toolkit-1.0.14.tgz","fileCount":69,"unpackedSize":397307,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDhIYfHq1jG+Yby1MFIDXwf+vW45mCBeh1KnopUQdHLoQIgMQ1vkz+6yPbAq3IUpiGgh59nspuhu23/YP7wf0Wl2KA="}]},"_npmUser":{"name":"igbaryya","email":"igbaryya@gmail.com"},"directories":{},"maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/toolkit_1.0.14_1763276797971_0.7170906507078574"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-03T11:15:22.165Z","modified":"2025-11-16T07:06:38.397Z","1.0.0":"2025-09-03T11:15:22.411Z","1.0.2":"2025-09-03T18:36:31.858Z","1.0.3":"2025-09-03T20:00:30.267Z","1.0.4":"2025-09-03T20:07:32.058Z","1.0.5":"2025-09-04T07:57:17.849Z","1.0.6":"2025-09-05T18:30:10.502Z","1.0.7":"2025-09-05T18:58:18.227Z","1.0.8":"2025-09-05T19:21:05.157Z","1.0.9":"2025-09-05T19:44:43.957Z","1.0.10":"2025-09-05T19:55:17.590Z","1.0.11":"2025-09-20T14:13:40.757Z","1.0.12":"2025-09-20T14:22:18.983Z","1.0.13":"2025-09-29T08:04:17.612Z","1.0.14":"2025-11-16T07:06:38.167Z"},"bugs":{"url":"https://github.com/appna-io/apx-toolkit/issues"},"author":{"name":"AppNA UX Team"},"license":"ISC","homepage":"https://github.com/appna-io/apx-toolkit#readme","keywords":["utility","validation","formatters","date","currency","regex","typescript","frontend","web"],"repository":{"type":"git","url":"git+https://github.com/appna-io/apx-toolkit.git"},"description":"Universal Web Utility SDK for apx-ui (AppNA UX/UI) frontend applications","maintainers":[{"name":"igbaryya","email":"igbaryya@gmail.com"},{"name":"appna_dev","email":"support@appna.io"}],"readme":"# @apx-ui/toolkit\r\n\r\n[![Apx Toolkit](https://img.shields.io/badge/apx-toolkit-blue.svg)](https://github.com/appna-io/apx-toolkit)\r\n[![AppNA.io](https://img.shields.io/badge/appna.io--UX/UI-orange.svg)](https://appna.io)\r\n[![apx-ui](https://img.shields.io/badge/tag-apx--ui-purple.svg)](https://github.com/appna-io/apx-toolkit)\r\n[![apx-ui](https://img.shields.io/badge/tag-AllInOne--Utility-purple.svg)](https://github.com/appna-io/apx-toolkit)\r\n[![220 test cases passed](https://img.shields.io/badge/passed-220--Tests-passed--green.svg)](https://github.com/appna-io/apx-toolkit/tree/main/src/__tests__)\r\n\r\nA modern utility SDK for frontend web applications.  \r\nIncludes regex-based validators, generic helpers, formatting utilities, date tools, magic constants, phone number formatting, scroll utilities, storage persister, and more.\r\n\r\n## Table of Contents\r\n\r\n- [Getting Started](#getting-started)\r\n  - [Installation](#1-installation)\r\n  - [Initialize Context](#2-initialize-context-recommended)\r\n  - [Basic Usage](#3-basic-usage)\r\n  - [Running Examples](#4-running-examples)\r\n- [What's Included?](#whats-included)\r\n  - [Validators (Regex-based)](#validators-regex-based)\r\n  - [Date & Time Utilities](#date--time-utilities)\r\n  - [Currency & Number Formatters](#currency--number-formatters)\r\n  - [Currency Utilities (Locale-based)](#currency-utilities-locale-based)\r\n  - [Phone Number Formatting](#phone-number-formatting)\r\n  - [Context System (Global Configuration)](#context-system-global-configuration)\r\n  - [I18N Formatters (Internationalization)](#i18n-formatters-internationalization)\r\n  - [Constants](#constants)\r\n  - [Regex Patterns](#regex-patterns)\r\n  - [Generic Helpers](#generic-helpers)\r\n  - [Scroll Utilities](#scroll-utilities)\r\n  - [Credit Card Utilities](#credit-card-utilities)\r\n  - [Opening Hours Formatter](#opening-hours-formatter)\r\n  - [Storage Persister](#storage-persister)\r\n- [Directory Structure](#directory-structure)\r\n- [Usage Examples](#usage-examples)\r\n  - [Validation](#validation)\r\n  - [Formatting](#formatting)\r\n  - [Date Utilities](#date-utilities)\r\n  - [Generic Helpers](#generic-helpers-1)\r\n  - [Constants](#constants-1)\r\n  - [Scroll Utilities](#scroll-utilities-1)\r\n  - [Storage Persister](#storage-persister-1)\r\n- [Testing](#testing)\r\n- [Contributing](#contributing)\r\n- [License](#license)\r\n\r\n---\r\n\r\n## Getting Started\r\n\r\n### 1. Installation\r\n\r\n```bash\r\nnpm install @apx-ui/toolkit\r\n```\r\n\r\nor\r\n\r\n```bash\r\nyarn add @apx-ui/toolkit\r\n```\r\n\r\n> **Note**: This package has **zero external dependencies**, making it lightweight and secure for production use.\r\n\r\n### 2. Initialize Context (Recommended)\r\n\r\nWe strongly recommend initializing the library context at the start of your application. This provides a centralized configuration for all utilities and ensures consistent behavior across your app.\r\n\r\n```typescript\r\nimport { config } from '@apx-ui/toolkit';\r\n\r\n// Initialize once at app startup\r\nconfig({\r\n    defaultLanguage: 'en',\r\n    defaultCurrency: 'USD', \r\n    defaultTimezone: 'America/New_York',\r\n    defaultRegion: 'US',\r\n    persist: 'localStorage', // 'localStorage' | 'sessionStorage' | 'memory' | false\r\n    debug: false\r\n});\r\n```\r\n\r\n**Context Benefits:**\r\n- All formatters automatically use your configured settings\r\n- User preferences persist across sessions\r\n- Consistent formatting throughout your application\r\n- Easy to change settings globally\r\n\r\n### 3. Basic Usage\r\n\r\n```typescript\r\nimport { \r\n    formatCurrencyI18N, \r\n    formatPhoneNumber, \r\n    isEmail, \r\n    scrollToTop \r\n} from '@apx-ui/toolkit';\r\n\r\n// Currency formatting uses context settings\r\nformatCurrencyI18N(1234.56); // Uses context currency & locale\r\n\r\n// Phone number formatting\r\nformatPhoneNumber('+12345678901', '+C (PPP)-EEE-SSSS'); // '+1 (234)-567-8901'\r\n\r\n// Validation\r\nisEmail('user@example.com'); // true\r\n\r\n// Scroll utilities\r\nscrollToTop({ duration: 1000, easing: 'easeInOut' });\r\n```\r\n\r\n### 4. Running Examples\r\n\r\nThe project includes comprehensive examples in the `examples/` directory:\r\n\r\n```bash\r\n# Run specific examples\r\nnpx ts-node examples/basic-usage.ts\r\nnpx ts-node examples/phone-formatting-examples.ts\r\nnpx ts-node examples/scroll-utilities-demo.ts\r\nnpx ts-node examples/persister-demo.ts\r\nnpx ts-node examples/real-world-usage.ts\r\n```\r\n\r\n**Available Examples:**\r\n- `basic-usage.ts` - Core utilities overview\r\n- `comprehensive-validators-demo.ts` - All validation functions with examples\r\n- `comprehensive-formatters-demo.ts` - All formatting functions with examples\r\n- `comprehensive-date-utilities-demo.ts` - All date utilities with examples\r\n- `comprehensive-generic-utilities-demo.ts` - All generic helper functions with examples\r\n- `credit-card-demo.ts` - Credit card utilities with formatting, validation, and dummy generation\r\n- `opening-hours-demo.ts` - Opening hours formatting with multi-language support\r\n- `phone-formatting-examples.ts` - Phone number formatting patterns\r\n- `phone-number-demo.ts` - Phone number utility demo\r\n- `scroll-utilities-demo.ts` - Smooth scrolling utilities\r\n- `persister-demo.ts` - Storage with TTL functionality\r\n- `real-world-usage.ts` - Production-ready patterns\r\n- `context-demo.ts` - Context system usage\r\n- `i18n-formatters-demo.ts` - Internationalization\r\n- `region-currency-demo.ts` - Currency mapping\r\n- `currency-utils-example.ts` - Locale-based currency utilities\r\n- `time-formatter-demo.ts` - Time formatting\r\n- `translations-demo.ts` - Translation utilities\r\n\r\n---\r\n\r\n## What's Included?\r\n\r\n### Validators (Regex-based)\r\n\r\n```ts\r\nisEmail(value: string): boolean\r\nisPhone(value: string): boolean\r\nisNumeric(value: string): boolean\r\nisAlphanumeric(value: string): boolean\r\nisValidURL(value: string): boolean\r\nisStrongPassword(value: string): boolean\r\nisCreditCard(value: string): boolean\r\nisIPv4(value: string): boolean\r\nisDate(value: string): boolean\r\nisTime(value: string): boolean\r\nisUUID(value: string): boolean\r\nisPostalCode(value: string): boolean\r\nisSSN(value: string): boolean\r\nisCurrency(value: string): boolean\r\nisHexColor(value: string): boolean\r\nisDomain(value: string): boolean\r\nisUsername(value: string): boolean\r\nhasValidFileExtension(value: string): boolean\r\nvalidateWithRegex(value: string, pattern: RegexPattern): boolean\r\n\r\n// Validation with detailed results\r\nvalidateEmail(email: string): ValidationResult\r\nvalidatePhone(phone: string): ValidationResult\r\nvalidateURL(url: string): ValidationResult\r\nvalidatePassword(password: string): ValidationResult\r\n```\r\n\r\n**Comprehensive Examples:**\r\n```ts\r\n// Basic validation\r\nisEmail('user@example.com'); // true\r\nisPhone('+1234567890'); // true\r\nisValidURL('https://example.com'); // true\r\nisStrongPassword('MyPass123!'); // true\r\n\r\n// Advanced validation\r\nisCreditCard('4111111111111111'); // true (Visa)\r\nisIPv4('192.168.1.1'); // true\r\nisUUID('550e8400-e29b-41d4-a716-446655440000'); // true\r\nisHexColor('#FF0000'); // true\r\nisDomain('example.com'); // true\r\n\r\n// Validation with detailed results\r\nconst emailResult = validateEmail('invalid-email');\r\nconsole.log(emailResult); // { valid: false, error: 'Invalid email format' }\r\n\r\nconst passwordResult = validatePassword('weak');\r\nconsole.log(passwordResult); // { valid: false, error: 'Password must be at least 8 characters long' }\r\n\r\n// Form validation example\r\nconst formData = {\r\n    email: 'user@example.com',\r\n    phone: '+1234567890',\r\n    password: 'MyPass123!',\r\n    website: 'https://example.com'\r\n};\r\n\r\nconst validation = {\r\n    email: validateEmail(formData.email),\r\n    phone: validatePhone(formData.phone),\r\n    password: validatePassword(formData.password),\r\n    website: validateURL(formData.website)\r\n};\r\n\r\n// Check all validations\r\nconst isFormValid = Object.values(validation).every(result => result.valid);\r\n```\r\n\r\n**Available Regex Patterns:**\r\n```ts\r\nREGEX = {\r\n    email: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/,\r\n    phone: /^(\\+?\\d{1,3})?\\d{7,14}$/,\r\n    numeric: /^\\d+$/,\r\n    alphanumeric: /^[a-zA-Z0-9]+$/,\r\n    url: /^(https?|ftp):\\/\\/[^\\s/$.?#].[^\\s]*$/i,\r\n    strongPassword: /^(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*]).{8,}$/,\r\n    creditCard: /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3[0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})$/,\r\n    ipv4: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,\r\n    date: /^\\d{4}-\\d{2}-\\d{2}$/,\r\n    time: /^([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/,\r\n    uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\r\n    postalCode: /^\\d{5}(-\\d{4})?$/,\r\n    ssn: /^\\d{3}-\\d{2}-\\d{4}$/,\r\n    currency: /^\\$?\\d+(\\.\\d{2})?$/,\r\n    hexColor: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,\r\n    domain: /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\\.[a-zA-Z]{2,}$/,\r\n    username: /^[a-zA-Z0-9_]{3,20}$/,\r\n    fileExtension: /\\.(jpg|jpeg|png|gif|pdf|doc|docx|txt|zip|rar)$/i\r\n}\r\n```\r\n\r\n### Date & Time Utilities\r\n\r\n```ts\r\nformatDate(date: Date | string, format?: string): string  // Default: 'YYYY-MM-DD'\r\ngetTimeAgo(date: Date | string): string                   // e.g., '3 hours ago'\r\nisSameDay(date1: Date, date2: Date): boolean\r\nisSameMonth(date1: Date, date2: Date): boolean\r\nisSameYear(date1: Date, date2: Date): boolean\r\ntoISOStringUTC(date: Date): string\r\nstartOfDay(date: Date): Date\r\nendOfDay(date: Date): Date\r\nstartOfWeek(date: Date): Date\r\nendOfWeek(date: Date): Date\r\nstartOfMonth(date: Date): Date\r\nendOfMonth(date: Date): Date\r\naddDays(date: Date, days: number): Date\r\naddMonths(date: Date, months: number): Date\r\naddYears(date: Date, years: number): Date\r\ngetDaysDifference(date1: Date, date2: Date): number\r\ngetHoursDifference(date1: Date, date2: Date): number\r\ngetMinutesDifference(date1: Date, date2: Date): number\r\nisToday(date: Date): boolean\r\nisYesterday(date: Date): boolean\r\nisTomorrow(date: Date): boolean\r\nisPast(date: Date): boolean\r\nisFuture(date: Date): boolean\r\ngetAge(birthDate: Date): number\r\nisLeapYear(year: number): boolean\r\ngetDaysInMonth(year: number, month: number): number\r\nformatDateLocale(date: Date, locale?: string, options?: Intl.DateTimeFormatOptions): string\r\n```\r\n\r\n### Currency & Number Formatters\r\n\r\n```ts\r\nformatCurrency(amount: number, currency?: string, locale?: string): string\r\nformatCompactNumber(num: number): string       // e.g., 1.5K, 2M\r\nformatFileSize(bytes: number): string\r\nformatPercentage(value: number, decimals?: number, locale?: string): string\r\nformatNumber(num: number, locale?: string, options?: Intl.NumberFormatOptions): string\r\nformatCreditCard(cardNumber: string, mask?: boolean): string\r\nformatSSN(ssn: string, mask?: boolean): string\r\nformatPostalCode(postalCode: string): string\r\nformatDuration(seconds: number): string\r\nformatRelativeTime(date: Date | string | number): string\r\nformatOrdinal(num: number): string\r\nformatBytes(bytes: number, decimals?: number): string\r\n```\r\n\r\n**Comprehensive Examples:**\r\n```ts\r\n// Currency formatting\r\nformatCurrency(1234.56); // $1,234.56\r\nformatCurrency(1234.56, 'EUR', 'de-DE'); // 1.234,56 €\r\nformatCurrency(1234.56, 'JPY', 'ja-JP'); // ¥1,235\r\n\r\n// Compact number formatting\r\nformatCompactNumber(1500); // 1.5K\r\nformatCompactNumber(2000000); // 2.0M\r\nformatCompactNumber(1500000000); // 1.5B\r\n\r\n// File size formatting\r\nformatFileSize(1024); // 1 KB\r\nformatFileSize(1048576); // 1 MB\r\nformatBytes(1024, 2); // 1.00 KB\r\n\r\n// Percentage formatting\r\nformatPercentage(12.5); // 12.50%\r\nformatPercentage(0.5, 1); // 0.5%\r\n\r\n// Personal data formatting\r\nformatCreditCard('4111111111111111', true); // ************1111\r\nformatSSN('123456789', true); // ***-**-6789\r\nformatPostalCode('123456789'); // 12345-6789\r\n\r\n// Time formatting\r\nformatDuration(3661); // 1h 1m 1s\r\nformatRelativeTime(new Date(Date.now() - 2 * 60 * 60 * 1000)); // 2 hours ago\r\nformatOrdinal(21); // 21st\r\nformatOrdinal(22); // 22nd\r\n\r\n// Number formatting with options\r\nformatNumber(1234.56, 'en-US', { \r\n    style: 'currency', \r\n    currency: 'USD' \r\n}); // $1,234.56\r\n\r\nformatNumber(0.1234, 'en-US', { \r\n    style: 'percent' \r\n}); // 12%\r\n```\r\n\r\n**Real-World Usage:**\r\n```ts\r\n// E-commerce product display\r\nconst product = {\r\n    name: 'Premium Headphones',\r\n    price: 299.99,\r\n    discount: 15,\r\n    fileSize: 1048576,\r\n    rating: 4.5\r\n};\r\n\r\nconsole.log(`Product: ${product.name}`);\r\nconsole.log(`Price: ${formatCurrency(product.price, 'USD')}`);\r\nconsole.log(`Discount: ${formatPercentage(product.discount)}`);\r\nconsole.log(`Final Price: ${formatCurrency(product.price * (1 - product.discount / 100), 'USD')}`);\r\nconsole.log(`File Size: ${formatFileSize(product.fileSize)}`);\r\nconsole.log(`Rating: ${formatNumber(product.rating, 'en-US', { minimumFractionDigits: 1, maximumFractionDigits: 1 })}/5`);\r\n```\r\n\r\n### Currency Utilities (Locale-based)\r\n\r\nGet currency information (code, symbol, name) from locale strings. Supports 50+ countries including Israel, UAE, USA, and Asian countries.\r\n\r\n```ts\r\ngetCurrencyByLocale(locale: string): CurrencyInfo | null\r\ngetCurrencyCode(locale: string): string | null\r\ngetCurrencySymbol(locale: string): string | null\r\nhasCurrencyMapping(locale: string): boolean\r\ngetSupportedCountryCodes(): string[]\r\ngetAllCurrencies(): CurrencyInfo[]\r\n\r\n// Types\r\ninterface CurrencyInfo {\r\n  code: string;    // ISO 4217 currency code (e.g., 'ILS', 'USD')\r\n  symbol: string;  // Currency symbol (e.g., '₪', '$')\r\n  name: string;    // Full currency name (e.g., 'Israeli New Shekel')\r\n}\r\n```\r\n\r\n**Supported Locale Formats:**\r\n\r\nThe utility handles various locale string formats:\r\n- Country code only: `IL`, `US`, `AE`\r\n- Language-Country with slash: `he/IL`, `en/US`, `ar/AE`\r\n- Language-Country with dash (BCP 47): `he-IL`, `en-US`, `ar-AE`\r\n- Language-Country with underscore: `he_IL`, `en_US`, `ar_AE`\r\n- Case-insensitive: `il`, `IL`, `Il`\r\n\r\n**Examples:**\r\n\r\n```ts\r\n// Israel - all formats return ILS\r\ngetCurrencyByLocale('he/IL'); // { code: 'ILS', symbol: '₪', name: 'Israeli New Shekel' }\r\ngetCurrencyByLocale('IL');    // { code: 'ILS', symbol: '₪', name: 'Israeli New Shekel' }\r\ngetCurrencyByLocale('he-IL'); // { code: 'ILS', symbol: '₪', name: 'Israeli New Shekel' }\r\ngetCurrencyByLocale('ar-IL'); // { code: 'ILS', symbol: '₪', name: 'Israeli New Shekel' }\r\n\r\n// Get just the currency code\r\ngetCurrencyCode('he/IL'); // 'ILS'\r\ngetCurrencyCode('IL');    // 'ILS'\r\ngetCurrencyCode('US');    // 'USD'\r\ngetCurrencyCode('ar-AE'); // 'AED'\r\n\r\n// Get just the currency symbol\r\ngetCurrencySymbol('IL');    // '₪'\r\ngetCurrencySymbol('US');    // '$'\r\ngetCurrencySymbol('en-GB'); // '£'\r\ngetCurrencySymbol('ar-AE'); // 'د.إ'\r\n\r\n// UAE and other Asian countries\r\ngetCurrencyCode('ar-AE'); // 'AED' (UAE Dirham)\r\ngetCurrencyCode('ar-SA'); // 'SAR' (Saudi Riyal)\r\ngetCurrencyCode('ja-JP'); // 'JPY' (Japanese Yen)\r\ngetCurrencyCode('zh-CN'); // 'CNY' (Chinese Yuan)\r\ngetCurrencyCode('ko-KR'); // 'KRW' (South Korean Won)\r\ngetCurrencyCode('hi-IN'); // 'INR' (Indian Rupee)\r\n\r\n// Check if locale has currency mapping\r\nhasCurrencyMapping('IL');     // true\r\nhasCurrencyMapping('he-IL');  // true\r\nhasCurrencyMapping('xyz-XYZ'); // false\r\n\r\n// Get all supported country codes\r\nconst codes = getSupportedCountryCodes();\r\n// ['IL', 'AE', 'SA', 'QA', 'KW', 'US', 'GB', 'DE', ...]\r\n\r\n// Get all unique currencies\r\nconst currencies = getAllCurrencies();\r\ncurrencies.forEach(currency => {\r\n  console.log(`${currency.code} (${currency.symbol}) - ${currency.name}`);\r\n});\r\n// ILS (₪) - Israeli New Shekel\r\n// USD ($) - US Dollar\r\n// EUR (€) - Euro\r\n// ...\r\n```\r\n\r\n**Supported Regions:** 50+ countries including:\r\n- 🇮🇱 Israel, 🇦🇪 UAE, 🇸🇦 Saudi Arabia, 🇶🇦 Qatar, 🇰🇼 Kuwait (Middle East)\r\n- 🇯🇵 Japan, 🇨🇳 China, 🇰🇷 South Korea, 🇮🇳 India, 🇸🇬 Singapore, 🇹🇭 Thailand (Asia)\r\n- 🇺🇸 USA, 🇨🇦 Canada, 🇲🇽 Mexico, 🇧🇷 Brazil (Americas)\r\n- 🇬🇧 UK, 🇩🇪 Germany, 🇫🇷 France, 🇪🇸 Spain (Europe)\r\n- 🇦🇺 Australia, 🇳🇿 New Zealand (Oceania)\r\n\r\n**Real-World Usage:**\r\n\r\n```ts\r\n// Multi-currency e-commerce\r\nconst getUserCurrency = (userLocale: string) => {\r\n  const currency = getCurrencyByLocale(userLocale);\r\n  if (currency) {\r\n    return formatCurrency(product.price, currency.code, userLocale);\r\n  }\r\n  return formatCurrency(product.price, 'USD', 'en-US'); // Fallback\r\n};\r\n\r\n// Internationalization setup\r\nconst initializeApp = (locale: string) => {\r\n  const currencyInfo = getCurrencyByLocale(locale);\r\n  if (currencyInfo) {\r\n    config({\r\n      defaultLanguage: locale.split(/[/-_]/)[0],\r\n      defaultCurrency: currencyInfo.code,\r\n      defaultRegion: locale.split(/[/-_]/)[1] || 'US'\r\n    });\r\n  }\r\n};\r\n\r\n// Display currency selector\r\nconst CurrencySelector = ({ currentLocale }: { currentLocale: string }) => {\r\n  const currencies = getAllCurrencies();\r\n  const currentCurrency = getCurrencyByLocale(currentLocale);\r\n  \r\n  return (\r\n    <select value={currentCurrency?.code}>\r\n      {currencies.map(currency => (\r\n        <option key={currency.code} value={currency.code}>\r\n          {currency.symbol} {currency.name}\r\n        </option>\r\n      ))}\r\n    </select>\r\n  );\r\n};\r\n```\r\n\r\nFor complete documentation, see [Currency Utilities Documentation](./docs/CURRENCY_UTILS.md).\r\n\r\n### Phone Number Formatting\r\n\r\n```ts\r\nformatPhoneNumber(\r\n  phone: string,\r\n  format: \"PPP - EEE SSSS\" | \"(PPP) - EEE SSSS\" | \"(PP)  EEE SSSS\" | \"PP-EEE SSSS\" | \"PPP-EEE SSSS\" | \"+C (PPP)-EEE-SSSS\" | \"+C (PPP) EEESSSS\" | \"E.164\" | string,\r\n  options?: {\r\n    leadingDigitPad?: string\r\n    inputIncludesCountry?: boolean | \"autoDetect\"\r\n    nationalNumberLength?: number\r\n    originCountry?: keyof typeof COUNTRY_CODES\r\n  }\r\n): string\r\n\r\n// Country codes constant\r\nCOUNTRY_CODES: {\r\n  IL: 972, US: 1, CA: 1, GB: 44, FR: 33, DE: 49, IT: 39, ES: 34, NL: 31, BE: 32, CH: 41, AT: 43, SE: 46, NO: 47, DK: 45, FI: 358, IE: 353, AU: 61, NZ: 64, AE: 971, SA: 966, JO: 962, EG: 20, TR: 90\r\n}\r\n```\r\n\r\n**E.164 format**\r\n\r\n- **What it is**: International standard, `+` country code + national number (no spaces/dashes/parentheses)\r\n- **Behavior**: Removes a single leading national trunk `0` from the national number when present\r\n\r\n```ts\r\n// Without country code (uses originCountry)\r\nformatPhoneNumber('0502892553', 'E.164', { originCountry: 'IL' });\r\n// '+972502892553'\r\n\r\n// With country code in input\r\nformatPhoneNumber('+9720502892553', 'E.164');\r\n// '+972502892553'\r\n```\r\n\r\n### Context System (Global Configuration)\r\n\r\nInitialize the library once with your preferred settings:\r\n\r\n```ts\r\nimport { config } from '@apx-ui/toolkit';\r\n\r\n// Initialize library on app startup\r\nconfig({\r\n    defaultLanguage: 'en',\r\n    defaultCurrency: 'USD', \r\n    defaultTimezone: 'America/New_York',\r\n    persist: 'localStorage', // 'localStorage' | 'sessionStorage' | 'memory' | false\r\n    debug: false\r\n});\r\n```\r\n\r\n**Context Functions**:\r\n```ts\r\n// Configuration\r\nconfig(options: ApxContextOptions): void\r\n\r\n// Language & Locale\r\nsetLanguage(language: string): void\r\ngetLanguage(): string\r\nsetLocale(locale: string): void\r\ngetLocale(): string\r\n\r\n// Currency & Timezone  \r\nsetCurrency(currency: string): void\r\ngetCurrency(): string\r\nsetTimezone(timezone: string): void\r\ngetTimezone(): string\r\n\r\n// Utilities\r\nresetContext(): void\r\nisInitialized(): boolean\r\nisBrowser(): boolean\r\n```\r\n\r\n**Storage Options**:\r\n```ts\r\npersist: 'localStorage'    // Persists across browser sessions\r\npersist: 'sessionStorage'  // Persists until tab closes  \r\npersist: 'memory'          // In-memory only (no persistence)\r\npersist: false             // No persistence, always use defaults\r\n```\r\n\r\n**Singleton Behavior**:\r\nThe context system is a singleton, meaning:\r\n- Initialize once at app startup with `config()`\r\n- Subsequent `config()` calls are ignored if already initialized\r\n- Use `resetContext()` to clear and reinitialize if needed\r\n- Perfect for SPAs where you want settings to persist across route changes\r\n\r\n### I18N Formatters (Internationalization)\r\n\r\n```ts\r\nformatCurrencyI18N(amount: number, currency?: string, locale?: string): string\r\nformatDateI18N(date: Date | string | number, format?: string, variant?: 'appointment' | 'default', locale?: string): string\r\nformatTimeI18N(value: number, unit: TimeUnit, locale?: string): string\r\n```\r\n\r\n**Context-Aware Usage** (Recommended):\r\n```ts\r\nimport { config, formatCurrencyI18N, setLanguage } from '@apx-ui/toolkit';\r\n\r\n// Initialize once\r\nconfig({ defaultCurrency: 'USD', defaultLanguage: 'en' });\r\n\r\n// Use formatters without parameters - they read from context\r\nformatCurrencyI18N(1234.56); // Uses context currency & locale\r\n\r\n// Change context globally\r\nsetLanguage('he');\r\nformatCurrencyI18N(1234.56); // Now uses Hebrew locale & context currency\r\n\r\n// Override context per call\r\nformatCurrencyI18N(1234.56, 'EUR', 'de-DE'); // German Euro formatting\r\n```\r\n\r\n**Legacy Functions** (Deprecated):\r\n```ts\r\nsetCurrentLanguage(languageCode: keyof typeof LANGUAGES): void  // Use setLanguage instead\r\nsetCurrentLocale(locale: string): void                         // Use setLocale instead  \r\ngetCurrentLocale(): string                                     // Use getLocale instead\r\ngetCurrentLanguageCode(): keyof typeof LANGUAGES              // Use getLanguage instead\r\ngetCurrentLocaleFromStorage(): string | null\r\nisBrowser(): boolean                                           // Use context system instead\r\n```\r\n\r\n### Constants\r\n\r\n#### Countries\r\n#### Languages & Translations\r\n```ts\r\n// Language codes and locales\r\nLANGUAGES: Record<string, ApxLanguageObject>\r\nRTL_LANGUAGES: string[]\r\n\r\n// Translation functions and data\r\ngetLocaleConjunction(locale: string): string\r\ngetTimeUnitTranslation(locale: string, unit: TimeUnit, value: number): string\r\ngetDayTranslation(language: string, day: DayName, format: 'short' | 'long'): string\r\ngetMonthTranslation(language: string, month: MonthName, format: 'short' | 'long'): string\r\ngetDaysForLanguage(language: string): Record<DayName, DayTranslation>\r\ngetMonthsForLanguage(language: string): Record<MonthName, MonthTranslation>\r\n\r\n// Translation constants\r\nLOCALE_CONJUNCTIONS: Record<string, string>\r\nTIME_UNIT_TRANSLATIONS: Record<string, Record<TimeUnit, { singular: string; plural: string }>>\r\nDAYS_TRANSLATIONS: Record<string, Record<DayName, DayTranslation>>\r\nMONTHS_TRANSLATIONS: Record<string, Record<MonthName, MonthTranslation>>\r\n\r\n// Types\r\nTimeUnit: 'ms' | 's' | 'm' | 'h' | 'd' | 'w' | 'mo' | 'y'\r\nDayName: 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday'\r\nMonthName: 'january' | 'february' | 'march' | 'april' | 'may' | 'june' | 'july' | 'august' | 'september' | 'october' | 'november' | 'december'\r\n```\r\n\r\n```ts\r\nCOUNTRIES = [\r\n  { code: 'US', name: 'United States', phoneCode: '+1' },\r\n  { code: 'IL', name: 'Israel', phoneCode: '+972' },\r\n  ...\r\n]\r\n\r\ngetCountryByCode(code: string): Country | undefined\r\ngetCountryByName(name: string): Country | undefined\r\ngetCountriesByPhoneCode(phoneCode: string): Country[]\r\n```\r\n\r\n#### Languages\r\n\r\n```ts\r\nLANGUAGES = [\r\n  { code: 'en', label: 'English', nativeName: 'English' },\r\n  { code: 'he', label: 'Hebrew', nativeName: 'עברית' },\r\n  ...\r\n]\r\n\r\ngetLanguageByCode(code: string): Language | undefined\r\ngetLanguageByLabel(label: string): Language | undefined\r\ngetSupportedLanguageCodes(): string[]\r\n```\r\n\r\n#### Magic Numbers\r\n\r\n```ts\r\nSECONDS_IN_MINUTE = 60\r\nMILLISECONDS_IN_SECOND = 1000\r\nMILLISECONDS_IN_MINUTE = 60000\r\nNUMBER_1000 = 1000\r\n// ... and many more time and mathematical constants\r\n```\r\n\r\n#### Region & Currency Mapping\r\n\r\n```ts\r\nREGION_CURRENCY_MAP: Record<string, string>  // Maps country codes to currency codes\r\ngetCurrencyForRegion(region: string): string | undefined\r\ngetSupportedRegions(): string[]\r\ngetSupportedCurrencies(): string[]\r\n\r\n// Examples:\r\ngetCurrencyForRegion('US') // 'USD'\r\ngetCurrencyForRegion('IL') // 'ILS'\r\ngetCurrencyForRegion('GB') // 'GBP'\r\n```\r\n\r\n### Regex Patterns\r\n\r\n```ts\r\nREGEX = {\r\n  email: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/,\r\n  phone: /^(\\+?\\d{1,3})?\\d{7,14}$/,\r\n  numeric: /^\\d+$/,\r\n  url: /^(https?|ftp):\\/\\/[^\\s/$.?#].[^\\s]*$/i,\r\n  strongPassword: /^(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*]).{8,}$/,\r\n  // ... and many more patterns\r\n}\r\n```\r\n\r\n### Generic Helpers\r\n\r\n```ts\r\nisEmpty(value: any): boolean\r\nisDefined<T>(val: T | undefined | null): val is T\r\ntoNumberSafe(value: any, fallback = 0): number\r\nisString(value: any): value is string\r\nisNumber(value: any): value is number\r\nisBoolean(value: any): value is boolean\r\nisObject(value: any): value is object\r\nisArray(value: any): value is any[]\r\nisFunction(value: any): value is Function\r\nisNull(value: any): value is null\r\nisUndefined(value: any): value is undefined\r\ngetValueOrFallback<T>(value: T | null | undefined, fallback: T): T\r\ndeepClone<T>(obj: T): T\r\npick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K>\r\nomit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>\r\ndebounce<T extends (...args: any[]) => any>(func: T, delay: number): (...args: Parameters<T>) => void\r\nthrottle<T extends (...args: any[]) => any>(func: T, delay: number): (...args: Parameters<T>) => void\r\nrandomString(length?: number): string\r\nrandomNumber(min: number, max: number): number\r\ncapitalize(str: string): string\r\ntoCamelCase(str: string): string\r\ntoKebabCase(str: string): string\r\ntoSnakeCase(str: string): string\r\ntoPascalCase(str: string): string\r\ntruncate(str: string, length: number, suffix?: string): string\r\nunique<T>(array: T[]): T[]\r\ngroupBy<T, K extends keyof T>(array: T[], key: K): Record<string, T[]>\r\nsortBy<T, K extends keyof T>(array: T[], key: K, order?: 'asc' | 'desc'): T[]\r\n```\r\n\r\n**Comprehensive Examples:**\r\n```ts\r\n// Type checking\r\nisEmpty(''); // true\r\nisEmpty([]); // true\r\nisEmpty({}); // true\r\nisEmpty('hello'); // false\r\n\r\nisDefined(null); // false\r\nisDefined(undefined); // false\r\nisDefined('hello'); // true\r\n\r\nisString('hello'); // true\r\nisNumber(123); // true\r\nisBoolean(true); // true\r\nisArray([1, 2, 3]); // true\r\nisObject({}); // true\r\n\r\n// Safe value conversion\r\ntoNumberSafe('123'); // 123\r\ntoNumberSafe('abc', 0); // 0\r\ntoNumberSafe(null, 999); // 999\r\n\r\ngetValueOrFallback(null, 'default'); // 'default'\r\ngetValueOrFallback('hello', 'default'); // 'hello'\r\n\r\n// Object manipulation\r\nconst user = { id: 1, name: 'John', email: 'john@example.com', age: 30 };\r\n\r\nconst userBasic = pick(user, ['name', 'email']); // { name: 'John', email: 'john@example.com' }\r\nconst userWithoutId = omit(user, ['id', 'age']); // { name: 'John', email: 'john@example.com' }\r\n\r\n// Deep cloning\r\nconst original = { user: { name: 'John' }, items: [1, 2, 3] };\r\nconst cloned = deepClone(original);\r\ncloned.user.name = 'Jane';\r\nconsole.log(original.user.name); // 'John' (unchanged)\r\n\r\n// String utilities\r\ncapitalize('hello world'); // 'Hello world'\r\ntoCamelCase('hello-world'); // 'helloWorld'\r\ntoKebabCase('helloWorld'); // 'hello-world'\r\ntoSnakeCase('helloWorld'); // 'hello_world'\r\ntoPascalCase('hello world'); // 'HelloWorld'\r\ntruncate('This is a very long string', 20, '...'); // 'This is a very long...'\r\n\r\n// Array utilities\r\nunique([1, 2, 2, 3, 3, 3]); // [1, 2, 3]\r\n\r\nconst users = [\r\n    { name: 'John', department: 'Engineering', age: 30 },\r\n    { name: 'Jane', department: 'Marketing', age: 25 },\r\n    { name: 'Bob', department: 'Engineering', age: 35 }\r\n];\r\n\r\ngroupBy(users, 'department');\r\n// { Engineering: [{ name: 'John', ... }, { name: 'Bob', ... }], Marketing: [{ name: 'Jane', ... }] }\r\n\r\nsortBy(users, 'age'); // Sort by age ascending\r\nsortBy(users, 'age', 'desc'); // Sort by age descending\r\n```\r\n\r\n```javascript\r\n// Performance Utility\r\n\r\n// Debounce\r\n\r\n// JS Example:\r\nconst debouncedSearch = debounce((query: string) => {\r\n    console.log('Searching for:', query);\r\n}, 300);\r\n\r\n// React onClick example:\r\n\r\n<button onClick={debounce(() => console.log(\"Clicked!\"), 500)}>\r\n  Click me\r\n</button>\r\n/**\r\n * \r\n * If the user clicks 5 times rapidly:\r\n - All previous timers get canceled.\r\n - After 500ms of no further clicks, the callback fires once.\r\n \r\n * Effect: “Only run after the last click in a burst.”\r\n */\r\n\r\n\r\n// Throttle\r\n\r\n// JS Example:\r\nconst throttledScroll = throttle(() => {\r\n    console.log('Scroll event');\r\n}, 100);\r\n\r\n// React onClick example:\r\n<button onClick={throttle(() => console.log(\"Clicked!\"), 1000)}>\r\n  Click me\r\n</button>\r\n\r\n/**\r\n * \r\n * If the user clicks 5 times rapidly:\r\n   - First click triggers immediately.\r\n  - Next clicks within 1000ms are ignored.\r\n  - After 1000ms, another click will be accepted.\r\n\r\n * Effect: “Run immediately, then ignore until delay passes.”\r\n*/\r\n```\r\n\r\n```javascript\r\n// Random utilities\r\nrandomString(10); // 'aB3xY9mK2p'\r\nrandomNumber(1, 100); // Random number between 1 and 100\r\n```\r\n\r\n\r\n**Real-World Usage:**\r\n```ts\r\n// Form data sanitization\r\nconst sanitizeFormData = (data: any) => {\r\n    return {\r\n        name: data.name?.trim() || '',\r\n        email: data.email?.trim() || '',\r\n        age: toNumberSafe(data.age, 0),\r\n        phone: data.phone?.replace(/\\D/g, '') || '',\r\n        bio: truncate(data.bio?.trim() || '', 100, '...')\r\n    };\r\n};\r\n\r\n// Data processing pipeline\r\nconst processUsers = (users: any[]) => {\r\n    // Filter out invalid users\r\n    const validUsers = users.filter(user => \r\n        isDefined(user.name) && \r\n        isDefined(user.email) && \r\n        !isEmpty(user.name)\r\n    );\r\n    \r\n    // Group by department\r\n    const byDepartment = groupBy(validUsers, 'department');\r\n    \r\n    // Sort by name\r\n    const sorted = sortBy(validUsers, 'name');\r\n    \r\n    return { validUsers, byDepartment, sorted };\r\n};\r\n\r\n// API response handling\r\nconst handleApiResponse = (response: any) => {\r\n    const data = getValueOrFallback(response.data, []);\r\n    const error = getValueOrFallback(response.error, null);\r\n    \r\n    if (isDefined(error)) {\r\n        console.error('API Error:', error);\r\n        return [];\r\n    }\r\n    \r\n    return isArray(data) ? data : [];\r\n};\r\n```\r\n\r\n### Scroll Utilities\r\n\r\n```ts\r\nscrollToTop(options?: ScrollOptions): void\r\nscrollToElement(element: Element, options?: ScrollOptions, offset?: number): void\r\nscrollToPosition(position: number, options?: ScrollOptions): void\r\nisInViewport(element: Element, threshold?: number): boolean\r\ngetScrollPosition(target?: Window | Element): number\r\nstopScroll(target?: Window | Element): void\r\n\r\n// Types\r\ntype ScrollBehavior = 'auto' | 'smooth'\r\ninterface ScrollOptions {\r\n  behavior?: ScrollBehavior\r\n  duration?: number\r\n  easing?: 'linear' | 'easeInOut' | 'easeIn' | 'easeOut'\r\n  target?: Window | Element\r\n}\r\n```\r\n\r\n### Credit Card Utilities\r\n\r\n```ts\r\n// Credit card formatting\r\nformatCreditCard(cardNumber: string, options?: CreditCardFormatOptions): string\r\ngetCreditCardType(cardNumber: string): CreditCardType | null\r\ngetLast4Digits(cardNumber: string): string\r\nmaskCreditCard(cardNumber: string, maskChar?: string): string\r\n\r\n// Credit card validation\r\nisValidCreditCardNumber(cardNumber: string): boolean\r\n\r\n// Dummy card generation\r\ngetRandomDummyCreditCard(type?: CreditCardType): string\r\n\r\n// Credit card information\r\ngetCreditCardInfo(cardNumber: string, options?: CreditCardFormatOptions): CreditCardInfo\r\ngetAvailableCreditCardTypes(): Array<{ type: CreditCardType; name: string; format: string }>\r\n\r\n// Types\r\ntype CreditCardType = 'VISA' | 'MASTERCARD' | 'AMERICAN_EXPRESS' | 'DISCOVER' | 'DINERS_CLUB' | 'JCB' | 'UNIONPAY'\r\ntype CreditCardFormatOptions = {\r\n  mask?: boolean\r\n  format?: string\r\n  maskChar?: string\r\n}\r\ntype CreditCardInfo = {\r\n  type: CreditCardType | null\r\n  typeName: string | null\r\n  number: string\r\n  formatted: string\r\n  last4: string\r\n  isValid: boolean\r\n  length: number\r\n}\r\n```\r\n\r\n**Comprehensive Examples:**\r\n```ts\r\n// Basic formatting\r\nformatCreditCard('4111111111111111'); // '4111 1111 1111 1111'\r\n\r\n// Custom format with placeholders\r\nformatCreditCard('4111111111111111', { \r\n  format: 'AAAA-BBBB-CCCC-DDDD' \r\n}); // '4111-1111-1111-1111'\r\n\r\n// Masked formatting\r\nformatCreditCard('4111111111111111', { \r\n  mask: true \r\n}); // '************1111'\r\n\r\n// Custom mask character\r\nformatCreditCard('4111111111111111', { \r\n  mask: true, \r\n  maskChar: 'X' \r\n}); // 'XXXXXXXXXXXX1111'\r\n\r\n// Credit card type detection\r\ngetCreditCardType('4111111111111111'); // 'VISA'\r\ngetCreditCardType('5555555555554444'); // 'MASTERCARD'\r\n\r\n// Last 4 digits\r\ngetLast4Digits('4111111111111111'); // '1111'\r\n\r\n// Validation\r\nisValidCreditCardNumber('4111111111111111'); // true\r\nisValidCreditCardNumber('1234567890123456'); // false\r\n\r\n// Dummy card generation\r\ngetRandomDummyCreditCard('VISA'); // '4111111111111111'\r\ngetRandomDummyCreditCard(); // Random card of any type\r\n\r\n// Complete card information\r\nconst info = getCreditCardInfo('4111111111111111');\r\nconsole.log(info);\r\n// {\r\n//   type: 'VISA',\r\n//   typeName: 'Visa',\r\n//   number: '4111111111111111',\r\n//   formatted: '4111 1111 1111 1111',\r\n//   last4: '1111',\r\n//   isValid: true,\r\n//   length: 16\r\n// }\r\n```\r\n\r\n**Supported Credit Card Types:**\r\n- **Visa**: 4xxx (13, 16, 19 digits)\r\n- **MasterCard**: 5xxx (16 digits)\r\n- **American Express**: 3x (15 digits)\r\n- **Discover**: 6xxx (16 digits)\r\n- **Diners Club**: 3xxx (14 digits)\r\n- **JCB**: 3xxx (15, 16 digits)\r\n- **UnionPay**: 62xx (16-19 digits)\r\n\r\n**Real-World Usage:**\r\n```ts\r\n// Payment form validation\r\nconst validatePaymentForm = (cardNumber: string) => {\r\n  const info = getCreditCardInfo(cardNumber);\r\n  \r\n  if (!info.isValid) {\r\n    return { valid: false, error: 'Invalid credit card number' };\r\n  }\r\n  \r\n  return {\r\n    valid: true,\r\n    type: info.typeName,\r\n    last4: info.last4,\r\n    formatted: info.formatted\r\n  };\r\n};\r\n\r\n// Display saved cards\r\nconst displaySavedCards = (cards: string[]) => {\r\n  return cards.map(card => {\r\n    const info = getCreditCardInfo(card);\r\n    return {\r\n      type: info.typeName,\r\n      last4: info.last4,\r\n      masked: maskCreditCard(card)\r\n    };\r\n  });\r\n};\r\n\r\n// Test card generation for development\r\nconst generateTestCards = () => {\r\n  return {\r\n    visa: getRandomDummyCreditCard('VISA'),\r\n    mastercard: getRandomDummyCreditCard('MASTERCARD'),\r\n    amex: getRandomDummyCreditCard('AMERICAN_EXPRESS')\r\n  };\r\n};\r\n```\r\n\r\n### Opening Hours Formatter\r\n\r\n```ts\r\nformatOpeningHours(\r\n  storeHours: StoreHours,\r\n  options?: {\r\n    locale?: string\r\n    use24Hour?: boolean\r\n    language?: string\r\n  }\r\n): string[]\r\n\r\n// Types\r\ntype StoreHours = Array<{\r\n  open: string | false\r\n  closed: string | false\r\n} | Array<{\r\n  open: string\r\n  closed: string\r\n}>>\r\n```\r\n\r\n**Comprehensive Examples:**\r\n```ts\r\n// Standard business hours\r\nconst standardHours: StoreHours = [\r\n    { \"closed\": false, \"open\": false }, // Sunday - Closed\r\n    [{ \"closed\": \"17:00\", \"open\": \"09:00\" }], // Monday - 9:00-17:00\r\n    [{ \"closed\": \"17:00\", \"open\": \"09:00\" }], // Tuesday - 9:00-17:00\r\n    [{ \"closed\": \"17:00\", \"open\": \"09:00\" }], // Wednesday - 9:00-17:00\r\n    [{ \"closed\": \"17:00\", \"open\": \"09:00\" }], // Thursday - 9:00-17:00\r\n    [{ \"closed\": \"17:00\", \"open\": \"09:00\" }], // Friday - 9:00-17:00\r\n    [{ \"closed\": \"15:00\", \"open\": \"09:00\" }]  // Saturday - 9:00-15:00\r\n];\r\n\r\n// English with 12-hour format\r\nconst englishHours = formatOpeningHours(standardHours, {\r\n    locale: 'en-US',\r\n    use24Hour: false,\r\n    language: 'en'\r\n});\r\n// ['Sunday, Saturday: 9:00 AM - 6:00 PM', 'Monday - Friday: 9:00 AM - 5:00 PM']\r\n\r\n// Hebrew with 12-hour format\r\nconst hebrewHours = formatOpeningHours(standardHours, {\r\n    locale: 'he-IL',\r\n    use24Hour: false,\r\n    language: 'he'\r\n});\r\n// ['ראשון, שבת: 9:00 AM - 6:00 PM', 'שני - שישי: 9:00 AM - 5:00 PM']\r\n\r\n// Arabic with 24-hour format\r\nconst arabicHours = formatOpeningHours(standardHours, {\r\n    locale: 'ar-SA',\r\n    use24Hour: true,\r\n    language: 'ar'\r\n});\r\n// ['الأحد, السبت: ٠٩:٠٠ - ١٨:٠٠', 'الاثنين - الجمعة: ٠٩:٠٠ - ١٧:٠٠']\r\n\r\n// Restaurant with lunch break\r\nconst restaurantHours: StoreHours = [\r\n    { \"closed\": false, \"open\": false }, // Sunday - Closed\r\n    [\r\n        { \"closed\": \"14:00\", \"open\": \"11:00\" },\r\n        { \"closed\": \"22:00\", \"open\": \"17:00\" }\r\n    ], // Monday - 11:00-14:00, 17:00-22:00\r\n    // ... similar for other days\r\n];\r\n\r\nconst restaurantFormatted = formatOpeningHours(restaurantHours, {\r\n    locale: 'en-US',\r\n    use24Hour: false,\r\n    language: 'en'\r\n});\r\n// ['Monday - Saturday: 11:00 AM - 2:00 PM, 5:00 PM - 10:00 PM', 'Sunday: Closed']\r\n\r\n// 24/7 Store\r\nconst store24_7: StoreHours = [\r\n    [{ \"closed\": \"23:59\", \"open\": \"00:00\" }], // Sunday - 24/7\r\n    [{ \"closed\": \"23:59\", \"open\": \"00:00\" }], // Monday - 24/7\r\n    // ... similar for all days\r\n];\r\n\r\nconst store24_7Formatted = formatOpeningHours(store24_7, {\r\n    locale: 'en-US',\r\n    use24Hour: true,\r\n    language: 'en'\r\n});\r\n// ['Sunday - Saturday: 00:00 - 23:59']\r\n```\r\n\r\n**Real-World Usage:**\r\n```ts\r\n// Business hours display component\r\nconst BusinessHoursDisplay = ({ hours, locale = 'en-US' }: { hours: StoreHours, locale?: string }) => {\r\n    const formattedHours = formatOpeningHours(hours, {\r\n        locale,\r\n        use24Hour: false,\r\n        language: locale.split('-')[0]\r\n    });\r\n    \r\n    return (\r\n        <div className=\"business-hours\">\r\n            <h3>Opening Hours</h3>\r\n            {formattedHours.map((line, index) => (\r\n                <p key={index}>{line}</p>\r\n            ))}\r\n        </div>\r\n    );\r\n};\r\n\r\n// Multi-language support\r\nconst getBusinessHours = (language: string) => {\r\n    const hours = getStoreHours(); // Your business hours data\r\n    \r\n    return formatOpeningHours(hours, {\r\n        locale: `${language}-${getCountryCode(language)}`,\r\n        use24Hour: language === 'ar' || language === 'he', // Use 24-hour for Arabic/Hebrew\r\n        language\r\n    });\r\n};\r\n```\r\n\r\n### Storage Persister\r\n\r\n```ts\r\n// Main Persister class\r\nPersister.setLocalStorage(data: PersisterData): void\r\nPersister.getLocalStorage<T>(key: string): T | null\r\nPersister.removeLocalStorage(key: string): void\r\nPersister.setSessionStorage(data: PersisterData): void\r\nPersister.getSessionStorage<T>(key: string): T | null\r\nPersister.removeSessionStorage(key: string): void\r\nPersister.has(key: string, storageType?: StorageType): boolean\r\nPersister.keys(storageType?: StorageType): string[]\r\nPersister.getStorageSize(storageType?: StorageType): number\r\nPersister.clear(storageType?: StorageType): void\r\nPersister.getRemainingTTL(key: string, storageType?: StorageType): number | null\r\nPersister.cleanupExpiredTTL(storageType?: StorageType): void\r\n\r\n// Convenience classes\r\nLocalStorage.set(data: PersisterData): void\r\nLocalStorage.get<T>(key: string): T | null\r\nLocalStorage.remove(key: string): void\r\nLocalStorage.has(key: string): boolean\r\nLocalStorage.keys(): string[]\r\nLocalStorage.clear(): void\r\nLocalStorage.cleanupExpiredTTL(): void\r\nLocalStorage.getRemainingTTL(key: string): number | null\r\n\r\nSessionStorage.set(data: PersisterData): void\r\nSessionStorage.get<T>(key: string): T | null\r\nSessionStorage.remove(key: string): void\r\nSessionStorage.has(key: string): boolean\r\nSessionStorage.keys(): string[]\r\nSessionStorage.clear(): void\r\nSessionStorage.cleanupExpiredTTL(): void\r\nSessionStorage.getRemainingTTL(key: string): number | null\r\n\r\n// Types\r\ntype PersisterData = Record<string, {\r\n  value: any\r\n  encode?: boolean\r\n  ttl?: number\r\n}>\r\ntype StorageType = 'localStorage' | 'sessionStorage'\r\n```\r\n\r\n---\r\n\r\n## Directory Structure\r\n\r\n```\r\nsrc/\r\n├── constants/\r\n│   ├── countries.ts\r\n│   ├── languages.ts\r\n│   ├── magicNumbers.ts\r\n│   ├── days.ts\r\n│   ├── months.ts\r\n│   ├── regions.ts\r\n│   └── translations.ts\r\n├── context/\r\n│   └── index.ts\r\n├── persister/\r\n│   ├── index.ts\r\n│   └── utils.ts\r\n├── regex/\r\n│   └── patterns.ts\r\n├── utils/\r\n│   ├── validators.ts\r\n│   ├── formatters.ts\r\n│   ├── dateUtils.ts\r\n│   ├── generic.ts\r\n│   ├── i18nFormatters.ts\r\n│   ├── phoneNumber.ts\r\n│   └── scrollUtils.ts\r\n├── common-types/\r\n│   └── index.ts\r\n└── index.ts\r\n```\r\n\r\n---\r\n\r\n## Usage Examples\r\n\r\n### Validation\r\n\r\n```ts\r\nimport { isEmail, validateEmail, isPhone, isStrongPassword } from '@apx-ui/toolkit';\r\n\r\n// Simple validation\r\nisEmail('user@example.com'); // true\r\nisPhone('+1234567890'); // true\r\nisStrongPassword('MyPass123!'); // true\r\n\r\n// Detailed validation with error messages\r\nconst emailResult = validateEmail('invalid-email');\r\nconsole.log(emailResult); // { valid: false, error: 'Invalid email format' }\r\n```\r\n\r\n### Formatting\r\n\r\n```ts\r\nimport { formatCurrency, formatPhoneNumber, formatCompactNumber } from '@apx-ui/toolkit';\r\n\r\nformatCurrency(1234.56, 'USD', 'en-US'); // '$1,234.56'\r\nformatPhoneNumber('+12345678901', '+C (PPP)-EEE-SSSS'); // '+1 (234)-567-8901'\r\nformatPhoneNumber('1234567890', 'PPP - EEE SSSS'); // '123 - 456 7890'\r\nformatCompactNumber(1500); // '1.5K'\r\n```\r\n\r\n### Date Utilities\r\n\r\n```ts\r\nimport { formatDate, getTimeAgo, isToday, addDays } from '@apx-ui/toolkit';\r\n\r\nformatDate(new Date(), 'YYYY-MM-DD'); // '2024-01-15'\r\ngetTimeAgo(new Date('2024-01-10')); // '5 days ago'\r\nisToday(new Date()); // true\r\naddDays(new Date(), 7); // Date object 7 days from now\r\n```\r\n\r\n### Generic Helpers\r\n\r\n```ts\r\nimport { isEmpty, isDefined, toNumberSafe, deepClone } from '@apx-ui/toolkit';\r\n\r\nisEmpty(''); // true\r\nisEmpty([]); // true\r\nisEmpty({}); // true\r\n\r\nisDefined(null); // false\r\nisDefined(undefined); // false\r\nisDefined('hello'); // true\r\n\r\ntoNumberSafe('123'); // 123\r\ntoNumberSafe('abc', 0); // 0\r\n\r\nconst obj = { a: 1, b: { c: 2 } };\r\nconst cloned = deepClone(obj); // Deep copy\r\n```\r\n\r\n### Constants\r\n\r\n```ts\r\nimport { COUNTRIES, LANGUAGES, SECONDS_IN_MINUTE, getCurrencyForRegion } from '@apx-ui/toolkit';\r\n\r\nconst israel = COUNTRIES.find(c => c.code === 'IL');\r\nconsole.log(israel); // { code: 'IL', name: 'Israel', phoneCode: '+972' }\r\n\r\nconst english = LANGUAGES.find(l => l.code === 'en');\r\nconsole.log(english); // { code: 'en', label: 'English', nativeName: 'English' }\r\n\r\nconsole.log(SECONDS_IN_MINUTE); // 60\r\nconsole.log(getCurrencyForRegion('US')); // 'USD'\r\n```\r\n\r\n### Scroll Utilities\r\n\r\n```ts\r\nimport { scrollToTop, scrollToElement, isInViewport } from '@apx-ui/toolkit';\r\n\r\n// Smooth scroll to top\r\nscrollToTop({ duration: 1000, easing: 'easeInOut' });\r\n\r\n// Scroll to element with offset\r\nconst element = document.getElementById('section');\r\nscrollToElement(element, { duration: 500 }, 100);\r\n\r\n// Check if element is visible\r\nconst isVisible = isInViewport(element, 0.5); // 50% threshold\r\n```\r\n\r\n### Storage Persister\r\n\r\n```ts\r\nimport { LocalStorage, SessionStorage } from '@apx-ui/toolkit';\r\n\r\n// Store data with TTL (time to live)\r\nLocalStorage.set({\r\n  user: { value: { id: 1, name: 'John' }, ttl: 3600 }, // Expires in 1 hour\r\n  settings: { value: { theme: 'dark' } } // No expiration\r\n});\r\n\r\n// Retrieve data\r\nconst user = LocalStorage.get('user');\r\nconst settings = LocalStorage.get('settings');\r\n\r\n// Check if key exists and get remaining TTL\r\nif (LocalStorage.has('user')) {\r\n  const remainingTime = LocalStorage.getRemainingTTL('user'); // seconds\r\n  console.log(`User data expires in ${remainingTime} seconds`);\r\n}\r\n\r\n// Clean up expired items\r\nLocalStorage.cleanupExpiredTTL();\r\n```\r\n\r\n---\r\n\r\n## Testing\r\n\r\n```bash\r\nnpm test\r\n```\r\n\r\n---\r\n\r\n## Contributing\r\n\r\n1. Clone the repo\r\n2. Install deps: `npm install`\r\n3. Run tests: `npm test`\r\n4. Add your utility to `src/` and export it in `index.ts`\r\n\r\nPRs and suggestions are welcome!\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT © 2025 [AppNA.io](https://appna.io)","readmeFilename":"README.md"}