mirror of
https://github.com/Polaris-Entertainment/bytefy.git
synced 2026-07-08 00:25:09 +00:00
added tools v1
This commit is contained in:
11
angular.json
11
angular.json
@@ -7,7 +7,7 @@
|
|||||||
"projectType": "application",
|
"projectType": "application",
|
||||||
"schematics": {
|
"schematics": {
|
||||||
"@schematics/angular:component": {
|
"@schematics/angular:component": {
|
||||||
"style": "sass"
|
"style": "scss"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "",
|
"root": "",
|
||||||
@@ -20,17 +20,18 @@
|
|||||||
"outputPath": "dist/tools",
|
"outputPath": "dist/tools",
|
||||||
"index": "src/index.html",
|
"index": "src/index.html",
|
||||||
"browser": "src/main.ts",
|
"browser": "src/main.ts",
|
||||||
|
"aot": true,
|
||||||
"polyfills": [
|
"polyfills": [
|
||||||
"zone.js"
|
"zone.js"
|
||||||
],
|
],
|
||||||
"tsConfig": "tsconfig.app.json",
|
"tsConfig": "tsconfig.app.json",
|
||||||
"inlineStyleLanguage": "sass",
|
"inlineStyleLanguage": "scss",
|
||||||
"assets": [
|
"assets": [
|
||||||
"src/favicon.ico",
|
"src/favicon.ico",
|
||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.sass"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
},
|
},
|
||||||
@@ -84,13 +85,13 @@
|
|||||||
"zone.js/testing"
|
"zone.js/testing"
|
||||||
],
|
],
|
||||||
"tsConfig": "tsconfig.spec.json",
|
"tsConfig": "tsconfig.spec.json",
|
||||||
"inlineStyleLanguage": "sass",
|
"inlineStyleLanguage": "scss",
|
||||||
"assets": [
|
"assets": [
|
||||||
"src/favicon.ico",
|
"src/favicon.ico",
|
||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.sass"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
}
|
}
|
||||||
|
|||||||
104
package-lock.json
generated
104
package-lock.json
generated
@@ -9,6 +9,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^17.3.0",
|
"@angular/animations": "^17.3.0",
|
||||||
|
"@angular/cdk": "^17.3.10",
|
||||||
"@angular/common": "^17.3.0",
|
"@angular/common": "^17.3.0",
|
||||||
"@angular/compiler": "^17.3.0",
|
"@angular/compiler": "^17.3.0",
|
||||||
"@angular/core": "^17.3.0",
|
"@angular/core": "^17.3.0",
|
||||||
@@ -16,7 +17,13 @@
|
|||||||
"@angular/platform-browser": "^17.3.0",
|
"@angular/platform-browser": "^17.3.0",
|
||||||
"@angular/platform-browser-dynamic": "^17.3.0",
|
"@angular/platform-browser-dynamic": "^17.3.0",
|
||||||
"@angular/router": "^17.3.0",
|
"@angular/router": "^17.3.0",
|
||||||
|
"@ng-icons/core": "^29.5.1",
|
||||||
|
"@ng-icons/css.gg": "^29.5.1",
|
||||||
|
"@ng-icons/heroicons": "^29.5.1",
|
||||||
|
"primeicons": "^7.0.0",
|
||||||
|
"primeng": "^18.0.0-beta.2",
|
||||||
"rxjs": "~7.8.0",
|
"rxjs": "~7.8.0",
|
||||||
|
"tailwindcss-primeui": "^0.3.4",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"zone.js": "~0.14.3"
|
"zone.js": "~0.14.3"
|
||||||
},
|
},
|
||||||
@@ -275,6 +282,22 @@
|
|||||||
"@angular/core": "17.3.12"
|
"@angular/core": "17.3.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@angular/cdk": {
|
||||||
|
"version": "17.3.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-17.3.10.tgz",
|
||||||
|
"integrity": "sha512-b1qktT2c1TTTe5nTji/kFAVW92fULK0YhYAvJ+BjZTPKu2FniZNe8o4qqQ0pUuvtMu+ZQxp/QqFYoidIVCjScg==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"parse5": "^7.1.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "^17.0.0 || ^18.0.0",
|
||||||
|
"@angular/core": "^17.0.0 || ^18.0.0",
|
||||||
|
"rxjs": "^6.5.3 || ^7.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@angular/cli": {
|
"node_modules/@angular/cli": {
|
||||||
"version": "17.3.10",
|
"version": "17.3.10",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.3.10.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.3.10.tgz",
|
||||||
@@ -2878,6 +2901,35 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ng-icons/core": {
|
||||||
|
"version": "29.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ng-icons/core/-/core-29.5.1.tgz",
|
||||||
|
"integrity": "sha512-wPpNqgoAlbJ0QAxfH2EAfT10ohtwXLQSXoWQ4a1tEhqXOn5kUAA8MqGgl5kILkiVCd8vvvPckLrt84LXQPWVCQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.2.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": ">=18.0.0",
|
||||||
|
"@angular/core": ">=18.0.0",
|
||||||
|
"rxjs": "^6.5.3 || ^7.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ng-icons/css.gg": {
|
||||||
|
"version": "29.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ng-icons/css.gg/-/css.gg-29.5.1.tgz",
|
||||||
|
"integrity": "sha512-kHHBF6dNI/59qNFPpSd8WAyKpvPfdV4lYwmLM9hAnmTU845YDefc4wVW4/xaXG1j9dQxeQzOl9+/O0i/aUbUbA==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ng-icons/heroicons": {
|
||||||
|
"version": "29.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ng-icons/heroicons/-/heroicons-29.5.1.tgz",
|
||||||
|
"integrity": "sha512-pcOpbZ32+TlMZRxmNAHXYHxTw8fkYEiLrPUbcA3YcbzFv8VzJ+FcnosyM70mGixkSjvf+tsERp63rvpJBUBP+w==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@ngtools/webpack": {
|
"node_modules/@ngtools/webpack": {
|
||||||
"version": "17.3.10",
|
"version": "17.3.10",
|
||||||
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.3.10.tgz",
|
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.3.10.tgz",
|
||||||
@@ -3222,6 +3274,25 @@
|
|||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@primeuix/styled": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-bOya+/7WzCeF8D4N0BgGNk3Xe4F4PLEGu7V+btRlUOoEbda2uhp4nqqj2fOdzSERmjEUkkYds8dIVgVM56w1NA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@primeuix/utils": "^0.0.6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@primeuix/utils": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-7RQ2/LkZpSbi08NAlfZfajqBtWFM2csimf+xk97EoQDhpouzzbHFwf6WFbAyniZC9aPGJ+m+2qgyLxvYzA0x3g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.24.0",
|
"version": "4.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz",
|
||||||
@@ -5719,7 +5790,7 @@
|
|||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12"
|
"node": ">=0.12"
|
||||||
},
|
},
|
||||||
@@ -9248,7 +9319,7 @@
|
|||||||
"version": "7.1.2",
|
"version": "7.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
|
||||||
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
|
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"entities": "^4.4.0"
|
"entities": "^4.4.0"
|
||||||
},
|
},
|
||||||
@@ -9626,6 +9697,27 @@
|
|||||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
|
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/primeicons": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/primeicons/-/primeicons-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw=="
|
||||||
|
},
|
||||||
|
"node_modules/primeng": {
|
||||||
|
"version": "18.0.0-beta.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/primeng/-/primeng-18.0.0-beta.2.tgz",
|
||||||
|
"integrity": "sha512-zCC36qtQsruPObuB/awdxHX0KvuRXa0Ebew0jTGNwal8YpJenF6ytxB4UIn6BetnuCYDuRAXW5zklxveIgxXiw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@primeuix/styled": "0.0.6",
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "^17.0.0 || ^18.0.0",
|
||||||
|
"@angular/core": "^17.0.0 || ^18.0.0",
|
||||||
|
"@angular/forms": "^17.0.0 || ^18.0.0",
|
||||||
|
"rxjs": "^6.0.0 || ^7.8.1",
|
||||||
|
"zone.js": "~0.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/proc-log": {
|
"node_modules/proc-log": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz",
|
||||||
@@ -11001,6 +11093,14 @@
|
|||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tailwindcss-primeui": {
|
||||||
|
"version": "0.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/tailwindcss-primeui/-/tailwindcss-primeui-0.3.4.tgz",
|
||||||
|
"integrity": "sha512-5+Qfoe5Kpq2Iwrd6umBUb3rQH6b7+pL4jxJUId0Su5agUM6TwCyH5Pyl9R0y3QQB3IRuTxBNmeS11B41f+30zw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"tailwindcss": ">=3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tapable": {
|
"node_modules/tapable": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^17.3.0",
|
"@angular/animations": "^17.3.0",
|
||||||
|
"@angular/cdk": "^17.3.10",
|
||||||
"@angular/common": "^17.3.0",
|
"@angular/common": "^17.3.0",
|
||||||
"@angular/compiler": "^17.3.0",
|
"@angular/compiler": "^17.3.0",
|
||||||
"@angular/core": "^17.3.0",
|
"@angular/core": "^17.3.0",
|
||||||
@@ -18,7 +19,13 @@
|
|||||||
"@angular/platform-browser": "^17.3.0",
|
"@angular/platform-browser": "^17.3.0",
|
||||||
"@angular/platform-browser-dynamic": "^17.3.0",
|
"@angular/platform-browser-dynamic": "^17.3.0",
|
||||||
"@angular/router": "^17.3.0",
|
"@angular/router": "^17.3.0",
|
||||||
|
"@ng-icons/core": "^29.5.1",
|
||||||
|
"@ng-icons/css.gg": "^29.5.1",
|
||||||
|
"@ng-icons/heroicons": "^29.5.1",
|
||||||
|
"primeicons": "^7.0.0",
|
||||||
|
"primeng": "^18.0.0-beta.2",
|
||||||
"rxjs": "~7.8.0",
|
"rxjs": "~7.8.0",
|
||||||
|
"tailwindcss-primeui": "^0.3.4",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"zone.js": "~0.14.3"
|
"zone.js": "~0.14.3"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,336 +1,4 @@
|
|||||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
<app-header></app-header>
|
||||||
<!-- * * * * * * * * * * * The content below * * * * * * * * * * * -->
|
<div class="main-content">
|
||||||
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * -->
|
<router-outlet></router-outlet>
|
||||||
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * -->
|
|
||||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
|
||||||
<!-- * * * * * * * * * Delete the template below * * * * * * * * * -->
|
|
||||||
<!-- * * * * * * * to get started with your project! * * * * * * * -->
|
|
||||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
|
||||||
|
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
--bright-blue: oklch(51.01% 0.274 263.83);
|
|
||||||
--electric-violet: oklch(53.18% 0.28 296.97);
|
|
||||||
--french-violet: oklch(47.66% 0.246 305.88);
|
|
||||||
--vivid-pink: oklch(69.02% 0.277 332.77);
|
|
||||||
--hot-red: oklch(61.42% 0.238 15.34);
|
|
||||||
--orange-red: oklch(63.32% 0.24 31.68);
|
|
||||||
|
|
||||||
--gray-900: oklch(19.37% 0.006 300.98);
|
|
||||||
--gray-700: oklch(36.98% 0.014 302.71);
|
|
||||||
--gray-400: oklch(70.9% 0.015 304.04);
|
|
||||||
|
|
||||||
--red-to-pink-to-purple-vertical-gradient: linear-gradient(
|
|
||||||
180deg,
|
|
||||||
var(--orange-red) 0%,
|
|
||||||
var(--vivid-pink) 50%,
|
|
||||||
var(--electric-violet) 100%
|
|
||||||
);
|
|
||||||
|
|
||||||
--red-to-pink-to-purple-horizontal-gradient: linear-gradient(
|
|
||||||
90deg,
|
|
||||||
var(--orange-red) 0%,
|
|
||||||
var(--vivid-pink) 50%,
|
|
||||||
var(--electric-violet) 100%
|
|
||||||
);
|
|
||||||
|
|
||||||
--pill-accent: var(--bright-blue);
|
|
||||||
|
|
||||||
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
||||||
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
|
||||||
"Segoe UI Symbol";
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 3.125rem;
|
|
||||||
color: var(--gray-900);
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 100%;
|
|
||||||
letter-spacing: -0.125rem;
|
|
||||||
margin: 0;
|
|
||||||
font-family: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
||||||
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
|
||||||
"Segoe UI Symbol";
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--gray-700);
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding: 1rem;
|
|
||||||
box-sizing: inherit;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.angular-logo {
|
|
||||||
max-width: 9.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 700px;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content h1 {
|
|
||||||
margin-top: 1.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content p {
|
|
||||||
margin-top: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divider {
|
|
||||||
width: 1px;
|
|
||||||
background: var(--red-to-pink-to-purple-vertical-gradient);
|
|
||||||
margin-inline: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pill-group {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: start;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pill {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
--pill-accent: var(--bright-blue);
|
|
||||||
background: color-mix(in srgb, var(--pill-accent) 5%, transparent);
|
|
||||||
color: var(--pill-accent);
|
|
||||||
padding-inline: 0.75rem;
|
|
||||||
padding-block: 0.375rem;
|
|
||||||
border-radius: 2.75rem;
|
|
||||||
border: 0;
|
|
||||||
transition: background 0.3s ease;
|
|
||||||
font-family: var(--inter-font);
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 1.4rem;
|
|
||||||
letter-spacing: -0.00875rem;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pill:hover {
|
|
||||||
background: color-mix(in srgb, var(--pill-accent) 15%, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pill-group .pill:nth-child(6n + 1) {
|
|
||||||
--pill-accent: var(--bright-blue);
|
|
||||||
}
|
|
||||||
.pill-group .pill:nth-child(6n + 2) {
|
|
||||||
--pill-accent: var(--french-violet);
|
|
||||||
}
|
|
||||||
.pill-group .pill:nth-child(6n + 3),
|
|
||||||
.pill-group .pill:nth-child(6n + 4),
|
|
||||||
.pill-group .pill:nth-child(6n + 5) {
|
|
||||||
--pill-accent: var(--hot-red);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pill-group svg {
|
|
||||||
margin-inline-start: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-links {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.73rem;
|
|
||||||
margin-top: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-links path {
|
|
||||||
transition: fill 0.3s ease;
|
|
||||||
fill: var(--gray-400);
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-links a:hover svg path {
|
|
||||||
fill: var(--gray-900);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 650px) {
|
|
||||||
.content {
|
|
||||||
flex-direction: column;
|
|
||||||
width: max-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divider {
|
|
||||||
height: 1px;
|
|
||||||
width: 100%;
|
|
||||||
background: var(--red-to-pink-to-purple-horizontal-gradient);
|
|
||||||
margin-block: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<main class="main">
|
|
||||||
<div class="content">
|
|
||||||
<div class="left-side">
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 982 239"
|
|
||||||
fill="none"
|
|
||||||
class="angular-logo"
|
|
||||||
>
|
|
||||||
<g clip-path="url(#a)">
|
|
||||||
<path
|
|
||||||
fill="url(#b)"
|
|
||||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
fill="url(#c)"
|
|
||||||
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<radialGradient
|
|
||||||
id="c"
|
|
||||||
cx="0"
|
|
||||||
cy="0"
|
|
||||||
r="1"
|
|
||||||
gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
>
|
|
||||||
<stop stop-color="#FF41F8" />
|
|
||||||
<stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
|
|
||||||
<stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
|
|
||||||
</radialGradient>
|
|
||||||
<linearGradient
|
|
||||||
id="b"
|
|
||||||
x1="0"
|
|
||||||
x2="982"
|
|
||||||
y1="192"
|
|
||||||
y2="192"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
>
|
|
||||||
<stop stop-color="#F0060B" />
|
|
||||||
<stop offset="0" stop-color="#F0070C" />
|
|
||||||
<stop offset=".526" stop-color="#CC26D5" />
|
|
||||||
<stop offset="1" stop-color="#7702FF" />
|
|
||||||
</linearGradient>
|
|
||||||
<clipPath id="a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
<h1>Hello, {{ title }}</h1>
|
|
||||||
<p>Congratulations! Your app is running. 🎉</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="divider" role="separator" aria-label="Divider"></div>
|
|
||||||
<div class="right-side">
|
|
||||||
<div class="pill-group">
|
|
||||||
@for (item of [
|
|
||||||
{ title: 'Explore the Docs', link: 'https://angular.dev' },
|
|
||||||
{ title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' },
|
|
||||||
{ title: 'CLI Docs', link: 'https://angular.dev/tools/cli' },
|
|
||||||
{ title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' },
|
|
||||||
{ title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' },
|
|
||||||
]; track item.title) {
|
|
||||||
<a
|
|
||||||
class="pill"
|
|
||||||
[href]="item.link"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>
|
|
||||||
<span>{{ item.title }}</span>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
height="14"
|
|
||||||
viewBox="0 -960 960 960"
|
|
||||||
width="14"
|
|
||||||
fill="currentColor"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="social-links">
|
|
||||||
<a
|
|
||||||
href="https://github.com/angular/angular"
|
|
||||||
aria-label="Github"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
width="25"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 25 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
alt="Github"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M12.3047 0C5.50634 0 0 5.50942 0 12.3047C0 17.7423 3.52529 22.3535 8.41332 23.9787C9.02856 24.0946 9.25414 23.7142 9.25414 23.3871C9.25414 23.0949 9.24389 22.3207 9.23876 21.2953C5.81601 22.0377 5.09414 19.6444 5.09414 19.6444C4.53427 18.2243 3.72524 17.8449 3.72524 17.8449C2.61064 17.082 3.81137 17.0973 3.81137 17.0973C5.04697 17.1835 5.69604 18.3647 5.69604 18.3647C6.79321 20.2463 8.57636 19.7029 9.27978 19.3881C9.39052 18.5924 9.70736 18.0499 10.0591 17.7423C7.32641 17.4347 4.45429 16.3765 4.45429 11.6618C4.45429 10.3185 4.9311 9.22133 5.72065 8.36C5.58222 8.04931 5.16694 6.79833 5.82831 5.10337C5.82831 5.10337 6.85883 4.77319 9.2121 6.36459C10.1965 6.09082 11.2424 5.95546 12.2883 5.94931C13.3342 5.95546 14.3801 6.09082 15.3644 6.36459C17.7023 4.77319 18.7328 5.10337 18.7328 5.10337C19.3942 6.79833 18.9789 8.04931 18.8559 8.36C19.6403 9.22133 20.1171 10.3185 20.1171 11.6618C20.1171 16.3888 17.2409 17.4296 14.5031 17.7321C14.9338 18.1012 15.3337 18.8559 15.3337 20.0084C15.3337 21.6552 15.3183 22.978 15.3183 23.3779C15.3183 23.7009 15.5336 24.0854 16.1642 23.9623C21.0871 22.3484 24.6094 17.7341 24.6094 12.3047C24.6094 5.50942 19.0999 0 12.3047 0Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://twitter.com/angular"
|
|
||||||
aria-label="Twitter"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
alt="Twitter"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://www.youtube.com/channel/UCbn1OgGei-DV7aSRo_HaAiw"
|
|
||||||
aria-label="Youtube"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
width="29"
|
|
||||||
height="20"
|
|
||||||
viewBox="0 0 29 20"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
alt="Youtube"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill-rule="evenodd"
|
|
||||||
clip-rule="evenodd"
|
|
||||||
d="M27.4896 1.52422C27.9301 1.96749 28.2463 2.51866 28.4068 3.12258C29.0004 5.35161 29.0004 10 29.0004 10C29.0004 10 29.0004 14.6484 28.4068 16.8774C28.2463 17.4813 27.9301 18.0325 27.4896 18.4758C27.0492 18.9191 26.5 19.2389 25.8972 19.4032C23.6778 20 14.8068 20 14.8068 20C14.8068 20 5.93586 20 3.71651 19.4032C3.11363 19.2389 2.56449 18.9191 2.12405 18.4758C1.68361 18.0325 1.36732 17.4813 1.20683 16.8774C0.613281 14.6484 0.613281 10 0.613281 10C0.613281 10 0.613281 5.35161 1.20683 3.12258C1.36732 2.51866 1.68361 1.96749 2.12405 1.52422C2.56449 1.08095 3.11363 0.76113 3.71651 0.596774C5.93586 0 14.8068 0 14.8068 0C14.8068 0 23.6778 0 25.8972 0.596774C26.5 0.76113 27.0492 1.08095 27.4896 1.52422ZM19.3229 10L11.9036 5.77905V14.221L19.3229 10Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
|
||||||
<!-- * * * * * * * * * * * The content above * * * * * * * * * * * * -->
|
|
||||||
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * * -->
|
|
||||||
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * -->
|
|
||||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
|
||||||
<!-- * * * * * * * * * * End of Placeholder * * * * * * * * * * * * -->
|
|
||||||
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
|
|
||||||
|
|
||||||
|
|
||||||
<router-outlet />
|
|
||||||
|
|||||||
9
src/app/app.component.scss
Normal file
9
src/app/app.component.scss
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// .main-content {
|
||||||
|
// display: flex;
|
||||||
|
// flex-direction: row;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// router-outlet {
|
||||||
|
// flex: 1;
|
||||||
|
// padding: 20px;
|
||||||
|
// }
|
||||||
@@ -1,13 +1,20 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import { RouterOutlet } from '@angular/router';
|
||||||
|
import { HeaderComponent } from './header/header.component';
|
||||||
|
import { PrimeNGConfig } from 'primeng/api';
|
||||||
|
import { Lara } from 'primeng/themes/lara';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [RouterOutlet],
|
imports: [RouterOutlet, HeaderComponent],
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.sass'
|
styleUrls: ['./app.component.scss']
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
title = 'tools';
|
title = 'tools';
|
||||||
|
|
||||||
|
constructor(private config: PrimeNGConfig) {
|
||||||
|
this.config.theme.set({ preset: Lara });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,13 @@ import { ApplicationConfig } from '@angular/core';
|
|||||||
import { provideRouter } from '@angular/router';
|
import { provideRouter } from '@angular/router';
|
||||||
|
|
||||||
import { routes } from './app.routes';
|
import { routes } from './app.routes';
|
||||||
|
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
|
||||||
|
import { provideNgIconsConfig } from '@ng-icons/core';
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
providers: [provideRouter(routes)]
|
providers: [provideRouter(routes),
|
||||||
|
provideAnimationsAsync("animations"),
|
||||||
|
provideNgIconsConfig({
|
||||||
|
size: '1.5em',
|
||||||
|
}),]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,36 @@
|
|||||||
import { Routes } from '@angular/router';
|
import { Routes } from '@angular/router';
|
||||||
|
import { AsciiToTextComponent } from '../tools/ascii-to-text/ascii-to-text.component';
|
||||||
|
import { GuidComponent } from '../tools/guid/guid.component';
|
||||||
|
import { Base64ConverterComponent } from '../tools/base64-converter/base64-converter.component';
|
||||||
|
import { JwtToJsonComponent } from '../tools/jwt-to-json/jwt-to-json.component';
|
||||||
|
import { TextToCronComponent } from '../tools/text-to-cron/text-to-cron.component';
|
||||||
|
|
||||||
|
// create route to the ascii-to-text component
|
||||||
|
export const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: 'ascii-to-text',
|
||||||
|
pathMatch: 'full',
|
||||||
|
component: AsciiToTextComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'guid',
|
||||||
|
pathMatch: 'full',
|
||||||
|
component: GuidComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'base64-converter',
|
||||||
|
pathMatch: 'full',
|
||||||
|
component: Base64ConverterComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'jwt-decoder',
|
||||||
|
pathMatch: 'full',
|
||||||
|
component: JwtToJsonComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'text-to-cron',
|
||||||
|
pathMatch: 'full',
|
||||||
|
component: TextToCronComponent
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
export const routes: Routes = [];
|
|
||||||
|
|||||||
1
src/app/header/header.component.html
Normal file
1
src/app/header/header.component.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<p-megamenu [model]="items" />
|
||||||
28
src/app/header/header.component.spec.ts
Normal file
28
src/app/header/header.component.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/* tslint:disable:no-unused-variable */
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
|
import { HeaderComponent } from './header.component';
|
||||||
|
|
||||||
|
describe('HeaderComponent', () => {
|
||||||
|
let component: HeaderComponent;
|
||||||
|
let fixture: ComponentFixture<HeaderComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ HeaderComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(HeaderComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
59
src/app/header/header.component.ts
Normal file
59
src/app/header/header.component.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { MegaMenuItem } from 'primeng/api';
|
||||||
|
import { MegaMenuModule } from 'primeng/megamenu';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { AvatarModule } from 'primeng/avatar';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-header',
|
||||||
|
templateUrl: './header.component.html',
|
||||||
|
standalone: true,
|
||||||
|
imports: [MegaMenuModule, ButtonModule, CommonModule, AvatarModule]
|
||||||
|
})
|
||||||
|
export class HeaderComponent implements OnInit {
|
||||||
|
items: MegaMenuItem[] | undefined;
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.items = [
|
||||||
|
{
|
||||||
|
label: 'Text Tools',
|
||||||
|
icon: 'pi pi-box',
|
||||||
|
items: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: 'Ascii to text',
|
||||||
|
routerLink: 'ascii-to-text',
|
||||||
|
routerLinkActiveOptions: { exact: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Guid Generator',
|
||||||
|
routerLink: 'guid',
|
||||||
|
routerLinkActiveOptions: { exact: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Base64 Converter',
|
||||||
|
routerLink: 'base64-converter',
|
||||||
|
routerLinkActiveOptions: { exact: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Jwt decoder',
|
||||||
|
routerLink: 'jwt-decoder',
|
||||||
|
routerLinkActiveOptions: { exact: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Text to Cron Expression',
|
||||||
|
routerLink: 'text-to-cron',
|
||||||
|
routerLinkActiveOptions: { exact: true }
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/app/shared/dual-textarea/dual-textarea.component.html
Normal file
21
src/app/shared/dual-textarea/dual-textarea.component.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<div class="card flex justify-center">
|
||||||
|
<p-panel [header]="title">
|
||||||
|
<textarea
|
||||||
|
(keyup)="onTopChange($event)"
|
||||||
|
[disabled]="topDisabled"
|
||||||
|
pTextarea
|
||||||
|
[value]="topValue"
|
||||||
|
[placeholder]="topPlaceholder">
|
||||||
|
</textarea>
|
||||||
|
<div>
|
||||||
|
<i class="pi pi-arrow-right-arrow-left" style="font-size: 1rem"></i>
|
||||||
|
</div>
|
||||||
|
<textarea
|
||||||
|
(keyup)="onBottomChange($event)"
|
||||||
|
[disabled]="bottomDisabled"
|
||||||
|
pTextarea
|
||||||
|
[value]="bottomValue"
|
||||||
|
[placeholder]="bottomPlaceholder">
|
||||||
|
</textarea>
|
||||||
|
</p-panel>
|
||||||
|
</div>
|
||||||
36
src/app/shared/dual-textarea/dual-textarea.component.scss
Normal file
36
src/app/shared/dual-textarea/dual-textarea.component.scss
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
width: 98vw;
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 1140px;
|
||||||
|
|
||||||
|
.conversion {
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 70vh;
|
||||||
|
|
||||||
|
p-floatlabel {
|
||||||
|
width: 30vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 540px;
|
||||||
|
height: 175px;
|
||||||
|
padding: 12px 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 16px;
|
||||||
|
resize: none;
|
||||||
|
background-color: var(--primary-contrast);
|
||||||
|
color: var(--text-color)
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/app/shared/dual-textarea/dual-textarea.component.ts
Normal file
42
src/app/shared/dual-textarea/dual-textarea.component.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Component, Input, Output, EventEmitter, input } from '@angular/core';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { FloatLabelModule } from 'primeng/floatlabel';
|
||||||
|
import { InputTextareaModule } from 'primeng/inputtextarea';
|
||||||
|
import { PanelModule } from 'primeng/panel';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-dual-textarea',
|
||||||
|
templateUrl: 'dual-textarea.component.html',
|
||||||
|
styleUrls: ['dual-textarea.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
FloatLabelModule,
|
||||||
|
InputTextareaModule,
|
||||||
|
FormsModule,
|
||||||
|
PanelModule,
|
||||||
|
CommonModule
|
||||||
|
]
|
||||||
|
|
||||||
|
})
|
||||||
|
export class DualTextareaComponent {
|
||||||
|
@Input() topDisabled: boolean = false;
|
||||||
|
@Input() bottomDisabled: boolean = false;
|
||||||
|
@Input() title: string = 'Dual Textarea';
|
||||||
|
@Input() topPlaceholder: string = 'Left Textarea';
|
||||||
|
@Input() bottomPlaceholder: string = 'Right Textarea';
|
||||||
|
@Input() topValue: string = '';
|
||||||
|
@Input() bottomValue: string = '';
|
||||||
|
@Output() topChange = new EventEmitter<string>();
|
||||||
|
@Output() bottomChange = new EventEmitter<string>();
|
||||||
|
|
||||||
|
onTopChange(event: Event): void {
|
||||||
|
const input = (event.target as HTMLTextAreaElement).value;
|
||||||
|
this.topChange.emit(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
onBottomChange(event: Event): void {
|
||||||
|
const input = (event.target as HTMLTextAreaElement).value;
|
||||||
|
this.bottomChange.emit(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,5 +2,4 @@ import { bootstrapApplication } from '@angular/platform-browser';
|
|||||||
import { appConfig } from './app/app.config';
|
import { appConfig } from './app/app.config';
|
||||||
import { AppComponent } from './app/app.component';
|
import { AppComponent } from './app/app.component';
|
||||||
|
|
||||||
bootstrapApplication(AppComponent, appConfig)
|
bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));
|
||||||
.catch((err) => console.error(err));
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
@import "primeicons/primeicons.css";
|
||||||
9
src/tools/ascii-to-text/ascii-to-text.component.html
Normal file
9
src/tools/ascii-to-text/ascii-to-text.component.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<app-dual-textarea
|
||||||
|
title="Ascii to text"
|
||||||
|
[topPlaceholder]="'Enter ascii here...'"
|
||||||
|
[bottomPlaceholder]="'Text will appear here...'"
|
||||||
|
[topValue]="convertedAscii"
|
||||||
|
[bottomValue]="convertedText"
|
||||||
|
(topChange)="onAsciiChange($event)"
|
||||||
|
(bottomChange)="onTextChange($event)">
|
||||||
|
</app-dual-textarea>
|
||||||
34
src/tools/ascii-to-text/ascii-to-text.component.scss
Normal file
34
src/tools/ascii-to-text/ascii-to-text.component.scss
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
width: 98vw;
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 1140;
|
||||||
|
|
||||||
|
.conversion {
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 70vh;
|
||||||
|
|
||||||
|
p-floatlabel {
|
||||||
|
width: 30vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
height: 50vh;
|
||||||
|
padding: 12px 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 16px;
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/tools/ascii-to-text/ascii-to-text.component.ts
Normal file
39
src/tools/ascii-to-text/ascii-to-text.component.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { DualTextareaComponent } from '../../app/shared/dual-textarea/dual-textarea.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-ascii-to-text',
|
||||||
|
templateUrl: './ascii-to-text.component.html',
|
||||||
|
styleUrls: ['./ascii-to-text.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [DualTextareaComponent]
|
||||||
|
})
|
||||||
|
export class AsciiToTextComponent {
|
||||||
|
convertedText: string = '';
|
||||||
|
convertedAscii: string = '';
|
||||||
|
|
||||||
|
onAsciiChange(input: string): void {
|
||||||
|
this.convertedText = this.convertAsciiToText(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
convertAsciiToText(ascii: string): string {
|
||||||
|
return ascii
|
||||||
|
.split(' ')
|
||||||
|
.map(char => String.fromCharCode(parseInt(char, 10)))
|
||||||
|
.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChange(input: string): void {
|
||||||
|
this.convertedAscii = this.convertTextToAscii(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
convertTextToAscii(text: string): string {
|
||||||
|
return text
|
||||||
|
.split('')
|
||||||
|
.map(char => {
|
||||||
|
const asciiValue = char.charCodeAt(0).toString();
|
||||||
|
return asciiValue.padStart(3, '0');
|
||||||
|
})
|
||||||
|
.join(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<app-dual-textarea
|
||||||
|
title="base64 to text"
|
||||||
|
topPlaceholder="Enter base64 here..."
|
||||||
|
bottomPlaceholder="Text will appear here..."
|
||||||
|
[topValue]="convertedBase64"
|
||||||
|
[bottomValue]="convertedText"
|
||||||
|
(topChange)="base64Decoded($event)"
|
||||||
|
(bottomChange)="base64Encoded($event)">
|
||||||
|
</app-dual-textarea>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/* tslint:disable:no-unused-variable */
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
|
import { Base64ConverterComponent } from './base64-converter.component';
|
||||||
|
|
||||||
|
describe('Base64ConverterComponent', () => {
|
||||||
|
let component: Base64ConverterComponent;
|
||||||
|
let fixture: ComponentFixture<Base64ConverterComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ Base64ConverterComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(Base64ConverterComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
24
src/tools/base64-converter/base64-converter.component.ts
Normal file
24
src/tools/base64-converter/base64-converter.component.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { DualTextareaComponent } from '../../app/shared/dual-textarea/dual-textarea.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-base64-converter',
|
||||||
|
templateUrl: './base64-converter.component.html',
|
||||||
|
styleUrls: ['./base64-converter.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [DualTextareaComponent]
|
||||||
|
})
|
||||||
|
export class Base64ConverterComponent {
|
||||||
|
convertedBase64: string = '';
|
||||||
|
convertedText: string = '';
|
||||||
|
|
||||||
|
base64Encoded(event: string): void {
|
||||||
|
this.convertedBase64 = btoa(event);
|
||||||
|
this.convertedText = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
base64Decoded(event: string): void {
|
||||||
|
this.convertedText = atob(event);
|
||||||
|
this.convertedBase64 = event;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/tools/guid/guid.component.html
Normal file
44
src/tools/guid/guid.component.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<p-panel header="Guid Generator">
|
||||||
|
<div>
|
||||||
|
<div *ngFor="let setting of settings" class="guid-row">
|
||||||
|
<p-radiobutton [inputId]="setting.code" name="category" [value]="setting" [(ngModel)]="selectedGuid" />
|
||||||
|
<label [for]="setting.code">
|
||||||
|
{{ setting.name }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template pTemplate="footer">
|
||||||
|
<div>
|
||||||
|
<div class="icon-wrapper">
|
||||||
|
<p-button
|
||||||
|
pTooltip="Regenerate new Guid."
|
||||||
|
icon="pi pi-refresh"
|
||||||
|
[rounded]="true"
|
||||||
|
[text]="true"
|
||||||
|
(onClick)="generateGuid(true)"
|
||||||
|
/>
|
||||||
|
<p-button
|
||||||
|
pTooltip="Copy selected Guid to clipboard."
|
||||||
|
icon="pi pi-clipboard"
|
||||||
|
severity="secondary"
|
||||||
|
[rounded]="true"
|
||||||
|
[text]="true"
|
||||||
|
(onClick)="onCopyToClipboard()"
|
||||||
|
/>
|
||||||
|
<p-button
|
||||||
|
pTooltip="Change casing."
|
||||||
|
icon="pi"
|
||||||
|
severity="secondary"
|
||||||
|
[rounded]="true"
|
||||||
|
[text]="true"
|
||||||
|
(onClick)="onCasingChange()"
|
||||||
|
>
|
||||||
|
<ng-template pTemplate="uppercase">
|
||||||
|
<ng-icon name="cssFormatUppercase"></ng-icon>
|
||||||
|
</ng-template>
|
||||||
|
</p-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</p-panel>
|
||||||
30
src/tools/guid/guid.component.scss
Normal file
30
src/tools/guid/guid.component.scss
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
width: 98vw;
|
||||||
|
|
||||||
|
p-panel {
|
||||||
|
width: 576px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guid-row {
|
||||||
|
padding: 8px 0px;
|
||||||
|
border-bottom: solid 1px var(--p-button-text-secondary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
p-floatlabel {
|
||||||
|
width: 30vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
ng-icon {
|
||||||
|
color: var(--p-button-text-secondary-color)
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-wrapper{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
100
src/tools/guid/guid.component.ts
Normal file
100
src/tools/guid/guid.component.ts
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { InputTextareaModule } from 'primeng/inputtextarea';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { FloatLabelModule } from 'primeng/floatlabel';
|
||||||
|
import { RadioButtonModule, } from 'primeng/radiobutton';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { ToggleButtonModule } from 'primeng/togglebutton';
|
||||||
|
import { Clipboard } from '@angular/cdk/clipboard';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { PanelModule } from 'primeng/panel';
|
||||||
|
import { NgIconComponent, provideIcons } from '@ng-icons/core';
|
||||||
|
import { cssFormatUppercase } from '@ng-icons/css.gg';
|
||||||
|
import { DividerModule } from 'primeng/divider';
|
||||||
|
import { TooltipModule } from 'primeng/tooltip';
|
||||||
|
|
||||||
|
interface setting {
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-guid',
|
||||||
|
templateUrl: './guid.component.html',
|
||||||
|
styleUrls: ['./guid.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
viewProviders: [provideIcons({cssFormatUppercase})],
|
||||||
|
imports: [
|
||||||
|
NgIconComponent,
|
||||||
|
PanelModule,
|
||||||
|
DividerModule,
|
||||||
|
FloatLabelModule,
|
||||||
|
InputTextareaModule,
|
||||||
|
FormsModule,
|
||||||
|
RadioButtonModule,
|
||||||
|
CommonModule,
|
||||||
|
ToggleButtonModule,
|
||||||
|
ButtonModule,
|
||||||
|
TooltipModule
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class GuidComponent implements OnInit {
|
||||||
|
settings: setting[] | undefined;
|
||||||
|
selectedGuid: setting | undefined;
|
||||||
|
guid: string = '';
|
||||||
|
isUppercase: boolean = false;
|
||||||
|
|
||||||
|
constructor(private clipboard: Clipboard) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.generateGuid(false);
|
||||||
|
this.setGuids();
|
||||||
|
}
|
||||||
|
|
||||||
|
onCopyToClipboard(): void {
|
||||||
|
this.clipboard.copy(this.selectedGuid?.name!);
|
||||||
|
}
|
||||||
|
|
||||||
|
onCasingChange(): void {
|
||||||
|
this.isUppercase = !this.isUppercase;
|
||||||
|
|
||||||
|
if (this.isUppercase) {
|
||||||
|
this.guid = this.guid.toUpperCase();
|
||||||
|
} else {
|
||||||
|
this.guid = this.guid.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setGuids();
|
||||||
|
}
|
||||||
|
|
||||||
|
generateGuid(input: boolean) {
|
||||||
|
this.guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(character) {
|
||||||
|
const randomValue = Math.random() * 16 | 0;
|
||||||
|
const value = character === 'x' ? randomValue : (randomValue & 0x3 | 0x8);
|
||||||
|
return value.toString(16);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.isUppercase) {
|
||||||
|
this.guid = this.guid.toUpperCase();
|
||||||
|
} else {
|
||||||
|
this.guid = this.guid.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input)
|
||||||
|
this.setGuids();
|
||||||
|
}
|
||||||
|
|
||||||
|
setGuids() {
|
||||||
|
this.settings = [
|
||||||
|
{ name: this.guid, code: '00' },
|
||||||
|
{ name: `"${this.guid}"`, code: '01' },
|
||||||
|
{ name: `{${this.guid}}`, code: '02' },
|
||||||
|
{ name: `new Guid("${this.guid}")`, code: '03' },
|
||||||
|
{ name: `[Guid("${this.guid}")]`, code: '04' },
|
||||||
|
];
|
||||||
|
|
||||||
|
if (this.settings!.length > 0) {
|
||||||
|
this.selectedGuid = this.settings![0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/tools/jwt-to-json/jwt-to-json.component.html
Normal file
8
src/tools/jwt-to-json/jwt-to-json.component.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<app-dual-textarea
|
||||||
|
title="Decode JWT Token"
|
||||||
|
topPlaceholder="Enter JWT Token here..."
|
||||||
|
bottomPlaceholder="Json will appear here..."
|
||||||
|
[bottomDisabled]="true"
|
||||||
|
[bottomValue]="readableToken"
|
||||||
|
(topChange)="decodeJwtToken($event)">
|
||||||
|
</app-dual-textarea>
|
||||||
0
src/tools/jwt-to-json/jwt-to-json.component.scss
Normal file
0
src/tools/jwt-to-json/jwt-to-json.component.scss
Normal file
28
src/tools/jwt-to-json/jwt-to-json.component.spec.ts
Normal file
28
src/tools/jwt-to-json/jwt-to-json.component.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/* tslint:disable:no-unused-variable */
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
|
import { JwtToJsonComponent } from './jwt-to-json.component';
|
||||||
|
|
||||||
|
describe('JwtToJsonComponent', () => {
|
||||||
|
let component: JwtToJsonComponent;
|
||||||
|
let fixture: ComponentFixture<JwtToJsonComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ JwtToJsonComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(JwtToJsonComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
43
src/tools/jwt-to-json/jwt-to-json.component.ts
Normal file
43
src/tools/jwt-to-json/jwt-to-json.component.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { DualTextareaComponent } from '../../app/shared/dual-textarea/dual-textarea.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-jwt-to-json',
|
||||||
|
templateUrl: './jwt-to-json.component.html',
|
||||||
|
styleUrls: ['./jwt-to-json.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [DualTextareaComponent]
|
||||||
|
})
|
||||||
|
export class JwtToJsonComponent {
|
||||||
|
readableToken: string = '';
|
||||||
|
|
||||||
|
decodeBase64Url(base64Url: string): string {
|
||||||
|
const base64 = base64Url
|
||||||
|
.replace(/-/g, '+')
|
||||||
|
.replace(/_/g, '/');
|
||||||
|
|
||||||
|
const jsonPayload = decodeURIComponent(
|
||||||
|
atob(base64)
|
||||||
|
.split('')
|
||||||
|
.map(char => '%' + ('00' + char.charCodeAt(0).toString(16)).slice(-2))
|
||||||
|
.join('')
|
||||||
|
);
|
||||||
|
|
||||||
|
return jsonPayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
decodeJwtToken(token: string): void {
|
||||||
|
const parts = token.split('.');
|
||||||
|
|
||||||
|
if (parts.length !== 3) {
|
||||||
|
throw new Error('Invalid JWT Token');
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = this.decodeBase64Url(parts[1]);
|
||||||
|
try {
|
||||||
|
this.readableToken = JSON.stringify(JSON.parse(payload), null, 2);
|
||||||
|
} catch (error) {
|
||||||
|
this.readableToken = 'Invalid JWT Token';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/tools/text-to-cron/text-to-cron.component.html
Normal file
10
src/tools/text-to-cron/text-to-cron.component.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<app-dual-textarea
|
||||||
|
title="Text to Cron Expression"
|
||||||
|
topPlaceholder="every 5 minutes"
|
||||||
|
bottomPlaceholder="*/5 * * * *"
|
||||||
|
[bottomDisabled]="true"
|
||||||
|
[bottomValue]="cronExpression"
|
||||||
|
(topChange)="getCronExpression($event)">
|
||||||
|
</app-dual-textarea>
|
||||||
|
|
||||||
|
<p>Still in beta, don't rely on this tool!</p>
|
||||||
0
src/tools/text-to-cron/text-to-cron.component.scss
Normal file
0
src/tools/text-to-cron/text-to-cron.component.scss
Normal file
28
src/tools/text-to-cron/text-to-cron.component.spec.ts
Normal file
28
src/tools/text-to-cron/text-to-cron.component.spec.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/* tslint:disable:no-unused-variable */
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
|
import { TextToCronComponent } from './text-to-cron.component';
|
||||||
|
|
||||||
|
describe('TextToCronComponent', () => {
|
||||||
|
let component: TextToCronComponent;
|
||||||
|
let fixture: ComponentFixture<TextToCronComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ TextToCronComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(TextToCronComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
50
src/tools/text-to-cron/text-to-cron.component.ts
Normal file
50
src/tools/text-to-cron/text-to-cron.component.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { DualTextareaComponent } from '../../app/shared/dual-textarea/dual-textarea.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-text-to-cron',
|
||||||
|
templateUrl: './text-to-cron.component.html',
|
||||||
|
styleUrls: ['./text-to-cron.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [DualTextareaComponent]
|
||||||
|
})
|
||||||
|
export class TextToCronComponent {
|
||||||
|
|
||||||
|
cronExpression: string = '';
|
||||||
|
|
||||||
|
getCronExpression(description: string): string {
|
||||||
|
let minute = "*";
|
||||||
|
let hour = "*";
|
||||||
|
let dayOfMonth = "*";
|
||||||
|
let month = "*";
|
||||||
|
let dayOfWeek = "*";
|
||||||
|
|
||||||
|
description = description.toLowerCase().trim();
|
||||||
|
|
||||||
|
const parts = description.split(" ");
|
||||||
|
parts.forEach((part, index) => {
|
||||||
|
if (part === "minute" || part === "minutes") {
|
||||||
|
if (index > 0 && !isNaN(parseInt(parts[index - 1]))) {
|
||||||
|
minute = `*/${parts[index - 1]}`;
|
||||||
|
}
|
||||||
|
} else if (part === "hour" || part === "hours") {
|
||||||
|
if (index > 0 && !isNaN(parseInt(parts[index - 1]))) {
|
||||||
|
hour = `*/${parts[index - 1]}`;
|
||||||
|
}
|
||||||
|
} else if (part === "day" && parts[index + 1] === "of") {
|
||||||
|
if (parts[index + 2] === "month" && index > 0 && !isNaN(parseInt(parts[index - 1]))) {
|
||||||
|
dayOfMonth = `${parts[index - 1]}`;
|
||||||
|
} else if (parts[index + 2] === "week" && index > 0 && !isNaN(parseInt(parts[index - 1]))) {
|
||||||
|
dayOfWeek = `${parts[index - 1]}`;
|
||||||
|
}
|
||||||
|
} else if (part === "month" || part === "months") {
|
||||||
|
if (index > 0 && !isNaN(parseInt(parts[index - 1]))) {
|
||||||
|
month = `*/${parts[index - 1]}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.cronExpression = `${minute} ${hour} ${dayOfMonth} ${month} ${dayOfWeek}`;
|
||||||
|
return `${minute} ${hour} ${dayOfMonth} ${month} ${dayOfWeek}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user