├── .gitignore ├── Contributing.md ├── Dashboard ├── .eslintrc.cjs ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── public │ ├── Logo.png │ ├── _redirects │ └── vite.svg ├── src │ ├── App.css │ ├── App.tsx │ ├── api │ │ └── api.ts │ ├── assets │ │ └── react.svg │ ├── components │ │ ├── Auth │ │ │ ├── AlternateText.tsx │ │ │ ├── AuthContainer.tsx │ │ │ ├── Fields.tsx │ │ │ ├── Form.tsx │ │ │ ├── SideBanner.tsx │ │ │ └── SocialAuth.tsx │ │ ├── Avatar.tsx │ │ ├── Buttons.tsx │ │ ├── Charts │ │ │ ├── CustomLegends.tsx │ │ │ ├── DisplayMonthChart.tsx │ │ │ ├── MonthSelect.tsx │ │ │ └── ProductChart.tsx │ │ ├── DashBoard │ │ │ ├── DataCards.tsx │ │ │ └── VisualisationSpace.tsx │ │ ├── MobileMenu.tsx │ │ ├── RouteProxy.tsx │ │ ├── Schedule │ │ │ ├── Schedule.tsx │ │ │ └── ScheduleSummary.tsx │ │ ├── SearchBox.tsx │ │ ├── Spinner.tsx │ │ └── Text.tsx │ ├── data │ │ ├── DataCardsData.ts │ │ ├── FieldsData.ts │ │ └── Links.ts │ ├── hooks │ │ ├── useIsMobile.tsx │ │ └── useMediaQuery.tsx │ ├── icons │ │ ├── Apple.png │ │ └── Google.png │ ├── index.css │ ├── layout │ │ ├── Navbar.tsx │ │ └── SideNav.tsx │ ├── main.tsx │ ├── pages │ │ ├── Auth.tsx │ │ └── DashBoard.tsx │ ├── types │ │ ├── Auth.d.ts │ │ ├── Button.d.ts │ │ ├── CustomLegends.d.ts │ │ ├── DataCards.d.ts │ │ ├── MonthlyChart.d.ts │ │ ├── ProductChartProps.d.ts │ │ ├── Schedule.d.ts │ │ ├── SideNavLinks.d.ts │ │ └── Text.d.ts │ └── vite-env.d.ts ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── Drizzle-CRUD-API ├── Readme.md ├── drizzle.config.ts ├── package-lock.json ├── package.json └── src │ ├── controllers │ ├── createBlog.ts │ ├── createUser.ts │ ├── deleteUser.ts │ ├── getUsers.ts │ └── updateUser.ts │ ├── db │ ├── schema.ts │ └── setup.ts │ ├── index.ts │ └── routes │ ├── blogs.ts │ └── users.ts ├── MDNotesApp ├── .eslintrc.cjs ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.css │ ├── App.tsx │ ├── assets │ │ └── react.svg │ ├── components │ │ ├── NewNote.tsx │ │ └── NoteForm.tsx │ ├── hooks │ │ └── useLocalStorage.tsx │ ├── index.css │ ├── main.tsx │ ├── types │ │ ├── Note.type.ts │ │ ├── NoteData.type.ts │ │ └── RawNote.type.ts │ └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── MUI-Select ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── VisibleOption.ts │ ├── counter.ts │ ├── main.ts │ ├── style.css │ ├── typescript.svg │ └── vite-env.d.ts └── tsconfig.json ├── Readme.md ├── TODO-List ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── interfaces │ │ └── task.ts │ ├── main.ts │ ├── style.css │ ├── typescript.svg │ └── vite-env.d.ts └── tsconfig.json └── typewriter ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── public └── vite.svg ├── src ├── TypeWriter.ts ├── main.ts ├── style.css ├── typescript.svg └── vite-env.d.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/node 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=node 3 | 4 | ### Node ### 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | .pnpm-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | *.lcov 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | 33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 34 | .grunt 35 | 36 | # Bower dependency directory (https://bower.io/) 37 | bower_components 38 | 39 | # node-waf configuration 40 | .lock-wscript 41 | 42 | # Compiled binary addons (https://nodejs.org/api/addons.html) 43 | build/Release 44 | 45 | # Dependency directories 46 | node_modules/ 47 | jspm_packages/ 48 | 49 | # Snowpack dependency directory (https://snowpack.dev/) 50 | web_modules/ 51 | 52 | # TypeScript cache 53 | *.tsbuildinfo 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Optional stylelint cache 62 | .stylelintcache 63 | 64 | # Microbundle cache 65 | .rpt2_cache/ 66 | .rts2_cache_cjs/ 67 | .rts2_cache_es/ 68 | .rts2_cache_umd/ 69 | 70 | # Optional REPL history 71 | .node_repl_history 72 | 73 | # Output of 'npm pack' 74 | *.tgz 75 | 76 | # Yarn Integrity file 77 | .yarn-integrity 78 | 79 | # dotenv environment variable files 80 | .env 81 | .env.development.local 82 | .env.test.local 83 | .env.production.local 84 | .env.local 85 | 86 | # parcel-bundler cache (https://parceljs.org/) 87 | .cache 88 | .parcel-cache 89 | 90 | # Next.js build output 91 | .next 92 | out 93 | 94 | # Nuxt.js build / generate output 95 | .nuxt 96 | dist 97 | 98 | # Gatsby files 99 | .cache/ 100 | # Comment in the public line in if your project uses Gatsby and not Next.js 101 | # https://nextjs.org/blog/next-9-1#public-directory-support 102 | # public 103 | 104 | # vuepress build output 105 | .vuepress/dist 106 | 107 | # vuepress v2.x temp and cache directory 108 | .temp 109 | 110 | # Docusaurus cache and generated files 111 | .docusaurus 112 | 113 | # Serverless directories 114 | .serverless/ 115 | 116 | # FuseBox cache 117 | .fusebox/ 118 | 119 | # DynamoDB Local files 120 | .dynamodb/ 121 | 122 | # TernJS port file 123 | .tern-port 124 | 125 | # Stores VSCode versions used for testing VSCode extensions 126 | .vscode-test 127 | 128 | # yarn v2 129 | .yarn/cache 130 | .yarn/unplugged 131 | .yarn/build-state.yml 132 | .yarn/install-state.gz 133 | .pnp.* 134 | 135 | ### Node Patch ### 136 | # Serverless Webpack directories 137 | .webpack/ 138 | 139 | # Optional stylelint cache 140 | 141 | # SvelteKit build / generate output 142 | .svelte-kit 143 | 144 | # End of https://www.toptal.com/developers/gitignore/api/node 145 | -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | * Clone the repo 3 | ``` 4 | git clone 5 | ``` 6 | * Create a separate branch with the following format 7 | ``` 8 | project/project-name 9 | ``` 10 | * Initialise a separate project folder 11 | * Follow the home read me about setupping up typescript projects 12 | -------------------------------------------------------------------------------- /Dashboard/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:@typescript-eslint/recommended', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | ignorePatterns: ['dist', '.eslintrc.cjs'], 10 | parser: '@typescript-eslint/parser', 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': [ 14 | 'warn', 15 | { allowConstantExport: true }, 16 | ], 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /Dashboard/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /Dashboard/README.md: -------------------------------------------------------------------------------- 1 | # Dashboard 2 | * Tech - Typescript + React + react charts + tailwind + auth0 3 | * Things learnt - Polymorphic components -------------------------------------------------------------------------------- /Dashboard/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Dashboard 8 | 9 | 10 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Dashboard/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dashboard", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite --host", 8 | "build": "tsc && vite build", 9 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@auth0/auth0-react": "^2.2.1", 14 | "@headlessui/react": "^1.7.17", 15 | "chart.js": "^4.4.0", 16 | "react": "^18.2.0", 17 | "react-chartjs-2": "^5.2.0", 18 | "react-dom": "^18.2.0", 19 | "react-error-boundary": "^4.0.11", 20 | "react-icons": "^4.11.0", 21 | "react-router-dom": "^6.16.0", 22 | "tailwind-merge": "^1.14.0", 23 | "uninstall": "^0.0.0" 24 | }, 25 | "devDependencies": { 26 | "@types/react": "^18.2.15", 27 | "@types/react-dom": "^18.2.7", 28 | "@typescript-eslint/eslint-plugin": "^6.0.0", 29 | "@typescript-eslint/parser": "^6.0.0", 30 | "@vitejs/plugin-react": "^4.0.3", 31 | "autoprefixer": "^10.4.15", 32 | "eslint": "^8.45.0", 33 | "eslint-plugin-react-hooks": "^4.6.0", 34 | "eslint-plugin-react-refresh": "^0.4.3", 35 | "postcss": "^8.4.29", 36 | "tailwindcss": "^3.3.3", 37 | "typescript": "^5.0.2", 38 | "vite": "^4.4.5" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Dashboard/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /Dashboard/public/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnabChatterjee20k/TypeScript-Projects/1a821e5391a918115bf780455803094c7d9da5f3/Dashboard/public/Logo.png -------------------------------------------------------------------------------- /Dashboard/public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /Dashboard/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dashboard/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /Dashboard/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { BrowserRouter, Route, Routes } from "react-router-dom"; 2 | import Auth from "./pages/Auth"; 3 | import DashBoard from "./pages/DashBoard"; 4 | import { Auth0Provider } from "@auth0/auth0-react"; 5 | import { authApi } from "./api/api"; 6 | import RouteProxy from "./components/RouteProxy"; 7 | 8 | export default function App() { 9 | return ( 10 | <> 11 | 18 | 19 | 20 | } /> 21 | } /> 22 | } /> 23 | 24 | 25 | 26 | 27 | ); 28 | } -------------------------------------------------------------------------------- /Dashboard/src/api/api.ts: -------------------------------------------------------------------------------- 1 | export const authApi = { 2 | data: { 3 | domain: "", 4 | clientId: "", 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /Dashboard/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Dashboard/src/components/Auth/AlternateText.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | 3 | export default function AlternateText() { 4 | return ( 5 |

6 | Don’t have an account?{" "} 7 | 8 | Register here 9 | 10 |

11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /Dashboard/src/components/Auth/AuthContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { AuthProps } from "../../types/Auth"; 3 | import { twMerge } from "tailwind-merge"; 4 | 5 | export default function AuthContainer({ 6 | as, 7 | children, 8 | className, 9 | ...props 10 | }: AuthProps & React.ComponentPropsWithoutRef) { 11 | const Component = as || "div"; 12 | return ( 13 | 14 | {children} 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /Dashboard/src/components/Auth/Fields.tsx: -------------------------------------------------------------------------------- 1 | import { FieldProps } from "../../types/Auth"; 2 | export default function Fields({label,type,placeholder}:FieldProps) { 3 | return ( 4 |
5 | 6 | 7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /Dashboard/src/components/Auth/Form.tsx: -------------------------------------------------------------------------------- 1 | import AuthContainer from "./AuthContainer"; 2 | import Fields from "./Fields"; 3 | import FieldsData from "../../data/FieldsData"; 4 | import { Link } from "react-router-dom"; 5 | import { PrimaryButton } from "../Buttons"; 6 | import Text from "../Text"; 7 | import SocialAuth from "./SocialAuth"; 8 | import AlternateText from "./AlternateText"; 9 | import useIsMobile from "../../hooks/useIsMobile"; 10 | import {twMerge} from "tailwind-merge" 11 | export default function Form() { 12 | const isMobile = useIsMobile() 13 | return ( 14 |
15 | 16 | 17 | 21 | {FieldsData.map((props) => ( 22 | 23 | ))} 24 | 25 | Forgot password? 26 | 27 | 28 | 29 |
30 | 31 |
32 |
33 | ); 34 | } 35 | 36 | function FormHeading() { 37 | return ( 38 |
39 | Sign In 40 |

Sign in to your account

41 |
42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /Dashboard/src/components/Auth/SideBanner.tsx: -------------------------------------------------------------------------------- 1 | import Text from "../Text"; 2 | 3 | export default function SideBanner() { 4 | return ( 5 |
6 | Target. 7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /Dashboard/src/components/Auth/SocialAuth.tsx: -------------------------------------------------------------------------------- 1 | import AuthContainer from "./AuthContainer"; 2 | import Google from "../../icons/Google.png"; 3 | import Apple from "../../icons/Apple.png"; 4 | import Text from "../Text"; 5 | import { useAuth0 } from "@auth0/auth0-react"; 6 | 7 | export default function SocialAuth() { 8 | return ( 9 |
10 | 11 | 12 |
13 | ); 14 | } 15 | 16 | function GoogleAuth() { 17 | const {loginWithRedirect} = useAuth0() 18 | return ( 19 | loginWithRedirect()} 22 | className="flex items-center gap-2 px-5 py-2 rounded-md social-login" 23 | > 24 | 25 | Sign in with Google 26 | 27 | ); 28 | } 29 | 30 | function AppleAuth() { 31 | return ( 32 | 36 | 37 | Sign in with Apple 38 | 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /Dashboard/src/components/Avatar.tsx: -------------------------------------------------------------------------------- 1 | import {useAuth0} from "@auth0/auth0-react" 2 | import {FaUserCircle} from "react-icons/fa" 3 | export default function Avatar() { 4 | const {user,isLoading,logout} = useAuth0() 5 | if(isLoading) return 6 | return ( 7 | logout()} 9 | className="cursor-pointer hover:ring-2 ring-black inline-block h-[1.5rem] w-[1.5rem] md:h-[2rem] md:w-[2rem] rounded-full" 10 | // src="https://images.unsplash.com/photo-1568602471122-7832951cc4c5?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=2&w=300&h=300&q=80" 11 | src={user?.picture} 12 | alt="Image Description" 13 | /> 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /Dashboard/src/components/Buttons.tsx: -------------------------------------------------------------------------------- 1 | import { ButtonProps } from "../types/Button"; 2 | import { twMerge } from "tailwind-merge"; 3 | import { ComponentPropsWithoutRef } from "react"; 4 | export function PrimaryButton({ 5 | text, 6 | className, 7 | ...props 8 | }: ButtonProps & ComponentPropsWithoutRef<"button">) { 9 | return ( 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /Dashboard/src/components/Charts/CustomLegends.tsx: -------------------------------------------------------------------------------- 1 | import CustomLegendsProps from "../../types/CustomLegends"; 2 | import {twMerge} from "tailwind-merge" 3 | export default function CustomLegends({ color, title ,lableClassName,pointClassName}: CustomLegendsProps) { 4 | return ( 5 |
6 |
10 | {title} 11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /Dashboard/src/components/Charts/DisplayMonthChart.tsx: -------------------------------------------------------------------------------- 1 | import MonthlyChartProps from "../../types/MonthlyChart"; 2 | import { 3 | Chart as ChartJS, 4 | CategoryScale, 5 | LinearScale, 6 | PointElement, 7 | LineElement, 8 | Title, 9 | Tooltip, 10 | Legend, 11 | } from "chart.js"; 12 | import { Line } from "react-chartjs-2"; 13 | import CustomLegends from "./CustomLegends"; 14 | import MonthSelect from "./MonthSelect"; 15 | 16 | ChartJS.register( 17 | CategoryScale, 18 | LinearScale, 19 | PointElement, 20 | LineElement, 21 | Title, 22 | Tooltip, 23 | Legend 24 | ); 25 | 26 | const USERCOLOR = "#9BDD7C"; 27 | const GUESTCOLOR = "#E9A0A0"; 28 | 29 | export function DisplayMonthChart({ chartData }: MonthlyChartProps) { 30 | const { User, Guest } = chartData; 31 | const dataLabels = Object.keys(User); 32 | 33 | const dataSet = [ 34 | { label: "Guest", data: Object.values(Guest), borderColor: GUESTCOLOR }, 35 | { label: "User", data: Object.values(User), borderColor: USERCOLOR }, 36 | ]; 37 | 38 | return ( 39 |
40 |
41 |
42 |
Activites
43 | 44 |
45 |
46 | {dataSet.map(({ label, borderColor }) => ( 47 | 48 | ))} 49 |
50 |
51 | { 77 | // Check if the tick value is 0 and return an empty string ('') in that case 78 | return value === 0 ? "" : value; 79 | }, 80 | }, 81 | }, 82 | }, 83 | }} 84 | data={{ labels: dataLabels, datasets: dataSet }} 85 | /> 86 |
87 | ); 88 | } 89 | -------------------------------------------------------------------------------- /Dashboard/src/components/Charts/MonthSelect.tsx: -------------------------------------------------------------------------------- 1 | export default function MonthSelect() { 2 | return ( 3 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /Dashboard/src/components/Charts/ProductChart.tsx: -------------------------------------------------------------------------------- 1 | import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js"; 2 | import { Pie } from "react-chartjs-2"; 3 | import ProductChartProps from "../../types/ProductChartProps"; 4 | import CustomLegends from "./CustomLegends"; 5 | import MonthSelect from "./MonthSelect"; 6 | 7 | ChartJS.register(ArcElement, Tooltip, Legend); 8 | 9 | const colors = [ 10 | "#98D89E", 11 | "#F6DC7D", 12 | "#EE8484", 13 | "#FF5733", 14 | "#337DFF", 15 | "#FFD633", 16 | ]; 17 | 18 | const ProductChart = ({ chartData }: ProductChartProps) => { 19 | const dataLabels = Object.keys(chartData); 20 | const dataSet = Object.values(chartData); 21 | 22 | const data = { 23 | labels: dataLabels, 24 | datasets: [ 25 | { 26 | data: dataSet, 27 | backgroundColor: colors, 28 | }, 29 | ], 30 | }; 31 | 32 | return ( 33 |
34 |
35 |
Top Products
36 | 37 |
38 |
39 | 55 |
56 | {dataLabels.map((label, index) => ( 57 |
58 | 63 | 64 | {dataSet[index]}% 65 | 66 |
67 | ))} 68 |
69 |
70 |
71 | ); 72 | }; 73 | 74 | export default ProductChart; 75 | -------------------------------------------------------------------------------- /Dashboard/src/components/DashBoard/DataCards.tsx: -------------------------------------------------------------------------------- 1 | import { DataCardsData } from "../../data/DataCardsData"; 2 | import { DataCardsProps } from "../../types/DataCards"; 3 | 4 | export default function DataCards() { 5 | return ( 6 |
7 | {DataCardsData.map((data) => ( 8 | 9 | ))} 10 |
11 | ); 12 | } 13 | 14 | function Card({ Icon, heading, value, color }: DataCardsProps) { 15 | return ( 16 |
20 | 24 |
25 |

{heading}

26 |

{value}

27 |
28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /Dashboard/src/components/DashBoard/VisualisationSpace.tsx: -------------------------------------------------------------------------------- 1 | import { DisplayMonthChart } from "../Charts/DisplayMonthChart"; 2 | import DataCards from "./DataCards"; 3 | import MonthlyChartProps from "../../types/MonthlyChart"; 4 | import ProductChart from "../Charts/ProductChart"; 5 | import ProductChartProps from "../../types/ProductChartProps"; 6 | import ScheduleProps from "../../types/Schedule"; 7 | import Schedule from "../Schedule/Schedule"; 8 | 9 | const chartsData: MonthlyChartProps = { 10 | chartData: { 11 | User: { 12 | Week0: 100, 13 | Week1: 400, 14 | Week2: 200, 15 | Week3: 500, 16 | Week4: 250, 17 | Week5: 367, 18 | }, 19 | Guest: { 20 | Week0: 200, 21 | Week1: 400, 22 | Week2: 200, 23 | Week3: 500, 24 | Week4: 700, 25 | Week5: 267, 26 | }, 27 | }, 28 | }; 29 | 30 | const productChartData: ProductChartProps = { 31 | chartData: { 32 | "Basic Trees": 55, 33 | "Super Hoodies": 14, 34 | "Custom Short Pants": 31, 35 | }, 36 | }; 37 | 38 | const schedule:ScheduleProps = { 39 | todaysSchedule: [ 40 | { 41 | time: "14.00-15.00", 42 | location: "Sunset Road, Kuta, Bali ", 43 | meetingTitle: "Meeting with suppliers from Kuta Bali", 44 | }, 45 | { 46 | time: "18.00-20.00", 47 | location: "Central Jakarta", 48 | meetingTitle: "Check operation at Giga Factory 1", 49 | }, 50 | ], 51 | }; 52 | export default function VisualisationSpace() { 53 | return ( 54 |
55 | 56 | 57 |
58 | 59 | 60 |
61 |
62 | ); 63 | } 64 | -------------------------------------------------------------------------------- /Dashboard/src/components/MobileMenu.tsx: -------------------------------------------------------------------------------- 1 | import { Fragment } from "react"; 2 | import { Menu, Transition } from "@headlessui/react"; 3 | import { Links } from "../data/Links"; 4 | import { FiMenu } from "react-icons/fi"; 5 | import { Link } from "react-router-dom"; 6 | 7 | export default function MobileNav() { 8 | return ( 9 |
10 | 11 | 12 | 13 | 14 | 23 | 24 | {Links.map(({ Icon, label, link }) => { 25 | return ( 26 | 27 |
28 | 29 | {label} 30 |
31 |
32 | ); 33 | })} 34 |
35 |
36 |
37 |
38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /Dashboard/src/components/RouteProxy.tsx: -------------------------------------------------------------------------------- 1 | import { useAuth0 } from "@auth0/auth0-react"; 2 | import { useNavigate } from "react-router-dom"; 3 | import { useEffect } from "react"; // Import useEffect and useState 4 | import Text from "./Text"; 5 | import Spinner from "./Spinner"; 6 | 7 | export default function RouteProxy() { 8 | const { isLoading, isAuthenticated } = useAuth0(); 9 | const nav = useNavigate(); 10 | 11 | useEffect(() => { 12 | if(!isLoading){ 13 | if(isAuthenticated) nav("/dashboard") 14 | else nav("/auth") 15 | } 16 | }, [isLoading,isAuthenticated]); 17 | 18 | return ( 19 |
20 | Target. 21 | {isLoading && } 22 |
23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /Dashboard/src/components/Schedule/Schedule.tsx: -------------------------------------------------------------------------------- 1 | import ScheduleProps from "../../types/Schedule"; 2 | import ScheduleSummary from "./ScheduleSummary"; 3 | 4 | export default function Schedule({ todaysSchedule }: ScheduleProps) { 5 | return ( 6 |
7 |
8 |
9 | Today’s schedule 10 |
11 | Sea All {`>`} 12 |
13 |
14 | 15 |
16 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /Dashboard/src/components/Schedule/ScheduleSummary.tsx: -------------------------------------------------------------------------------- 1 | import { ScheduleData } from "../../types/Schedule"; 2 | import ScheduleProps from "../../types/Schedule"; 3 | const colors = ["#9BDD7C", "#6972C3"]; 4 | export default function ScheduleSummary({ todaysSchedule }: ScheduleProps) { 5 | return ( 6 |
7 | {todaysSchedule.map((props, index) => ( 8 | 9 | ))} 10 |
11 | ); 12 | } 13 | 14 | function SchedulePoints({ 15 | location, 16 | meetingTitle, 17 | time, 18 | color, 19 | }: ScheduleData & { color: string }) { 20 | return ( 21 |
22 |
23 |
24 |

{meetingTitle}

25 |

{time}

26 |

{location}

27 |
28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /Dashboard/src/components/SearchBox.tsx: -------------------------------------------------------------------------------- 1 | import { CiSearch } from "react-icons/ci"; 2 | import { BiSearch } from "react-icons/bi"; 3 | 4 | import useIsMobile from "../hooks/useIsMobile"; 5 | 6 | export default function SearchBox() { 7 | const isMobile = useIsMobile() 8 | if(isMobile) return 9 | return ( 10 |
11 | 12 | 13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /Dashboard/src/components/Spinner.tsx: -------------------------------------------------------------------------------- 1 | export default function Spinner() { 2 | return ( 3 |
4 | 20 | Loading... 21 |
22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /Dashboard/src/components/Text.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { twMerge } from "tailwind-merge"; 3 | import { TextProps, TextAllowed } from "../types/Text"; 4 | export default function Text({ 5 | as, 6 | children, 7 | className, 8 | ...props 9 | }: TextProps & React.ComponentPropsWithoutRef) { 10 | const Component: TextAllowed = as || "p"; 11 | return ( 12 | 13 | {children} 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /Dashboard/src/data/DataCardsData.ts: -------------------------------------------------------------------------------- 1 | import { BsTags } from "react-icons/bs"; 2 | import { MdOutlinePayments } from "react-icons/md"; 3 | import { FaThumbsUp } from "react-icons/fa"; 4 | import { FiUsers } from "react-icons/fi"; 5 | 6 | import { DataCardsProps } from "../types/DataCards"; 7 | export const DataCardsData: DataCardsProps[] = [ 8 | { heading: "Total Revenues", value: "$2,129,430", Icon: MdOutlinePayments,color:"#DDEFE0" }, 9 | { heading: "Total Transactions", value: "1,520", Icon: BsTags , color:"#DEE0EF"}, 10 | { heading: "Total Likes", value: "9,721", Icon: FaThumbsUp ,color:"#EFDADA"}, 11 | { heading: "Total Users", value: "892", Icon: FiUsers ,color:"#F4ECDD"}, 12 | ]; 13 | -------------------------------------------------------------------------------- /Dashboard/src/data/FieldsData.ts: -------------------------------------------------------------------------------- 1 | import { FieldProps } from "../types/Auth" 2 | const FieldsData:FieldProps[] = [ 3 | {label:"Email address",type:"email",placeholder:"Enter your email"}, 4 | {label:"Password",type:"password",placeholder:"Enter your password"}, 5 | ] 6 | export default FieldsData -------------------------------------------------------------------------------- /Dashboard/src/data/Links.ts: -------------------------------------------------------------------------------- 1 | import { SideNavLinks } from "../types/SideNavLinks"; 2 | import { 3 | AiOutlinePieChart, 4 | AiOutlineCalendar, 5 | AiOutlineSetting, 6 | } from "react-icons/ai"; 7 | import { BsTags } from "react-icons/bs"; 8 | import { FaRegUserCircle } from "react-icons/fa"; 9 | export const Links: SideNavLinks[] = [ 10 | { label: "Dashboard", link: "/dashboard", Icon: AiOutlinePieChart }, 11 | { label: "Transactions", link: "/link", Icon: BsTags }, 12 | { label: "Schedules", link: "/link", Icon: AiOutlineCalendar }, 13 | { label: "Users", link: "/link", Icon: FaRegUserCircle }, 14 | { label: "Setting", link: "/link", Icon: AiOutlineSetting }, 15 | ]; 16 | -------------------------------------------------------------------------------- /Dashboard/src/hooks/useIsMobile.tsx: -------------------------------------------------------------------------------- 1 | import { useMediaQuery } from "./useMediaQuery"; 2 | 3 | export default function useIsMobile(): boolean { 4 | return useMediaQuery("(max-width: 35.9375em)"); 5 | } 6 | -------------------------------------------------------------------------------- /Dashboard/src/hooks/useMediaQuery.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | 3 | export function useMediaQuery(query: string): boolean { 4 | const getMatches = (query: string): boolean => { 5 | // Prevents SSR issues 6 | if (typeof window !== 'undefined') { 7 | return window.matchMedia(query).matches 8 | } 9 | return false 10 | } 11 | 12 | const [matches, setMatches] = useState(getMatches(query)) 13 | 14 | function handleChange() { 15 | setMatches(getMatches(query)) 16 | } 17 | 18 | useEffect(() => { 19 | const matchMedia = window.matchMedia(query) 20 | 21 | // Triggered at the first client-side load and if query changes 22 | handleChange() 23 | 24 | // Listen matchMedia 25 | if (matchMedia.addListener) { 26 | matchMedia.addListener(handleChange) 27 | } else { 28 | matchMedia.addEventListener('change', handleChange) 29 | } 30 | 31 | return () => { 32 | if (matchMedia.removeListener) { 33 | matchMedia.removeListener(handleChange) 34 | } else { 35 | matchMedia.removeEventListener('change', handleChange) 36 | } 37 | } 38 | // eslint-disable-next-line react-hooks/exhaustive-deps 39 | }, [query]) 40 | 41 | return matches 42 | } -------------------------------------------------------------------------------- /Dashboard/src/icons/Apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnabChatterjee20k/TypeScript-Projects/1a821e5391a918115bf780455803094c7d9da5f3/Dashboard/src/icons/Apple.png -------------------------------------------------------------------------------- /Dashboard/src/icons/Google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnabChatterjee20k/TypeScript-Projects/1a821e5391a918115bf780455803094c7d9da5f3/Dashboard/src/icons/Google.png -------------------------------------------------------------------------------- /Dashboard/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body{ 6 | background-color: #F5F5F5; 7 | } 8 | .social-login{ 9 | cursor: pointer; 10 | } 11 | .social-login:hover{ 12 | background-color: #f7f7f7; 13 | } 14 | 15 | .lds-dual-ring { 16 | display: inline-block; 17 | width: 20px; 18 | height: 20px; 19 | } 20 | .lds-dual-ring:after { 21 | content: " "; 22 | display: block; 23 | width: 64px; 24 | height: 64px; 25 | margin: 8px; 26 | border-radius: 50%; 27 | border: 6px solid black; 28 | border-color: #fff transparent #fff transparent; 29 | animation: lds-dual-ring 1.2s linear infinite; 30 | } 31 | @keyframes lds-dual-ring { 32 | 0% { 33 | transform: rotate(0deg); 34 | } 35 | 100% { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Dashboard/src/layout/Navbar.tsx: -------------------------------------------------------------------------------- 1 | import Avatar from "../components/Avatar"; 2 | import MobileMenu from "../components/MobileMenu"; 3 | import SearchBox from "../components/SearchBox"; 4 | import { BiBell } from "react-icons/bi"; 5 | export default function Navbar() { 6 | return ( 7 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /Dashboard/src/layout/SideNav.tsx: -------------------------------------------------------------------------------- 1 | import { Link, useLocation } from "react-router-dom"; 2 | import { Links } from "../data/Links"; 3 | import { twMerge } from "tailwind-merge"; 4 | 5 | export default function SideNav() { 6 | return ( 7 | 18 | ); 19 | } 20 | 21 | function DashboardLinks() { 22 | const { pathname } = useLocation(); 23 | return ( 24 |
25 | {Links.map(({ Icon, label, link }) => { 26 | return ( 27 | 28 | 29 | 35 | {label} 36 | 37 | 38 | ); 39 | })} 40 |
41 | ); 42 | } 43 | 44 | function UserHelp() { 45 | return ( 46 |
47 | 51 | Help 52 | 53 | 57 | Contact Us 58 | 59 |
60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /Dashboard/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import "./index.css" 5 | ReactDOM.createRoot(document.getElementById('root')!).render( 6 | 7 | 8 | , 9 | ) 10 | -------------------------------------------------------------------------------- /Dashboard/src/pages/Auth.tsx: -------------------------------------------------------------------------------- 1 | import Form from "../components/Auth/Form"; 2 | import SideBanner from "../components/Auth/SideBanner"; 3 | import useIsMobile from "../hooks/useIsMobile"; 4 | import { twMerge } from "tailwind-merge"; 5 | export default function Auth() { 6 | const isMobile = useIsMobile(); 7 | return ( 8 |
9 | {!isMobile && } 10 |
16 |
17 |
18 |
19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /Dashboard/src/pages/DashBoard.tsx: -------------------------------------------------------------------------------- 1 | import VisualisationSpace from "../components/DashBoard/VisualisationSpace"; 2 | import Navbar from "../layout/Navbar"; 3 | import SideNav from "../layout/SideNav"; 4 | 5 | export default function DashBoard() { 6 | return ( 7 |
8 | 9 |
10 | 11 | 12 |
13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /Dashboard/src/types/Auth.d.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export type AuthProps = { 4 | as?: T; 5 | children?: React.ReactNode; 6 | }; 7 | 8 | export type FieldProps = { 9 | type: "email" | "password"; 10 | label: string; 11 | placeholder: string; 12 | }; -------------------------------------------------------------------------------- /Dashboard/src/types/Button.d.ts: -------------------------------------------------------------------------------- 1 | export type ButtonProps = { 2 | text:string, 3 | className?:string 4 | } -------------------------------------------------------------------------------- /Dashboard/src/types/CustomLegends.d.ts: -------------------------------------------------------------------------------- 1 | export default interface CustomLegendsProps{ 2 | color:string, 3 | title:string, 4 | lableClassName?:string, 5 | pointClassName?:string, 6 | } -------------------------------------------------------------------------------- /Dashboard/src/types/DataCards.d.ts: -------------------------------------------------------------------------------- 1 | import { IconBaseProps } from "react-icons"; 2 | import React from "react"; 3 | export type DataCardsProps = { 4 | heading: string; 5 | value: string; 6 | color: "#DDEFE0" | "#F4ECDD" | "#EFDADA" | "#DEE0EF"; 7 | Icon: (props: IconBaseProps) => React.ReactNode; 8 | }; 9 | -------------------------------------------------------------------------------- /Dashboard/src/types/MonthlyChart.d.ts: -------------------------------------------------------------------------------- 1 | export default interface MonthlyChartProps { 2 | chartData:{ 3 | User: { 4 | [key: string]: number; 5 | }; 6 | Guest: { 7 | [key: string]: number; 8 | }; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Dashboard/src/types/ProductChartProps.d.ts: -------------------------------------------------------------------------------- 1 | export default interface ProductChartProps { 2 | chartData:{ 3 | [key: string]: number; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Dashboard/src/types/Schedule.d.ts: -------------------------------------------------------------------------------- 1 | export default interface ScheduleProps { 2 | todaysSchedule: ScheduleData[]; 3 | } 4 | 5 | export interface ScheduleData { 6 | time: string; 7 | location: string; 8 | meetingTitle: string; 9 | } -------------------------------------------------------------------------------- /Dashboard/src/types/SideNavLinks.d.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { IconBaseProps } from "react-icons"; 3 | export type SideNavLinks = { 4 | link: string; 5 | label: string; 6 | Icon: (props: IconBaseProps) => React.ReactNode; 7 | }; 8 | -------------------------------------------------------------------------------- /Dashboard/src/types/Text.d.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export type TextAllowed = "h1"|"h2"|"h3"|"h4"|"h5"|"h6"|"p"|"span" 4 | 5 | export type TextProps = { 6 | as?: T; 7 | children?: React.ReactNode; 8 | }; -------------------------------------------------------------------------------- /Dashboard/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /Dashboard/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | const defaultTheme = require('tailwindcss/defaultTheme'); 3 | export default { 4 | content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], 5 | theme: { 6 | extend: { 7 | fontFamily: { 8 | monteserat: ["Montserrat", ...defaultTheme.fontFamily.sans], 9 | }, 10 | }, 11 | }, 12 | plugins: [], 13 | }; 14 | -------------------------------------------------------------------------------- /Dashboard/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /Dashboard/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /Dashboard/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /Drizzle-CRUD-API/Readme.md: -------------------------------------------------------------------------------- 1 | ### Rest API 2 | - Tech -> Typescript , Node , Express , Drizzle 3 | - Learnings -> CRUD operation with relationships 4 | 5 | ### Local Setup 6 | - Install node ts for running node with ts files easily 7 | 8 | ### Feature not used 9 | - Not included migrations of drizzle. And `db push` getting used -------------------------------------------------------------------------------- /Drizzle-CRUD-API/drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "drizzle-kit"; 2 | import { DB_URL } from "./src/db/setup"; 3 | 4 | export default { 5 | schema: "./src/db/schema.ts", 6 | out: "./src/db/migrations", 7 | dbCredentials: { 8 | connectionString: DB_URL, 9 | }, 10 | driver: "mysql2", 11 | } satisfies Config; -------------------------------------------------------------------------------- /Drizzle-CRUD-API/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "drizzle-crud-api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "nodemon src/index.ts", 8 | "build": "tsc", 9 | "db:generate": "drizzle-kit generate:mysql", 10 | "db:push": "drizzle-kit push:mysql" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "dependencies": { 16 | "body-parser": "^1.20.2", 17 | "cors": "^2.8.5", 18 | "dotenv": "^16.3.1", 19 | "drizzle-orm": "^0.28.6", 20 | "express": "^4.18.2", 21 | "mysql2": "^3.6.1" 22 | }, 23 | "devDependencies": { 24 | "@types/body-parser": "^1.19.2", 25 | "@types/cors": "^2.8.14", 26 | "@types/express": "^4.17.17", 27 | "@types/node": "^20.6.0", 28 | "drizzle-kit": "^0.19.13", 29 | "nodemon": "^3.0.1", 30 | "ts-node": "^10.9.1", 31 | "typescript": "^5.2.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/controllers/createBlog.ts: -------------------------------------------------------------------------------- 1 | import { db } from "../db/setup"; 2 | import { blogs, users } from "../db/schema"; 3 | import e, { Request, Response } from "express"; 4 | import { eq } from "drizzle-orm"; 5 | 6 | export const createBlog = async (req: Request, res: Response) => { 7 | const { content, userId }: { content: string; userId: number } = req.body; 8 | if (!content) { 9 | return res 10 | .status(400) 11 | .json({ success: false, data: null, message: "Content is required" }); 12 | } 13 | if (!userId) { 14 | return res 15 | .status(400) 16 | .json({ success: false, data: null, message: "userId is required" }); 17 | } 18 | 19 | try { 20 | await db.insert(blogs).values({ content: content, userId: userId }); 21 | console.log(await db.query.blogs.findMany({ 22 | with: { 23 | author: true, 24 | }, 25 | })) 26 | return res.status(201).json({ 27 | success: true, 28 | data: { content }, 29 | message: "Added Successfully", 30 | }); 31 | } catch (error) { 32 | return res 33 | .status(500) 34 | .json({ success: false, data: null, message: "Unable to add" }); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/controllers/createUser.ts: -------------------------------------------------------------------------------- 1 | import { db } from "../db/setup"; 2 | import { users } from "../db/schema"; 3 | import { Request, Response } from "express"; 4 | export const createUser = async (req: Request, res: Response) => { 5 | const { name, email }: { name: string; email: string } = req.body; 6 | if (!name) { 7 | return res 8 | .status(400) 9 | .json({ success: false, data: null, message: "Name is required" }); 10 | } 11 | if (!email) { 12 | return res 13 | .status(400) 14 | .json({ success: false, data: null, message: "Email is required" }); 15 | } 16 | 17 | try { 18 | await db.insert(users).values({ name: name, email: email }); 19 | 20 | return res.status(201).json({ 21 | success: true, 22 | data: { name, email }, 23 | message: "Added Successfully", 24 | }); 25 | } catch (error) { 26 | return res 27 | .status(500) 28 | .json({ success: false, data: null, message: "Unable to add" }); 29 | } 30 | }; -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/controllers/deleteUser.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import { eq } from "drizzle-orm"; 3 | import { db } from "../db/setup"; 4 | import { users } from "../db/schema"; 5 | 6 | const deleteUser = async (req: Request, res: Response) => { 7 | const { userId } = req.params; 8 | 9 | try { 10 | await db.delete(users).where(eq(users.id, Number(userId))); 11 | return res 12 | .status(200) 13 | .json({ success: true, message: "Delete Successfully" }); 14 | } catch (error) { 15 | return res.status(500).json({ success: true, message: "Cannot Delete" }); 16 | } 17 | }; 18 | 19 | export default deleteUser; -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/controllers/getUsers.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import { db } from "../db/setup"; 3 | import * as schema from "../db/schema"; 4 | 5 | const getUsers = async (req: Request, res: Response) => { 6 | try { 7 | // const allUsersWithoutEmail = await db 8 | // .select({ userId: users.id, userName: users.name }) 9 | // .from(users); 10 | const allUsersWithoutEmail = await db.query.users.findMany({ 11 | with: { 12 | articles: true, 13 | }, 14 | columns:{ 15 | name:true 16 | } 17 | }); 18 | return res.status(200).json({ success: true, data: allUsersWithoutEmail }); 19 | } catch (error) { 20 | return res 21 | .status(500) 22 | .json({ success: false, data: null, message: "Unable to get users" }); 23 | } 24 | }; 25 | 26 | export default getUsers; 27 | -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/controllers/updateUser.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import { eq } from "drizzle-orm"; 3 | import { users } from "../db/schema"; 4 | import { db } from "../db/setup"; 5 | 6 | const updateUser = async (req: Request, res: Response) => { 7 | const { name, email }: { name: string; email: string } = req.body; 8 | const { userId } = req.params; 9 | 10 | try { 11 | if (!userId) { 12 | return res 13 | .status(400) 14 | .json({ success: false, message: "Please provide user_id to update" }); 15 | } 16 | if (!name && !email) { 17 | return res 18 | .status(400) 19 | .json({ success: false, message: "Please provide field to update" }); 20 | } 21 | const updateData: { name?: string; email?: string } = {}; 22 | 23 | if (name) { 24 | updateData.name = name; 25 | } 26 | if (email) { 27 | updateData.email = email; 28 | } 29 | await db 30 | .update(users) 31 | .set(updateData) 32 | .where(eq(users.id, Number(userId))); 33 | return res 34 | .status(200) 35 | .json({ success: true, message: "Updated Successfully" }); 36 | } catch (error) { 37 | return res.status(500).json({ success: true, message: "Cannot Update" }); 38 | } 39 | }; 40 | 41 | export default updateUser; -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/db/schema.ts: -------------------------------------------------------------------------------- 1 | import { relations } from "drizzle-orm"; 2 | import { mysqlTable, serial, varchar, text, int } from "drizzle-orm/mysql-core"; 3 | 4 | export const users = mysqlTable("users", { 5 | id: serial("id").primaryKey(), 6 | name: varchar("name", { length: 256 }).notNull(), 7 | email: varchar("email", { length: 256 }).notNull().unique(), 8 | }); 9 | 10 | export const blogs = mysqlTable("blogs", { 11 | id: serial("id").primaryKey(), 12 | content: text("content"), 13 | userId: int("user_id"), 14 | }); 15 | 16 | export const userRelations = relations(users, ({ many }) => ({ 17 | articles: many(blogs), 18 | })); 19 | 20 | export const postRelations = relations(blogs, ({ one }) => ({ 21 | author: one(users, { 22 | fields: [blogs.userId], 23 | references: [users.id], 24 | }), 25 | })); 26 | -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/db/setup.ts: -------------------------------------------------------------------------------- 1 | import {drizzle} from "drizzle-orm/mysql2" 2 | import mysql from "mysql2" 3 | import * as schema from "./schema" 4 | 5 | export const DB_URL = "mysql://root:91hQaH7Z3QSwH0rjDD5B@containers-us-west-198.railway.app:6028/railway" 6 | 7 | const connection = mysql.createConnection(DB_URL) 8 | 9 | export const db = drizzle(connection,{schema,mode:"default"}) -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/index.ts: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import userRoutes from "./routes/users" 3 | import blogRoutes from "./routes/blogs"; 4 | import bodyParser from "body-parser"; 5 | 6 | const app = express() 7 | 8 | app.use(express.json()); 9 | app.use(bodyParser.urlencoded({ extended: false })); 10 | app.use(bodyParser.json()); 11 | 12 | const PORT = process.env.PORT || 5000; 13 | 14 | app.use("/users", userRoutes); 15 | app.use("/blogs",blogRoutes ); 16 | 17 | app.listen(PORT, () => { 18 | console.log(`App running on PORT ${PORT}`); 19 | }); -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/routes/blogs.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { createBlog } from "../controllers/createBlog"; 3 | 4 | const router = Router() 5 | router.post("/",createBlog) 6 | export default router -------------------------------------------------------------------------------- /Drizzle-CRUD-API/src/routes/users.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { createUser } from "../controllers/createUser"; 3 | import getUsers from "../controllers/getUsers"; 4 | import updateUser from "../controllers/updateUser"; 5 | import deleteUser from "../controllers/deleteUser"; 6 | 7 | const router = Router() 8 | router.post("/",createUser) 9 | router.get("/",getUsers) 10 | router.patch("/:userId",updateUser) 11 | router.delete("/:userId",deleteUser) 12 | export default router -------------------------------------------------------------------------------- /MDNotesApp/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:@typescript-eslint/recommended', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | ignorePatterns: ['dist', '.eslintrc.cjs'], 10 | parser: '@typescript-eslint/parser', 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': [ 14 | 'warn', 15 | { allowConstantExport: true }, 16 | ], 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /MDNotesApp/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /MDNotesApp/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | parserOptions: { 18 | ecmaVersion: 'latest', 19 | sourceType: 'module', 20 | project: ['./tsconfig.json', './tsconfig.node.json'], 21 | tsconfigRootDir: __dirname, 22 | }, 23 | ``` 24 | 25 | - Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` 26 | - Optionally add `plugin:@typescript-eslint/stylistic-type-checked` 27 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list 28 | -------------------------------------------------------------------------------- /MDNotesApp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /MDNotesApp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mdnotesapp", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "bootstrap": "^5.3.1", 14 | "react": "^18.2.0", 15 | "react-bootstrap": "^2.8.0", 16 | "react-dom": "^18.2.0", 17 | "react-router-dom": "^6.14.2", 18 | "react-select": "^5.7.4" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.2.15", 22 | "@types/react-dom": "^18.2.7", 23 | "@typescript-eslint/eslint-plugin": "^6.0.0", 24 | "@typescript-eslint/parser": "^6.0.0", 25 | "@vitejs/plugin-react": "^4.0.3", 26 | "eslint": "^8.45.0", 27 | "eslint-plugin-react-hooks": "^4.6.0", 28 | "eslint-plugin-react-refresh": "^0.4.3", 29 | "typescript": "^5.0.2", 30 | "vite": "^4.4.5" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MDNotesApp/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MDNotesApp/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /MDNotesApp/src/App.tsx: -------------------------------------------------------------------------------- 1 | import "bootstrap/dist/css/bootstrap.min.css"; 2 | import { Container } from "react-bootstrap"; 3 | import { Routes, Route, Navigate } from "react-router-dom"; 4 | import { NewNote } from "./components/NewNote"; 5 | import useLocalStorage from "./hooks/useLocalStorage"; 6 | import { RawNote, RawNoteData } from "./types/RawNote.type"; 7 | import { NoteData, Tag } from "./types/NoteData.type"; 8 | import { useMemo } from "react"; 9 | 10 | function App() { 11 | const [notes, setNotes] = useLocalStorage("NOTES", []); 12 | const [tags, setTags] = useLocalStorage("TAGS", []); 13 | 14 | const notesWithTags = useMemo(() => { 15 | return notes.map((note) => { 16 | return { 17 | ...note, 18 | tags: tags.filter((tag) => note.tagIds.includes(tag.id)), 19 | }; 20 | }); 21 | }, [notes, tags]); 22 | 23 | function onCreateNote(data: NoteData) { 24 | setNotes((prevNotes) => { 25 | return [ 26 | ...prevNotes, 27 | { ...data, id: crypto.randomUUID(), tagIds: tags.map((tag) => tag.id) }, 28 | ]; 29 | }); 30 | } 31 | return ( 32 | 33 | 34 | Home} /> 35 | } /> 36 | {/* 37 | Show} /> 38 | edit} /> 39 | */} 40 | } /> 41 | 42 | 43 | ); 44 | } 45 | 46 | export default App; 47 | -------------------------------------------------------------------------------- /MDNotesApp/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MDNotesApp/src/components/NewNote.tsx: -------------------------------------------------------------------------------- 1 | import NoteForm from "./NoteForm"; 2 | import { NoteData } from "../types/NoteData.type"; 3 | 4 | type NewNoteProps = { 5 | onSubmit:(data:NoteData)=>void 6 | } 7 | export function NewNote({onSubmit}:NewNoteProps) { 8 | return ( 9 | <> 10 |

New Note

11 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /MDNotesApp/src/components/NoteForm.tsx: -------------------------------------------------------------------------------- 1 | import { FormEvent, useRef, useState } from "react"; 2 | import { Col, Form, Row, Stack, Button } from "react-bootstrap"; 3 | import { Link } from "react-router-dom"; 4 | import CreatableSelect from "react-select/creatable"; 5 | import { NoteData, Tag } from "../types/NoteData.type"; 6 | 7 | type NoteFormProps = { 8 | onSubmit: (data: NoteData) => void; 9 | }; 10 | 11 | export default function NoteForm({ onSubmit }: NoteFormProps) { 12 | const titleRef = useRef(null); 13 | const bodyRef = useRef(null); 14 | 15 | const [selectedTags, setSelectedTags] = useState([]); 16 | 17 | function handleSubmit(e: FormEvent) { 18 | e.preventDefault(); 19 | onSubmit({ 20 | title: titleRef.current!.value, 21 | markdown: bodyRef.current!.value, 22 | tags: [], 23 | }); 24 | } 25 | return ( 26 | 27 | 28 | 29 | 30 | 31 | Title 32 | 33 | 34 | 35 | 36 | 37 | 38 | Tags 39 | { 42 | return { label, value: id }; 43 | })} 44 | onChange={(tags) => { 45 | const allTags = tags.map(({ label, value }) => { 46 | return { label, id: value }; 47 | }); 48 | setSelectedTags(allTags); 49 | }} 50 | onCreateOption={} 51 | /> 52 | 53 | 54 | 55 | 56 | 57 | Body 58 | 59 | 60 | 61 | 62 | 63 | 66 | 67 | 68 | 69 | 70 | ); 71 | } 72 | -------------------------------------------------------------------------------- /MDNotesApp/src/hooks/useLocalStorage.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | // the initial value is either of Type T or a function returning a type T 4 | export default function useLocalStorage( 5 | key: string, 6 | initial: T | (() => T) 7 | ) { 8 | const [value, setValue] = useState(() => { 9 | const jsonVal = localStorage.getItem(key); 10 | if (jsonVal === null) { 11 | if (typeof initial === "function") { 12 | return (initial as () => T)(); 13 | } else return initial; 14 | } else { 15 | return JSON.parse(jsonVal); 16 | } 17 | }); 18 | 19 | useEffect(() => { 20 | localStorage.setItem(key, JSON.stringify(value)); 21 | }, [key, value]); 22 | 23 | return [value, setValue] as [T, typeof setValue]; 24 | } 25 | -------------------------------------------------------------------------------- /MDNotesApp/src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnabChatterjee20k/TypeScript-Projects/1a821e5391a918115bf780455803094c7d9da5f3/MDNotesApp/src/index.css -------------------------------------------------------------------------------- /MDNotesApp/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import './index.css' 5 | import { BrowserRouter } from 'react-router-dom'; 6 | 7 | ReactDOM.createRoot(document.getElementById('root')!).render( 8 | 9 | 10 | 11 | 12 | , 13 | ) 14 | -------------------------------------------------------------------------------- /MDNotesApp/src/types/Note.type.ts: -------------------------------------------------------------------------------- 1 | import { NoteData } from "./NoteData.type"; 2 | 3 | export type Note = { 4 | id: string; 5 | } & NoteData; -------------------------------------------------------------------------------- /MDNotesApp/src/types/NoteData.type.ts: -------------------------------------------------------------------------------- 1 | export type NoteData = { 2 | title: string; 3 | markdown: string; 4 | tags: Tag[]; 5 | }; 6 | 7 | export type Tag = { 8 | id: string; 9 | label: string; 10 | }; 11 | -------------------------------------------------------------------------------- /MDNotesApp/src/types/RawNote.type.ts: -------------------------------------------------------------------------------- 1 | export type RawNote = { 2 | id: string; 3 | } & RawNoteData; 4 | 5 | export type RawNoteData = { 6 | title: string; 7 | markdown: string; 8 | tagIds: string[]; 9 | }; 10 | -------------------------------------------------------------------------------- /MDNotesApp/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /MDNotesApp/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /MDNotesApp/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /MDNotesApp/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /MUI-Select/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /MUI-Select/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 |
11 | 15 | 19 |
20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /MUI-Select/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mui-select", 3 | "version": "0.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "mui-select", 9 | "version": "0.0.0", 10 | "devDependencies": { 11 | "typescript": "^5.0.2", 12 | "vite": "^4.4.5" 13 | } 14 | }, 15 | "node_modules/@esbuild/android-arm": { 16 | "version": "0.18.16", 17 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.16.tgz", 18 | "integrity": "sha512-gCHjjQmA8L0soklKbLKA6pgsLk1byULuHe94lkZDzcO3/Ta+bbeewJioEn1Fr7kgy9NWNFy/C+MrBwC6I/WCug==", 19 | "cpu": [ 20 | "arm" 21 | ], 22 | "dev": true, 23 | "optional": true, 24 | "os": [ 25 | "android" 26 | ], 27 | "engines": { 28 | "node": ">=12" 29 | } 30 | }, 31 | "node_modules/@esbuild/android-arm64": { 32 | "version": "0.18.16", 33 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.16.tgz", 34 | "integrity": "sha512-wsCqSPqLz+6Ov+OM4EthU43DyYVVyfn15S4j1bJzylDpc1r1jZFFfJQNfDuT8SlgwuqpmpJXK4uPlHGw6ve7eA==", 35 | "cpu": [ 36 | "arm64" 37 | ], 38 | "dev": true, 39 | "optional": true, 40 | "os": [ 41 | "android" 42 | ], 43 | "engines": { 44 | "node": ">=12" 45 | } 46 | }, 47 | "node_modules/@esbuild/android-x64": { 48 | "version": "0.18.16", 49 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.16.tgz", 50 | "integrity": "sha512-ldsTXolyA3eTQ1//4DS+E15xl0H/3DTRJaRL0/0PgkqDsI0fV/FlOtD+h0u/AUJr+eOTlZv4aC9gvfppo3C4sw==", 51 | "cpu": [ 52 | "x64" 53 | ], 54 | "dev": true, 55 | "optional": true, 56 | "os": [ 57 | "android" 58 | ], 59 | "engines": { 60 | "node": ">=12" 61 | } 62 | }, 63 | "node_modules/@esbuild/darwin-arm64": { 64 | "version": "0.18.16", 65 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.16.tgz", 66 | "integrity": "sha512-aBxruWCII+OtluORR/KvisEw0ALuw/qDQWvkoosA+c/ngC/Kwk0lLaZ+B++LLS481/VdydB2u6tYpWxUfnLAIw==", 67 | "cpu": [ 68 | "arm64" 69 | ], 70 | "dev": true, 71 | "optional": true, 72 | "os": [ 73 | "darwin" 74 | ], 75 | "engines": { 76 | "node": ">=12" 77 | } 78 | }, 79 | "node_modules/@esbuild/darwin-x64": { 80 | "version": "0.18.16", 81 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.16.tgz", 82 | "integrity": "sha512-6w4Dbue280+rp3LnkgmriS1icOUZDyPuZo/9VsuMUTns7SYEiOaJ7Ca1cbhu9KVObAWfmdjUl4gwy9TIgiO5eA==", 83 | "cpu": [ 84 | "x64" 85 | ], 86 | "dev": true, 87 | "optional": true, 88 | "os": [ 89 | "darwin" 90 | ], 91 | "engines": { 92 | "node": ">=12" 93 | } 94 | }, 95 | "node_modules/@esbuild/freebsd-arm64": { 96 | "version": "0.18.16", 97 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.16.tgz", 98 | "integrity": "sha512-x35fCebhe9s979DGKbVAwXUOcTmCIE32AIqB9CB1GralMIvxdnMLAw5CnID17ipEw9/3MvDsusj/cspYt2ZLNQ==", 99 | "cpu": [ 100 | "arm64" 101 | ], 102 | "dev": true, 103 | "optional": true, 104 | "os": [ 105 | "freebsd" 106 | ], 107 | "engines": { 108 | "node": ">=12" 109 | } 110 | }, 111 | "node_modules/@esbuild/freebsd-x64": { 112 | "version": "0.18.16", 113 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.16.tgz", 114 | "integrity": "sha512-YM98f+PeNXF3GbxIJlUsj+McUWG1irguBHkszCIwfr3BXtXZsXo0vqybjUDFfu9a8Wr7uUD/YSmHib+EeGAFlg==", 115 | "cpu": [ 116 | "x64" 117 | ], 118 | "dev": true, 119 | "optional": true, 120 | "os": [ 121 | "freebsd" 122 | ], 123 | "engines": { 124 | "node": ">=12" 125 | } 126 | }, 127 | "node_modules/@esbuild/linux-arm": { 128 | "version": "0.18.16", 129 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.16.tgz", 130 | "integrity": "sha512-b5ABb+5Ha2C9JkeZXV+b+OruR1tJ33ePmv9ZwMeETSEKlmu/WJ45XTTG+l6a2KDsQtJJ66qo/hbSGBtk0XVLHw==", 131 | "cpu": [ 132 | "arm" 133 | ], 134 | "dev": true, 135 | "optional": true, 136 | "os": [ 137 | "linux" 138 | ], 139 | "engines": { 140 | "node": ">=12" 141 | } 142 | }, 143 | "node_modules/@esbuild/linux-arm64": { 144 | "version": "0.18.16", 145 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.16.tgz", 146 | "integrity": "sha512-XIqhNUxJiuy+zsR77+H5Z2f7s4YRlriSJKtvx99nJuG5ATuJPjmZ9n0ANgnGlPCpXGSReFpgcJ7O3SMtzIFeiQ==", 147 | "cpu": [ 148 | "arm64" 149 | ], 150 | "dev": true, 151 | "optional": true, 152 | "os": [ 153 | "linux" 154 | ], 155 | "engines": { 156 | "node": ">=12" 157 | } 158 | }, 159 | "node_modules/@esbuild/linux-ia32": { 160 | "version": "0.18.16", 161 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.16.tgz", 162 | "integrity": "sha512-no+pfEpwnRvIyH+txbBAWtjxPU9grslmTBfsmDndj7bnBmr55rOo/PfQmRfz7Qg9isswt1FP5hBbWb23fRWnow==", 163 | "cpu": [ 164 | "ia32" 165 | ], 166 | "dev": true, 167 | "optional": true, 168 | "os": [ 169 | "linux" 170 | ], 171 | "engines": { 172 | "node": ">=12" 173 | } 174 | }, 175 | "node_modules/@esbuild/linux-loong64": { 176 | "version": "0.18.16", 177 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.16.tgz", 178 | "integrity": "sha512-Zbnczs9ZXjmo0oZSS0zbNlJbcwKXa/fcNhYQjahDs4Xg18UumpXG/lwM2lcSvHS3mTrRyCYZvJbmzYc4laRI1g==", 179 | "cpu": [ 180 | "loong64" 181 | ], 182 | "dev": true, 183 | "optional": true, 184 | "os": [ 185 | "linux" 186 | ], 187 | "engines": { 188 | "node": ">=12" 189 | } 190 | }, 191 | "node_modules/@esbuild/linux-mips64el": { 192 | "version": "0.18.16", 193 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.16.tgz", 194 | "integrity": "sha512-YMF7hih1HVR/hQVa/ot4UVffc5ZlrzEb3k2ip0nZr1w6fnYypll9td2qcoMLvd3o8j3y6EbJM3MyIcXIVzXvQQ==", 195 | "cpu": [ 196 | "mips64el" 197 | ], 198 | "dev": true, 199 | "optional": true, 200 | "os": [ 201 | "linux" 202 | ], 203 | "engines": { 204 | "node": ">=12" 205 | } 206 | }, 207 | "node_modules/@esbuild/linux-ppc64": { 208 | "version": "0.18.16", 209 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.16.tgz", 210 | "integrity": "sha512-Wkz++LZ29lDwUyTSEnzDaaP5OveOgTU69q9IyIw9WqLRxM4BjTBjz9un4G6TOvehWpf/J3gYVFN96TjGHrbcNQ==", 211 | "cpu": [ 212 | "ppc64" 213 | ], 214 | "dev": true, 215 | "optional": true, 216 | "os": [ 217 | "linux" 218 | ], 219 | "engines": { 220 | "node": ">=12" 221 | } 222 | }, 223 | "node_modules/@esbuild/linux-riscv64": { 224 | "version": "0.18.16", 225 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.16.tgz", 226 | "integrity": "sha512-LFMKZ30tk78/mUv1ygvIP+568bwf4oN6reG/uczXnz6SvFn4e2QUFpUpZY9iSJT6Qpgstrhef/nMykIXZtZWGQ==", 227 | "cpu": [ 228 | "riscv64" 229 | ], 230 | "dev": true, 231 | "optional": true, 232 | "os": [ 233 | "linux" 234 | ], 235 | "engines": { 236 | "node": ">=12" 237 | } 238 | }, 239 | "node_modules/@esbuild/linux-s390x": { 240 | "version": "0.18.16", 241 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.16.tgz", 242 | "integrity": "sha512-3ZC0BgyYHYKfZo3AV2/66TD/I9tlSBaW7eWTEIkrQQKfJIifKMMttXl9FrAg+UT0SGYsCRLI35Gwdmm96vlOjg==", 243 | "cpu": [ 244 | "s390x" 245 | ], 246 | "dev": true, 247 | "optional": true, 248 | "os": [ 249 | "linux" 250 | ], 251 | "engines": { 252 | "node": ">=12" 253 | } 254 | }, 255 | "node_modules/@esbuild/linux-x64": { 256 | "version": "0.18.16", 257 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.16.tgz", 258 | "integrity": "sha512-xu86B3647DihHJHv/wx3NCz2Dg1gjQ8bbf9cVYZzWKY+gsvxYmn/lnVlqDRazObc3UMwoHpUhNYaZset4X8IPA==", 259 | "cpu": [ 260 | "x64" 261 | ], 262 | "dev": true, 263 | "optional": true, 264 | "os": [ 265 | "linux" 266 | ], 267 | "engines": { 268 | "node": ">=12" 269 | } 270 | }, 271 | "node_modules/@esbuild/netbsd-x64": { 272 | "version": "0.18.16", 273 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.16.tgz", 274 | "integrity": "sha512-uVAgpimx9Ffw3xowtg/7qQPwHFx94yCje+DoBx+LNm2ePDpQXHrzE+Sb0Si2VBObYz+LcRps15cq+95YM7gkUw==", 275 | "cpu": [ 276 | "x64" 277 | ], 278 | "dev": true, 279 | "optional": true, 280 | "os": [ 281 | "netbsd" 282 | ], 283 | "engines": { 284 | "node": ">=12" 285 | } 286 | }, 287 | "node_modules/@esbuild/openbsd-x64": { 288 | "version": "0.18.16", 289 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.16.tgz", 290 | "integrity": "sha512-6OjCQM9wf7z8/MBi6BOWaTL2AS/SZudsZtBziXMtNI8r/U41AxS9x7jn0ATOwVy08OotwkPqGRMkpPR2wcTJXA==", 291 | "cpu": [ 292 | "x64" 293 | ], 294 | "dev": true, 295 | "optional": true, 296 | "os": [ 297 | "openbsd" 298 | ], 299 | "engines": { 300 | "node": ">=12" 301 | } 302 | }, 303 | "node_modules/@esbuild/sunos-x64": { 304 | "version": "0.18.16", 305 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.16.tgz", 306 | "integrity": "sha512-ZoNkruFYJp9d1LbUYCh8awgQDvB9uOMZqlQ+gGEZR7v6C+N6u7vPr86c+Chih8niBR81Q/bHOSKGBK3brJyvkQ==", 307 | "cpu": [ 308 | "x64" 309 | ], 310 | "dev": true, 311 | "optional": true, 312 | "os": [ 313 | "sunos" 314 | ], 315 | "engines": { 316 | "node": ">=12" 317 | } 318 | }, 319 | "node_modules/@esbuild/win32-arm64": { 320 | "version": "0.18.16", 321 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.16.tgz", 322 | "integrity": "sha512-+j4anzQ9hrs+iqO+/wa8UE6TVkKua1pXUb0XWFOx0FiAj6R9INJ+WE//1/Xo6FG1vB5EpH3ko+XcgwiDXTxcdw==", 323 | "cpu": [ 324 | "arm64" 325 | ], 326 | "dev": true, 327 | "optional": true, 328 | "os": [ 329 | "win32" 330 | ], 331 | "engines": { 332 | "node": ">=12" 333 | } 334 | }, 335 | "node_modules/@esbuild/win32-ia32": { 336 | "version": "0.18.16", 337 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.16.tgz", 338 | "integrity": "sha512-5PFPmq3sSKTp9cT9dzvI67WNfRZGvEVctcZa1KGjDDu4n3H8k59Inbk0du1fz0KrAbKKNpJbdFXQMDUz7BG4rQ==", 339 | "cpu": [ 340 | "ia32" 341 | ], 342 | "dev": true, 343 | "optional": true, 344 | "os": [ 345 | "win32" 346 | ], 347 | "engines": { 348 | "node": ">=12" 349 | } 350 | }, 351 | "node_modules/@esbuild/win32-x64": { 352 | "version": "0.18.16", 353 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.16.tgz", 354 | "integrity": "sha512-sCIVrrtcWN5Ua7jYXNG1xD199IalrbfV2+0k/2Zf2OyV2FtnQnMgdzgpRAbi4AWlKJj1jkX+M+fEGPQj6BQB4w==", 355 | "cpu": [ 356 | "x64" 357 | ], 358 | "dev": true, 359 | "optional": true, 360 | "os": [ 361 | "win32" 362 | ], 363 | "engines": { 364 | "node": ">=12" 365 | } 366 | }, 367 | "node_modules/esbuild": { 368 | "version": "0.18.16", 369 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.16.tgz", 370 | "integrity": "sha512-1xLsOXrDqwdHxyXb/x/SOyg59jpf/SH7YMvU5RNSU7z3TInaASNJWNFJ6iRvLvLETZMasF3d1DdZLg7sgRimRQ==", 371 | "dev": true, 372 | "hasInstallScript": true, 373 | "bin": { 374 | "esbuild": "bin/esbuild" 375 | }, 376 | "engines": { 377 | "node": ">=12" 378 | }, 379 | "optionalDependencies": { 380 | "@esbuild/android-arm": "0.18.16", 381 | "@esbuild/android-arm64": "0.18.16", 382 | "@esbuild/android-x64": "0.18.16", 383 | "@esbuild/darwin-arm64": "0.18.16", 384 | "@esbuild/darwin-x64": "0.18.16", 385 | "@esbuild/freebsd-arm64": "0.18.16", 386 | "@esbuild/freebsd-x64": "0.18.16", 387 | "@esbuild/linux-arm": "0.18.16", 388 | "@esbuild/linux-arm64": "0.18.16", 389 | "@esbuild/linux-ia32": "0.18.16", 390 | "@esbuild/linux-loong64": "0.18.16", 391 | "@esbuild/linux-mips64el": "0.18.16", 392 | "@esbuild/linux-ppc64": "0.18.16", 393 | "@esbuild/linux-riscv64": "0.18.16", 394 | "@esbuild/linux-s390x": "0.18.16", 395 | "@esbuild/linux-x64": "0.18.16", 396 | "@esbuild/netbsd-x64": "0.18.16", 397 | "@esbuild/openbsd-x64": "0.18.16", 398 | "@esbuild/sunos-x64": "0.18.16", 399 | "@esbuild/win32-arm64": "0.18.16", 400 | "@esbuild/win32-ia32": "0.18.16", 401 | "@esbuild/win32-x64": "0.18.16" 402 | } 403 | }, 404 | "node_modules/fsevents": { 405 | "version": "2.3.2", 406 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 407 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 408 | "dev": true, 409 | "hasInstallScript": true, 410 | "optional": true, 411 | "os": [ 412 | "darwin" 413 | ], 414 | "engines": { 415 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 416 | } 417 | }, 418 | "node_modules/nanoid": { 419 | "version": "3.3.6", 420 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 421 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 422 | "dev": true, 423 | "funding": [ 424 | { 425 | "type": "github", 426 | "url": "https://github.com/sponsors/ai" 427 | } 428 | ], 429 | "bin": { 430 | "nanoid": "bin/nanoid.cjs" 431 | }, 432 | "engines": { 433 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 434 | } 435 | }, 436 | "node_modules/picocolors": { 437 | "version": "1.0.0", 438 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 439 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 440 | "dev": true 441 | }, 442 | "node_modules/postcss": { 443 | "version": "8.4.27", 444 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", 445 | "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", 446 | "dev": true, 447 | "funding": [ 448 | { 449 | "type": "opencollective", 450 | "url": "https://opencollective.com/postcss/" 451 | }, 452 | { 453 | "type": "tidelift", 454 | "url": "https://tidelift.com/funding/github/npm/postcss" 455 | }, 456 | { 457 | "type": "github", 458 | "url": "https://github.com/sponsors/ai" 459 | } 460 | ], 461 | "dependencies": { 462 | "nanoid": "^3.3.6", 463 | "picocolors": "^1.0.0", 464 | "source-map-js": "^1.0.2" 465 | }, 466 | "engines": { 467 | "node": "^10 || ^12 || >=14" 468 | } 469 | }, 470 | "node_modules/rollup": { 471 | "version": "3.26.3", 472 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz", 473 | "integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==", 474 | "dev": true, 475 | "bin": { 476 | "rollup": "dist/bin/rollup" 477 | }, 478 | "engines": { 479 | "node": ">=14.18.0", 480 | "npm": ">=8.0.0" 481 | }, 482 | "optionalDependencies": { 483 | "fsevents": "~2.3.2" 484 | } 485 | }, 486 | "node_modules/source-map-js": { 487 | "version": "1.0.2", 488 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 489 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 490 | "dev": true, 491 | "engines": { 492 | "node": ">=0.10.0" 493 | } 494 | }, 495 | "node_modules/typescript": { 496 | "version": "5.1.6", 497 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", 498 | "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", 499 | "dev": true, 500 | "bin": { 501 | "tsc": "bin/tsc", 502 | "tsserver": "bin/tsserver" 503 | }, 504 | "engines": { 505 | "node": ">=14.17" 506 | } 507 | }, 508 | "node_modules/vite": { 509 | "version": "4.4.7", 510 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.7.tgz", 511 | "integrity": "sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==", 512 | "dev": true, 513 | "dependencies": { 514 | "esbuild": "^0.18.10", 515 | "postcss": "^8.4.26", 516 | "rollup": "^3.25.2" 517 | }, 518 | "bin": { 519 | "vite": "bin/vite.js" 520 | }, 521 | "engines": { 522 | "node": "^14.18.0 || >=16.0.0" 523 | }, 524 | "funding": { 525 | "url": "https://github.com/vitejs/vite?sponsor=1" 526 | }, 527 | "optionalDependencies": { 528 | "fsevents": "~2.3.2" 529 | }, 530 | "peerDependencies": { 531 | "@types/node": ">= 14", 532 | "less": "*", 533 | "lightningcss": "^1.21.0", 534 | "sass": "*", 535 | "stylus": "*", 536 | "sugarss": "*", 537 | "terser": "^5.4.0" 538 | }, 539 | "peerDependenciesMeta": { 540 | "@types/node": { 541 | "optional": true 542 | }, 543 | "less": { 544 | "optional": true 545 | }, 546 | "lightningcss": { 547 | "optional": true 548 | }, 549 | "sass": { 550 | "optional": true 551 | }, 552 | "stylus": { 553 | "optional": true 554 | }, 555 | "sugarss": { 556 | "optional": true 557 | }, 558 | "terser": { 559 | "optional": true 560 | } 561 | } 562 | } 563 | }, 564 | "dependencies": { 565 | "@esbuild/android-arm": { 566 | "version": "0.18.16", 567 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.16.tgz", 568 | "integrity": "sha512-gCHjjQmA8L0soklKbLKA6pgsLk1byULuHe94lkZDzcO3/Ta+bbeewJioEn1Fr7kgy9NWNFy/C+MrBwC6I/WCug==", 569 | "dev": true, 570 | "optional": true 571 | }, 572 | "@esbuild/android-arm64": { 573 | "version": "0.18.16", 574 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.16.tgz", 575 | "integrity": "sha512-wsCqSPqLz+6Ov+OM4EthU43DyYVVyfn15S4j1bJzylDpc1r1jZFFfJQNfDuT8SlgwuqpmpJXK4uPlHGw6ve7eA==", 576 | "dev": true, 577 | "optional": true 578 | }, 579 | "@esbuild/android-x64": { 580 | "version": "0.18.16", 581 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.16.tgz", 582 | "integrity": "sha512-ldsTXolyA3eTQ1//4DS+E15xl0H/3DTRJaRL0/0PgkqDsI0fV/FlOtD+h0u/AUJr+eOTlZv4aC9gvfppo3C4sw==", 583 | "dev": true, 584 | "optional": true 585 | }, 586 | "@esbuild/darwin-arm64": { 587 | "version": "0.18.16", 588 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.16.tgz", 589 | "integrity": "sha512-aBxruWCII+OtluORR/KvisEw0ALuw/qDQWvkoosA+c/ngC/Kwk0lLaZ+B++LLS481/VdydB2u6tYpWxUfnLAIw==", 590 | "dev": true, 591 | "optional": true 592 | }, 593 | "@esbuild/darwin-x64": { 594 | "version": "0.18.16", 595 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.16.tgz", 596 | "integrity": "sha512-6w4Dbue280+rp3LnkgmriS1icOUZDyPuZo/9VsuMUTns7SYEiOaJ7Ca1cbhu9KVObAWfmdjUl4gwy9TIgiO5eA==", 597 | "dev": true, 598 | "optional": true 599 | }, 600 | "@esbuild/freebsd-arm64": { 601 | "version": "0.18.16", 602 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.16.tgz", 603 | "integrity": "sha512-x35fCebhe9s979DGKbVAwXUOcTmCIE32AIqB9CB1GralMIvxdnMLAw5CnID17ipEw9/3MvDsusj/cspYt2ZLNQ==", 604 | "dev": true, 605 | "optional": true 606 | }, 607 | "@esbuild/freebsd-x64": { 608 | "version": "0.18.16", 609 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.16.tgz", 610 | "integrity": "sha512-YM98f+PeNXF3GbxIJlUsj+McUWG1irguBHkszCIwfr3BXtXZsXo0vqybjUDFfu9a8Wr7uUD/YSmHib+EeGAFlg==", 611 | "dev": true, 612 | "optional": true 613 | }, 614 | "@esbuild/linux-arm": { 615 | "version": "0.18.16", 616 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.16.tgz", 617 | "integrity": "sha512-b5ABb+5Ha2C9JkeZXV+b+OruR1tJ33ePmv9ZwMeETSEKlmu/WJ45XTTG+l6a2KDsQtJJ66qo/hbSGBtk0XVLHw==", 618 | "dev": true, 619 | "optional": true 620 | }, 621 | "@esbuild/linux-arm64": { 622 | "version": "0.18.16", 623 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.16.tgz", 624 | "integrity": "sha512-XIqhNUxJiuy+zsR77+H5Z2f7s4YRlriSJKtvx99nJuG5ATuJPjmZ9n0ANgnGlPCpXGSReFpgcJ7O3SMtzIFeiQ==", 625 | "dev": true, 626 | "optional": true 627 | }, 628 | "@esbuild/linux-ia32": { 629 | "version": "0.18.16", 630 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.16.tgz", 631 | "integrity": "sha512-no+pfEpwnRvIyH+txbBAWtjxPU9grslmTBfsmDndj7bnBmr55rOo/PfQmRfz7Qg9isswt1FP5hBbWb23fRWnow==", 632 | "dev": true, 633 | "optional": true 634 | }, 635 | "@esbuild/linux-loong64": { 636 | "version": "0.18.16", 637 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.16.tgz", 638 | "integrity": "sha512-Zbnczs9ZXjmo0oZSS0zbNlJbcwKXa/fcNhYQjahDs4Xg18UumpXG/lwM2lcSvHS3mTrRyCYZvJbmzYc4laRI1g==", 639 | "dev": true, 640 | "optional": true 641 | }, 642 | "@esbuild/linux-mips64el": { 643 | "version": "0.18.16", 644 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.16.tgz", 645 | "integrity": "sha512-YMF7hih1HVR/hQVa/ot4UVffc5ZlrzEb3k2ip0nZr1w6fnYypll9td2qcoMLvd3o8j3y6EbJM3MyIcXIVzXvQQ==", 646 | "dev": true, 647 | "optional": true 648 | }, 649 | "@esbuild/linux-ppc64": { 650 | "version": "0.18.16", 651 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.16.tgz", 652 | "integrity": "sha512-Wkz++LZ29lDwUyTSEnzDaaP5OveOgTU69q9IyIw9WqLRxM4BjTBjz9un4G6TOvehWpf/J3gYVFN96TjGHrbcNQ==", 653 | "dev": true, 654 | "optional": true 655 | }, 656 | "@esbuild/linux-riscv64": { 657 | "version": "0.18.16", 658 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.16.tgz", 659 | "integrity": "sha512-LFMKZ30tk78/mUv1ygvIP+568bwf4oN6reG/uczXnz6SvFn4e2QUFpUpZY9iSJT6Qpgstrhef/nMykIXZtZWGQ==", 660 | "dev": true, 661 | "optional": true 662 | }, 663 | "@esbuild/linux-s390x": { 664 | "version": "0.18.16", 665 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.16.tgz", 666 | "integrity": "sha512-3ZC0BgyYHYKfZo3AV2/66TD/I9tlSBaW7eWTEIkrQQKfJIifKMMttXl9FrAg+UT0SGYsCRLI35Gwdmm96vlOjg==", 667 | "dev": true, 668 | "optional": true 669 | }, 670 | "@esbuild/linux-x64": { 671 | "version": "0.18.16", 672 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.16.tgz", 673 | "integrity": "sha512-xu86B3647DihHJHv/wx3NCz2Dg1gjQ8bbf9cVYZzWKY+gsvxYmn/lnVlqDRazObc3UMwoHpUhNYaZset4X8IPA==", 674 | "dev": true, 675 | "optional": true 676 | }, 677 | "@esbuild/netbsd-x64": { 678 | "version": "0.18.16", 679 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.16.tgz", 680 | "integrity": "sha512-uVAgpimx9Ffw3xowtg/7qQPwHFx94yCje+DoBx+LNm2ePDpQXHrzE+Sb0Si2VBObYz+LcRps15cq+95YM7gkUw==", 681 | "dev": true, 682 | "optional": true 683 | }, 684 | "@esbuild/openbsd-x64": { 685 | "version": "0.18.16", 686 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.16.tgz", 687 | "integrity": "sha512-6OjCQM9wf7z8/MBi6BOWaTL2AS/SZudsZtBziXMtNI8r/U41AxS9x7jn0ATOwVy08OotwkPqGRMkpPR2wcTJXA==", 688 | "dev": true, 689 | "optional": true 690 | }, 691 | "@esbuild/sunos-x64": { 692 | "version": "0.18.16", 693 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.16.tgz", 694 | "integrity": "sha512-ZoNkruFYJp9d1LbUYCh8awgQDvB9uOMZqlQ+gGEZR7v6C+N6u7vPr86c+Chih8niBR81Q/bHOSKGBK3brJyvkQ==", 695 | "dev": true, 696 | "optional": true 697 | }, 698 | "@esbuild/win32-arm64": { 699 | "version": "0.18.16", 700 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.16.tgz", 701 | "integrity": "sha512-+j4anzQ9hrs+iqO+/wa8UE6TVkKua1pXUb0XWFOx0FiAj6R9INJ+WE//1/Xo6FG1vB5EpH3ko+XcgwiDXTxcdw==", 702 | "dev": true, 703 | "optional": true 704 | }, 705 | "@esbuild/win32-ia32": { 706 | "version": "0.18.16", 707 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.16.tgz", 708 | "integrity": "sha512-5PFPmq3sSKTp9cT9dzvI67WNfRZGvEVctcZa1KGjDDu4n3H8k59Inbk0du1fz0KrAbKKNpJbdFXQMDUz7BG4rQ==", 709 | "dev": true, 710 | "optional": true 711 | }, 712 | "@esbuild/win32-x64": { 713 | "version": "0.18.16", 714 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.16.tgz", 715 | "integrity": "sha512-sCIVrrtcWN5Ua7jYXNG1xD199IalrbfV2+0k/2Zf2OyV2FtnQnMgdzgpRAbi4AWlKJj1jkX+M+fEGPQj6BQB4w==", 716 | "dev": true, 717 | "optional": true 718 | }, 719 | "esbuild": { 720 | "version": "0.18.16", 721 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.16.tgz", 722 | "integrity": "sha512-1xLsOXrDqwdHxyXb/x/SOyg59jpf/SH7YMvU5RNSU7z3TInaASNJWNFJ6iRvLvLETZMasF3d1DdZLg7sgRimRQ==", 723 | "dev": true, 724 | "requires": { 725 | "@esbuild/android-arm": "0.18.16", 726 | "@esbuild/android-arm64": "0.18.16", 727 | "@esbuild/android-x64": "0.18.16", 728 | "@esbuild/darwin-arm64": "0.18.16", 729 | "@esbuild/darwin-x64": "0.18.16", 730 | "@esbuild/freebsd-arm64": "0.18.16", 731 | "@esbuild/freebsd-x64": "0.18.16", 732 | "@esbuild/linux-arm": "0.18.16", 733 | "@esbuild/linux-arm64": "0.18.16", 734 | "@esbuild/linux-ia32": "0.18.16", 735 | "@esbuild/linux-loong64": "0.18.16", 736 | "@esbuild/linux-mips64el": "0.18.16", 737 | "@esbuild/linux-ppc64": "0.18.16", 738 | "@esbuild/linux-riscv64": "0.18.16", 739 | "@esbuild/linux-s390x": "0.18.16", 740 | "@esbuild/linux-x64": "0.18.16", 741 | "@esbuild/netbsd-x64": "0.18.16", 742 | "@esbuild/openbsd-x64": "0.18.16", 743 | "@esbuild/sunos-x64": "0.18.16", 744 | "@esbuild/win32-arm64": "0.18.16", 745 | "@esbuild/win32-ia32": "0.18.16", 746 | "@esbuild/win32-x64": "0.18.16" 747 | } 748 | }, 749 | "fsevents": { 750 | "version": "2.3.2", 751 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 752 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 753 | "dev": true, 754 | "optional": true 755 | }, 756 | "nanoid": { 757 | "version": "3.3.6", 758 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 759 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 760 | "dev": true 761 | }, 762 | "picocolors": { 763 | "version": "1.0.0", 764 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 765 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 766 | "dev": true 767 | }, 768 | "postcss": { 769 | "version": "8.4.27", 770 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", 771 | "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", 772 | "dev": true, 773 | "requires": { 774 | "nanoid": "^3.3.6", 775 | "picocolors": "^1.0.0", 776 | "source-map-js": "^1.0.2" 777 | } 778 | }, 779 | "rollup": { 780 | "version": "3.26.3", 781 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz", 782 | "integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==", 783 | "dev": true, 784 | "requires": { 785 | "fsevents": "~2.3.2" 786 | } 787 | }, 788 | "source-map-js": { 789 | "version": "1.0.2", 790 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 791 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 792 | "dev": true 793 | }, 794 | "typescript": { 795 | "version": "5.1.6", 796 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", 797 | "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", 798 | "dev": true 799 | }, 800 | "vite": { 801 | "version": "4.4.7", 802 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.7.tgz", 803 | "integrity": "sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==", 804 | "dev": true, 805 | "requires": { 806 | "esbuild": "^0.18.10", 807 | "fsevents": "~2.3.2", 808 | "postcss": "^8.4.26", 809 | "rollup": "^3.25.2" 810 | } 811 | } 812 | } 813 | } 814 | -------------------------------------------------------------------------------- /MUI-Select/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mui-select", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "typescript": "^5.0.2", 13 | "vite": "^4.4.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MUI-Select/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MUI-Select/src/VisibleOption.ts: -------------------------------------------------------------------------------- 1 | export class VisibleOption { 2 | private visible: boolean; 3 | constructor( 4 | public renderCallback: Function | null, 5 | public removeCallback: Function | null 6 | ) { 7 | this.visible = false; 8 | } 9 | public set setVisible(v: boolean) { 10 | this.visible = v; 11 | if (this.visible) { 12 | this.renderCallback && this.renderCallback(); 13 | } else { 14 | this.removeCallback && this.removeCallback(); 15 | } 16 | } 17 | 18 | public get getVisible():boolean{ 19 | return this.visible 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MUI-Select/src/counter.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArnabChatterjee20k/TypeScript-Projects/1a821e5391a918115bf780455803094c7d9da5f3/MUI-Select/src/counter.ts -------------------------------------------------------------------------------- /MUI-Select/src/main.ts: -------------------------------------------------------------------------------- 1 | import "./style.css"; 2 | import { VisibleOption } from "./VisibleOption"; 3 | const ID = "custom-select"; 4 | const app = document.getElementById("app") as HTMLDivElement; 5 | const select = document.createElement("div"); 6 | let multiple = true; 7 | select.id = ID; 8 | app.appendChild(select); 9 | 10 | const options: string[] = [ 11 | "Events", 12 | "Workshops", 13 | "Hackathons", 14 | "OSS Projects", 15 | "Building", 16 | ]; 17 | 18 | const selectStack: number[] = []; 19 | 20 | const visibleOption = new VisibleOption(renderOptions, removeOptions); 21 | 22 | const radioButtons = document.querySelectorAll( 23 | "input[name='selectionType']" 24 | ); 25 | radioButtons.forEach((radio: HTMLInputElement) => { 26 | radio.addEventListener("change", () => { 27 | multiple = radio.value === "multiple"; 28 | selectStack.length = 0; 29 | visibleOption.setVisible = false 30 | removeOptions(); 31 | renderSelectedOptions(); 32 | }); 33 | }); 34 | 35 | createSelect(); 36 | 37 | function createSelect(): void { 38 | renderSelectedOptions(); 39 | } 40 | 41 | function renderSelectedOptions() { 42 | const selectDisplay = select.querySelector( 43 | ".selectDisplay" 44 | ) as HTMLDivElement; 45 | const optionsDisplay = selectDisplay || document.createElement("div"); 46 | 47 | if (!selectDisplay) { 48 | optionsDisplay.classList.add("selectDisplay"); 49 | select.appendChild(optionsDisplay); 50 | } 51 | 52 | optionsDisplay.onclick = () => { 53 | // debugger; 54 | const state = visibleOption.getVisible; 55 | visibleOption.setVisible = !state; 56 | }; 57 | 58 | const batch = document.createDocumentFragment(); 59 | if (multiple) { 60 | selectStack.forEach((option) => batch.append(createChip(options[option]))); 61 | } else { 62 | const selectedOption = options[selectStack[0]]; 63 | batch.append(createChip(selectedOption)); 64 | console.log(selectStack); 65 | } 66 | 67 | optionsDisplay.textContent = ""; 68 | optionsDisplay.append(batch); 69 | 70 | if (selectStack.length === 0) { 71 | optionsDisplay.textContent = "No Options Selected!"; 72 | } 73 | } 74 | 75 | function renderOptions(): void { 76 | let optionList = document.querySelector( 77 | ".selectList" 78 | ) as HTMLUListElement | null; 79 | 80 | if (!optionList) { 81 | optionList = document.createElement("ul"); 82 | optionList.classList.add("selectList"); 83 | } 84 | options?.map((option: string, index: number): void => { 85 | const listItem = createOption(option, index); 86 | optionList?.appendChild(listItem); 87 | }); 88 | select.appendChild(optionList); 89 | } 90 | 91 | function removeOptions(): void { 92 | const optionsDisplay = document.querySelector(".selectList"); 93 | if (optionsDisplay) optionsDisplay.parentNode?.removeChild(optionsDisplay); 94 | } 95 | 96 | function createOption(value: string, index: number): HTMLLIElement { 97 | const listItem = document.createElement("li"); 98 | listItem.classList.add("option"); 99 | listItem.textContent = value; 100 | listItem.setAttribute("data-value", index.toString()); 101 | 102 | if (selectStack.includes(index)) { 103 | listItem.classList.add("selected"); 104 | listItem.addEventListener("click", (event: MouseEvent) => { 105 | const element = event.target as HTMLLIElement; 106 | const index = element.getAttribute("data-value"); 107 | if (index) 108 | selectStack.splice(selectStack.indexOf(Number.parseInt(index)), 1); 109 | removeOptions(); 110 | renderOptions(); 111 | renderSelectedOptions(); 112 | }); 113 | } else { 114 | listItem.addEventListener("click", (event: MouseEvent) => { 115 | const element = event.target as HTMLLIElement; 116 | const index = element.getAttribute("data-value"); 117 | if (index) { 118 | multiple 119 | ? selectStack.push(Number.parseInt(index)) 120 | : (selectStack[0] = Number.parseInt(index)); 121 | } 122 | renderSelectedOptions(); 123 | removeOptions(); 124 | renderOptions(); 125 | }); 126 | } 127 | 128 | return listItem; 129 | } 130 | 131 | function createChip(value: string): HTMLParagraphElement { 132 | const chip = document.createElement("p"); 133 | chip.classList.add("chip"); 134 | chip.textContent = value; 135 | return chip; 136 | } 137 | -------------------------------------------------------------------------------- /MUI-Select/src/style.css: -------------------------------------------------------------------------------- 1 | *:root { 2 | font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 3 | Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; 4 | } 5 | 6 | * { 7 | padding: 0; 8 | } 9 | .option { 10 | list-style: none; 11 | padding: 10px 20px; 12 | cursor: pointer; 13 | } 14 | .option:hover { 15 | background: #f6f4f4; 16 | } 17 | 18 | .selectList { 19 | display: flex; 20 | flex-direction: column; 21 | box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px; 22 | } 23 | 24 | .selectDisplay { 25 | border: 1px solid gray; 26 | border-radius: 10px; 27 | padding: 10px; 28 | display: flex; 29 | gap: 5px; 30 | flex-wrap: wrap; 31 | cursor: pointer; 32 | } 33 | 34 | .chip { 35 | border-radius: 20px; 36 | padding-block: 4px; 37 | padding-inline: 8px; 38 | margin-block: 2px; 39 | cursor: pointer; 40 | background-color: #e0e0e0; 41 | transition-duration: 150ms; 42 | } 43 | .chip:hover { 44 | background: #c6c5c5; 45 | } 46 | 47 | .selected { 48 | background-color: aliceblue; 49 | } 50 | 51 | .selected:hover { 52 | background-color: rgb(214, 236, 255); 53 | } 54 | -------------------------------------------------------------------------------- /MUI-Select/src/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MUI-Select/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /MUI-Select/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Setting Up TS project 2 | 3 | ## With vite 4 | 5 | Just create a new vanilla ts project 6 | 7 | ## Manually 8 | 9 | ### Generating TypeScript Config files 10 | 11 | `tsc --init` 12 | 13 | or 14 | 15 | `npx tsc --init` 16 | 17 | ### Change the output of TS to specific folder 18 | 19 | - Find the outdir in the ts config and change it to "./dest" to compile the ts to js scripts and save their 20 | 21 | - Otherwise the .js equivalent will be generated in the same folder as that of .ts 22 | 23 | ### Running tsc 24 | 25 | `tsc` 26 | 27 | ### Running tsc in watch mode 28 | 29 | It will autmatically converts the .ts to .js 30 | `tsc --watch` 31 | 32 | ### Changing module system to es6 33 | 34 | Change module to "ES6" in tsconfig 35 | 36 | # Types for libraries 37 | 38 | Some of the libraries like uuid dont provide types by default. Either download it or write your own 39 | You can download them by hovering around the import 40 | -------------------------------------------------------------------------------- /TODO-List/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /TODO-List/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 |
11 |
12 | 13 | 14 |
15 |
    16 |
    17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /TODO-List/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "todo-list", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "uuid": "^9.0.0" 12 | }, 13 | "devDependencies": { 14 | "@types/uuid": "^9.0.2", 15 | "typescript": "^5.0.2", 16 | "vite": "^4.4.5" 17 | } 18 | }, 19 | "node_modules/@esbuild/android-arm": { 20 | "version": "0.18.15", 21 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.15.tgz", 22 | "integrity": "sha512-wlkQBWb79/jeEEoRmrxt/yhn5T1lU236OCNpnfRzaCJHZ/5gf82uYx1qmADTBWE0AR/v7FiozE1auk2riyQd3w==", 23 | "cpu": [ 24 | "arm" 25 | ], 26 | "dev": true, 27 | "optional": true, 28 | "os": [ 29 | "android" 30 | ], 31 | "engines": { 32 | "node": ">=12" 33 | } 34 | }, 35 | "node_modules/@esbuild/android-arm64": { 36 | "version": "0.18.15", 37 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.15.tgz", 38 | "integrity": "sha512-NI/gnWcMl2kXt1HJKOn2H69SYn4YNheKo6NZt1hyfKWdMbaGadxjZIkcj4Gjk/WPxnbFXs9/3HjGHaknCqjrww==", 39 | "cpu": [ 40 | "arm64" 41 | ], 42 | "dev": true, 43 | "optional": true, 44 | "os": [ 45 | "android" 46 | ], 47 | "engines": { 48 | "node": ">=12" 49 | } 50 | }, 51 | "node_modules/@esbuild/android-x64": { 52 | "version": "0.18.15", 53 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.15.tgz", 54 | "integrity": "sha512-FM9NQamSaEm/IZIhegF76aiLnng1kEsZl2eve/emxDeReVfRuRNmvT28l6hoFD9TsCxpK+i4v8LPpEj74T7yjA==", 55 | "cpu": [ 56 | "x64" 57 | ], 58 | "dev": true, 59 | "optional": true, 60 | "os": [ 61 | "android" 62 | ], 63 | "engines": { 64 | "node": ">=12" 65 | } 66 | }, 67 | "node_modules/@esbuild/darwin-arm64": { 68 | "version": "0.18.15", 69 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.15.tgz", 70 | "integrity": "sha512-XmrFwEOYauKte9QjS6hz60FpOCnw4zaPAb7XV7O4lx1r39XjJhTN7ZpXqJh4sN6q60zbP6QwAVVA8N/wUyBH/w==", 71 | "cpu": [ 72 | "arm64" 73 | ], 74 | "dev": true, 75 | "optional": true, 76 | "os": [ 77 | "darwin" 78 | ], 79 | "engines": { 80 | "node": ">=12" 81 | } 82 | }, 83 | "node_modules/@esbuild/darwin-x64": { 84 | "version": "0.18.15", 85 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.15.tgz", 86 | "integrity": "sha512-bMqBmpw1e//7Fh5GLetSZaeo9zSC4/CMtrVFdj+bqKPGJuKyfNJ5Nf2m3LknKZTS+Q4oyPiON+v3eaJ59sLB5A==", 87 | "cpu": [ 88 | "x64" 89 | ], 90 | "dev": true, 91 | "optional": true, 92 | "os": [ 93 | "darwin" 94 | ], 95 | "engines": { 96 | "node": ">=12" 97 | } 98 | }, 99 | "node_modules/@esbuild/freebsd-arm64": { 100 | "version": "0.18.15", 101 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.15.tgz", 102 | "integrity": "sha512-LoTK5N3bOmNI9zVLCeTgnk5Rk0WdUTrr9dyDAQGVMrNTh9EAPuNwSTCgaKOKiDpverOa0htPcO9NwslSE5xuLA==", 103 | "cpu": [ 104 | "arm64" 105 | ], 106 | "dev": true, 107 | "optional": true, 108 | "os": [ 109 | "freebsd" 110 | ], 111 | "engines": { 112 | "node": ">=12" 113 | } 114 | }, 115 | "node_modules/@esbuild/freebsd-x64": { 116 | "version": "0.18.15", 117 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.15.tgz", 118 | "integrity": "sha512-62jX5n30VzgrjAjOk5orYeHFq6sqjvsIj1QesXvn5OZtdt5Gdj0vUNJy9NIpjfdNdqr76jjtzBJKf+h2uzYuTQ==", 119 | "cpu": [ 120 | "x64" 121 | ], 122 | "dev": true, 123 | "optional": true, 124 | "os": [ 125 | "freebsd" 126 | ], 127 | "engines": { 128 | "node": ">=12" 129 | } 130 | }, 131 | "node_modules/@esbuild/linux-arm": { 132 | "version": "0.18.15", 133 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.15.tgz", 134 | "integrity": "sha512-dT4URUv6ir45ZkBqhwZwyFV6cH61k8MttIwhThp2BGiVtagYvCToF+Bggyx2VI57RG4Fbt21f9TmXaYx0DeUJg==", 135 | "cpu": [ 136 | "arm" 137 | ], 138 | "dev": true, 139 | "optional": true, 140 | "os": [ 141 | "linux" 142 | ], 143 | "engines": { 144 | "node": ">=12" 145 | } 146 | }, 147 | "node_modules/@esbuild/linux-arm64": { 148 | "version": "0.18.15", 149 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.15.tgz", 150 | "integrity": "sha512-BWncQeuWDgYv0jTNzJjaNgleduV4tMbQjmk/zpPh/lUdMcNEAxy+jvneDJ6RJkrqloG7tB9S9rCrtfk/kuplsQ==", 151 | "cpu": [ 152 | "arm64" 153 | ], 154 | "dev": true, 155 | "optional": true, 156 | "os": [ 157 | "linux" 158 | ], 159 | "engines": { 160 | "node": ">=12" 161 | } 162 | }, 163 | "node_modules/@esbuild/linux-ia32": { 164 | "version": "0.18.15", 165 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.15.tgz", 166 | "integrity": "sha512-JPXORvgHRHITqfms1dWT/GbEY89u848dC08o0yK3fNskhp0t2TuNUnsrrSgOdH28ceb1hJuwyr8R/1RnyPwocw==", 167 | "cpu": [ 168 | "ia32" 169 | ], 170 | "dev": true, 171 | "optional": true, 172 | "os": [ 173 | "linux" 174 | ], 175 | "engines": { 176 | "node": ">=12" 177 | } 178 | }, 179 | "node_modules/@esbuild/linux-loong64": { 180 | "version": "0.18.15", 181 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.15.tgz", 182 | "integrity": "sha512-kArPI0DopjJCEplsVj/H+2Qgzz7vdFSacHNsgoAKpPS6W/Ndh8Oe24HRDQ5QCu4jHgN6XOtfFfLpRx3TXv/mEg==", 183 | "cpu": [ 184 | "loong64" 185 | ], 186 | "dev": true, 187 | "optional": true, 188 | "os": [ 189 | "linux" 190 | ], 191 | "engines": { 192 | "node": ">=12" 193 | } 194 | }, 195 | "node_modules/@esbuild/linux-mips64el": { 196 | "version": "0.18.15", 197 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.15.tgz", 198 | "integrity": "sha512-b/tmngUfO02E00c1XnNTw/0DmloKjb6XQeqxaYuzGwHe0fHVgx5/D6CWi+XH1DvkszjBUkK9BX7n1ARTOst59w==", 199 | "cpu": [ 200 | "mips64el" 201 | ], 202 | "dev": true, 203 | "optional": true, 204 | "os": [ 205 | "linux" 206 | ], 207 | "engines": { 208 | "node": ">=12" 209 | } 210 | }, 211 | "node_modules/@esbuild/linux-ppc64": { 212 | "version": "0.18.15", 213 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.15.tgz", 214 | "integrity": "sha512-KXPY69MWw79QJkyvUYb2ex/OgnN/8N/Aw5UDPlgoRtoEfcBqfeLodPr42UojV3NdkoO4u10NXQdamWm1YEzSKw==", 215 | "cpu": [ 216 | "ppc64" 217 | ], 218 | "dev": true, 219 | "optional": true, 220 | "os": [ 221 | "linux" 222 | ], 223 | "engines": { 224 | "node": ">=12" 225 | } 226 | }, 227 | "node_modules/@esbuild/linux-riscv64": { 228 | "version": "0.18.15", 229 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.15.tgz", 230 | "integrity": "sha512-komK3NEAeeGRnvFEjX1SfVg6EmkfIi5aKzevdvJqMydYr9N+pRQK0PGJXk+bhoPZwOUgLO4l99FZmLGk/L1jWg==", 231 | "cpu": [ 232 | "riscv64" 233 | ], 234 | "dev": true, 235 | "optional": true, 236 | "os": [ 237 | "linux" 238 | ], 239 | "engines": { 240 | "node": ">=12" 241 | } 242 | }, 243 | "node_modules/@esbuild/linux-s390x": { 244 | "version": "0.18.15", 245 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.15.tgz", 246 | "integrity": "sha512-632T5Ts6gQ2WiMLWRRyeflPAm44u2E/s/TJvn+BP6M5mnHSk93cieaypj3VSMYO2ePTCRqAFXtuYi1yv8uZJNA==", 247 | "cpu": [ 248 | "s390x" 249 | ], 250 | "dev": true, 251 | "optional": true, 252 | "os": [ 253 | "linux" 254 | ], 255 | "engines": { 256 | "node": ">=12" 257 | } 258 | }, 259 | "node_modules/@esbuild/linux-x64": { 260 | "version": "0.18.15", 261 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.15.tgz", 262 | "integrity": "sha512-MsHtX0NgvRHsoOtYkuxyk4Vkmvk3PLRWfA4okK7c+6dT0Fu4SUqXAr9y4Q3d8vUf1VWWb6YutpL4XNe400iQ1g==", 263 | "cpu": [ 264 | "x64" 265 | ], 266 | "dev": true, 267 | "optional": true, 268 | "os": [ 269 | "linux" 270 | ], 271 | "engines": { 272 | "node": ">=12" 273 | } 274 | }, 275 | "node_modules/@esbuild/netbsd-x64": { 276 | "version": "0.18.15", 277 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.15.tgz", 278 | "integrity": "sha512-djST6s+jQiwxMIVQ5rlt24JFIAr4uwUnzceuFL7BQT4CbrRtqBPueS4GjXSiIpmwVri1Icj/9pFRJ7/aScvT+A==", 279 | "cpu": [ 280 | "x64" 281 | ], 282 | "dev": true, 283 | "optional": true, 284 | "os": [ 285 | "netbsd" 286 | ], 287 | "engines": { 288 | "node": ">=12" 289 | } 290 | }, 291 | "node_modules/@esbuild/openbsd-x64": { 292 | "version": "0.18.15", 293 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.15.tgz", 294 | "integrity": "sha512-naeRhUIvhsgeounjkF5mvrNAVMGAm6EJWiabskeE5yOeBbLp7T89tAEw0j5Jm/CZAwyLe3c67zyCWH6fsBLCpw==", 295 | "cpu": [ 296 | "x64" 297 | ], 298 | "dev": true, 299 | "optional": true, 300 | "os": [ 301 | "openbsd" 302 | ], 303 | "engines": { 304 | "node": ">=12" 305 | } 306 | }, 307 | "node_modules/@esbuild/sunos-x64": { 308 | "version": "0.18.15", 309 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.15.tgz", 310 | "integrity": "sha512-qkT2+WxyKbNIKV1AEhI8QiSIgTHMcRctzSaa/I3kVgMS5dl3fOeoqkb7pW76KwxHoriImhx7Mg3TwN/auMDsyQ==", 311 | "cpu": [ 312 | "x64" 313 | ], 314 | "dev": true, 315 | "optional": true, 316 | "os": [ 317 | "sunos" 318 | ], 319 | "engines": { 320 | "node": ">=12" 321 | } 322 | }, 323 | "node_modules/@esbuild/win32-arm64": { 324 | "version": "0.18.15", 325 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.15.tgz", 326 | "integrity": "sha512-HC4/feP+pB2Vb+cMPUjAnFyERs+HJN7E6KaeBlFdBv799MhD+aPJlfi/yk36SED58J9TPwI8MAcVpJgej4ud0A==", 327 | "cpu": [ 328 | "arm64" 329 | ], 330 | "dev": true, 331 | "optional": true, 332 | "os": [ 333 | "win32" 334 | ], 335 | "engines": { 336 | "node": ">=12" 337 | } 338 | }, 339 | "node_modules/@esbuild/win32-ia32": { 340 | "version": "0.18.15", 341 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.15.tgz", 342 | "integrity": "sha512-ovjwoRXI+gf52EVF60u9sSDj7myPixPxqzD5CmkEUmvs+W9Xd0iqISVBQn8xcx4ciIaIVlWCuTbYDOXOnOL44Q==", 343 | "cpu": [ 344 | "ia32" 345 | ], 346 | "dev": true, 347 | "optional": true, 348 | "os": [ 349 | "win32" 350 | ], 351 | "engines": { 352 | "node": ">=12" 353 | } 354 | }, 355 | "node_modules/@esbuild/win32-x64": { 356 | "version": "0.18.15", 357 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.15.tgz", 358 | "integrity": "sha512-imUxH9a3WJARyAvrG7srLyiK73XdX83NXQkjKvQ+7vPh3ZxoLrzvPkQKKw2DwZ+RV2ZB6vBfNHP8XScAmQC3aA==", 359 | "cpu": [ 360 | "x64" 361 | ], 362 | "dev": true, 363 | "optional": true, 364 | "os": [ 365 | "win32" 366 | ], 367 | "engines": { 368 | "node": ">=12" 369 | } 370 | }, 371 | "node_modules/@types/uuid": { 372 | "version": "9.0.2", 373 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", 374 | "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", 375 | "dev": true 376 | }, 377 | "node_modules/esbuild": { 378 | "version": "0.18.15", 379 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.15.tgz", 380 | "integrity": "sha512-3WOOLhrvuTGPRzQPU6waSDWrDTnQriia72McWcn6UCi43GhCHrXH4S59hKMeez+IITmdUuUyvbU9JIp+t3xlPQ==", 381 | "dev": true, 382 | "hasInstallScript": true, 383 | "bin": { 384 | "esbuild": "bin/esbuild" 385 | }, 386 | "engines": { 387 | "node": ">=12" 388 | }, 389 | "optionalDependencies": { 390 | "@esbuild/android-arm": "0.18.15", 391 | "@esbuild/android-arm64": "0.18.15", 392 | "@esbuild/android-x64": "0.18.15", 393 | "@esbuild/darwin-arm64": "0.18.15", 394 | "@esbuild/darwin-x64": "0.18.15", 395 | "@esbuild/freebsd-arm64": "0.18.15", 396 | "@esbuild/freebsd-x64": "0.18.15", 397 | "@esbuild/linux-arm": "0.18.15", 398 | "@esbuild/linux-arm64": "0.18.15", 399 | "@esbuild/linux-ia32": "0.18.15", 400 | "@esbuild/linux-loong64": "0.18.15", 401 | "@esbuild/linux-mips64el": "0.18.15", 402 | "@esbuild/linux-ppc64": "0.18.15", 403 | "@esbuild/linux-riscv64": "0.18.15", 404 | "@esbuild/linux-s390x": "0.18.15", 405 | "@esbuild/linux-x64": "0.18.15", 406 | "@esbuild/netbsd-x64": "0.18.15", 407 | "@esbuild/openbsd-x64": "0.18.15", 408 | "@esbuild/sunos-x64": "0.18.15", 409 | "@esbuild/win32-arm64": "0.18.15", 410 | "@esbuild/win32-ia32": "0.18.15", 411 | "@esbuild/win32-x64": "0.18.15" 412 | } 413 | }, 414 | "node_modules/fsevents": { 415 | "version": "2.3.2", 416 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 417 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 418 | "dev": true, 419 | "hasInstallScript": true, 420 | "optional": true, 421 | "os": [ 422 | "darwin" 423 | ], 424 | "engines": { 425 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 426 | } 427 | }, 428 | "node_modules/nanoid": { 429 | "version": "3.3.6", 430 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 431 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 432 | "dev": true, 433 | "funding": [ 434 | { 435 | "type": "github", 436 | "url": "https://github.com/sponsors/ai" 437 | } 438 | ], 439 | "bin": { 440 | "nanoid": "bin/nanoid.cjs" 441 | }, 442 | "engines": { 443 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 444 | } 445 | }, 446 | "node_modules/picocolors": { 447 | "version": "1.0.0", 448 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 449 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 450 | "dev": true 451 | }, 452 | "node_modules/postcss": { 453 | "version": "8.4.27", 454 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", 455 | "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", 456 | "dev": true, 457 | "funding": [ 458 | { 459 | "type": "opencollective", 460 | "url": "https://opencollective.com/postcss/" 461 | }, 462 | { 463 | "type": "tidelift", 464 | "url": "https://tidelift.com/funding/github/npm/postcss" 465 | }, 466 | { 467 | "type": "github", 468 | "url": "https://github.com/sponsors/ai" 469 | } 470 | ], 471 | "dependencies": { 472 | "nanoid": "^3.3.6", 473 | "picocolors": "^1.0.0", 474 | "source-map-js": "^1.0.2" 475 | }, 476 | "engines": { 477 | "node": "^10 || ^12 || >=14" 478 | } 479 | }, 480 | "node_modules/rollup": { 481 | "version": "3.26.3", 482 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz", 483 | "integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==", 484 | "dev": true, 485 | "bin": { 486 | "rollup": "dist/bin/rollup" 487 | }, 488 | "engines": { 489 | "node": ">=14.18.0", 490 | "npm": ">=8.0.0" 491 | }, 492 | "optionalDependencies": { 493 | "fsevents": "~2.3.2" 494 | } 495 | }, 496 | "node_modules/source-map-js": { 497 | "version": "1.0.2", 498 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 499 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 500 | "dev": true, 501 | "engines": { 502 | "node": ">=0.10.0" 503 | } 504 | }, 505 | "node_modules/typescript": { 506 | "version": "5.1.6", 507 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", 508 | "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", 509 | "dev": true, 510 | "bin": { 511 | "tsc": "bin/tsc", 512 | "tsserver": "bin/tsserver" 513 | }, 514 | "engines": { 515 | "node": ">=14.17" 516 | } 517 | }, 518 | "node_modules/uuid": { 519 | "version": "9.0.0", 520 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", 521 | "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", 522 | "bin": { 523 | "uuid": "dist/bin/uuid" 524 | } 525 | }, 526 | "node_modules/vite": { 527 | "version": "4.4.6", 528 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.6.tgz", 529 | "integrity": "sha512-EY6Mm8vJ++S3D4tNAckaZfw3JwG3wa794Vt70M6cNJ6NxT87yhq7EC8Rcap3ahyHdo8AhCmV9PTk+vG1HiYn1A==", 530 | "dev": true, 531 | "dependencies": { 532 | "esbuild": "^0.18.10", 533 | "postcss": "^8.4.26", 534 | "rollup": "^3.25.2" 535 | }, 536 | "bin": { 537 | "vite": "bin/vite.js" 538 | }, 539 | "engines": { 540 | "node": "^14.18.0 || >=16.0.0" 541 | }, 542 | "funding": { 543 | "url": "https://github.com/vitejs/vite?sponsor=1" 544 | }, 545 | "optionalDependencies": { 546 | "fsevents": "~2.3.2" 547 | }, 548 | "peerDependencies": { 549 | "@types/node": ">= 14", 550 | "less": "*", 551 | "lightningcss": "^1.21.0", 552 | "sass": "*", 553 | "stylus": "*", 554 | "sugarss": "*", 555 | "terser": "^5.4.0" 556 | }, 557 | "peerDependenciesMeta": { 558 | "@types/node": { 559 | "optional": true 560 | }, 561 | "less": { 562 | "optional": true 563 | }, 564 | "lightningcss": { 565 | "optional": true 566 | }, 567 | "sass": { 568 | "optional": true 569 | }, 570 | "stylus": { 571 | "optional": true 572 | }, 573 | "sugarss": { 574 | "optional": true 575 | }, 576 | "terser": { 577 | "optional": true 578 | } 579 | } 580 | } 581 | } 582 | } 583 | -------------------------------------------------------------------------------- /TODO-List/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "@types/uuid": "^9.0.2", 13 | "typescript": "^5.0.2", 14 | "vite": "^4.4.5" 15 | }, 16 | "dependencies": { 17 | "uuid": "^9.0.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /TODO-List/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /TODO-List/src/interfaces/task.ts: -------------------------------------------------------------------------------- 1 | export default interface Task { 2 | id: string; 3 | title: string; 4 | completed: boolean; 5 | createdAt: Date; 6 | } 7 | -------------------------------------------------------------------------------- /TODO-List/src/main.ts: -------------------------------------------------------------------------------- 1 | import "./style.css"; 2 | import { v4 as uuid } from "uuid"; 3 | import Task from "./interfaces/task"; 4 | 5 | // by default the elements are html element so they will be showing element | null 6 | 7 | const list = document.querySelector("#list"); 8 | const taskForm = document.querySelector("#task-form"); 9 | 10 | // if using getElementById 11 | const input = document.getElementById("task-title") as HTMLInputElement; 12 | 13 | const tasks: Task[] = loadTasks(); 14 | console.log(tasks); 15 | 16 | tasks.forEach(addListItem) 17 | 18 | taskForm?.addEventListener("submit", (e) => { 19 | e.preventDefault(); 20 | 21 | if (input?.value === "" || input?.value === null) return; 22 | 23 | const task: Task = { 24 | id: uuid(), 25 | completed: false, 26 | title: input.value, 27 | createdAt: new Date(), 28 | }; 29 | tasks.push(task); 30 | addListItem(task); 31 | saveTasks() 32 | input.value = ""; 33 | }); 34 | 35 | function addListItem(task: Task) { 36 | const item = document.createElement("li"); 37 | const label = document.createElement("label"); 38 | const checkbox = document.createElement("input"); 39 | checkbox.addEventListener("change", () => { 40 | task.completed = checkbox.checked; 41 | console.log(task); 42 | }); 43 | checkbox.type = "checkbox"; 44 | checkbox.checked = task.completed; 45 | label.append(checkbox, task.title); 46 | item.append(label); 47 | list?.append(item); 48 | } 49 | 50 | function saveTasks() { 51 | localStorage.setItem("TASKS", JSON.stringify(tasks)); 52 | } 53 | 54 | function loadTasks(): Task[] { 55 | const tasks = localStorage.getItem("TASKS"); 56 | if (tasks == null) return []; 57 | return JSON.parse(tasks); 58 | } 59 | -------------------------------------------------------------------------------- /TODO-List/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | a:hover { 23 | color: #535bf2; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | display: flex; 29 | place-items: center; 30 | min-width: 320px; 31 | min-height: 100vh; 32 | } 33 | 34 | h1 { 35 | font-size: 3.2em; 36 | line-height: 1.1; 37 | } 38 | 39 | #app { 40 | max-width: 1280px; 41 | margin: 0 auto; 42 | padding: 2rem; 43 | text-align: center; 44 | } 45 | 46 | .logo { 47 | height: 6em; 48 | padding: 1.5em; 49 | will-change: filter; 50 | transition: filter 300ms; 51 | } 52 | .logo:hover { 53 | filter: drop-shadow(0 0 2em #646cffaa); 54 | } 55 | .logo.vanilla:hover { 56 | filter: drop-shadow(0 0 2em #3178c6aa); 57 | } 58 | 59 | .card { 60 | padding: 2em; 61 | } 62 | 63 | .read-the-docs { 64 | color: #888; 65 | } 66 | 67 | button { 68 | border-radius: 8px; 69 | border: 1px solid transparent; 70 | padding: 0.6em 1.2em; 71 | font-size: 1em; 72 | font-weight: 500; 73 | font-family: inherit; 74 | background-color: #1a1a1a; 75 | cursor: pointer; 76 | transition: border-color 0.25s; 77 | } 78 | button:hover { 79 | border-color: #646cff; 80 | } 81 | button:focus, 82 | button:focus-visible { 83 | outline: 4px auto -webkit-focus-ring-color; 84 | } 85 | 86 | @media (prefers-color-scheme: light) { 87 | :root { 88 | color: #213547; 89 | background-color: #ffffff; 90 | } 91 | a:hover { 92 | color: #747bff; 93 | } 94 | button { 95 | background-color: #f9f9f9; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /TODO-List/src/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /TODO-List/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /TODO-List/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /typewriter/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /typewriter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 |
    11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /typewriter/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typewriter", 3 | "version": "0.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "typewriter", 9 | "version": "0.0.0", 10 | "devDependencies": { 11 | "typescript": "^5.0.2", 12 | "vite": "^4.4.5" 13 | } 14 | }, 15 | "node_modules/@esbuild/android-arm": { 16 | "version": "0.18.15", 17 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.15.tgz", 18 | "integrity": "sha512-wlkQBWb79/jeEEoRmrxt/yhn5T1lU236OCNpnfRzaCJHZ/5gf82uYx1qmADTBWE0AR/v7FiozE1auk2riyQd3w==", 19 | "cpu": [ 20 | "arm" 21 | ], 22 | "dev": true, 23 | "optional": true, 24 | "os": [ 25 | "android" 26 | ], 27 | "engines": { 28 | "node": ">=12" 29 | } 30 | }, 31 | "node_modules/@esbuild/android-arm64": { 32 | "version": "0.18.15", 33 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.15.tgz", 34 | "integrity": "sha512-NI/gnWcMl2kXt1HJKOn2H69SYn4YNheKo6NZt1hyfKWdMbaGadxjZIkcj4Gjk/WPxnbFXs9/3HjGHaknCqjrww==", 35 | "cpu": [ 36 | "arm64" 37 | ], 38 | "dev": true, 39 | "optional": true, 40 | "os": [ 41 | "android" 42 | ], 43 | "engines": { 44 | "node": ">=12" 45 | } 46 | }, 47 | "node_modules/@esbuild/android-x64": { 48 | "version": "0.18.15", 49 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.15.tgz", 50 | "integrity": "sha512-FM9NQamSaEm/IZIhegF76aiLnng1kEsZl2eve/emxDeReVfRuRNmvT28l6hoFD9TsCxpK+i4v8LPpEj74T7yjA==", 51 | "cpu": [ 52 | "x64" 53 | ], 54 | "dev": true, 55 | "optional": true, 56 | "os": [ 57 | "android" 58 | ], 59 | "engines": { 60 | "node": ">=12" 61 | } 62 | }, 63 | "node_modules/@esbuild/darwin-arm64": { 64 | "version": "0.18.15", 65 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.15.tgz", 66 | "integrity": "sha512-XmrFwEOYauKte9QjS6hz60FpOCnw4zaPAb7XV7O4lx1r39XjJhTN7ZpXqJh4sN6q60zbP6QwAVVA8N/wUyBH/w==", 67 | "cpu": [ 68 | "arm64" 69 | ], 70 | "dev": true, 71 | "optional": true, 72 | "os": [ 73 | "darwin" 74 | ], 75 | "engines": { 76 | "node": ">=12" 77 | } 78 | }, 79 | "node_modules/@esbuild/darwin-x64": { 80 | "version": "0.18.15", 81 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.15.tgz", 82 | "integrity": "sha512-bMqBmpw1e//7Fh5GLetSZaeo9zSC4/CMtrVFdj+bqKPGJuKyfNJ5Nf2m3LknKZTS+Q4oyPiON+v3eaJ59sLB5A==", 83 | "cpu": [ 84 | "x64" 85 | ], 86 | "dev": true, 87 | "optional": true, 88 | "os": [ 89 | "darwin" 90 | ], 91 | "engines": { 92 | "node": ">=12" 93 | } 94 | }, 95 | "node_modules/@esbuild/freebsd-arm64": { 96 | "version": "0.18.15", 97 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.15.tgz", 98 | "integrity": "sha512-LoTK5N3bOmNI9zVLCeTgnk5Rk0WdUTrr9dyDAQGVMrNTh9EAPuNwSTCgaKOKiDpverOa0htPcO9NwslSE5xuLA==", 99 | "cpu": [ 100 | "arm64" 101 | ], 102 | "dev": true, 103 | "optional": true, 104 | "os": [ 105 | "freebsd" 106 | ], 107 | "engines": { 108 | "node": ">=12" 109 | } 110 | }, 111 | "node_modules/@esbuild/freebsd-x64": { 112 | "version": "0.18.15", 113 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.15.tgz", 114 | "integrity": "sha512-62jX5n30VzgrjAjOk5orYeHFq6sqjvsIj1QesXvn5OZtdt5Gdj0vUNJy9NIpjfdNdqr76jjtzBJKf+h2uzYuTQ==", 115 | "cpu": [ 116 | "x64" 117 | ], 118 | "dev": true, 119 | "optional": true, 120 | "os": [ 121 | "freebsd" 122 | ], 123 | "engines": { 124 | "node": ">=12" 125 | } 126 | }, 127 | "node_modules/@esbuild/linux-arm": { 128 | "version": "0.18.15", 129 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.15.tgz", 130 | "integrity": "sha512-dT4URUv6ir45ZkBqhwZwyFV6cH61k8MttIwhThp2BGiVtagYvCToF+Bggyx2VI57RG4Fbt21f9TmXaYx0DeUJg==", 131 | "cpu": [ 132 | "arm" 133 | ], 134 | "dev": true, 135 | "optional": true, 136 | "os": [ 137 | "linux" 138 | ], 139 | "engines": { 140 | "node": ">=12" 141 | } 142 | }, 143 | "node_modules/@esbuild/linux-arm64": { 144 | "version": "0.18.15", 145 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.15.tgz", 146 | "integrity": "sha512-BWncQeuWDgYv0jTNzJjaNgleduV4tMbQjmk/zpPh/lUdMcNEAxy+jvneDJ6RJkrqloG7tB9S9rCrtfk/kuplsQ==", 147 | "cpu": [ 148 | "arm64" 149 | ], 150 | "dev": true, 151 | "optional": true, 152 | "os": [ 153 | "linux" 154 | ], 155 | "engines": { 156 | "node": ">=12" 157 | } 158 | }, 159 | "node_modules/@esbuild/linux-ia32": { 160 | "version": "0.18.15", 161 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.15.tgz", 162 | "integrity": "sha512-JPXORvgHRHITqfms1dWT/GbEY89u848dC08o0yK3fNskhp0t2TuNUnsrrSgOdH28ceb1hJuwyr8R/1RnyPwocw==", 163 | "cpu": [ 164 | "ia32" 165 | ], 166 | "dev": true, 167 | "optional": true, 168 | "os": [ 169 | "linux" 170 | ], 171 | "engines": { 172 | "node": ">=12" 173 | } 174 | }, 175 | "node_modules/@esbuild/linux-loong64": { 176 | "version": "0.18.15", 177 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.15.tgz", 178 | "integrity": "sha512-kArPI0DopjJCEplsVj/H+2Qgzz7vdFSacHNsgoAKpPS6W/Ndh8Oe24HRDQ5QCu4jHgN6XOtfFfLpRx3TXv/mEg==", 179 | "cpu": [ 180 | "loong64" 181 | ], 182 | "dev": true, 183 | "optional": true, 184 | "os": [ 185 | "linux" 186 | ], 187 | "engines": { 188 | "node": ">=12" 189 | } 190 | }, 191 | "node_modules/@esbuild/linux-mips64el": { 192 | "version": "0.18.15", 193 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.15.tgz", 194 | "integrity": "sha512-b/tmngUfO02E00c1XnNTw/0DmloKjb6XQeqxaYuzGwHe0fHVgx5/D6CWi+XH1DvkszjBUkK9BX7n1ARTOst59w==", 195 | "cpu": [ 196 | "mips64el" 197 | ], 198 | "dev": true, 199 | "optional": true, 200 | "os": [ 201 | "linux" 202 | ], 203 | "engines": { 204 | "node": ">=12" 205 | } 206 | }, 207 | "node_modules/@esbuild/linux-ppc64": { 208 | "version": "0.18.15", 209 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.15.tgz", 210 | "integrity": "sha512-KXPY69MWw79QJkyvUYb2ex/OgnN/8N/Aw5UDPlgoRtoEfcBqfeLodPr42UojV3NdkoO4u10NXQdamWm1YEzSKw==", 211 | "cpu": [ 212 | "ppc64" 213 | ], 214 | "dev": true, 215 | "optional": true, 216 | "os": [ 217 | "linux" 218 | ], 219 | "engines": { 220 | "node": ">=12" 221 | } 222 | }, 223 | "node_modules/@esbuild/linux-riscv64": { 224 | "version": "0.18.15", 225 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.15.tgz", 226 | "integrity": "sha512-komK3NEAeeGRnvFEjX1SfVg6EmkfIi5aKzevdvJqMydYr9N+pRQK0PGJXk+bhoPZwOUgLO4l99FZmLGk/L1jWg==", 227 | "cpu": [ 228 | "riscv64" 229 | ], 230 | "dev": true, 231 | "optional": true, 232 | "os": [ 233 | "linux" 234 | ], 235 | "engines": { 236 | "node": ">=12" 237 | } 238 | }, 239 | "node_modules/@esbuild/linux-s390x": { 240 | "version": "0.18.15", 241 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.15.tgz", 242 | "integrity": "sha512-632T5Ts6gQ2WiMLWRRyeflPAm44u2E/s/TJvn+BP6M5mnHSk93cieaypj3VSMYO2ePTCRqAFXtuYi1yv8uZJNA==", 243 | "cpu": [ 244 | "s390x" 245 | ], 246 | "dev": true, 247 | "optional": true, 248 | "os": [ 249 | "linux" 250 | ], 251 | "engines": { 252 | "node": ">=12" 253 | } 254 | }, 255 | "node_modules/@esbuild/linux-x64": { 256 | "version": "0.18.15", 257 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.15.tgz", 258 | "integrity": "sha512-MsHtX0NgvRHsoOtYkuxyk4Vkmvk3PLRWfA4okK7c+6dT0Fu4SUqXAr9y4Q3d8vUf1VWWb6YutpL4XNe400iQ1g==", 259 | "cpu": [ 260 | "x64" 261 | ], 262 | "dev": true, 263 | "optional": true, 264 | "os": [ 265 | "linux" 266 | ], 267 | "engines": { 268 | "node": ">=12" 269 | } 270 | }, 271 | "node_modules/@esbuild/netbsd-x64": { 272 | "version": "0.18.15", 273 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.15.tgz", 274 | "integrity": "sha512-djST6s+jQiwxMIVQ5rlt24JFIAr4uwUnzceuFL7BQT4CbrRtqBPueS4GjXSiIpmwVri1Icj/9pFRJ7/aScvT+A==", 275 | "cpu": [ 276 | "x64" 277 | ], 278 | "dev": true, 279 | "optional": true, 280 | "os": [ 281 | "netbsd" 282 | ], 283 | "engines": { 284 | "node": ">=12" 285 | } 286 | }, 287 | "node_modules/@esbuild/openbsd-x64": { 288 | "version": "0.18.15", 289 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.15.tgz", 290 | "integrity": "sha512-naeRhUIvhsgeounjkF5mvrNAVMGAm6EJWiabskeE5yOeBbLp7T89tAEw0j5Jm/CZAwyLe3c67zyCWH6fsBLCpw==", 291 | "cpu": [ 292 | "x64" 293 | ], 294 | "dev": true, 295 | "optional": true, 296 | "os": [ 297 | "openbsd" 298 | ], 299 | "engines": { 300 | "node": ">=12" 301 | } 302 | }, 303 | "node_modules/@esbuild/sunos-x64": { 304 | "version": "0.18.15", 305 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.15.tgz", 306 | "integrity": "sha512-qkT2+WxyKbNIKV1AEhI8QiSIgTHMcRctzSaa/I3kVgMS5dl3fOeoqkb7pW76KwxHoriImhx7Mg3TwN/auMDsyQ==", 307 | "cpu": [ 308 | "x64" 309 | ], 310 | "dev": true, 311 | "optional": true, 312 | "os": [ 313 | "sunos" 314 | ], 315 | "engines": { 316 | "node": ">=12" 317 | } 318 | }, 319 | "node_modules/@esbuild/win32-arm64": { 320 | "version": "0.18.15", 321 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.15.tgz", 322 | "integrity": "sha512-HC4/feP+pB2Vb+cMPUjAnFyERs+HJN7E6KaeBlFdBv799MhD+aPJlfi/yk36SED58J9TPwI8MAcVpJgej4ud0A==", 323 | "cpu": [ 324 | "arm64" 325 | ], 326 | "dev": true, 327 | "optional": true, 328 | "os": [ 329 | "win32" 330 | ], 331 | "engines": { 332 | "node": ">=12" 333 | } 334 | }, 335 | "node_modules/@esbuild/win32-ia32": { 336 | "version": "0.18.15", 337 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.15.tgz", 338 | "integrity": "sha512-ovjwoRXI+gf52EVF60u9sSDj7myPixPxqzD5CmkEUmvs+W9Xd0iqISVBQn8xcx4ciIaIVlWCuTbYDOXOnOL44Q==", 339 | "cpu": [ 340 | "ia32" 341 | ], 342 | "dev": true, 343 | "optional": true, 344 | "os": [ 345 | "win32" 346 | ], 347 | "engines": { 348 | "node": ">=12" 349 | } 350 | }, 351 | "node_modules/@esbuild/win32-x64": { 352 | "version": "0.18.15", 353 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.15.tgz", 354 | "integrity": "sha512-imUxH9a3WJARyAvrG7srLyiK73XdX83NXQkjKvQ+7vPh3ZxoLrzvPkQKKw2DwZ+RV2ZB6vBfNHP8XScAmQC3aA==", 355 | "cpu": [ 356 | "x64" 357 | ], 358 | "dev": true, 359 | "optional": true, 360 | "os": [ 361 | "win32" 362 | ], 363 | "engines": { 364 | "node": ">=12" 365 | } 366 | }, 367 | "node_modules/esbuild": { 368 | "version": "0.18.15", 369 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.15.tgz", 370 | "integrity": "sha512-3WOOLhrvuTGPRzQPU6waSDWrDTnQriia72McWcn6UCi43GhCHrXH4S59hKMeez+IITmdUuUyvbU9JIp+t3xlPQ==", 371 | "dev": true, 372 | "hasInstallScript": true, 373 | "bin": { 374 | "esbuild": "bin/esbuild" 375 | }, 376 | "engines": { 377 | "node": ">=12" 378 | }, 379 | "optionalDependencies": { 380 | "@esbuild/android-arm": "0.18.15", 381 | "@esbuild/android-arm64": "0.18.15", 382 | "@esbuild/android-x64": "0.18.15", 383 | "@esbuild/darwin-arm64": "0.18.15", 384 | "@esbuild/darwin-x64": "0.18.15", 385 | "@esbuild/freebsd-arm64": "0.18.15", 386 | "@esbuild/freebsd-x64": "0.18.15", 387 | "@esbuild/linux-arm": "0.18.15", 388 | "@esbuild/linux-arm64": "0.18.15", 389 | "@esbuild/linux-ia32": "0.18.15", 390 | "@esbuild/linux-loong64": "0.18.15", 391 | "@esbuild/linux-mips64el": "0.18.15", 392 | "@esbuild/linux-ppc64": "0.18.15", 393 | "@esbuild/linux-riscv64": "0.18.15", 394 | "@esbuild/linux-s390x": "0.18.15", 395 | "@esbuild/linux-x64": "0.18.15", 396 | "@esbuild/netbsd-x64": "0.18.15", 397 | "@esbuild/openbsd-x64": "0.18.15", 398 | "@esbuild/sunos-x64": "0.18.15", 399 | "@esbuild/win32-arm64": "0.18.15", 400 | "@esbuild/win32-ia32": "0.18.15", 401 | "@esbuild/win32-x64": "0.18.15" 402 | } 403 | }, 404 | "node_modules/fsevents": { 405 | "version": "2.3.2", 406 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 407 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 408 | "dev": true, 409 | "hasInstallScript": true, 410 | "optional": true, 411 | "os": [ 412 | "darwin" 413 | ], 414 | "engines": { 415 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 416 | } 417 | }, 418 | "node_modules/nanoid": { 419 | "version": "3.3.6", 420 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 421 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 422 | "dev": true, 423 | "funding": [ 424 | { 425 | "type": "github", 426 | "url": "https://github.com/sponsors/ai" 427 | } 428 | ], 429 | "bin": { 430 | "nanoid": "bin/nanoid.cjs" 431 | }, 432 | "engines": { 433 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 434 | } 435 | }, 436 | "node_modules/picocolors": { 437 | "version": "1.0.0", 438 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 439 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 440 | "dev": true 441 | }, 442 | "node_modules/postcss": { 443 | "version": "8.4.27", 444 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", 445 | "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", 446 | "dev": true, 447 | "funding": [ 448 | { 449 | "type": "opencollective", 450 | "url": "https://opencollective.com/postcss/" 451 | }, 452 | { 453 | "type": "tidelift", 454 | "url": "https://tidelift.com/funding/github/npm/postcss" 455 | }, 456 | { 457 | "type": "github", 458 | "url": "https://github.com/sponsors/ai" 459 | } 460 | ], 461 | "dependencies": { 462 | "nanoid": "^3.3.6", 463 | "picocolors": "^1.0.0", 464 | "source-map-js": "^1.0.2" 465 | }, 466 | "engines": { 467 | "node": "^10 || ^12 || >=14" 468 | } 469 | }, 470 | "node_modules/rollup": { 471 | "version": "3.26.3", 472 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz", 473 | "integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==", 474 | "dev": true, 475 | "bin": { 476 | "rollup": "dist/bin/rollup" 477 | }, 478 | "engines": { 479 | "node": ">=14.18.0", 480 | "npm": ">=8.0.0" 481 | }, 482 | "optionalDependencies": { 483 | "fsevents": "~2.3.2" 484 | } 485 | }, 486 | "node_modules/source-map-js": { 487 | "version": "1.0.2", 488 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 489 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 490 | "dev": true, 491 | "engines": { 492 | "node": ">=0.10.0" 493 | } 494 | }, 495 | "node_modules/typescript": { 496 | "version": "5.1.6", 497 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", 498 | "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", 499 | "dev": true, 500 | "bin": { 501 | "tsc": "bin/tsc", 502 | "tsserver": "bin/tsserver" 503 | }, 504 | "engines": { 505 | "node": ">=14.17" 506 | } 507 | }, 508 | "node_modules/vite": { 509 | "version": "4.4.6", 510 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.6.tgz", 511 | "integrity": "sha512-EY6Mm8vJ++S3D4tNAckaZfw3JwG3wa794Vt70M6cNJ6NxT87yhq7EC8Rcap3ahyHdo8AhCmV9PTk+vG1HiYn1A==", 512 | "dev": true, 513 | "dependencies": { 514 | "esbuild": "^0.18.10", 515 | "postcss": "^8.4.26", 516 | "rollup": "^3.25.2" 517 | }, 518 | "bin": { 519 | "vite": "bin/vite.js" 520 | }, 521 | "engines": { 522 | "node": "^14.18.0 || >=16.0.0" 523 | }, 524 | "funding": { 525 | "url": "https://github.com/vitejs/vite?sponsor=1" 526 | }, 527 | "optionalDependencies": { 528 | "fsevents": "~2.3.2" 529 | }, 530 | "peerDependencies": { 531 | "@types/node": ">= 14", 532 | "less": "*", 533 | "lightningcss": "^1.21.0", 534 | "sass": "*", 535 | "stylus": "*", 536 | "sugarss": "*", 537 | "terser": "^5.4.0" 538 | }, 539 | "peerDependenciesMeta": { 540 | "@types/node": { 541 | "optional": true 542 | }, 543 | "less": { 544 | "optional": true 545 | }, 546 | "lightningcss": { 547 | "optional": true 548 | }, 549 | "sass": { 550 | "optional": true 551 | }, 552 | "stylus": { 553 | "optional": true 554 | }, 555 | "sugarss": { 556 | "optional": true 557 | }, 558 | "terser": { 559 | "optional": true 560 | } 561 | } 562 | } 563 | }, 564 | "dependencies": { 565 | "@esbuild/android-arm": { 566 | "version": "0.18.15", 567 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.15.tgz", 568 | "integrity": "sha512-wlkQBWb79/jeEEoRmrxt/yhn5T1lU236OCNpnfRzaCJHZ/5gf82uYx1qmADTBWE0AR/v7FiozE1auk2riyQd3w==", 569 | "dev": true, 570 | "optional": true 571 | }, 572 | "@esbuild/android-arm64": { 573 | "version": "0.18.15", 574 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.15.tgz", 575 | "integrity": "sha512-NI/gnWcMl2kXt1HJKOn2H69SYn4YNheKo6NZt1hyfKWdMbaGadxjZIkcj4Gjk/WPxnbFXs9/3HjGHaknCqjrww==", 576 | "dev": true, 577 | "optional": true 578 | }, 579 | "@esbuild/android-x64": { 580 | "version": "0.18.15", 581 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.15.tgz", 582 | "integrity": "sha512-FM9NQamSaEm/IZIhegF76aiLnng1kEsZl2eve/emxDeReVfRuRNmvT28l6hoFD9TsCxpK+i4v8LPpEj74T7yjA==", 583 | "dev": true, 584 | "optional": true 585 | }, 586 | "@esbuild/darwin-arm64": { 587 | "version": "0.18.15", 588 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.15.tgz", 589 | "integrity": "sha512-XmrFwEOYauKte9QjS6hz60FpOCnw4zaPAb7XV7O4lx1r39XjJhTN7ZpXqJh4sN6q60zbP6QwAVVA8N/wUyBH/w==", 590 | "dev": true, 591 | "optional": true 592 | }, 593 | "@esbuild/darwin-x64": { 594 | "version": "0.18.15", 595 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.15.tgz", 596 | "integrity": "sha512-bMqBmpw1e//7Fh5GLetSZaeo9zSC4/CMtrVFdj+bqKPGJuKyfNJ5Nf2m3LknKZTS+Q4oyPiON+v3eaJ59sLB5A==", 597 | "dev": true, 598 | "optional": true 599 | }, 600 | "@esbuild/freebsd-arm64": { 601 | "version": "0.18.15", 602 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.15.tgz", 603 | "integrity": "sha512-LoTK5N3bOmNI9zVLCeTgnk5Rk0WdUTrr9dyDAQGVMrNTh9EAPuNwSTCgaKOKiDpverOa0htPcO9NwslSE5xuLA==", 604 | "dev": true, 605 | "optional": true 606 | }, 607 | "@esbuild/freebsd-x64": { 608 | "version": "0.18.15", 609 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.15.tgz", 610 | "integrity": "sha512-62jX5n30VzgrjAjOk5orYeHFq6sqjvsIj1QesXvn5OZtdt5Gdj0vUNJy9NIpjfdNdqr76jjtzBJKf+h2uzYuTQ==", 611 | "dev": true, 612 | "optional": true 613 | }, 614 | "@esbuild/linux-arm": { 615 | "version": "0.18.15", 616 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.15.tgz", 617 | "integrity": "sha512-dT4URUv6ir45ZkBqhwZwyFV6cH61k8MttIwhThp2BGiVtagYvCToF+Bggyx2VI57RG4Fbt21f9TmXaYx0DeUJg==", 618 | "dev": true, 619 | "optional": true 620 | }, 621 | "@esbuild/linux-arm64": { 622 | "version": "0.18.15", 623 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.15.tgz", 624 | "integrity": "sha512-BWncQeuWDgYv0jTNzJjaNgleduV4tMbQjmk/zpPh/lUdMcNEAxy+jvneDJ6RJkrqloG7tB9S9rCrtfk/kuplsQ==", 625 | "dev": true, 626 | "optional": true 627 | }, 628 | "@esbuild/linux-ia32": { 629 | "version": "0.18.15", 630 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.15.tgz", 631 | "integrity": "sha512-JPXORvgHRHITqfms1dWT/GbEY89u848dC08o0yK3fNskhp0t2TuNUnsrrSgOdH28ceb1hJuwyr8R/1RnyPwocw==", 632 | "dev": true, 633 | "optional": true 634 | }, 635 | "@esbuild/linux-loong64": { 636 | "version": "0.18.15", 637 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.15.tgz", 638 | "integrity": "sha512-kArPI0DopjJCEplsVj/H+2Qgzz7vdFSacHNsgoAKpPS6W/Ndh8Oe24HRDQ5QCu4jHgN6XOtfFfLpRx3TXv/mEg==", 639 | "dev": true, 640 | "optional": true 641 | }, 642 | "@esbuild/linux-mips64el": { 643 | "version": "0.18.15", 644 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.15.tgz", 645 | "integrity": "sha512-b/tmngUfO02E00c1XnNTw/0DmloKjb6XQeqxaYuzGwHe0fHVgx5/D6CWi+XH1DvkszjBUkK9BX7n1ARTOst59w==", 646 | "dev": true, 647 | "optional": true 648 | }, 649 | "@esbuild/linux-ppc64": { 650 | "version": "0.18.15", 651 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.15.tgz", 652 | "integrity": "sha512-KXPY69MWw79QJkyvUYb2ex/OgnN/8N/Aw5UDPlgoRtoEfcBqfeLodPr42UojV3NdkoO4u10NXQdamWm1YEzSKw==", 653 | "dev": true, 654 | "optional": true 655 | }, 656 | "@esbuild/linux-riscv64": { 657 | "version": "0.18.15", 658 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.15.tgz", 659 | "integrity": "sha512-komK3NEAeeGRnvFEjX1SfVg6EmkfIi5aKzevdvJqMydYr9N+pRQK0PGJXk+bhoPZwOUgLO4l99FZmLGk/L1jWg==", 660 | "dev": true, 661 | "optional": true 662 | }, 663 | "@esbuild/linux-s390x": { 664 | "version": "0.18.15", 665 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.15.tgz", 666 | "integrity": "sha512-632T5Ts6gQ2WiMLWRRyeflPAm44u2E/s/TJvn+BP6M5mnHSk93cieaypj3VSMYO2ePTCRqAFXtuYi1yv8uZJNA==", 667 | "dev": true, 668 | "optional": true 669 | }, 670 | "@esbuild/linux-x64": { 671 | "version": "0.18.15", 672 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.15.tgz", 673 | "integrity": "sha512-MsHtX0NgvRHsoOtYkuxyk4Vkmvk3PLRWfA4okK7c+6dT0Fu4SUqXAr9y4Q3d8vUf1VWWb6YutpL4XNe400iQ1g==", 674 | "dev": true, 675 | "optional": true 676 | }, 677 | "@esbuild/netbsd-x64": { 678 | "version": "0.18.15", 679 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.15.tgz", 680 | "integrity": "sha512-djST6s+jQiwxMIVQ5rlt24JFIAr4uwUnzceuFL7BQT4CbrRtqBPueS4GjXSiIpmwVri1Icj/9pFRJ7/aScvT+A==", 681 | "dev": true, 682 | "optional": true 683 | }, 684 | "@esbuild/openbsd-x64": { 685 | "version": "0.18.15", 686 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.15.tgz", 687 | "integrity": "sha512-naeRhUIvhsgeounjkF5mvrNAVMGAm6EJWiabskeE5yOeBbLp7T89tAEw0j5Jm/CZAwyLe3c67zyCWH6fsBLCpw==", 688 | "dev": true, 689 | "optional": true 690 | }, 691 | "@esbuild/sunos-x64": { 692 | "version": "0.18.15", 693 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.15.tgz", 694 | "integrity": "sha512-qkT2+WxyKbNIKV1AEhI8QiSIgTHMcRctzSaa/I3kVgMS5dl3fOeoqkb7pW76KwxHoriImhx7Mg3TwN/auMDsyQ==", 695 | "dev": true, 696 | "optional": true 697 | }, 698 | "@esbuild/win32-arm64": { 699 | "version": "0.18.15", 700 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.15.tgz", 701 | "integrity": "sha512-HC4/feP+pB2Vb+cMPUjAnFyERs+HJN7E6KaeBlFdBv799MhD+aPJlfi/yk36SED58J9TPwI8MAcVpJgej4ud0A==", 702 | "dev": true, 703 | "optional": true 704 | }, 705 | "@esbuild/win32-ia32": { 706 | "version": "0.18.15", 707 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.15.tgz", 708 | "integrity": "sha512-ovjwoRXI+gf52EVF60u9sSDj7myPixPxqzD5CmkEUmvs+W9Xd0iqISVBQn8xcx4ciIaIVlWCuTbYDOXOnOL44Q==", 709 | "dev": true, 710 | "optional": true 711 | }, 712 | "@esbuild/win32-x64": { 713 | "version": "0.18.15", 714 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.15.tgz", 715 | "integrity": "sha512-imUxH9a3WJARyAvrG7srLyiK73XdX83NXQkjKvQ+7vPh3ZxoLrzvPkQKKw2DwZ+RV2ZB6vBfNHP8XScAmQC3aA==", 716 | "dev": true, 717 | "optional": true 718 | }, 719 | "esbuild": { 720 | "version": "0.18.15", 721 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.15.tgz", 722 | "integrity": "sha512-3WOOLhrvuTGPRzQPU6waSDWrDTnQriia72McWcn6UCi43GhCHrXH4S59hKMeez+IITmdUuUyvbU9JIp+t3xlPQ==", 723 | "dev": true, 724 | "requires": { 725 | "@esbuild/android-arm": "0.18.15", 726 | "@esbuild/android-arm64": "0.18.15", 727 | "@esbuild/android-x64": "0.18.15", 728 | "@esbuild/darwin-arm64": "0.18.15", 729 | "@esbuild/darwin-x64": "0.18.15", 730 | "@esbuild/freebsd-arm64": "0.18.15", 731 | "@esbuild/freebsd-x64": "0.18.15", 732 | "@esbuild/linux-arm": "0.18.15", 733 | "@esbuild/linux-arm64": "0.18.15", 734 | "@esbuild/linux-ia32": "0.18.15", 735 | "@esbuild/linux-loong64": "0.18.15", 736 | "@esbuild/linux-mips64el": "0.18.15", 737 | "@esbuild/linux-ppc64": "0.18.15", 738 | "@esbuild/linux-riscv64": "0.18.15", 739 | "@esbuild/linux-s390x": "0.18.15", 740 | "@esbuild/linux-x64": "0.18.15", 741 | "@esbuild/netbsd-x64": "0.18.15", 742 | "@esbuild/openbsd-x64": "0.18.15", 743 | "@esbuild/sunos-x64": "0.18.15", 744 | "@esbuild/win32-arm64": "0.18.15", 745 | "@esbuild/win32-ia32": "0.18.15", 746 | "@esbuild/win32-x64": "0.18.15" 747 | } 748 | }, 749 | "fsevents": { 750 | "version": "2.3.2", 751 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 752 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 753 | "dev": true, 754 | "optional": true 755 | }, 756 | "nanoid": { 757 | "version": "3.3.6", 758 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 759 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 760 | "dev": true 761 | }, 762 | "picocolors": { 763 | "version": "1.0.0", 764 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 765 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 766 | "dev": true 767 | }, 768 | "postcss": { 769 | "version": "8.4.27", 770 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", 771 | "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", 772 | "dev": true, 773 | "requires": { 774 | "nanoid": "^3.3.6", 775 | "picocolors": "^1.0.0", 776 | "source-map-js": "^1.0.2" 777 | } 778 | }, 779 | "rollup": { 780 | "version": "3.26.3", 781 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.3.tgz", 782 | "integrity": "sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ==", 783 | "dev": true, 784 | "requires": { 785 | "fsevents": "~2.3.2" 786 | } 787 | }, 788 | "source-map-js": { 789 | "version": "1.0.2", 790 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 791 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 792 | "dev": true 793 | }, 794 | "typescript": { 795 | "version": "5.1.6", 796 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", 797 | "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", 798 | "dev": true 799 | }, 800 | "vite": { 801 | "version": "4.4.6", 802 | "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.6.tgz", 803 | "integrity": "sha512-EY6Mm8vJ++S3D4tNAckaZfw3JwG3wa794Vt70M6cNJ6NxT87yhq7EC8Rcap3ahyHdo8AhCmV9PTk+vG1HiYn1A==", 804 | "dev": true, 805 | "requires": { 806 | "esbuild": "^0.18.10", 807 | "fsevents": "~2.3.2", 808 | "postcss": "^8.4.26", 809 | "rollup": "^3.25.2" 810 | } 811 | } 812 | } 813 | } 814 | -------------------------------------------------------------------------------- /typewriter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typewriter", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "typescript": "^5.0.2", 13 | "vite": "^4.4.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /typewriter/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /typewriter/src/TypeWriter.ts: -------------------------------------------------------------------------------- 1 | type QueueItem = () => Promise; // a function returing promise void 2 | 3 | export default class TypeWriter { 4 | private element: HTMLElement; 5 | private loop: boolean; 6 | private typingSpeed: number; 7 | private deletingSpeed: number; 8 | private queue: QueueItem[] = []; 9 | constructor( 10 | public parent: HTMLElement, 11 | { loop = false, typingSpeed = 50, deletingSpeed = 50 } = {} 12 | ) { 13 | this.element = document.createElement("div"); 14 | this.element.classList.add("whitespace"); 15 | parent.appendChild(this.element); 16 | this.loop = loop; 17 | this.typingSpeed = typingSpeed; 18 | this.deletingSpeed = deletingSpeed; 19 | } 20 | 21 | typeString(string: String): TypeWriter { 22 | this.addToQueue((resolve) => { 23 | // add string to screen 24 | let i = 0; 25 | const interval = setInterval(() => { 26 | this.element.append(string[i] as unknown as Node); 27 | i++; 28 | if (i >= string.length) { 29 | clearInterval(interval); 30 | resolve(); 31 | } 32 | }, this.typingSpeed); 33 | }); 34 | return this; 35 | } 36 | 37 | deleteChars(number: number): TypeWriter { 38 | this.addToQueue((resolve) => { 39 | // add string to screen 40 | let i = 0; 41 | const interval = setInterval(() => { 42 | this.element.textContent = this.element.textContent?.substring( 43 | 0, 44 | this.element.textContent.length - 1 45 | ) as string; // we can also use innerText if we dont want type assertions 46 | i++; 47 | if (i >= number) { 48 | clearInterval(interval); 49 | resolve(); 50 | } 51 | }, this.deletingSpeed); 52 | }); 53 | return this; 54 | } 55 | 56 | deleteAll(deleteSpeed = this.deletingSpeed): TypeWriter { 57 | this.addToQueue((resolve) => { 58 | // add string to screen 59 | const interval = setInterval(() => { 60 | this.element.textContent = this.element.textContent?.substring( 61 | 0, 62 | this.element.textContent.length - 1 63 | ) as string; // we can also use innerText if we dont want type assertions 64 | if (this.element.textContent.length === 0) { 65 | clearInterval(interval); 66 | resolve(); 67 | } 68 | }, deleteSpeed); 69 | }); 70 | return this; 71 | } 72 | 73 | pauseFor(duration: number): TypeWriter { 74 | this.addToQueue((resolve) => { 75 | setTimeout(resolve, duration); 76 | }); 77 | return this; 78 | } 79 | 80 | async start(): Promise { 81 | for (const cb of this.queue) { 82 | await cb(); 83 | if (this.loop) this.queue.push(cb); 84 | } 85 | return this; 86 | } 87 | 88 | // cb should be a function which takes resolve and returns void 89 | private addToQueue(cb: (resolve: () => void) => void) { 90 | this.queue.push(() => { 91 | return new Promise(cb); 92 | }); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /typewriter/src/main.ts: -------------------------------------------------------------------------------- 1 | import TypeWriter from "./TypeWriter"; 2 | import "./style.css"; 3 | 4 | const typeWriter = new TypeWriter(document.body, { 5 | loop: false, 6 | }); 7 | 8 | typeWriter 9 | .typeString("Hey Hi") 10 | .pauseFor(1000) 11 | .typeString("\n\nHeello") 12 | .deleteChars(10) 13 | .pauseFor(150) 14 | .typeString("\n\nHey HI") 15 | .pauseFor(1000) 16 | .deleteAll(10) 17 | .typeString("Bye Bye") 18 | .start() -------------------------------------------------------------------------------- /typewriter/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | .whitespace{ 18 | white-space: pre-wrap; 19 | } -------------------------------------------------------------------------------- /typewriter/src/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /typewriter/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /typewriter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | --------------------------------------------------------------------------------